Extra Training Day

Error executing template "Designs/Swift/Paragraph/COMM_AccordionTabs.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_cdef535fac93440ebba95592f806505f.Execute() in C:\inetpub\wwwroot\directions2023_dev\Files\Templates\Designs\Swift\Paragraph\COMM_AccordionTabs.cshtml:line 5
   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 Dynamicweb.Frontend 3 4 @{ 5 string title = Model.Item.GetString("Title"); 6 var accordionItems = Model.Item?.GetItems("Accordion_Items") ?? Enumerable.Empty<Dynamicweb.Frontend.ItemViewModel>().ToList(); 7 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 8 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 9 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 10 contentPadding = contentPadding == "small" ? "p-3 p-md-3" : contentPadding; 11 contentPadding = contentPadding == "large" ? "p-5 p-md-5" : contentPadding; 12 string displayType = Model.Item.GetRawValueString("Type", "accordion"); 13 14 @* START CUSTOM CODE *@ 15 string shadowCssClass = Model.Item.GetBoolean("AccordionItemShadow") ? "shadow" : string.Empty; 16 string roundedBorderClass = Model.Item.GetBoolean("AccordionItemRoundedBorders") ? "borders-rounded" : string.Empty; 17 string accordionItemSpacing = Model.Item.GetRawValueString("AccordionItemSpacing", ""); 18 accordionItemSpacing = accordionItemSpacing == "none" ? "p-0" : accordionItemSpacing; 19 accordionItemSpacing = accordionItemSpacing == "small" ? "m-3" : accordionItemSpacing; 20 accordionItemSpacing = accordionItemSpacing == "large" ? "m-5" : accordionItemSpacing; 21 @* END CUSTOM CODE *@ 22 } 23 24 <div class="@displayType@(theme) @(contentPadding) shadow rounded-7 h-100 item_@Model.Item.SystemName.ToLower() schedule-container" id="@(displayType + "-" + Pageview.CurrentParagraph.ID)"> 25 <a name="@Model.ID" class="user-select-none" style="scroll-margin-top:var(--header-height,150px)"></a> 26 @{ @RenderTitle() } 27 @if(displayType == "accordion") 28 { 29 foreach (var item in accordionItems) 30 { 31 <div class="accordion-item @shadowCssClass @accordionItemSpacing @roundedBorderClass"> 32 <h2 class="accordion-header" id="heading-@Pageview.CurrentParagraph.ID-@item.Id"> 33 <button class="accordion-button collapsed @roundedBorderClass" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-@Pageview.CurrentParagraph.ID-@item.Id" aria-expanded="false" aria-controls="collapse-@Pageview.CurrentParagraph.ID-@item.Id"> 34 @item.GetString("Title") 35 </button> 36 </h2> 37 <div id="collapse-@Pageview.CurrentParagraph.ID-@item.Id" class="accordion-collapse collapse" aria-labelledby="heading-@Pageview.CurrentParagraph.ID-@item.Id" data-bs-parent="#accordion-@Pageview.CurrentParagraph.ID"> 38 <div class="accordion-body mb-0-last-child opacity-75"> 39 @item.GetRawValueString("Content") 40 </div> 41 </div> 42 </div> 43 } 44 } else { 45 <nav class="tabsrounded-7"> 46 <ul class="nav nav-tabs days-tabs bg-light-grey rounded-7-top" role="tablist"> 47 @RenderContainer(accordionItems.ToList() , true) 48 49 </ul> 50 </nav> 51 <div class="tab-content days-tabs-container p-lg-4 p-2 overflow-auto"> 52 @RenderContainer(accordionItems.ToList() , false) 53 </div> 54 } 55 </div> 56 57 58 @helper RenderTitle() 59 { 60 if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) 61 { 62 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h2"); 63 string headingLevel = Model.Item.GetString("HeadingLevel", "h2"); 64 string headingLevelStart = $"<{headingLevel} class=\"{titleFontSize} mb-4\">"; 65 string headingLevelStop = $"</{headingLevel}>"; 66 67 @headingLevelStart 68 @Model.Item.GetString("Title") 69 @headingLevelStop 70 } 71 } 72 73 @helper RenderContainer(List<ItemViewModel> collection, bool isTab) 74 { 75 int count = 1; 76 foreach (var tab in collection) 77 { 78 79 string tabTitle = tab.GetString("Title"); 80 var description = tab.GetString("Content"); 81 var hrefAttr = "#tab" + tab.Id; 82 var ariaControlsAttr = "tab" + tab.Id; 83 var activeTabClass = count == 1 ? "active" : ""; 84 if (isTab) 85 { 86 var roundedClass = count == 1 ? "rounded-7-top-left" : ""; 87 var lastItemRoundedClass = count == collection.Count() ? "rounded-7-top-right" : ""; 88 <li class="flex-1" role="presentation"> 89 90 <a class="session-tab border-0 nav-link px-lg-4 py-lg-3 px-3 py-3 @roundedClass @lastItemRoundedClass @activeTabClass" href="@hrefAttr" role="tab" data-toggle="tab" aria-controls="@ariaControlsAttr" data-date="@ariaControlsAttr"> 91 <span>@tabTitle</span> 92 </a> 93 </li> 94 } 95 else 96 { 97 <div id="@ariaControlsAttr" data-controlled="@ariaControlsAttr" role="tabpanel" class="tab-pane @activeTabClass"> 98 <div class="tab-pane show fade in grid"> 99 <div class="g-col-12 theme light-violet"> 100 @if (!string.IsNullOrEmpty(description)) 101 { 102 <p class="m-0">@description</p> 103 } 104 </div> 105 @*<div class="schedule-item grid g-col-lg-12 g-col-12 gap-lg-4 border-bottom p-3 border rounded-7"> 106 107 </div>*@ 108 </div> 109 </div> 110 } 111 count ++; 112 } 113 }

Creating an App for salespeople with Business Central from scratch

Would you like to learn how to create your own Power App with Business Central without coding? In this workshop, I will teach you step by step, and with a practical case, how to create an app for your salespeople that they can use on a tablet or mobile. We will mainly see:

• Using the best practices recommended by Microsoft for Canvas App
• How to access the environment and create your sales app
• Basic controls in Canvas Power App.
• Connectors and Connections in Canvas Power Apps
• The Out-of-the-box Business Central API
• How to use the standard Business Central SaaS connector
• Variables in Canvas App
• Advanced controls in Canvas Power Apps
• How to use Power Automate to execute actions in Business Central
• How to add functionalities to connect directly with Business Central:

  • Show a list of my customers
  • Create a new customer
  • Show a list of my items
  • Create a quote
  • Send a quote by email
  • Convert a quote into an order

Bonus

• How to create a custom API with extra fields
• How to use these extra fields in our Canvas App


Takeaways:

In this training session you will learn:

•  how to prepare your Power Apps environment and how to create your Canvas App in a solution to export it to another environment.
•  How to use the most common controls in Canvas App
•  How to start to work with Business Central data from a Canvas App
•  How to create your custom API to use it from Canvas App or other software.


Requirements:

• Your laptop
• Basic knowledge of Business Central as a user or consultant. 
• You don't need any prior programming knowledge, but although it is low-code, we will teach a little about variables in Power Apps and how to create a basic custom API page for Business Central