Error executing template "Designs/Swift/QueryPublisher/Essve_SecondaryUsers.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_48652dbae2a3428eab4ecc31bc558e70.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.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
2 @using System.Linq
3 @using Dynamicweb
4 @using Dynamicweb.Security.UserManagement
5
6 @{
7 string contentPadding = Pageview.CurrentParagraph.Item["ContentPadding"] != null ? Pageview.CurrentParagraph.Item["ContentPadding"].ToString() : string.Empty;
8 contentPadding = contentPadding == "none" ? "px-0" : contentPadding;
9 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding;
10 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding;
11 var themeRaw = Pageview.CurrentParagraph.Item["Theme"]?.ToString();
12 string theme = !string.IsNullOrEmpty(themeRaw) ? " h-100 theme " + themeRaw.Replace(" ", "").Trim().ToLower() : string.Empty;
13 string searchTerm = string.Empty;
14 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["userquery"]))
15 {
16 searchTerm = Dynamicweb.Context.Current.Request["userquery"];
17
18 }
19 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/";
20
21 var queryItems = GetLoop("QueryResultItem");
22
23 //bool nowImpersonating = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("NowImpersonating")) ? Convert.ToBoolean(Dynamicweb.Context.Current.Request.QueryString.Get("NowImpersonating")) : false;
24 bool nowImpersonating = Dynamicweb.Security.UserManagement.User.GetCurrentSecondaryUser() != null;
25 bool isStandardSwiftTemplates = Pageview.AreaSettings.GetString("AddressFieldsBasedOn", "swift") == "swift";
26 UserGroupService service = new Dynamicweb.Security.UserManagement.UserGroupService();
27 UserGroup canImpersonateGroup = service.GetGroups().FirstOrDefault(x => x.Name == "UsersPortal_CanImpersonate");
28 bool canSeePage = nowImpersonating || (canImpersonateGroup != null && Pageview.User.GetGroups().Contains(canImpersonateGroup));
29 }
30
31 @if (canSeePage)
32 {
33 <div class="@(contentPadding)@(theme)">
34 <header class="">
35 <div class="grid grid-1 grid-sm-2 align-items-center">
36 @if (!string.IsNullOrEmpty(searchTerm))
37 {
38 <div class="d-flex align-items-baseline justify-content-between gap-3 mb-3">
39 <h1 class="h2">@Translate("You have searched for") "@searchTerm"</h1>
40 </div>
41 }
42 else
43 {
44 <h1 class="h2 mb-3">@Translate("Manage customer")</h1>
45 }
46 <div class="position-relative type-ahead-dropdown">
47 <form method="get" class="suggest-form">
48 <div class="d-flex align-items-center justify-content-end">
49 <label for="userQuery_@Pageview.CurrentParagraph.ID" class="visually-hidden">@Translate("Search for customer")</label>
50
51 <div class="d-flex align-items-center flex-fill" style="position: relative;">
52 <span class="position-absolute icon-2 reset-search px-3">
53 @ReadFile(iconPath + "search.svg")
54 </span>
55 <input id="userQuery_@Pageview.CurrentParagraph.ID"
56 type="search"
57 class="form-control form-control-sm rounded-pill type-ahead-field py-2 ps-5 pe-5"
58 placeholder="@Translate("Search for customer")"
59 aria-label="@Translate("Search for customer")"
60 aria-describedby="userQuery_@Pageview.CurrentParagraph.ID"
61 name="userquery"
62 value="@searchTerm"
63 data-original="@searchTerm">
64
65 <button type="button"
66 onclick="var f = document.getElementById('userQuery_@Pageview.CurrentParagraph.ID'); f.value = ''; f.focus(); f.closest('form').submit();"
67 class="btn position-absolute end-0 icon-2 reset-search"
68 aria-label="@Translate("Clear search field")"
69 style="opacity: 0; visibility: hidden; right: 0;">
70 @ReadFile(iconPath + "x.svg")
71 </button>
72 </div>
73
74 <button type="submit" class="ms-2 btn btn-secondary" aria-label="@Translate("Search")">
75 @Translate("Search")
76 </button>
77 </div>
78 </form>
79 </div>
80 </div>
81 </header>
82
83
84 @if (queryItems.Count() != 0)
85 {
86
87 @* Bootstrap only support horizontally scrolled tables. Thus, we need to have separate designs for large and small screens. *@
88
89 <table class="table d-none d-lg-table table-striped table-hover table-linked align-middle mb-0" border="1">
90 <thead>
91 <tr>
92 <th>
93 @Translate("Customer no")
94 </th>
95 <th>
96 @Translate("SignInAsCustomer:Company", "Company")
97 </th>
98 <th>
99 @Translate("SignInAsCustomer:Name","Customer")
100 </th>
101 <th>
102 @Translate("Email")
103 </th>
104 <th style="min-width: 155px;" aria-hidden="true">
105 <span>
106
107 </span>
108 </th>
109 </tr>
110 </thead>
111 <tbody class="border-top-0">
112 @foreach (var result in queryItems)
113 {
114 string UserLink = $"/Default.aspx?ID={Pageview.Page.ID}&DWExtranetSecondaryUserSelector={result.GetInteger("UserID")}&NowImpersonating=True";
115 bool hasAddressFormat = Dynamicweb.Ecommerce.International.Country.GetDisplayAddress(result.GetString("CountryCode")).Any();
116
117 <tr class="position-relative">
118 <td>
119 @if (!string.IsNullOrWhiteSpace(result.GetString("CustomerNumber")))
120 {
121 <a href="@UserLink" class="d-block text-decoration-none">
122 @result.GetString("CustomerNumber")
123 </a>
124 }
125 </td>
126 <td>
127 @if (!string.IsNullOrWhiteSpace(result.GetString("Company")))
128 {
129 <a href="@UserLink" class="d-block text-decoration-none">
130 @result.GetString("Company")
131 </a>
132 }
133 </td>
134 <td>
135 @if (!string.IsNullOrWhiteSpace(result.GetString("FirstName")) || !string.IsNullOrWhiteSpace(result.GetString("LastName")))
136 {
137 <a href="@UserLink" class="d-block text-decoration-none" tabindex="-1">
138 @result.GetString("FirstName") @result.GetString("LastName")
139 </a>
140 }
141 else if (!string.IsNullOrWhiteSpace(result.GetString("Name")))
142 {
143 <a href="@UserLink" class="d-block text-decoration-none" tabindex="-1">
144 @result.GetString("Name")
145 </a>
146 }
147 </td>
148 <td>
149 @if (!string.IsNullOrWhiteSpace(result.GetString("UserEmail")))
150 {
151 <a href="@UserLink" class="d-block text-decoration-none" tabindex="-1">
152 @result.GetString("UserEmail")
153 </a>
154 }
155 </td>
156 <td class="text-end ">
157 <a href="@UserLink" class="d-block text-decoration-none" tabindex="-1">
158 <span class="btn btn-sm btn-secondary">
159 @Translate("Manage customer")
160 </span>
161 </a>
162 </td>
163 </tr>
164 }
165 </tbody>
166 </table>
167
168 @* Bootstrap only support horizontally scrolled tables. Thus, we need to have separate designs for large and small screens. *@
169
170 <table class="table d-table d-lg-none table-borderless table-clean align-top mb-0">
171 @foreach (var result in queryItems)
172 {
173 string UserLink = $"/Default.aspx?ID={Pageview.Page.ID}&DWExtranetSecondaryUserSelector={result.GetInteger("UserID")}&NowImpersonating=True";
174
175 <tbody class="border-bottom">
176 <tr>
177 <th class="fs-8">
178 @Translate("Customer No")
179 </th>
180 <td class="text-end">
181 @if (!string.IsNullOrWhiteSpace(result.GetString("CustomerNumber")))
182 {
183 @result.GetString("CustomerNumber")
184 }
185 </td>
186 </tr>
187 <tr>
188 <th class="fs-8">
189 @Translate("SignInAsCustomer:Company", "Company")
190 </th>
191 <td class="text-end">
192 @if (!string.IsNullOrWhiteSpace(result.GetString("Company")))
193 {
194 @result.GetString("Company")
195 }
196 </td>
197 </tr>
198 <tr>
199 <th class="fs-8">
200 @Translate("SignInAsCustomer:Name","Customer")
201 </th>
202 <td class="text-end">
203 @if (!string.IsNullOrWhiteSpace(result.GetString("FirstName")) || !string.IsNullOrWhiteSpace(result.GetString("LastName")))
204 {
205 <span>@result.GetString("FirstName") @result.GetString("LastName")</span>
206 }
207 else if (!string.IsNullOrWhiteSpace(result.GetString("Name")))
208 {
209 @result.GetString("Name")
210 }
211 </td>
212 </tr>
213 <tr>
214 <th class="fs-8">
215 @Translate("Email")
216 </th>
217 <td class="text-end text-break">
218 @if (!string.IsNullOrWhiteSpace(result.GetString("UserEmail")))
219 {
220 @result.GetString("UserEmail")
221 }
222 </td>
223 </tr>
224 <tr>
225 <th class="fs-8">
226 @Translate("Address")
227 </th>
228 <td class="text-end">
229 @if (isStandardSwiftTemplates)
230 {
231 if (!string.IsNullOrWhiteSpace(result.GetString("Address")))
232 {
233 <text>
234 @result.GetString("Address"),
235 </text>
236 }
237 if (!string.IsNullOrEmpty(result.GetString("Address2")))
238 {
239 @result.GetString("Address2")
240 ;
241 }
242 if (!string.IsNullOrWhiteSpace(result.GetString("Zip")))
243 {
244 @result.GetString("Zip")
245 }
246 if (!string.IsNullOrWhiteSpace(result.GetString("City")))
247 {
248 @($", {result.GetString("City")}")
249 }
250 if (!string.IsNullOrEmpty(result.GetString("State")))
251 {
252 var countryCode = !string.IsNullOrEmpty(result.GetString("CountryCode")) ? result.GetString("CountryCode") : Pageview.Area.EcomCountryCode;
253 string stateName = Dynamicweb.Ecommerce.Services.Countries.GetRegion(countryCode, result.GetString("State"))?.GetName(Dynamicweb.Ecommerce.Common.Context.LanguageID) ?? string.Empty;
254
255 @($", {stateName}")
256 }
257 if (!string.IsNullOrEmpty(result.GetString("CountryCode")))
258 {
259 var countryCode = !string.IsNullOrEmpty(result.GetString("CountryCode")) ? result.GetString("CountryCode") : Pageview.Area.EcomCountryCode;
260 string countryName = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode)?.GetName(Dynamicweb.Ecommerce.Common.Context.LanguageID) ?? string.Empty;
261
262 @($", {countryName.ToUpper()}")
263 }
264 }
265 else
266 {
267 <text>
268 @RenderUserItemAddressInline(result)
269 </text>
270 }
271 </td>
272 </tr>
273 <tr>
274 <td colspan="2">
275 <a href="@UserLink" class="d-block text-decoration-none swift_manage-customer-button">
276 <div class="d-grid">
277 <span class="btn btn-sm btn-secondary">
278 @Translate("Manage customer")
279 </span>
280 </div>
281 </a>
282 </td>
283 </tr>
284 </tbody>
285 }
286 </table>
287 var pageLoopItem = GetLoop("DwPaging.LoopPageGroup");
288 int pageCount = GetInteger("DwPaging.PageCount"),
289 currentPage = GetInteger("DwPaging.CurrentPage"),
290 prevPage = GetInteger("DwPaging.PreviousPageNumber"),
291 nextPage = GetInteger("DwPaging.NextPageNumber"),
292 itemsToLoad = 10,
293 pageSize = GetInteger("DwPaging.PageSize"),
294 totalItems = GetInteger("DwPaging.TotalItems"),
295 loadMore = pageSize + itemsToLoad,
296 firstPage = 1,
297 lastPage = pageCount;
298
299 if (GetBoolean("DwPaging.Pageable") == true)
300 {
301 string prevDisabled = currentPage == 1 ? "disabled" : "";
302 string nextDisabled = currentPage == pageCount ? "disabled" : "";
303 <div class="d-none d-lg-block">
304 <form id="pagination_@Pageview.CurrentParagraph.ID">
305 <div class="p-3 mt-3">
306 <ul class="pagination m-0">
307 <li class="page-item @(prevDisabled)">
308 <button type="submit" class="page-link" onclick="paginationSubmit(event, '@firstPage')">
309 <span class="icon-2">
310 @ReadFile(iconPath + "chevrons-left.svg")
311 </span>
312 </button>
313 </li>
314 <li class="page-item @(prevDisabled)">
315 <a class="page-link" href="@prevPage" onclick="paginationSubmit(event, '@prevPage')">
316 <span class="icon-2">
317 @ReadFile(iconPath + "chevron-left.svg")
318 </span>
319 </a>
320 </li>
321 @foreach (var pages in pageLoopItem)
322 {
323 var css = pages.GetBoolean("PageGroup.ActivePage") ? "page-item active" : "page-item";
324
325 <li class="@css">
326 <a href="@pages.GetString("PageGroup.PageLink")" class="page-link" onclick="paginationSubmit(event, '@pages.GetInteger("PageGroup.PageNumber")')">@pages.GetInteger("PageGroup.PageNumber")</a>
327 </li>
328 }
329 <li class="page-item @(nextDisabled)">
330 <a class="page-link" href="@nextPage" onclick="paginationSubmit(event, '@nextPage')">
331 <span class="icon-2">
332 @ReadFile(iconPath + "chevron-right.svg")
333 </span>
334 </a>
335 </li>
336 <li class="page-item @(nextDisabled)">
337 <button type="submit" class="page-link" onclick="paginationSubmit(event, '@lastPage')">
338 <span class="icon-2">
339 @ReadFile(iconPath + "chevrons-right.svg")
340 </span>
341 </button>
342 </li>
343 </ul>
344 </div>
345 <input type="hidden" name="pagenum" id="pageNumber_@Pageview.CurrentParagraph.ID">
346 </form>
347 <script>
348 paginationSubmit = function (event, pageNumber) {
349 event.preventDefault();
350 document.querySelector('#pageNumber_@Pageview.CurrentParagraph.ID').value = pageNumber;
351 swift.PageUpdater.Update(document.querySelector("#pagination_@Pageview.CurrentParagraph.ID"));
352 }
353 </script>
354 </div>
355 <div class="d-block d-lg-none position-sticky bottom-0">
356 <form id="loadMore_@Pageview.CurrentParagraph.ID">
357 <input type="hidden" name="pagesize" id="pageSize_@Pageview.CurrentParagraph.ID">
358 <div class="gap-2 grid grid-1 mx-3 pb-2 theme">
359 <button class="btn btn-primary w-100" type="submit" onclick="loadMore(event, '@loadMore')">
360 @Translate("Show more")
361 </button>
362 <div class="text-center fs-8">Showing @pageSize/@totalItems</div>
363 </div>
364 </form>
365 <script>
366 loadMore = function (event, pageSize) {
367 event.preventDefault();
368 document.querySelector('#pageSize_@Pageview.CurrentParagraph.ID').value = pageSize;
369 swift.PageUpdater.Update(document.querySelector("#loadMore_@Pageview.CurrentParagraph.ID"));
370 }
371 </script>
372 </div>
373 }
374 }
375 else
376 {
377 if (!string.IsNullOrEmpty(searchTerm))
378 {
379 <div class="alert alert-info text-center mt-3" role="alert">
380 @Translate("Your search ") <strong> "@searchTerm" </strong>@Translate("did not return any customers that match your search")
381 </div>
382 }
383 else
384 {
385 <div class="alert alert-info text-center mt-3" role="alert">
386 @Translate("You have no customer you can sign in as")
387 </div>
388 }
389 }
390
391 <script>
392 function goToPage(page) {
393 let url = new URL(document.location.href);
394 url.searchParams.set('PageNum', page);
395 document.location.href = url;
396 }
397 </script>
398
399 @if (nowImpersonating)
400 {
401 <div class="position-fixed bottom-0 end-0 p-3">
402 <div id="signInToast" class="toast align-items-center w-auto show theme light" role="alert" aria-live="assertive" aria-atomic="true">
403 <div class="d-flex">
404 <div class="toast-body p-3 fs-6">
405 <span>
406 @Translate("You are now signed in as a customer")
407 </span>
408 @if (Pageview.User != null)
409 {
410 @if (!string.IsNullOrEmpty(Pageview.User.FirstName))
411 {
412 <span class="fw-bold">@Pageview.User.FirstName @Pageview.User.LastName</span>
413 }
414 else
415 {
416 <span class="fw-bold">@Pageview.User.Name</span>
417 }
418 }
419 </div>
420 <button type="button" class="btn h-100 icon-3 m-auto" data-bs-dismiss="toast" aria-label="@Translate("Close toast")">@ReadFile(iconPath + "x.svg")</button>
421 </div>
422 </div>
423 </div>
424
425 <script>
426 document.addEventListener("DOMContentLoaded", function (event) {
427 var signInToast = document.querySelector('#signInToast')
428 var showSignInToast = new bootstrap.Toast(signInToast)
429 showSignInToast.show()
430 });
431 </script>
432 }
433
434 </div>
435 }
436 else
437 {
438 <div><p>@Translate("No permission to see this page")</p></div>
439 }
440
441 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>
442 @using System.Linq
443 @using System.Text
444 @using System.Text.RegularExpressions
445 @using Dynamicweb.Ecommerce.International
446
447 @functions {
448 public string RenderUserItemAddressInline(LoopItem address)
449 {
450 var result = new StringBuilder();
451
452 List<List<string>> addressFormat = Dynamicweb.Ecommerce.International.Country.GetDisplayAddress(address.GetString("CountryCode"));
453 string regionCode = address.GetString("State");
454 string regionName = GetRegionName(address.GetString("CountryCode"), regionCode);
455 string countryName = Dynamicweb.Ecommerce.Services.Countries.GetCountry(address.GetString("CountryCode"))?.GetName(Dynamicweb.Ecommerce.Common.Context.LanguageID) ?? string.Empty;
456
457 foreach (List<string> addressLine in addressFormat)
458 {
459 for (var i = 0; i < addressLine.Count; i++)
460 {
461 addressLine[i] = Regex.Replace(addressLine[i], "{name}", string.Empty, RegexOptions.IgnoreCase); // his needs tobe empty because there is no 'Name' property on the user Address object, but the format from the UI will/could have it
462 addressLine[i] = Regex.Replace(addressLine[i], "{firstName}", string.Empty, RegexOptions.IgnoreCase); // This needs tobe empty because there is no 'First Name' property on the user Address object, but the format from the UI will/could have it
463 addressLine[i] = Regex.Replace(addressLine[i], "{lastName}", string.Empty, RegexOptions.IgnoreCase); // This needs tobe empty because there is no 'Last Name' property on the user Address object, but the format from the UI will/could have it
464 addressLine[i] = Regex.Replace(addressLine[i], "{company}", address.GetString("Company"), RegexOptions.IgnoreCase);
465 addressLine[i] = Regex.Replace(addressLine[i], "{address}", address.GetString("Address"), RegexOptions.IgnoreCase);
466 addressLine[i] = Regex.Replace(addressLine[i], "{address1}", address.GetString("Address"), RegexOptions.IgnoreCase);
467 addressLine[i] = Regex.Replace(addressLine[i], "{address2}", address.GetString("Address2"), RegexOptions.IgnoreCase);
468 addressLine[i] = Regex.Replace(addressLine[i], "{zip}", address.GetString("Zip"), RegexOptions.IgnoreCase);
469 addressLine[i] = Regex.Replace(addressLine[i], "{city}", address.GetString("City"), RegexOptions.IgnoreCase);
470 addressLine[i] = Regex.Replace(addressLine[i], "{regionCode}", regionCode, RegexOptions.IgnoreCase);
471 addressLine[i] = Regex.Replace(addressLine[i], "{region}", regionName, RegexOptions.IgnoreCase);
472 addressLine[i] = Regex.Replace(addressLine[i], "{countryCode}", address.GetString("CountryCode"), RegexOptions.IgnoreCase);
473 addressLine[i] = Regex.Replace(addressLine[i], "{country}", countryName, RegexOptions.IgnoreCase);
474
475 // Remove any bad placeholders the user may have submitted
476 addressLine[i] = Regex.Replace(addressLine[i], "{phone}", string.Empty, RegexOptions.IgnoreCase);
477 addressLine[i] = Regex.Replace(addressLine[i], "{email}", string.Empty, RegexOptions.IgnoreCase);
478 }
479
480 var completeLine = string.Join(string.Empty, addressLine.ToArray());
481 if (!string.IsNullOrWhiteSpace(completeLine))
482 {
483 result.Append($"<span>{completeLine}</span>");
484 }
485 }
486
487 return result.ToString();
488 }
489
490 public string GetRegionName(string countryCode, string regionValue)
491 {
492 CountryCollection allCountryRegions = Dynamicweb.Ecommerce.Services.Countries.GetRegions(countryCode);
493 Country matchedRegion = allCountryRegions.FirstOrDefault(r => r.RegionCode == regionValue || r.GetName(Dynamicweb.Ecommerce.Common.Context.LanguageID) == regionValue);
494
495 if (matchedRegion == null) return regionValue;
496
497 return matchedRegion.GetName(Dynamicweb.Ecommerce.Common.Context.LanguageID);
498 }
499 }
500
501