Komponent editor til: With Stock Locations

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
By clicking 'Accept All' you consent that we may collect information about you for various purposes, including: Statistics and Marketing