Error executing template "Designs/Swift/Paragraph/Swift_ProductStockLocations.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at Dynamicweb.Ecommerce.DynamicwebLiveIntegration_FJ.ProductViewModelExtensions.GetStockList(ProductViewModel productViewModel)
at CompiledRazorTemplates.Dynamic.RazorEngine_002715bdb76b43c991a76c1bf5b95b44.ExecuteAsync()
at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
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 Dynamicweb.Ecommerce.ProductCatalog
3
4 @{
5 ProductViewModel product = null;
6 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
7 {
8 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
9 }
10 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode)
11 {
12 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
13 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
14
15 if (productList?.Products is object)
16 {
17 product = productList.Products[0];
18 }
19 }
20 var stockList=Dynamicweb.Ecommerce.DynamicwebLiveIntegration_FJ.ProductViewModelExtensions.GetStockList(product);
21 }
22
23 @if (product is object && product.ProductType == Dynamicweb.Ecommerce.Products.ProductType.Stock)
24 {
25 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", "");
26 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign;
27 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign;
28
29 string modalId = $"stockLocationModal_{Model.ID}_{product.Id}";
30 modalId += !string.IsNullOrEmpty(product.VariantId) ? $"_{product.VariantId}" : "";
31 int inStockShopsCount = 0;
32
33 foreach (var unit in product.StockUnits)
34 {
35 if (unit.StockLevel > 0)
36 {
37 inStockShopsCount++;
38 }
39 }
40 <style>
41 .div-table {
42 display: table;
43 margin: 0 auto;
44 position: relative;
45 width: auto;
46 background-color: #eee;
47 border: 1px solid #666666;
48 border-spacing: 5px; /* cellspacing:poor IE support for this */
49 }
50
51 .div-table-row {
52 display: table-row;
53 width: auto;
54 clear: both;
55 }
56
57 .div-table-col {
58 float: left; /* fix for buggy browsers */
59 display: table-column;
60 width: 170px;
61 background-color: #ccc;
62 }
63 </style>
64 <div class="@horizontalAlign d-flex gap-1 item_@Model.Item.SystemName.ToLower()">
65
66
67 <div class="div-table">
68 <div class="div-table-row">
69 <div class="div-table-col">Location</div>
70 <div class="div-table-col">Available Stock</div>
71 </div>
72 @foreach (var stock in stockList)
73 {
74 <div class="div-table-row">
75 <div class="div-table-col">@stock.StockLocationName</div>
76 <div class="div-table-col">@stock.StockLevel</div>
77 </div>
78 }
79
80 </div>
81
82
83
84
85 @* @if (inStockShopsCount > 0)
86 {
87 string inStockText = $"{Translate("In stock in")}";
88 string inStockShopsText = $"{inStockShopsCount} {Translate("shops")}";
89
90 <span>
91 @inStockText
92 </span>
93
94 <button type="button" class="btn btn-link p-0" data-bs-toggle="modal" data-bs-target="#@modalId">
95 @inStockShopsText
96 </button>
97 }
98 else
99 {
100 <span>@Translate("Not currently in stock in any shops")</span>
101 } *@
102 </div>
103
104 @* <div class="modal fade js-stock-locations-modal" id="@modalId" tabindex="-1" aria-labelledby="@(modalId)Label" aria-hidden="true">
105 <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
106 <div class="modal-content theme light">
107 <div class="modal-header">
108 <h3 class="modal-title h5" id="@(modalId)Label">@Translate("Stock information")</h3>
109 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
110 </div>
111 <div class="modal-body p-0">
112 <div class="w-100 p-3">
113 <div class="mb-3">
114 <input type="text" class="form-control js-search-field" placeholder="@Translate("Search")" onkeyup="FilterStockLocations(this)">
115 </div>
116 <div class="form-check">
117 <input class="form-check-input js-show-stock-toggle" type="checkbox" value="" id="inStock_@(product.Id)_@(product.VariantId.Replace(".", "_"))_@Model.ID" checked onclick="ToggleShowStockLocations(this)">
118 <label class="form-check-label" for="inStock_@(product.Id)_@(product.VariantId.Replace(".", "_"))_@Model.ID">
119 @Translate("Show only shops, where products are on stock")
120 </label>
121 </div>
122 </div>
123 <ul class="list-group">
124 @foreach (var unit in product.StockUnits.OrderBy(s => s.StockLocationName))
125 {
126 string stockLocationName = unit.StockLocationName;
127 stockLocationName += unit.StockLocationAddress != null ? $" - {unit.StockLocationAddress.Address}, {unit.StockLocationAddress.Zip} {unit.StockLocationAddress.City}" : "";
128 bool inStock = unit.StockLevel > 0;
129 string hideNotInStockLocations = !inStock ? "d-none" : "";
130
131 <li class="list-group-item js-location @hideNotInStockLocations" data-in-stock="@inStock" data-filter-text="@stockLocationName.ToLower()">
132 <div class="fs-8 fw-bold">@stockLocationName</div>
133
134 @if (unit.StockLevel > 0)
135 {
136 <div class="fs-8 fw-bold text-success">@Translate("In stock"): @unit.StockLevel</div>
137 }
138 else
139 {
140 <div class="fs-8 fw-bold text-danger">@Translate("Out of stock")</div>
141 }
142 </li>
143 }
144 </ul>
145 </div>
146 <div class="modal-footer">
147 <button type="button" class="btn btn-sm btn-secondary" data-bs-toggle="modal" data-bs-target="#@modalId">
148 @Translate("Close")
149 </button>
150 </div>
151 </div>
152 </div>
153 </div> *@
154
155 @* <script>
156 ToggleShowStockLocations = function (toggleElement) {
157 const stockLocationsModal = toggleElement.closest('.js-stock-locations-modal');
158 const stockLocations = stockLocationsModal.querySelectorAll('.js-location');
159
160 const searchField = stockLocationsModal.querySelector('.js-search-field');
161
162 stockLocations.forEach((location) => {
163 if (location.getAttribute('data-filter-text').includes(searchField.value.toLowerCase())) {
164 if (location.getAttribute('data-in-stock') == 'False') {
165 location.classList.toggle('d-none');
166 }
167 }
168 });
169 }
170
171 FilterStockLocations = function (searchField) {
172 const stockLocationsModal = searchField.closest('.js-stock-locations-modal');
173 const stockLocations = stockLocationsModal.querySelectorAll('.js-location');
174
175 const showStockToggler = stockLocationsModal.querySelector('.js-show-stock-toggle').checked;
176
177 stockLocations.forEach((location) => {
178 if (location.getAttribute('data-in-stock') == 'True' || showStockToggler == false) {
179 if (!location.getAttribute('data-filter-text').includes(searchField.value.toLowerCase())) {
180 location.classList.add('d-none');
181 } else {
182 location.classList.remove('d-none');
183 }
184 }
185 });
186 }
187 </script> *@
188 }
189 else if (Pageview.IsVisualEditorMode)
190 {
191 <div class="alert alert-info">@Translate("No products available")</div>
192 }
193