alguidelines/docs/navpatterns/patterns/index.xml
2022-02-24 21:03:41 +00:00

4212 lines
No EOL
729 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>alguidelines.dev - Business Central Design Patterns 1. Patterns</title><link>https://alguidelines.dev/docs/navpatterns/patterns/</link><description>Recent content in 1. Patterns on alguidelines.dev - Business Central Design Patterns</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><atom:link href="https://alguidelines.dev/docs/navpatterns/patterns/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: Activity Logs</title><link>https://alguidelines.dev/docs/navpatterns/patterns/activity-log/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/activity-log/</guid><description>
&lt;p>&lt;em>Originally by Ciprian Iordache at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="activity-log">Activity Log&lt;/h2>
&lt;p>&lt;strong>Abstract&lt;/strong>&lt;/p>
&lt;p>The Activity Log pattern tracks execution of activities. This is a Dynamics NAV specific implementation of the &lt;a href="http://martinfowler.com/eaaDev/AuditLog.html">Audit Log&lt;/a> pattern.&lt;/p>
&lt;p>&lt;a href="Activity-Log.jpg">&lt;img src="Activity-Log.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Problem&lt;/strong>&lt;/p>
&lt;p>In general, integrating with external systems can be very challenging, due to the complexity of the situation &amp;ndash; connectivity issues, asynchronous operations, user errors, etc. These challenges require sometimes re-trying several times, polling the external system, re-send/re-get data as all these activities can succeed but can very well fail.&lt;/p>
&lt;p>Similar challenges exist in situations where a lengthy, complex task, composed of different steps is to be executed by various people in various timeframes. In case of errors (but sometimes also in case of success) there will be a need to track these activities to see what happened and the actual person which did a specific step.&lt;/p>
&lt;p>In all these cases, we need to be able to troubleshoot.&lt;/p>
&lt;p>A tracking/logging functionality could be implemented for each activity/step separately, but this would lead to code duplication and problems in maintaining the code in future.&lt;/p>
&lt;p>In NAV there is already the Change Log functionality which can record all the data changes that have been done to specific tables, specific fields. However, this functionality is not available for activities. Also, there are few places where separate logging/tracking implementations were done but the current pattern proposes an unified, central way of data recording and enables the user to track all/most of the activities.&lt;/p>
&lt;p>&lt;strong>Solution&lt;/strong>&lt;/p>
&lt;p>The Activity Log pattern tracks specific outcome of the activities, in order to be able to assess what went wrong/fine or who performed a specific activity.&lt;/p>
&lt;p>Activity Log pattern&lt;/p>
&lt;ul>
&lt;li>records the activity and its outcome (error or success messages)&lt;/li>
&lt;li>assembles all messages in one central view and presents them to the user filtered for the specific activity and ordered in reverse chronological order.&lt;/li>
&lt;/ul>
&lt;p>Figure below illustrates the how the Activity Log manifests in the UI. The figure shows a part of an activity log for a posted document that was sent to the document exchange service and illustrates both successful and failed activities.&lt;/p>
&lt;p>&lt;a href="Activity-Log-NAV.jpg">&lt;img src="Activity-Log-NAV.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>This functionality is implemented in the following way - Activity Log table (TAB710) contains a simple function that allows you to log the result of a task or activity:&lt;/p>
&lt;p>ActivityLog.LogActivity(ContextRecordID,ActivityLog.Status::Failed,ContextDescription,ActivityDescription,ActivityMessage);&lt;/p>
&lt;p>Similar to TAB700 for Error Messaging, the Activity Log table contains a RECORDID that is a link to the parent/context entity. That permits the Activity Log to be used in a generic way, for any kind of entities (tables) and it also permits filtering the data to a specific related entity only before being presenting to the user.&lt;/p>
&lt;p>The following parameters should be provided to the function:&lt;/p>
&lt;ul>
&lt;li>RecordID: The record/context for which the activity is logged&lt;/li>
&lt;li>Status: The task/activity outcome&lt;/li>
&lt;li>Descriptions/Messages: fields that will clearly describe the state and outcome of the task&lt;/li>
&lt;/ul>
&lt;p>To show the log, add a page action, with the caption including the name &amp;ldquo;&amp;lt;prefix&amp;gt; Log&amp;rdquo; and link it to the image named &amp;ldquo;Log&amp;rdquo;:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">{&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Action&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Name=ActivityLog&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CaptionML=ENU=&lt;span style="color:#4e9a06">&amp;#39;Activity Log&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToolTipML=ENU=&lt;span style="color:#4e9a06">&amp;#39;View the status and any errors if the document was sent as an electronic document or OCR file through the document exchange service.&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ApplicationArea=#Basic&lt;span style="color:#000;font-weight:bold">,&lt;/span>#Suite&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Image=Log&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnAction=&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ActivityLog@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">710&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ActivityLog&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ShowEntries&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">RECORDID&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>NAV usages&lt;/strong>&lt;/p>
&lt;p>In Dynamics NAV 2016, there is a new feature for sending documents in electronic format to a document exchange service. In this case, sending documents requires multiple steps as it is an asynchronous activity and as such, in order to keep track of what&amp;rsquo;s happening and when the Activity Log functionality was used. That offers later the possibility to see who sent and when a document was sent, when it was dispatched, if any dispatch errors and how many tries have been made until the document was finally dispatched or rejected.&lt;/p>
&lt;p>So as usages in NAV 2016, we have the document exchange and OCR features plus the related posted documents involved in the document exchange feature.&lt;/p>
&lt;ul>
&lt;li>COD1294.TXT&lt;/li>
&lt;li>COD1410.TXT&lt;/li>
&lt;li>PAG1270.TXT&lt;/li>
&lt;li>PAG1275.TXT&lt;/li>
&lt;li>PAG143.TXT&lt;/li>
&lt;li>PAG144.TXT&lt;/li>
&lt;li>PAG189.TXT&lt;/li>
&lt;li>TAB112.TXT&lt;/li>
&lt;li>TAB114.TXT&lt;/li>
&lt;li>TAB130.TXT&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Ideas for improvement&lt;/strong>&lt;/p>
&lt;p>Replace the scattered similar functionality (as mentioned above, we have several places having close functionality or similar requirements) with this new pattern.&lt;/p>
&lt;p>&lt;strong>Consequences&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Use with caution, similar to the Change Log functionality, as if the pattern will be used extensively in all the activities/operations within NAV, the table might become large containing many records and might cause some performance issues when presenting the data to the client (filtering on the specific activity).&lt;/li>
&lt;li>Do not log private or confidential information (passwords, amounts, salaries, sensitive data), unless you are ok with this data to be showed to all users (even to users which normally would not have access to this data), thus overriding the permission sets.&lt;/li>
&lt;li>Log only essential information (quality over quantity). Can the logged data be used to analyze the problem, or is it just junk data?&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>NAV Versions&lt;/strong>&lt;/p>
&lt;p>Supported from NAV 2016&lt;/p>
&lt;p>&lt;strong>Related Topics&lt;/strong>&lt;/p>
&lt;p>Error Message Processing &amp;ndash; provides a similar view and uses similar concepts: has a generic implementation (uses as link the same RECORDID feature) and uses same filtering functionality when displaying the data to the user.&lt;/p>
&lt;p>Audit Log &amp;ndash; as mentioned in the beginning, this pattern is a NAV specific implementation of the audit log pattern.&lt;/p></description></item><item><title>Docs: Argument Table</title><link>https://alguidelines.dev/docs/navpatterns/patterns/argument-table/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/argument-table/</guid><description>
&lt;p>&lt;em>Originally By Nikola Kukrika and waldo&lt;/em>&lt;/p>
&lt;h3 id="abstract">Abstract&lt;/h3>
&lt;p>The Argument Table pattern is used to provide an extension point for adding new arguments without changing the signature. By grouping multiple arguments into a table the code becomes more readable (function signature and the usage of the function).&lt;/p>
&lt;p>&lt;a href="0218.Argument-Table-image.png">&lt;img src="0218.Argument-Table-image.png" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="problem">Problem&lt;/h3>
&lt;p>In CAL overloading function signature is not supported. It is also not possible to provide default values for the function arguments.&lt;/p>
&lt;p>When an argument needs to be added to the function, the existing function needs to be extracted to a new method with an additional argument and the original function will call new method. This will cause an upgrade problem in the future, since the entire body of the method is replaced.&lt;/p>
&lt;p>Second commonly occurring problem is option duplication. In order to pass options often they are duplicated in the signature.&lt;/p>
&lt;p>The last problem that can be solved is high number of arguments. Functions with a high number of arguments are hard to understand. Having arguments grouped within the table with a meaningful name will improve readability and make code easier to understanding.&lt;/p>
&lt;p>Few examples of the bad implementations are as illustrated here:&lt;/p>
&lt;h4 id="bad-example-1">Bad example 1&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FillInVATReturnData@&lt;span style="color:#0000cf;font-weight:bold">1200001&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DeclarationID@&lt;span style="color:#0000cf;font-weight:bold">1200000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">20&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>LineID@&lt;span style="color:#0000cf;font-weight:bold">1200001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">20&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PeerID@&lt;span style="color:#0000cf;font-weight:bold">1200002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">20&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DocumentNo@&lt;span style="color:#0000cf;font-weight:bold">1200003&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">20&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NumberOfCopies@&lt;span style="color:#0000cf;font-weight:bold">1200007&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Uploaded@&lt;span style="color:#0000cf;font-weight:bold">1200004&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Correction@&lt;span style="color:#0000cf;font-weight:bold">1200005&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HasValidationErr@&lt;span style="color:#0000cf;font-weight:bold">1200006&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Call&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">FillInVATReturnData&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>NoSeries&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NextLineID&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CustomerID&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DocumentNo&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SingleCopy&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>???&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>??&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">....&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">...)
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In this example the code is hard to read and understand. Adding an additional argument will require refactoring of the existing function. Each time a new argument is added a new function will be created.&lt;/p>
&lt;h4 id="bad-example-2">Bad example 2&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetTableSyncSetupW1@&lt;span style="color:#0000cf;font-weight:bold">3&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>OldTableId@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>UpgradeTableId@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TableUpgradeMode@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;Check, Copy, Move, Force&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">CASE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OldTableId&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Header&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SetTableSyncSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableUpgradeMode&lt;span style="color:#000;font-weight:bold">::&lt;/span>Check&lt;span style="color:#000;font-weight:bold">,&lt;/span>UpgradeTableId&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableUpgradeMode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Posting Exch. Column Def&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SetTableSyncSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">104025&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableUpgradeMode&lt;span style="color:#000;font-weight:bold">::&lt;/span>Copy&lt;span style="color:#000;font-weight:bold">,&lt;/span>UpgradeTableId&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableUpgradeMode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Payment Export Data&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SetTableSyncSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableUpgradeMode&lt;span style="color:#000;font-weight:bold">::&lt;/span>Force&lt;span style="color:#000;font-weight:bold">,&lt;/span>UpgradeTableId&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableUpgradeMode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FALSE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In this example each time a new argument is added all function calls will have to be updated. Option is duplicated in the signature, which will cause issues if a new option is defined or the existing options are renamed.&lt;/p>
&lt;h3 id="solution">Solution&lt;/h3>
&lt;p>By grouping the arguments within the table it is possible to add additional argument and reuse it where it is needed without changing the signature.&lt;/p>
&lt;p>Multiple parameters are grouped within the single object with a meaningful name so the code becomes more readable.&lt;/p>
&lt;p>It is possible to assign default values and to have the code validation.&lt;/p>
&lt;p>Argument table should preferably be a temporary table since the implementation is simpler.&lt;/p>
&lt;p>The examples of usages addressing problems shown above are:&lt;/p>
&lt;h4 id="good-example-1">Good example 1&lt;/h4>
&lt;p>New table&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">TAB&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">50003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VAT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Return&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Data&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FillInVATReturnData@&lt;span style="color:#0000cf;font-weight:bold">1200001&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VATReturnData@&lt;span style="color:#0000cf;font-weight:bold">1200000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">50003&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VATReturnData&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>INIT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VATReturnData&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NumberOfCopies&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetDefaultNumberOfCopies&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VATReturnData&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Uploaded&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FALSE&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>FillInVATReturnData&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>VATReturnData&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>By introducing an argument table, code is much more readable since there is a single argument for a function. It is easy to see which arguments are passed in and which are modified in a function.&lt;/p>
&lt;h4 id="good-example-2">Good example 2&lt;/h4>
&lt;p>Good example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetTableSyncSetupW1@&lt;span style="color:#0000cf;font-weight:bold">3&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TableSynchSetup@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">2000000135&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SetTableSyncSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Header&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableSynchSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Mode&lt;span style="color:#000;font-weight:bold">::&lt;/span>Check&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SetTableSyncSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Posting Exch. Column Def&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">104025&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableSynchSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Mode&lt;span style="color:#000;font-weight:bold">::&lt;/span>Copy&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SetTableSyncSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Payment Export Data&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableSynchSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Mode&lt;span style="color:#000;font-weight:bold">::&lt;/span>Force&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Option definition is not encapsulated within the table. Arguments are grouped and we can add additional arguments without the need to change the signature.&lt;/p>
&lt;h3 id="downsides">Downsides&lt;/h3>
&lt;p>You need to create one more table&lt;/p>
&lt;p>Complex types can&amp;rsquo;t be embedded as fields in tables (cannot have a record field type etc).&lt;/p>
&lt;h3 id="nav-usages">NAV Usages&lt;/h3>
&lt;p>Upgrade Codeunits&lt;/p>
&lt;h3 id="related-patterns">Related Patterns&lt;/h3>
&lt;p>Posting Routine, Select behavior: Setting fields on existing records in order not to change the signatures.&lt;/p></description></item><item><title>Docs: Blocked Entity</title><link>https://alguidelines.dev/docs/navpatterns/patterns/blocked-entity/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/blocked-entity/</guid><description>
&lt;p>&lt;em>Originally by Abhishek Ghosh at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The Blocked Entity is used when it is required to stop transactions for an entity (mostly master data), temporarily or permanently.&lt;/p>
&lt;p>&lt;a href="2260.BlockedEntityPattern.png">&lt;img src="2260.BlockedEntityPattern.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>To block entities through metadata, read this pattern. To do the same thing through data, read &lt;a href="https://alguidelines.dev/navpatterns/1-patterns/blocked-entity/data-driven-blocked-entity/">Data Driven Blocked Entity pattern&lt;/a>.&lt;/p>
&lt;p>The business entity holds a state that controls if a given transaction is allowed. The state is used by the logic controlling transactions. The change of state could either be temporary or permanent.&lt;/p>
&lt;p>An example of a temporary halt is when a retail chain selling items has received lot of complaints about an item, and the company wants to stop all transactions, both purchase and sale, with that item until the dealer has clarified the issue with his supplier and possibly received a replacement for the defective stock. Another common example is during counting the physical inventory using cycle counting where the counting is done in one section of a warehouse at a time, so that the regular operations can continue in the other parts of the warehouse. In these situations, it is necessary to block all transactions, such as picks and put-aways, for a bin while warehouse counting is in progress for that bin.&lt;/p>
&lt;p>In contrast, a permanent halt to transactions could be required when an item has become obsolete (or is about to become obsolete), and the company wants to stop further purchase or sale of the item. However, the company wants to maintain the transaction history of the item and, therefore, does not want to delete the item record.&lt;/p>
&lt;p>A simple design implementation of such requirements in Microsoft Dynamics NAV is to add a Blocked field in the entity table (and on the associated page). The implementation takes this state into the logic and checks for the value of this field in related transactions. For most simple scenarios, it is sufficient to have two states on the Blocked field, specifying whether it is allowed to perform transactions for the entity or not.&lt;/p>
&lt;p>In certain situations, however, there could be different levels of blocking. For example, the company could block all sales to a customer that has overdue payments, and the company does not want to allow transactions with this customer until the payments are received. In other situations, the customer may have raised objections about an invoice, and the company has decided not to generate new invoices for the customer until the issue has been resolved. However, the company does want to continue shipping goods to the customer so as not to impact the customer&amp;rsquo;s operations. In these scenarios, it may be necessary to have multiple states on the Blocked field depending on the level of restriction that is needed.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>As mentioned in the previous section, there are two implementations depending on business requirements: The 2-state Boolean field for simple implementations and the multi-state option field for more complex requirements. The implementation flow is similar for both patterns, except how the validation is implemented. The following discusses the two scenarios one by one.&lt;/p>
&lt;h3 id="boolean-implementation">Boolean Implementation&lt;/h3>
&lt;p>Add a Boolean field named Blocked in the table.&lt;/p>
&lt;p>In the relevant logic, add a condition to check the status of the Blocked flag. The cheapest way is to use a TESTFIELD:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">&amp;lt;rec&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>variable\&amp;gt;&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">TESTFIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Blocked&lt;span style="color:#000;font-weight:bold">,&lt;/span>FALSE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Alternatively, you can throw a custom error message. However, you should only do that if the default error message thrown by TESTFIELD is not sufficient.&lt;/p>
&lt;h3 id="option-field-implementation">Option-Field Implementation&lt;/h3>
&lt;p>Add an option field named Blocked in the table. The option values will reflect the different blocked states required by the company.&lt;/p>
&lt;p>Add this field on the card page (or on the List page if the entity does not have a card). As with the Boolean implementation, the convention is to add this field in the right-hand column in the General FastTab of the card page.&lt;/p>
&lt;p>Implement a function in the table that takes the transaction context as input and evaluates the Blocked field to decide whether the transaction should be allowed or not. Optionally, the function can be responsible for notifying the user and bubble up an error message straight away.&lt;/p>
&lt;p>Note: the option field assumes that only one of the multiple options can be active at a time. In other words, the options should be mutually exclusive.&lt;/p>
&lt;p>How not to use the option field in this case: if we want to block an item from sale and/or purchase, the 4 combined options would be &lt;strong>Block none&lt;/strong> | &lt;strong>Block Sales&lt;/strong> | &lt;strong>Block Purchases&lt;/strong> | &lt;strong>Block Sales and Purchases&lt;/strong>. This doesn&amp;rsquo;t scale, because if now we need to block another transaction, the number of option would grow too fast. In this situations, it is better to use two Boolean fields: &lt;strong>Blocked Sale&lt;/strong>: &lt;strong>true|false&lt;/strong> and &lt;strong>Blocked Purchase: true|false&lt;/strong>.&lt;/p>
&lt;p>A good example of usage would be for varying the behavior depending on the chosen option, for example by displaying a different error message depending on the reason an Item is blocked. In this case we can have the item &lt;strong>Not Blocked&lt;/strong> | &lt;strong>Blocked due to defect&lt;/strong> | &lt;strong>Blocked waiting for approval&lt;/strong>, etc.&lt;/p>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;h3 id="boolean-implementation-1">Boolean Implementation&lt;/h3>
&lt;p>&lt;a href="8637.BlockedEntityPattern_5F00_5F00_5F00_Boolean.png">&lt;img src="8637.BlockedEntityPattern_5F00_5F00_5F00_Boolean.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>An example of the Boolean implementation on the Item card.&lt;/p>
&lt;p>In codeunit 22 &amp;ndash; Item Jnl.-Post Line, the following lines of code have implemented a check based on the value of the Blocked field:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CalledFromAdjustment&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Item&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">TESTFIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Blocked&lt;span style="color:#000;font-weight:bold">,&lt;/span>FALSE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="option-field-implementation-1">Option-Field Implementation&lt;/h3>
&lt;p>&lt;a href="3056.BlockedEntityPattern_5F00_5F00_5F00_Option.png">&lt;img src="3056.BlockedEntityPattern_5F00_5F00_5F00_Option.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>An example of the option field implementation on the Customer card.&lt;/p>
&lt;p>The CheckBlockedCustOnDocs and CheckBlockedCustOnJnls functions in the Customer table are responsible for validating the Blocked state with respect to the input document type. These functions are invoked in several areas, such as posting routines, where a status check on the Blocked field is required. This is a good practice where the Blocked implementation gets more complex, as this encourages reuse and ensures uniformity of implementation.&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>Entities where the Blocked Entity has been implemented include:&lt;/p>
&lt;ul>
&lt;li>Item&lt;/li>
&lt;li>G/L Account&lt;/li>
&lt;li>Customer&lt;/li>
&lt;li>Vendor&lt;/li>
&lt;li>Bin&lt;/li>
&lt;/ul>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>The &lt;a href="https://alguidelines.dev/navpatterns/1-patterns/released-entity/">Released Entity&lt;/a>.&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/O2R-fTSup1o" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Cached Web Server Calls</title><link>https://alguidelines.dev/docs/navpatterns/patterns/cached-web-service-calls/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/cached-web-service-calls/</guid><description>
&lt;p>&lt;em>Originally by Mostafa Balat, Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>In a service-oriented deployment, web services are used to extend NAV&amp;rsquo;s functionality and reach. Depending on how volatile this data is and the corresponding usage scheme, it is expected to be up-to-date within a pre-defined period of time (e.g. once a day).&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>When NAV is integrated with external services, then the user scenarios become dependent on the data and functions offered by such services. Eventually, there are different approaches through which the external data can be retrieved, stored and used.&lt;/p>
&lt;ul>
&lt;li>Dynamic: either exposed by the external service itself or by a separate catalog that NAV can query.
&lt;ul>
&lt;li>Advantage: data is always up-to-date&lt;/li>
&lt;li>Disadvantage: it requires constant connection to the data source.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Static: hard-coded in the database for the user to benefit from.
&lt;ul>
&lt;li>Advantage: data is promptly available when needed.&lt;/li>
&lt;li>Disadvantage: if data changes at some point, it will require a maintenance effort, which exposes the business process to a risk of failure.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Cached: offered through an external service and gets pulled according to a pre-defined refresh rate or manually.
&lt;ul>
&lt;li>Advantage: data is &amp;lsquo;up-to-date&amp;rsquo; within the rules acceptable by the business process, without extra load on the network resources or the external service.&lt;/li>
&lt;li>Disadvantage: if data changes while the auto-refresh did not happen yet, the user may not have access to the latest data; however, the user can manually force a refresh of the data, if asked to do so.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="when-to-use-it">When to Use It&lt;/h3>
&lt;p>Offer data in lookups that were cached from an external service.&lt;/p>
&lt;h3 id="diagram">Diagram&lt;/h3>
&lt;p>&lt;a href="Cached_5F00_Web_5F00_Service_5F00_Calls_5F00_Diagram.png">&lt;img src="Cached_5F00_Web_5F00_Service_5F00_Calls_5F00_Diagram.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>Set up an NAV feature to consume the data from an external service. Refresh the data on a pre-defined refresh rate (e.g. once a day) or when enforced by a power user or an admin. Cache the data in a table and offer it in lookups, as applicable.&lt;/p>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;h3 id="overview">Overview&lt;/h3>
&lt;p>&lt;strong>PAG1259 Bank Name - Data Conv. List&lt;/strong> offers the required functionality to refresh and display the list of bank names needed to specify which file format to convert to. The page can be accessed from &lt;strong>PAG1260 Bank Data Conv. Service Setup&lt;/strong> to display all available bank names. It is also used as a lookup on &lt;strong>PAG370 Bank Account Card&lt;/strong>, where it offers a filtered view of the cached bank names based on the Country/Region Code field.&lt;/p>
&lt;p>If &lt;strong>PAG1259 Bank Name - Data Conv. List&lt;/strong> is being open and the cached data is &amp;lsquo;old&amp;rsquo;, it refreshes the cache. The cached data is stored in &lt;strong>TAB1259 Bank Data Conv. Bank&lt;/strong>. Meanwhile, the user has the chance to refresh the data using&lt;/p>
&lt;h3 id="code-sample">Code Sample&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">OnInit=&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ShortTimeout&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">5000&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>LongTimeout&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">30000&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>OnOpenPage=&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1259&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ImpBankListExtDataHndl@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1289&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CountryRegionCode@&lt;span style="color:#0000cf;font-weight:bold">1004&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HideErrors@&lt;span style="color:#0000cf;font-weight:bold">1003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CountryRegionCode&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>IdentifyCountryRegionCode&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Rec&lt;span style="color:#000;font-weight:bold">,&lt;/span>GETFILTER&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Country/Region Code&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ISEMPTY&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ImpBankListExtDataHndl&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetBankListFromConversionService&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>HideErrors&lt;span style="color:#000;font-weight:bold">,&lt;/span>CountryRegionCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>ShortTimeout&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RefreshBankNamesOlderThanToday&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>CountryRegionCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>HideErrors&lt;span style="color:#000;font-weight:bold">,&lt;/span>ShortTimeout&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>OnAction=&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ImpBankListExtDataHndl@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1289&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FilterNotUsed@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ShowErrors@&lt;span style="color:#0000cf;font-weight:bold">1003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ShowErrors&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TRUE&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ImpBankListExtDataHndl&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetBankListFromConversionService&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ShowErrors&lt;span style="color:#000;font-weight:bold">,&lt;/span>FilterNotUsed&lt;span style="color:#000;font-weight:bold">,&lt;/span>LongTimeout&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>IdentifyCountryRegionCode@&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1259&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Filter&lt;/span>@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CompanyInformation@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">79&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BlankFilter@&lt;span style="color:#0000cf;font-weight:bold">1003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BlankFilter&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Filter&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BlankFilter&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CompanyInformation&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETFILTER&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Country/Region Code&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>CompanyInformation&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Country/Region Code&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>BankDataConvBank&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GETFILTER&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Country/Region Code&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Filter&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RefreshBankNamesOlderThanToday@&lt;span style="color:#0000cf;font-weight:bold">5&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>CountryRegionCode@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>ShowErrors@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>Timeout@&lt;span style="color:#0000cf;font-weight:bold">1004&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1259&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ImpBankListExtDataHndl@&lt;span style="color:#0000cf;font-weight:bold">1003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1289&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CountryRegionCode&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETFILTER&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Country/Region Code&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>CountryRegionCode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETFILTER&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Last Update Date&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;lt;%1&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TODAY&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvBank&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDFIRST&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ImpBankListExtDataHndl&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetBankListFromConversionService&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ShowErrors&lt;span style="color:#000;font-weight:bold">,&lt;/span>CountryRegionCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>Timeout&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>Bank name lookup on the Bank Account card for dynamically identifying the format to use to generate a bank-specific payment file.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for Improvement&lt;/h2>
&lt;p>Expose the refresh rate through a setup table to make it easily configurable without changing the code.&lt;/p></description></item><item><title>Docs: Conditional Cascading Update</title><link>https://alguidelines.dev/docs/navpatterns/patterns/conditional-cascading-update/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/conditional-cascading-update/</guid><description>
&lt;p>&lt;em>Originally by Jan Hoek at IDYN&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The Conditional Cascading Update pattern is used to intelligently populate fields whose values depend on other field values. In this pattern description, the field triggering the update will be called &amp;ldquo;source field&amp;rdquo;, and the depending field will be called &amp;ldquo;target field&amp;rdquo;.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>The value of one table field sometimes depends on the value of another field, typically following an application-defined transformation (note that we&amp;rsquo;re talking about transformations of field values here. This has nothing to do with e.g. form transformation), such as conversion to uppercase, removal of certain characters etc.&lt;/p>
&lt;p>If the target field is non-editable, said transformation is usually the only way for the target field to receive new values, so no irreproducible information can be lost. However, if the target field is editable, the user may have cared enough to override the default (transformed) value, in which case revalidating the source field should not blindly replace the target field&amp;rsquo;s value.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>In the OnValidate trigger of the source field, test if the target field value is either blank, or equal to the transformed value of the source field&amp;rsquo;s previous contents. If it is, populate the target field&amp;rsquo;s value with the transformed source field value. If it is not, do nothing (effectively preserving the value set by the user).&lt;/p>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;p>In the base application, this pattern can be found in Search Name/Search Description fields, which are updated with the uppercase value from the corresponding Name/Description field when the latter is validated, only if the Search Name/Description in question is currently blank, or equal to the (uppercase equivalent) of the previous contents of the Name/Description field.&lt;/p>
&lt;p>&lt;a href="3124.T18_5F00_Name_5F00_OnValidate.png">&lt;img src="3124.T18_5F00_Name_5F00_OnValidate.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>In this particular case, the transformation between source and target fields is implicit and due to the different data types of the fields (text vs. code). Note how the field triggers of the Search Name field itself do not contain any logic linked to this pattern.&lt;/p>
&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;p>There is a case when this pattern should not be used. If the target field is non-editable, this pattern will not add any value, since there won&amp;rsquo;t be any user-overridden values to protect.&lt;/p></description></item><item><title>Docs: Copy Document</title><link>https://alguidelines.dev/docs/navpatterns/patterns/copy-document/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/copy-document/</guid><description>
&lt;p>&lt;em>By Bogdan Sturzoiu at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The goal of the Copy Document pattern is to create a replica of an existing open or closed document (posted or not posted), by moving the lines and, optionally, the header information from the source document to a destination document.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Documents are widely used by most of our customers. Many times, a significant portion of these documents are similar to each other, either by sharing the same customer, vendor, type, or line structure. Being able to re-use a document as a base for creating a new one is therefore an important means of saving time.&lt;/p>
&lt;p>Other business scenarios require that a newly created document is applied to an existing document. For example, in returns management, a return order can be the reversal of an existing order and can therefore be copied from the original order. Other times, there is even a legal requirement to match the document to its source. For example, credit memos need to be applied to the originating Invoice.&lt;/p>
&lt;p>For these reasons, NAV supports the copying of documents as a method to re-use or link documents.&lt;/p>
&lt;p>The Copy Document functionality is used in the following situations:&lt;/p>
&lt;ul>
&lt;li>The user wants to create a new open sales document (Quote, Order, Blanket Order, Invoice, Return Order, Credit Memo) based on an existing posted or non-posted sales document (Quote, Blanket Order, Order, Invoice, Return Order, Credit Memo, Posted Shipment, Posted Invoice, Posted Return Receipt, Posted Credit Memo).&lt;/li>
&lt;li>The user wants to create a new open purchase document (Quote, Order, Blanket Order, Invoice, Return Order, Credit Memo) based on an existing posted or non-posted purchase document (Quote, Blanket Order, Order, Invoice, Return Order, Credit Memo, Posted Shipment, Posted Invoice, Posted Return Receipt, Posted Credit Memo).&lt;/li>
&lt;li>The user wants to create a new production order (Simulated, Planned, Firm Planned or Released) based on an existing production order (Simulated, Planned, Firm Planned, Released or Finished).&lt;/li>
&lt;li>The user wants to create a new assembly order based on an existing assembly document (Quote, Blanket Order, Order and Posted Order).&lt;/li>
&lt;li>The user wants to create a new service contract or quote based on an existing service contract or quote.&lt;/li>
&lt;li>The user wants to create all relevant return-related documents. For example, from a sales return order, the user can recreate the involved supply chain documentation, by copying the information upwards to a purchase return order (if the items need to be returned to the vendor), purchase order (if the items need to be reordered), and sales order (if the items need to be re-sent to the customer).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Note&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Not all to and from combinations are allowed. For example, you can only copy to open document types, since the posted documents are not editable.&lt;/li>
&lt;li>The destination document needs to have the header fully created. For example, a Sales Order will need to have the Sell-To Customer No. populated.&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The Dynamics NAV application developer can take into account using the Copy Document design pattern when they have requirements such as:&lt;/p>
&lt;ul>
&lt;li>To provide a quick and efficient way of moving content from a document to another.&lt;/li>
&lt;li>To allow reusing the document history as a template for new documents.&lt;/li>
&lt;li>To allow linking of documents that need to be applied to each other.&lt;/li>
&lt;/ul>
&lt;p>The Copy Document pattern involves the following entities:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Source document tables for document header and line. For example,Sales Header/Line.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Destination document tables for document header and line.&lt;br>
&lt;strong>Note:&lt;/strong> The source document header/line and destination document header/line tables do not need to be the same. For example, you can copy a Sales Shipment Header/Lines into a Sales Header/Lines.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Copy Document engine: COD6620, Copy Document Mgt.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Copy Document report for a specific document type. The report requires the following parameters:&lt;/p>
&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>Source Document Type&lt;/li>
&lt;li>Source Document No.&lt;/li>
&lt;li>Include Header (optional)&lt;/li>
&lt;li>Recalculate Lines (optional)&lt;/li>
&lt;/ul>
&lt;p>Example: REP901, Copy Assembly Document&lt;/p>
&lt;p>&lt;a href="clip_image002.gif-750x0.png">&lt;img src="clip_image002.gif-750x0.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage-sequence">Usage Sequence&lt;/h2>
&lt;p>&lt;strong>Precondition&lt;/strong>: The user creates a new destination document Header, filling up the required information.&lt;/p>
&lt;p>&lt;strong>Step 1&lt;/strong>: The user runs the Copy Document report (element no. 4), filling up the parameters:&lt;/p>
&lt;ul>
&lt;li>Source Document Type&lt;/li>
&lt;li>Source Document No.&lt;/li>
&lt;li>Include Header and/or Recalculate Lines (not all Copy Document reports have these).&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Step 2&lt;/strong>: The report copies the information in the source tables (Header and Line) into the destination tables (Header and Line).&lt;/p>
&lt;p>&lt;strong>Post processing&lt;/strong>: The user performs additional editing of the destination document.&lt;/p>
&lt;p>The sequence flow of the pattern is described in the following diagram.&lt;/p>
&lt;p>&lt;a href="clip_image004.gif-750x0.png">&lt;img src="clip_image004.gif-750x0.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Example: Copy Sales Document for Credit Memos.&lt;/p>
&lt;p>In the standard version of Microsoft Dynamics NAV, the Copy Document functionality is implemented in the Sales Credit Memo window as shown in the following section.&lt;/p>
&lt;hr>
&lt;p>&lt;strong>Precondition&lt;/strong>: The user enters data in PAGE44, Sales Credit Memo.&lt;/p>
&lt;p>&lt;a href="clip_5F00_image006.jpg">&lt;img src="clip_5F00_image006.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Step 1&lt;/strong>: The user runs REP292, Copy Sales Document from the Sales Credit Memo window, populating the required parameters. The Include Header and Recalculate Lines fields are selected.&lt;/p>
&lt;p>&lt;a href="clip_5F00_image008.jpg">&lt;img src="clip_5F00_image008.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Step 2&lt;/strong>: The Sales Credit Memo window is populated with information from the source sales document.&lt;/p>
&lt;p>&lt;a href="clip_5F00_image010.jpg">&lt;img src="clip_5F00_image010.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Post processing&lt;/strong>: The user can now do additional editing of the sales credit memo.&lt;/p>
&lt;h1 id="nav-implementations">NAV Implementations&lt;/h1>
&lt;ol>
&lt;li>Copy Sales Document (REP292)&lt;/li>
&lt;li>Copy Purchase Document (REP492)&lt;/li>
&lt;li>Copy Service Document (REP5979)&lt;/li>
&lt;li>Copy Assembly Document (REP901)&lt;/li>
&lt;/ol>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/aTiwroXwW0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Create Data from Templates</title><link>https://alguidelines.dev/docs/navpatterns/patterns/create-data-from-templates/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/create-data-from-templates/</guid><description>
&lt;p>&lt;em>Originally by Nikola Kukrika at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>For many records, such as Items, Customers, and Vendors, users have to enter the same sets of data again and again. This is tedious, error-prone (users forget to enter a field or they choose the wrong group), and difficult to learn for some users.&lt;/p>
&lt;p>We can group sets of data as templates to speed up and simplify the process of entering data in Microsoft Dynamics NAV. For example, the process of creating a new customer could be simplified so that users only have to enter information that is specific for every individual customer, e.g. Name and Address/Contact.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>This pattern solves the problem of creating new records based on their type. You should use it whenever there is a large set of data that could be grouped in a meaningful way.&lt;/p>
&lt;p>In Microsoft Dynamics NAV 2013 R2, we have extended the Configuration Templates feature so that templates can be used in different languages than the language they were created in. We have also added the ability to set related templates so that related records can be inserted, such as dimensions for customers, items, and vendors.&lt;/p>
&lt;p>The pattern consists of two parts:&lt;/p>
&lt;p>1. Using templates to create new records or applying templates to existing records&lt;/p>
&lt;p>2. Defining and updating existing templates&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>&lt;a href="4118.Picture1.png">&lt;img src="4118.Picture1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Using the patterns involves three steps.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>As a first step, we must insert a record. This can be done either through C/AL code or by letting the user create a record using the &lt;strong>New&lt;/strong> action.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>After the record is created, we must apply the template. This is done by using the &lt;strong>UpdateRecord&lt;/strong> function in the &lt;strong>Config. Template Management&lt;/strong> codeunit (8612).&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Config. Template Lines&lt;/strong> records reference one &lt;strong>Config. Template Header&lt;/strong> record (lines pattern). The lines can be of type:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Field&lt;/strong> - Stores a field value that will be applied to the record&lt;/li>
&lt;li>&lt;strong>Related&lt;/strong> Template &amp;ndash; References a Config. Template Header record for a related template.&lt;/li>
&lt;/ul>
&lt;p>The &lt;strong>UpdateRecord&lt;/strong> function applies values to the record one line at the time. One of the requirements was to be possible to use configuration templates in different language/regional settings than the template was created in.&lt;/p>
&lt;p>To support this scenario, when applying the &lt;strong>Config. Template Line&lt;/strong> record, &lt;strong>GLOBALLANGUAGE&lt;/strong> is set to the language ID of the field. This is important because the default value is stored as text, so we need to use the same formatting that NAV was running on when the template was created. Otherwise, data types, such as Boolean, Date, etc., will raise validation errors.&lt;/p>
&lt;p>Any updates to a &lt;strong>Config. Template Line&lt;/strong> record will automatically update the language ID to the current one. Since lines are applied one by one, it is supported to have lines with different language IDs belonging to the same template.&lt;/p>
&lt;ol start="3">
&lt;li>After we have applied the template to the record, we can insert related templates. For example, when you insert an item, you may want to insert dimensions as well. You must implement the logic to apply or then modify the related templates, since this depends on the logic and the relationship between the records. Lines with &lt;strong>Type = Related Template&lt;/strong> are used to reference related templates.&lt;/li>
&lt;/ol>
&lt;p>Code example (Insert a record, apply a template, and insert the related templates):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#8f5902;font-style:italic">// First insert a record Customer.INSERT(TRUE);
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#8f5902;font-style:italic">// Apply a template RecRef.GETTABLE(Customer);
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>ConfigTemplateMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UpdateRecord&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETTABLE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Customer&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#8f5902;font-style:italic">// Insert Dimensions -- related templates
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>MiniDimensionsTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InsertDimensionsFromTemplates&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>Customer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>Customer&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Code to insert related templates (dimensions):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">FUNCTION&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>InsertDimensionsFromTemplates&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateHeader&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Config. Template Header&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>MasterRecordNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">20&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>TableID&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// There are multiple records (multiple dimensions per master record)
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// We have to set filter
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ConfigTemplateLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>ConfigTemplateLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Related Template&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ConfigTemplateLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Data Template Code&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>ConfigTemplateHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ConfigTemplateLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ConfigTemplateHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Template Code&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// Ensure that the table where the template belongs to is Dimensions
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// We could have other related templates
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ConfigTemplateHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Default Dimension&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>InsertDimensionFromTemplate&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>MasterRecordNo&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableID&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ConfigTemplateLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#8f5902;font-style:italic">// Create a new Dimensions Record and link it to the Master Record
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">FUNCTION&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>InsertDimensionFromTemplate&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateHeader&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Config. Template Header&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>MasterRecordNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">20&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>TableID&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>DefaultDimension&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>INIT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DefaultDimension&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MasterRecordNo&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DefaultDimension&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TableID&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DefaultDimension&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Dimension Code&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetDefaultDimensionCode&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateHeader&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DefaultDimension&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GETTABLE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>DefaultDimension&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ConfigTemplateMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UpdateRecord&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ConfigTemplateHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETTABLE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>DefaultDimension&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>To surface the action in the product, you have three options:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Recommended&lt;/strong> - Implement a separate action called &lt;strong>New from Template&lt;/strong>.&lt;/li>
&lt;li>&lt;strong>Optional&lt;/strong> - Implement the apply template function on the document itself. This is especially good in scenarios where users are allowed to change the template.&lt;/li>
&lt;li>&lt;strong>Alternative&lt;/strong> - Remove the new action by configuration or set Insert Allowed to FALSE on the list (this will block the creation of new records from the lookup). Implement an application action named &lt;strong>New&lt;/strong> and tie it to your code.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Note:&lt;/strong> In Microsoft Dynamics C5 2014, we chose to remove the &lt;strong>New&lt;/strong> action with configuration since we wanted to promote the functionality and avoid the confusion in having too many options. However this might be difficult to maintain with a larger set of pages.&lt;/p>
&lt;p>&lt;strong>To view or edit templates, you have two options:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Use the &lt;strong>Config. Template List&lt;/strong> table (8620) and the &lt;strong>Config. Template Header Card&lt;/strong> table (8618).&lt;/li>
&lt;/ol>
&lt;p>This is a generic solution that is not very usable and is error-prone (no lookups, checks for length, table relation checks, etc.) The default value is a text field of 250 characters, which might be much more than the field length, and may lead to validation errors when used. Users will most likely not be able to use this page.&lt;/p>
&lt;p>&lt;a href="2816.Picture3.png">&lt;img src="2816.Picture3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>2. Implement custom pages resembling the document.&lt;/p>
&lt;p>This is optional if you want to enable the users to create and modify templates. In C5 2014, we created temporary tables with the same fields as the main record. Based on this temporary record, we built a page that resembles a document.&lt;/p>
&lt;p>Example of the &lt;strong>Customer Template&lt;/strong> page:&lt;/p>
&lt;p>&lt;a href="7271.Picture4.png">&lt;img src="7271.Picture4.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The goals of this solution were:&lt;/p>
&lt;ul>
&lt;li>To make the setup page resemble a document page so that it is easy to use with basic validation and lookups.&lt;/li>
&lt;li>To have only one place to store templates and maintain only one business logic for applying them, namely in the &lt;strong>Configuration Template Header&lt;/strong> table.&lt;/li>
&lt;li>To avoid any lateral effects of doing validation on the temporary master record. Doing validation on fields, even though the record itself is temporary, could permanently modify other data in the database. For example, if you insert a new record in the &lt;strong>Customer&lt;/strong> table, even in a temporary table, a Contact record is created, which will not be temporary.&lt;/li>
&lt;li>Testability: It is easy to test through RecordRef that the template table matches the main table. We can compare field lengths, data types, table relations, etc. The test is able to detect that they are out of sync, so it is easy to prevent errors.&lt;/li>
&lt;/ul>
&lt;p>One example in the product is the &lt;strong>Mini Customer Template&lt;/strong> table (1300).&lt;/p>
&lt;p>The table itself contains very little code. OnModify, OnInsert, and OnDelete triggers update the &lt;strong>Configuration Header&lt;/strong> and &lt;strong>Configuration Lines&lt;/strong> tables. The following functions in the &lt;strong>Config. Template Management&lt;/strong> codeunit (8612), are used for this:&lt;/p>
&lt;ul>
&lt;li>ConfigTemplateManagement.CreateConfigTemplateAndLines&lt;/li>
&lt;li>ConfigTemplateManagement.UpdateConfigTemplateAndLines&lt;/li>
&lt;li>ConfigTemplateManagement.DeleteRelatedTemplates&lt;/li>
&lt;/ul>
&lt;p>The CreateFieldRefArray function is used as an interface function on all the temporary template tables. It builds data to be read/written to the configuration templates.&lt;/p>
&lt;p>To further enhance the usability, we have provided the following additional functionality:&lt;/p>
&lt;ul>
&lt;li>Create a template from the existing record: The user opens an existing record and creates a template from that record. All the fields that are defined in the CreateFieldRefArray function are used to create the new template.&lt;/li>
&lt;li>Templates list: This page is used by users to select templates or create new ones. Depending on which templates they are working on, we show different template cards.&lt;/li>
&lt;/ul>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;p>In C5 2014, this is the workflow:&lt;/p>
&lt;p>The user opens the &lt;strong>Customers List&lt;/strong> window and selects &lt;strong>New&lt;/strong>&lt;/p>
&lt;p>&lt;a href="4341.Picture4.png">&lt;img src="4341.Picture4.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>From this page, the user can view the template, edit it, or create a new one. Selecting a template will populate the customer card and open a new record. From the existing record, the user has options to save as a template or opening a list of templates to maintain available templates. Selecting a template will populate the customer card and open a new record. From the existing record, the user has options to save as a template or opening a list of templates to maintain available templates.&lt;/p>
&lt;p>&lt;a href="3482.Picture-5.png">&lt;img src="3482.Picture-5.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>From the &lt;strong>Customer Card Template&lt;/strong> window, we can invoke the &lt;strong>Dimensions&lt;/strong> action, through which we can define the dimensions that will be inserted together with the template:&lt;/p>
&lt;p>&lt;a href="2134.Picture6.png">&lt;img src="2134.Picture6.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>This pattern is used in Microsoft Dynamics C5 2014 in the following objects:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Temporary template tables:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mini Customer Template&lt;/strong> table (1300)&lt;/li>
&lt;li>&lt;strong>Mini Item Template&lt;/strong> table (1301)&lt;/li>
&lt;li>&lt;strong>Mini Dimensions Template&lt;/strong> table(1302)&lt;/li>
&lt;li>&lt;strong>Mini Vendor Template&lt;/strong> table (1303)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Pages to define templates:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mini Customer Template Card&lt;/strong> page (1341)&lt;/li>
&lt;li>&lt;strong>Mini Item Template Card&lt;/strong> page (,1342)&lt;/li>
&lt;li>&lt;strong>Mini Dimensions Template List&lt;/strong> page (1343)&lt;/li>
&lt;li>&lt;strong>Mini Vendor Template Card&lt;/strong> page (1344)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Pages that use the templates:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mini Customer List&lt;/strong> page (1301)&lt;/li>
&lt;li>&lt;strong>Mini Item List&lt;/strong> page ( 1303)&lt;/li>
&lt;li>&lt;strong>Mini Vendor List&lt;/strong> page (1331)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>In the standard version of Microsoft Dynamics NAV, we use the &lt;strong>Apply Template&lt;/strong> action on the following pages:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Customer Card&lt;/strong> page (21)&lt;/li>
&lt;li>&lt;strong>Vendor Card&lt;/strong> page (26)&lt;/li>
&lt;li>&lt;strong>Item Card&lt;/strong> page (30)&lt;/li>
&lt;li>&lt;strong>Resource Card&lt;/strong> page (, 76)&lt;/li>
&lt;li>Other similar cards.&lt;/li>
&lt;/ul>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>Implement the solution in the standard version of Microsoft Dynamics NAV and extend the Apply Template functionality to insert dimensions.&lt;/p>
&lt;p>It is possible that users end up with a large number of templates if they need many different data combinations. An improvement could be to split templates into smaller groups, grouping only part of the fields that are related, and then apply only these.&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/F0CTvoyKSmI" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Create URLs to NAV Clients</title><link>https://alguidelines.dev/docs/navpatterns/patterns/create-urls-to-nav-clients/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/create-urls-to-nav-clients/</guid><description>
&lt;p>&lt;em>By Mike Borg Cardona and Bogdana Botez at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>This article illustrates NAV platform functionality to be used by C/AL developers.&lt;/p>
&lt;p>The URL builder function, GETURL, is released in Microsoft Dynamics NAV 2013 R2 to reduce coding time for developers who need to create various URL strings to run application objects in either the win client, the web client, or on web services. In addition, the GETURL function makes multitenancy features more transparent to C/AL developers.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Ever had to construct win client URLs like the one below?&lt;/p>
&lt;p>dynamicsnav://myserver:7046/myInstance/myCompany/runpage?page=26&lt;/p>
&lt;p>Today, Microsoft Dynamics NAV also provides a web client. This means that you must update your code to construct web client URLs too. What about multitenancy? The URL Builder should know if it is running in a multitenant setup and it should know how to choose the right tenant. What about maintaining this code?&lt;/p>
&lt;p>The good news is that GETURL has been introduced to handle all URL building for you.&lt;/p>
&lt;p>GETURL automatically handles:&lt;/p>
&lt;ul>
&lt;li>Multitenancy&lt;/li>
&lt;li>Correct URL format for each client&lt;/li>
&lt;li>Publicly accessible hostnames.&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The format is:&lt;/p>
&lt;p>[String :=] GETURL(ClientType[, Company][, Object Type][, Object Id][, Record])&lt;/p>
&lt;p>Where:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Client Type&lt;/strong> can be: Current, Default, Windows, Web, SOAP, or OData. This enables a range of scenarios for the C/AL developer, such as moving to the web client without changing code to decide where the URL should point to. This is done either by setting Client Type to Current, and just ensuring that web is used to invoke the link creation, or by setting Client Type to Default and changing its value to Web when it is ready to move to the web platform.&lt;/li>
&lt;li>&lt;strong>Object Type&lt;/strong> and &lt;strong>Object ID&lt;/strong> define the type of the application object to run (Table, Page, Report, Codeunit, Query, or XMLport) and its ID.&lt;/li>
&lt;li>&lt;strong>Record&lt;/strong> specifies the actual data to run the URL on, such as:&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">Vendor&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Account No.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>GETURL&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">CLIENTTYPE&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>WEB&lt;span style="color:#000;font-weight:bold">,&lt;/span>COMPANYNAME&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OBJECTTYPE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Page&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">27&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>Vendor&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Note&lt;/strong>: It is currently not possible to set filters on the record that you sent as a last parameter to the GETURL function. However, it is possible to write your own code to compute and append the filter string to the URL that is created by the GETURL function.&lt;/p>
&lt;p>The server name and instance are extracted automatically by GETURL and do not need to be specified by the C/AL developer. Furthermore, the multitenancy setup is transparent to the C/AL developer. No multitenancy parameters are specified when you call GETURL, because the function knows from the server setup if it is running in a multitenant environment and if so, it will add a string like &amp;ldquo;&amp;amp;tenant=MyTenant&amp;rdquo; to the URL.&lt;/p>
&lt;h2 id="when-to-use">When to Use&lt;/h2>
&lt;p>The GETURL function can generally be used every time a URL must be created. The following are some scenarios where the function is particularly useful.&lt;/p>
&lt;ul>
&lt;li>Document approvals. For more information, see the &amp;ldquo;NAV Usage Example&amp;rdquo; section.&lt;/li>
&lt;li>Reports containing drill-down links. (Beware of the resource cost of adding a new URL element to the Report dataset.)&lt;/li>
&lt;li>When planning to write code for, or migrate to, various display targets (Microsoft Dynamics NAV Windows client, Microsoft Dynamics NAV web client, Microsoft Dynamics NAV web services) without having to explicitly specify which client to use.&lt;/li>
&lt;/ul>
&lt;h2 id="examples-of-usage">Examples of Usage&lt;/h2>
&lt;p>The following are examples of calls to GETURL and their corresponding return value:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>URL&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Win)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71//&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web)&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData)&lt;/td>
&lt;td>http://MyServer:7048/DynamicsNAV71/OData&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP)&lt;/td>
&lt;td>http://MyServer:7047/DynamicsNAV71/WS/Services&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Current) ie. When running this code on a Win client session&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71//&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Default) ie. When the Server config key DefaultClient is set to Windows&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71//&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,'')&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71//&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,&amp;lsquo;NONEXISTING Corp&amp;rsquo;)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/NONEXISTING Corp/&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME)&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,'')&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,&amp;lsquo;NONEXISTING Corp&amp;rsquo;)&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=NONEXISTING Corp&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME)&lt;/td>
&lt;td>http://MyServer:7048/DynamicsNAV71/OData/Company(&amp;lsquo;CRONUS&amp;rsquo;)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,'')&lt;/td>
&lt;td>http://MyServer:7048/DynamicsNAV71/OData&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,&amp;lsquo;NONEXISTING Corp&amp;rsquo;)&lt;/td>
&lt;td>http://MyServer:7048/DynamicsNAV71/OData/Company(&amp;lsquo;NONEXISTING Corp&amp;rsquo;)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME)&lt;/td>
&lt;td>http://MyServer:7047/DynamicsNAV71/WS/CRONUS/Services&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,'')&lt;/td>
&lt;td>http://MyServer:7047/DynamicsNAV71/WS/Services&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,&amp;lsquo;NONEXISTING Corp&amp;rsquo;)&lt;/td>
&lt;td>http://MyServer:7047/DynamicsNAV71/WS/NONEXISTING Corp/Services&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Table,27)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runtable?table=27&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Page,27)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runpage?page=27&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Report,6)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runreport?report=6&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Codeunit,5065)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runcodeunit?codeunit=5065&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Query,9150)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runquery?query=9150&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::XmlPort,5150)&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runxmlport?xmlport=5150&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Page,27) ie. When the Web Service is published&lt;/td>
&lt;td>http://MyServer:7048/DynamicsNAV71/OData/Company(&amp;lsquo;CRONUS&amp;rsquo;)/PAG27Vendors&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Query,9150) ie. When the Web Service is published&lt;/td>
&lt;td>http://MyServer:7048/DynamicsNAV71/OData/Company(&amp;lsquo;CRONUS&amp;rsquo;)/QUE9150MyCustomers&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Page,27)Â ie. When the Web Service is published&lt;/td>
&lt;td>http://MyServer:7047/DynamicsNAV71/WS/CRONUS/Page/PAG27Vendors&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Codeunit,5065) ie. When the Web Service is published&lt;/td>
&lt;td>http://MyServer:7047/DynamicsNAV71/WS/CRONUS/Codeunit/COD5065EmailLogging&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Page,27,record) List Page&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runpage?page=27&amp;amp;bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Page,26,record) Card Page&lt;/td>
&lt;td>dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runpage?page=26&amp;amp;bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Page,27,record) List Page&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&amp;amp;page=27&amp;amp;bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Page,26,record) Card Page&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&amp;amp;page=26&amp;amp;bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Page,27,record)&lt;/td>
&lt;td>http://MyServer:7048/DynamicsNAV71/OData/Company(&amp;lsquo;CRONUS&amp;rsquo;)/PAG27Vendors(&amp;lsquo;IC1030&amp;rsquo;)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Page,27)&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&amp;amp;page=27&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Report,6)&lt;/td>
&lt;td>https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&amp;amp;report=6&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>If the GETURL function is called with invalid parameters, it will return an empty string. In that case, you can find the related error text by calling the GETLASTERRORTEXT function.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Function Call&lt;/th>
&lt;th>Error Message&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Table,27)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Codeunit,5065)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Query,9150)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::XmlPort,5150)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Table,27)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Page,27)&lt;/td>
&lt;td>The Page object, 27, that is specified for the GetUrl function has not been published in the Web Services table.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Report,6)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Codeunit,5065)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Query,9150)&lt;/td>
&lt;td>The Query object, 9150, that is specified for the GetUrl function has not been published in the Web Services table.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::XmlPort,5150)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Table,27)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Page,27)&lt;/td>
&lt;td>The Page object, 27, that is specified for the GetUrl function has not been published in the Web Services table.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Report,6)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Codeunit,5065)&lt;/td>
&lt;td>The Codeunit object, 5065, that is specified for the GetUrl function has not been published in the Web Services table.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Query,9150)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::XmlPort,5150)&lt;/td>
&lt;td>The specified object type parameter for the GetUrl function is not valid.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Page,27,record)&lt;/td>
&lt;td>You cannot specify a record parameter for the GetUrl function when the object type is SOAP&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;p>The following example shows how to use the GETURL function in codeunit 440 to ensure that the notification mail in Document Approvals can link to both the Microsoft Dynamics NAV Windows client and the Microsoft Dynamics NAV web client:&lt;/p>
&lt;p>&lt;a href="1778.url1.jpg">&lt;img src="1778.url1.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>This resulting UI looks as follows.&lt;/p>
&lt;p>&lt;a href="7802.url2.jpg">&lt;img src="7802.url2.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>The first link opens the approval document in the Microsoft Dynamics NAV Windows client. The second link (Web view) opens the same document in the Microsoft Dynamics NAV web client.&lt;/p></description></item><item><title>Docs: Creating Custom Charts</title><link>https://alguidelines.dev/docs/navpatterns/patterns/creating-custom-charts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/creating-custom-charts/</guid><description>
&lt;p>&lt;em>Originally by Nikola Kukrika at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The goal of this solution is to enable you to:&lt;/p>
&lt;ol>
&lt;li>Use charts in the web client.&lt;/li>
&lt;li>Create charts with custom functionality.&lt;/li>
&lt;/ol>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>This pattern enables you to implement a business chart (Specific Chart type) in a way that is maintainable and reusable on other pages. This also enables you to provide specific functionality that is not possible with the Generic Chart type and it enables you to show charts in the web client.&lt;/p>
&lt;p>The Business Chart add-in is a special because it is a combination of .NET and Javascript add-ins depending on the display target. In the web client, it renders a JavaScript control, while in the win client, it renders a .Net control. Because of this behavior, you can expect minor differences in how the chart is presented in the win client versus in the web client. Note that this implementation is specific to NAV platform code, because it is not possible to create add-ins that combines .NET and JavaScript by using a framework API.&lt;/p>
&lt;p>&lt;a href="5153.Picture1.png">&lt;img src="5153.Picture1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Example of the same chart in the win client:&lt;/p>
&lt;p>&lt;a href="1411.Picture2.png">&lt;img src="1411.Picture2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The most obvious differences in chart rendering in the two clients are: Slightly different line heights, slightly different chart height, legends in web-client charts can be used as toggle filters to show/hide groups (this is not possible in the win client).&lt;/p>
&lt;h3 id="implementation-overview">Implementation Overview&lt;/h3>
&lt;p>&lt;a href="1781.Picture5.png">&lt;img src="1781.Picture5.png" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="add-in-buffer-table">Add-in Buffer Table&lt;/h3>
&lt;p>This table is used to encapsulate the logic of the Business Chart Add-in. The table handles the following logic:&lt;/p>
&lt;ul>
&lt;li>Storing chart values and conversion from .NET to C/AL and vice versa&lt;/li>
&lt;li>Handling of captions: We must use C/AL to provide multilanguage text in add-ins. In addition, the multilanguage text must be encapsulated in a single place, because we pass/read the same dataset from/to the add-in.&lt;/li>
&lt;li>DrillDown logic&lt;/li>
&lt;li>Other helper data related functions, for displaying date, periods, etc.[Bogdana1] [NK2] [NK3]&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Note:&lt;/strong> It is recommended that you reuse the &lt;strong>Business Chart Buffer table&lt;/strong> (485) as a buffer table or extend. It is a generic table which should cover most of the use cases. Implement a new buffer table only if this table does not meet your needs.&lt;/p>
&lt;h3 id="cardpart-page">CardPart page&lt;/h3>
&lt;p>The CardPart page hosts the Business Chart add-in and must use the add-in buffer table as a source table.&lt;/p>
&lt;p>On the page, you must implement the following triggers:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>AddInReady&lt;/strong> &amp;ndash; Executed when the page is done rendering. Used to initialize the add-in.&lt;/li>
&lt;li>&lt;strong>DataPointClicked&lt;/strong> &amp;ndash; Single-click on an element on the chart.&lt;/li>
&lt;li>&lt;strong>DataPointDoubleClicked&lt;/strong> &amp;ndash; Double-click on an element on the chart&lt;/li>
&lt;/ul>
&lt;p>The CardPart usually contains a StatusText variable to provide more information about the chart or dataset and a set of actions to control the chart.&lt;/p>
&lt;p>The most commonly used actions are:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Select Chart&lt;/strong>, &lt;strong>Previous Chart&lt;/strong>, &lt;strong>Next Chart&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Set Period&lt;/strong>, &lt;strong>Work Date&lt;/strong>&lt;/li>
&lt;li>Actions to filter the data set&lt;/li>
&lt;li>&lt;strong>Refresh&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Chart Information&lt;/strong> &amp;ndash; a tooltip with a description of the chart and how data is calculated.&lt;/li>
&lt;/ul>
&lt;h3 id="optional-preserving-user-personalization">Optional: Preserving User Personalization&lt;/h3>
&lt;p>One of the most common functionalities is personalization. If the chart can be customized by the user, you should store the settings that the user has entered and apply them the next time the chart is loaded.&lt;/p>
&lt;p>To do this, you need the following:&lt;/p>
&lt;ul>
&lt;li>A setup record to store the data. You can use the &lt;strong>Business Chart User Setup&lt;/strong> table (487) or create a new setup table if you need to store more information.&lt;/li>
&lt;li>A management codeunit to write/apply the settings to the chart and to encapsulate other logic. Since we should not write code on pages, the code for the actions and other logic that does not apply to the setup record should go in this codeunit.&lt;/li>
&lt;li>Setup pages where users can customize how the chart is shown and set different settings.&lt;/li>
&lt;/ul>
&lt;p>The relation between the components is visualized in the following diagram:&lt;/p>
&lt;p>&lt;a href="0246.Picture6.png">&lt;img src="0246.Picture6.png" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="optional-show-multiple-charts-within-a-single-cardpart">Optional: Show Multiple Charts within a Single CardPart&lt;/h3>
&lt;p>This option is useful on a Role Center where you want to show multiple charts using different datasets within a single part. In that case, you need a record to store the last chart selection, the setup records, and code units for separate charts.&lt;/p>
&lt;p>See, for example, the implementation of the &lt;strong>Mini Generic Chart&lt;/strong> page (1390), which uses &lt;strong>MiniChartManagment&lt;/strong> CodeUnit to manage separate management codeunits for charts and their setup records. The last selected chart is stored in a separate table, &lt;strong>Mini Chart Definition&lt;/strong> (1310).&lt;/p>
&lt;p>&lt;a href="1803.Picture7.png">&lt;img src="1803.Picture7.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>To implement the pattern, create a new ChartPart and set the source table to &lt;strong>Business Chart Buffer&lt;/strong>.&lt;/p>
&lt;p>Add a field named &lt;strong>BusinessChart&lt;/strong> and set the ControlAddIn property to Microsoft.Dynamics.Nav.Client.BusinessChart.&lt;/p>
&lt;p>Then implement the AddInReady event. This event is executed when the page is done rendering. Code within this method must call the Update method from the &lt;strong>Business Chart Buffer&lt;/strong> table, Update(CurrPage.BusinessChart) to initialize the chart and assign initial values.&lt;/p>
&lt;p>If you need a setup record and codeunit, then it is a good idea to encapsulate this logic within a method.&lt;/p>
&lt;h3 id="nav-specific-example-1">NAV Specific Example 1&lt;/h3>
&lt;p>Implementation of the &lt;strong>Finance Performance Chart&lt;/strong> page (762)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">BusinessChart&lt;span style="color:#000;font-weight:bold">::&lt;/span>AddInReady&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>UpdateChart&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Period&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34; &amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>UpdateChart&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Period&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;,Next,Previous&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>MoveAndUpdateChart&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Period&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MoveAndUpdateChart&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Period&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;,Next,Previous&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>Move&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>AccSchedChartManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetSetupRecordset&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>AccountSchedulesChartSetup&lt;span style="color:#000;font-weight:bold">,&lt;/span>AccountSchedulesChartSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Name&lt;span style="color:#000;font-weight:bold">,&lt;/span>Move&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>AccSchedChartManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UpdateData&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Rec&lt;span style="color:#000;font-weight:bold">,&lt;/span>Period&lt;span style="color:#000;font-weight:bold">,&lt;/span>AccountSchedulesChartSetup&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Update&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>CurrPage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>BusinessChart&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>StatusText&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetCurrentSelectionText&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Period Filter Start Date&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;Period Filter End Date&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In the MoveAndUpdateChart method, the AccSchedChartManagement codeunit gets a setup record and updates it if necessary. Then, it initializes the chart with setup data and sets the StatusText to show the period for which data is displayed. The same method is used by the actions to move and update the chart so that there is no code duplication.&lt;/p>
&lt;p>The following code is used to implement &lt;strong>DataPointClicked&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">BusinessChart&lt;span style="color:#000;font-weight:bold">::&lt;/span>DataPointClicked&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>point&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Microsoft.Dynamics.Nav.Client.BusinessChart.BusinessChartDataPoint&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>SetDrillDownIndexes&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>point&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>AccSchedChartManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>DrillDown&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Rec&lt;span style="color:#000;font-weight:bold">,&lt;/span>AccountSchedulesChartSetup&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>SetDrillDownindexes is a method from the &lt;strong>Business Chart Buffer&lt;/strong> table that maps the DotNet point variable to C/AL data, so it must be used. The next method that you must implement is the action to be performed on Drilldown.&lt;/p>
&lt;p>The &lt;strong>DataPointDoubleClicked&lt;/strong> trigger has the same implementation logic as the DataPointClicked trigger.&lt;/p>
&lt;h3 id="nav-specific-example-2">NAV Specific Example 2&lt;/h3>
&lt;p>Implementation of chart part 1390 on the &lt;strong>Small Business Role Center&lt;/strong> page (9022)&lt;/p>
&lt;p>&lt;a href="1541.Picture7.png">&lt;img src="1541.Picture7.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>This chart part contains data from multiple charts within a single part. The &lt;strong>Status Text&lt;/strong> field shows the name of the chart and the current period. Users can browse through the charts with &lt;strong>Next Chart&lt;/strong> and &lt;strong>Previous Chart&lt;/strong> or use &lt;strong>Select Chart&lt;/strong> to choose from a list of available charts.&lt;/p>
&lt;p>&lt;a href="2553.Picture8.png">&lt;img src="2553.Picture8.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>On this dialog, users can choose if a chart should be enabled or disabled. If the chart is not enabled, it will be skipped on the &lt;strong>Previous Chart&lt;/strong> and &lt;strong>Next Chart&lt;/strong> actions. Charts used by this part use different codeunits and setup records. If the user changes the selected chart, this option will be saved and applied next time role center is opened.&lt;/p>
&lt;p>Users can also change the period length.&lt;/p>
&lt;p>&lt;a href="5545.Picture9.png">&lt;img src="5545.Picture9.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Choosing the &lt;strong>Chart Information&lt;/strong> button opens a short description of the chart.&lt;/p>
&lt;p>&lt;a href="5582.Picture10.png">&lt;img src="5582.Picture10.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>Implementation of multiple charts within a single part:&lt;/p>
&lt;ul>
&lt;li>Page 1390, &lt;strong>Mini Generic Chart&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Charts that use a setup record and select the chart with &lt;strong>Customize Chart Setup&lt;/strong> pages:&lt;/p>
&lt;ul>
&lt;li>Page 772, &lt;strong>Inventory Performance&lt;/strong>&lt;/li>
&lt;li>Page 771, &lt;strong>Purchase Performance&lt;/strong>&lt;/li>
&lt;li>Page 770, &lt;strong>Sales Performance&lt;/strong>&lt;/li>
&lt;li>Page 762, &lt;strong>Finance Performance&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Chart that uses the &lt;strong>Business Chart User Setup&lt;/strong> table:&lt;/p>
&lt;ul>
&lt;li>Page 768, &lt;strong>Aged Acc. Receivable Chart&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Other implementations:&lt;/p>
&lt;ul>
&lt;li>Page 972, &lt;strong>Time Sheet Chart&lt;/strong>&lt;/li>
&lt;li>Page 869, &lt;strong>Cash Flow Chart&lt;/strong>&lt;/li>
&lt;li>Page 760, &lt;strong>Trailing Sales Orders Chart&lt;/strong>&lt;/li>
&lt;/ul>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>We should consider making a generic table for the last chart that the user has used.&lt;/p>
&lt;p>We should investigate if we could make generic code for selecting periods and other common functionality by using RecordRefs.&lt;/p>
&lt;p>Add-In improvements &amp;ndash; Different ways to visualize the data and to pick colors for categories.&lt;/p>
&lt;p>As a nice-to-have feature, we could implement functionality to cycle through the charts with a timer.&lt;/p></description></item><item><title>Docs: Cross Session Events</title><link>https://alguidelines.dev/docs/navpatterns/patterns/cross-session-events/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/cross-session-events/</guid><description>
&lt;p>&lt;em>By Nikolai L&amp;rsquo;Estrange, from TVision Technology Ltd. in the UK&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>Track things that happen in other NAV Sessions.&lt;/p>
&lt;p>&lt;a href="PubSub.png">&lt;img src="PubSub.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="problem">Problem&lt;/h2>
&lt;p>In Microsoft Dynamics NAV you can fire a function whenever something changes within your session (and from NAV 2016 this is even easier with the new Event model), however there is not an easy way to know what is happening in other sessions. Sometimes you would like to know what has happened since your last read, without reading everything again, e.g. when you need to pass a large dataset to a Control Add-in.&lt;/p>
&lt;p>A common way of handling this with Ledger Tables is to make note of the last record you read, and continuously poll to see if there are any new records. However this is restricted to strictly sequentially entered tables.&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>There is a common pattern in many other languages called &lt;a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">Publish-Subscribe&lt;/a> (or PubSub) that solves the same issue. We can implement the same pattern in NAV using a Table as a message queue platform and polling this table. We have named this pattern &amp;ldquo;Cross Session Events&amp;rdquo; in order to avoid confusion with the standard NAV Events which use the terms Publisher and Subscriber, and to try and describe more accurately when you would need this pattern.&lt;/p>
&lt;p>The pattern has four components:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Publisher(s)&lt;/strong>: These push messages to the Message Broker.&lt;/li>
&lt;li>&lt;strong>Subscriber Records&lt;/strong>: Identifies the Subscriber and store filters to say what messages the Subscriber and interested in receiving.&lt;/li>
&lt;li>&lt;strong>Message Broker&lt;/strong>: This distributes all messages sent in to all Subscribers that have expressed an interest (i.e. the message is within their filters).&lt;/li>
&lt;li>&lt;strong>Message Queue&lt;/strong>: To hold the messages for each Subscriber. Generally once these messages are read, they are deleted.&lt;/li>
&lt;/ul>
&lt;h2 id="example">Example&lt;/h2>
&lt;p>An example of this would be when we have multiple users looking at the same set of data and we want their screens to update in &amp;ldquo;real time&amp;rdquo; whenever one of them makes a change, without doing a full refresh. We will use the &lt;a href="https://alguidelines.dev/navpatterns/1-patterns/observer/">Observer pattern&lt;/a> to capture the change (act as the Publisher) and then create a Table to hold Subscribers and Filters (Change Observer), a Table to be the Message Queue (Change Notification), and a Codeunit to be the Message Broker and help with the polling (ObserverMgt).&lt;/p>
&lt;p>Below are the table definitions:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;strong>Change Observer:&lt;/strong>&lt;/th>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&amp;ldquo;Table ID&amp;rdquo;&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>&amp;ldquo;Observable Table&amp;rdquo;&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;ldquo;Server ID&amp;rdquo;&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;ldquo;Session ID&amp;rdquo;&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;strong>Change Notification:&lt;/strong>&lt;/th>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&amp;ldquo;Table ID&amp;rdquo;&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>&amp;ldquo;Observable Table&amp;rdquo;&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;ldquo;Server ID&amp;rdquo;&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;ldquo;Session ID&amp;rdquo;&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;ldquo;Entry No.&amp;rdquo;&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>AutoIncrement&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;ldquo;Type of Change&amp;rdquo;&lt;/td>
&lt;td>Option&lt;/td>
&lt;td>Insert,Modify,Delete,Rename&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;ldquo;Record ID&amp;rdquo;&lt;/td>
&lt;td>RecordID&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&amp;hellip; (other fields to indicate what has changed)&lt;/td>
&lt;td>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The Change Observer table identifies the Subscriber using Server ID and Session ID, and then in this example there is only one filter, which is the Table ID we want to listen to any changes. In this case all three fields are in the Primary Key.&lt;/p>
&lt;p>The Change Notification table then has the same three fields plus an Entry No. as its Primary Key, and in this example borrows heavily from the Change Log code to fill in the rest of the message.&lt;/p>
&lt;p>&lt;em>&lt;strong>Note:&lt;/strong>&lt;/em> Other examples of the pattern could have very different fields to identify the Subscriber, Filters and then whatever fields needed for content of the Message.&lt;/p>
&lt;p>Our Message Broker Codeunit will also serve as a central place to create Subscribers (Listen and StopListening functions) and a place to Poll for Messages. Note that the Poll function deletes the Messages as it reads them.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">Listen&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TableID&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observer&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TableID&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Server ID&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SERVICEINSTANCEID&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Session ID&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SESSIONID&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>INSERT&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>COMMIT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>StopListening&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TableID&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observer&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RESET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Server ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>SERVICEINSTANCEID&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Session ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>SESSIONID&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableID&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DELETEALL&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>COMMIT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>NotifyAll&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ChangeNotification&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Change Notification&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observer&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RESET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>ChangeNotification&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Notify&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Observer&lt;span style="color:#000;font-weight:bold">,&lt;/span>ChangeNotification&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Notify&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Observer&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Change Observer&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>ChangeNotification&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Change Notification&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ChangeNotification&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Server ID&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Server ID&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Session ID&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Session ID&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Entry No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Poll&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TableID&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempChangeNotification&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TEMPORARY&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Change Notification&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ChangeNotification&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempChangeNotification&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RESET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempChangeNotification&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>DELETEALL&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RESET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>TableID&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Server ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>SERVICEINSTANCEID&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Session ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>SESSIONID&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempChangeNotification&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ChangeNotification&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempChangeNotification&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MARK&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MARKEDONLY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DELETEALL&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The final part of this example is an object that calls the functions above. In this example we will use a Page with a PingPong Timer Control to do the polling in (almost) real time. These are the functions on the page:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">OnQueryClosePage&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>CloseAction&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Action&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">None&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>ObserverMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>StopListening&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;NAV Whiteboard Booking&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Timer&lt;span style="color:#000;font-weight:bold">::&lt;/span>AddInReady&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ObserverMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Listen&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;NAV Whiteboard Booking&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CurrPage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Timer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Ping&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Timer&lt;span style="color:#000;font-weight:bold">::&lt;/span>Pong&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>CallUpdate&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CurrPage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Timer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Ping&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CallUpdate&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>ObserverMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Poll&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;NAV Whiteboard Booking&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>TempChangeNotification&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempChangeNotification&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Type of Change&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Type of Change&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Delete&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">...
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Record ID&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">...
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;p>The PingPong control is only available on the Windows Client, so if you want to use another client you will need to use another solution to Poll for Messages. Therefore this pattern is not always going to be &amp;ldquo;real time&amp;rdquo;.&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>This pattern was originally described in the following blog:&lt;/p>
&lt;p>&lt;a href="https://geeknikolai.wordpress.com/2015/10/30/pubsub-pattern-in-dynamics-nav-2016/">https://geeknikolai.wordpress.com/2015/10/30/pubsub-pattern-in-dynamics-nav-2016/&lt;/a>&lt;/p>
&lt;p>Below is the Wikipedia link to the PubSub pattern&lt;/p>
&lt;p>&lt;a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern&lt;/a>&lt;/p></description></item><item><title>Docs: Currently Active Record</title><link>https://alguidelines.dev/docs/navpatterns/patterns/currently-active-record/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/currently-active-record/</guid><description>
&lt;p>&lt;em>Authors: Henrik Langbak and Kim Ginnerup, Bording Data&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>Date controlled data is expensive to find in the database. This pattern describes how using a view with a sub-select and a linked table object will minimize the returned dataset.&lt;br>
A side effect is reduced and simplified code, increased performance and a more scalable solution that is almost independent of the amount of records in the table.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>There is no way in NAV to get a set of records from the database, which all have the newest starting date, that is less than or equal to today&amp;rsquo;s date. Having an ending date on the record will help, but it introduces some other problems. In Dynamics NAV this is normally done by reading too many records, either at the SQL Server level or in the middle tier and throw away the ones you do not need. That is a waste of resources:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The SQL Server is reading too many records&lt;/p>
&lt;/li>
&lt;li>
&lt;p>There would be too much data sent over the network.&lt;br>
(If the SQL Server and the NAV Service tier are on different machines.)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The NAV Service Tier receives and throws away data.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="ending-date-problem">Ending Date Problem&lt;/h2>
&lt;p>Ending Date may introduce some problems of its own.&lt;/p>
&lt;p>If your design requires to have one and only one active record per key in a dataset, then Ending Date introduces the possibility for overlapping or holes in the timeline.&lt;br>
Ending Date creates a dependency between two records. Changing a Starting Date, requires you to update the previous record. Changing the Ending Date requires you to update the next record.&lt;br>
If you add a record in between you will have to update both the before and the after record.&lt;/p>
&lt;p>The pattern we describe here will work whether there is an Ending Date or Not.&lt;/p>
&lt;p>The pattern is also relevant for other types than date. The pattern is usable whenever you have dependencies between rows in a table.&lt;/p>
&lt;p>Use the pattern whenever you read a set of data containing a Starting Date and you need to implement a loop to throw away unwanted records. An example could be Codeunit 7000 &amp;ldquo;Sales Price Calc. Mgt.&amp;rdquo;. In this codeunit there are many loop constructs to find prices and discounts.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>In the following example, we have a fictive table containing: Code, Starting Date and Price. The Primary Key consist of Code, Starting Date. The Database is the Demo Database, and the Company is Cronus.&lt;/p>
&lt;p>&lt;a href="6545.Table.png">&lt;img src="6545.Table.png" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="1-create-the-view">1. Create the view&lt;/h3>
&lt;p>You will need to create the view before you define the Table Object.&lt;br>
You will need to create a view for every company in the database.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sql" data-lang="sql">&lt;span style="color:#204a87;font-weight:bold">CREATE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VIEW&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">dbo&lt;/span>&lt;span style="color:#000;font-weight:bold">].[&lt;/span>&lt;span style="color:#000">CRONUS$PriceView&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">AS&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">SELECT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">Code&lt;/span>&lt;span style="color:#000;font-weight:bold">],&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">Starting&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87">Date&lt;/span>&lt;span style="color:#000;font-weight:bold">],&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">Price&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">FROM&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">dbo&lt;/span>&lt;span style="color:#000;font-weight:bold">.[&lt;/span>&lt;span style="color:#000">CRONUS$Price&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AS&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">A&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WHERE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">Starting&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87">Date&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">SELECT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">MAX&lt;/span>&lt;span style="color:#000;font-weight:bold">([&lt;/span>&lt;span style="color:#000">Starting&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87">Date&lt;/span>&lt;span style="color:#000;font-weight:bold">])&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">FROM&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">dbo&lt;/span>&lt;span style="color:#000;font-weight:bold">.[&lt;/span>&lt;span style="color:#000">CRONUS$Price&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AS&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">B&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WHERE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">B&lt;/span>&lt;span style="color:#000;font-weight:bold">.[&lt;/span>&lt;span style="color:#000">Code&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">A&lt;/span>&lt;span style="color:#000;font-weight:bold">.[&lt;/span>&lt;span style="color:#000">Code&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AND&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#000">B&lt;/span>&lt;span style="color:#000;font-weight:bold">.[&lt;/span>&lt;span style="color:#000">Starting&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87">Date&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&amp;lt;=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">GETDATE&lt;/span>&lt;span style="color:#000;font-weight:bold">())&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Test the view to ensure that you get the correct result. It is much easier to test now than later.&lt;/p>
&lt;h3 id="2-create-the-table-object">2. Create the Table object&lt;/h3>
&lt;p>Remember to set the link table property before you save it.&lt;/p>
&lt;h3 id="3-implement-the-code">3. Implement the code&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PriceView&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// You have them
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="4-create-a-deployment-codeunit">4. Create a deployment codeunit&lt;/h3>
&lt;p>Create a SQL Deployment codeunit to manage your views.&lt;br>
The codeunit needs to Create or Alter the views for all companies.&lt;br>
To see an example of how to talk to SQL Server using .NET see waldo&amp;rsquo;s blog here:&lt;br>
&lt;a href="http://dynamicsuser.net/blogs/waldo/archive/2011/07/19/net-interop-calling-stored-procedures-on-sql-server-example-1.aspx">http://dynamicsuser.net/blogs/waldo/archive/2011/07/19/net-interop-calling-stored-procedures-on-sql-server-example-1.aspx&lt;/a>&lt;/p>
&lt;h3 id="5-deployment">5. Deployment&lt;/h3>
&lt;p>You need to deploy in three steps:&lt;/p>
&lt;ol>
&lt;li>Delete the table objects referencing the views&lt;/li>
&lt;li>Deploy and run the deployment codeunit&lt;/li>
&lt;li>Deploy the new table objects that reference the views&lt;/li>
&lt;/ol>
&lt;h3 id="general-precaution">General precaution&lt;/h3>
&lt;p>If you later want to change the view, you need to follow these rules:&lt;/p>
&lt;ul>
&lt;li>If you add columns, you need to add them to the view first and then add them to the Table Object.&lt;/li>
&lt;li>If you want to remove columns from the view, you need to delete the Table Object, then change the view and last recreate the Table Object without the new columns.&lt;/li>
&lt;/ul>
&lt;h3 id="code-example-that-accomplish-the-same-but-without-using-the-pattern">Code example that accomplish the same but without using the pattern&lt;/h3>
&lt;p>This following example will give you the same result but the performance will deteriorate as time goes by and you get more and more old data.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETCURRENTKEY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;Starting Date&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETFILTER&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Starting Date&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;..%1&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TODAY&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDLAST&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Code&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PriceTemp&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Price&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PriceTemp&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Price&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#8f5902;font-style:italic">// PriceTemp will contain the Prices
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="comparison">Comparison&lt;/h3>
&lt;p>The above NAV example is for a very simple date controlled solution and is provided to give an idea of what the pattern changes seen from a NAV development point of view. But consider the following:&lt;/p>
&lt;ul>
&lt;li>The table has a more complex key.&lt;br>
This will require setting and clearing more filters&lt;/li>
&lt;li>You need to read from more than one table.&lt;br>
Say you need to apply discount from a separate table.&lt;br>
This may give several lines in PriceTemp.&lt;/li>
&lt;li>If the Code field is controlled by a Type field.&lt;br>
The Code field reference keys in different tables&lt;/li>
&lt;/ul>
&lt;p>All three examples above can be implemented directly in the view. By using the pattern, it will still only require a single line of NAV code.&lt;/p>
&lt;p>Using the pattern will only issue one SQL call and thereby one trip to the server.&lt;br>
The NAV Example will require an unknown number of SQL calls and thereby an unknown number of trips to the server. The number of SQL calls is dependent on the number of distinct Code values.&lt;br>
The NAV example will require SQL Server to read all data older than or equal to TODAY, but only return one row per Code. Over time, as old data piles up in the system, the NAV code will perform slower because the SQL statements will be slower.&lt;br>
The Pattern makes a scalable solution with a predictable performance. The performance will not deteriorate at the same rate as the NAV code example.&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>The pattern does not exist in NAV (yet J). We have used it several times in our code for an Add-On.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>Query Object should be able to handle sub-selects and Unions. A simple solution could be to allow the NAV developer to specify the actual Select statement inside the query Object in clear text. Opening up for writing your own queries and map the projection to the Query-defined fields will make the query Object very versatile and remove the pressure from Microsoft trying to create all the different permutations that a select statement can have. Microsoft and others have all tried to create wizards that can create SQL select statement. They all end up having a clear text option.&lt;/p>
&lt;p>An alternative would be better support for linked table objects, specifically views. The current implementation is very fragile.&lt;/p>
&lt;p>The pattern only supports fetching data for a given date (normally today). This is because you cannot control the where-clause of the sub-select.&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>The idea of having a linked table object pointing to a view could be a pattern of its own.&lt;/p></description></item><item><title>Docs: Data Migration Façade</title><link>https://alguidelines.dev/docs/navpatterns/patterns/data-migration-facade/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/data-migration-facade/</guid><description>
&lt;p>&lt;em>By David Bastide and Soumya Dutta at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;p>&lt;a href="8308.logo.png">&lt;img src="8308.logo.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="context">Context:&lt;/h2>
&lt;p>This pattern is describing how you can migrate data using the Data Migration Façade.&lt;/p>
&lt;h2 id="problem">Problem:&lt;/h2>
&lt;p>Writing migration code from an external source, such as a product from a competitor, can be time consuming, as you need to tackle the problems of what to migrate, in which order, exception handling&amp;hellip; and can result in code that is fragile due to deep dependencies on the NAV data model (high coupling). Any change to the NAV data model can easily break this code.&lt;/p>
&lt;h2 id="solution">Solution:&lt;/h2>
&lt;p>The idea of the Data Migration Façade is to provide an API that creates and updates master data and related entities (including transactions) without referencing NAV tables.&lt;/p>
&lt;p>Additionally, the framework around the Data Migration Façade provides tools for error handling, and a way to integrate the migration in the Data Migration Overview page (page 1799).&lt;/p>
&lt;p>The façade framework has the following components:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Two management codeunits:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Data Migration Façade&lt;/strong> (codeunit 6100): Integrates the extension to the Data Migration Wizard. Starts a migration, or restarts a migration that failed for some records.&lt;/li>
&lt;li>&lt;strong>Data Migration Status Facade&lt;/strong> (codeunit 6101): Initializes and updates the status of the migration. The status displays in the &lt;strong>Data Migration Overview&lt;/strong> page (page 1799).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Several master data migration façade codeunits that create and update entities. Each codeunit also contains events that help ensure that data is created in the correct order:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>GL Acc. Data Migration Façade&lt;/strong> (codeunit 6110)&lt;/li>
&lt;li>&lt;strong>Vendor Data Migration Façade&lt;/strong> (codeunit 6111)&lt;/li>
&lt;li>&lt;strong>Customer Data Migration Façade&lt;/strong> (codeunit 6112)&lt;/li>
&lt;li>&lt;strong>Item Data Migration Façade&lt;/strong> (codeunit 6113)&lt;/li>
&lt;li>If you want to migrate other entities, it is possible to define your own codeunit that will contain your custom code (see &amp;lsquo;Usage&amp;rsquo; below).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>A page where you can view the status and progress of the migration. It shows one line for each master data entity (item, customer, vendor, general ledger account) that was chosen for migration. You can also stop a migration by choosing the &lt;strong>Stop Migration&lt;/strong> action.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Data Migration Overview&lt;/strong> (page 1799)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage:&lt;/h2>
&lt;p>There are the following use cases:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Migration with staging tables, where data from another product is exported to a file or set of files, and the exported data is then imported to buffer tables, before running the migration logic. In this case, the migration is implemented in your extension codeunits, and it is called through events, one record at a time.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Migration without staging tables, for example, when you migrate data by importing it from an external tool such as external APIs and webservices. In this case, the migration is also implemented in your extension codeunits but it will be called through the OnRun procedure. You will be responsible for looping on the records to migrate, and you must migrate all records in this unique OnRun call for a given entity.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>To initialize and start the data migration, you must call the following procedures:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&amp;ldquo;Data Migration Status Façade&amp;rdquo;.InitStatusLine(&amp;lsquo;My Migration Type&amp;rsquo;,Database::Item,42000,0,Codeunit::&amp;ldquo;My extension Item migration codeunit&amp;rdquo;)&lt;/strong>&lt;br>
This deletes existing status lines for migrating Items for &amp;lsquo;My Migration Type&amp;rsquo;, and initializes a new status line with 0 records migrated out of 42000.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>&amp;ldquo;Data Migration Façade&amp;rdquo;.StartMigration(&amp;lsquo;My Migration Type&amp;rsquo;,false)&lt;/strong>&lt;br>
This starts the migration. False means this is not a retry. A re-try is when you migrate one or more records from the &lt;strong>Show Errors&lt;/strong> page, which is described later in this document. Retry = true is only used by the &lt;strong>Show Errors&lt;/strong> page and should not be used from extensions.&lt;/p>
&lt;h3 id="usage-without-staging-tables">Usage without staging tables:&lt;/h3>
&lt;p>The overall workflow is:&lt;/p>
&lt;ol>
&lt;li>Integrate your extension in the &lt;strong>Data Migration Wizard&lt;/strong> by subscribing to the events exposed by the &lt;strong>Data Migration Façade&lt;/strong>.&lt;/li>
&lt;li>From there, initialize the status of the migration so it can be displayed in the Data Migration Overview. When initializing the status lines, you provide the codeunit ID that will be called for each entity: &lt;strong>&amp;ldquo;Data Migration Status Façade&amp;rdquo;.InitStatusLine(&amp;lsquo;My Migration Type&amp;rsquo;,Database::Item,42000,0,Codeunit::&amp;ldquo;My extension Item migration codeunit&amp;rdquo;)&lt;/strong>.&lt;/li>
&lt;li>Launch the migration: &lt;strong>&amp;ldquo;Data Migration Façade&amp;rdquo;.StartMigration(&amp;lsquo;My Migration Type&amp;rsquo;,false).&lt;/strong>&lt;/li>
&lt;li>Your migration codeunits are called one at a time (&lt;strong>OnRun&lt;/strong>) in the following order:&lt;/li>
&lt;li>G/L accounts (first, because customer/vendor posting groups refer to G/L accounts)&lt;/li>
&lt;li>Customers&lt;/li>
&lt;li>Vendors&lt;/li>
&lt;li>Items (because discounts may refer to customer groups)&lt;/li>
&lt;li>Others&lt;/li>
&lt;li>Loop on all of the records to migrate. You can update the increment of the amount of records migrated: &lt;strong>&amp;ldquo;Data Migration Status Facade&amp;rdquo;.IncrementStatusLine(&amp;lsquo;My Migration Type&amp;rsquo;,Database::Item,42).&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>&lt;a href="NoStagingTableNew2.png">&lt;img src="NoStagingTableNew2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 1: sequence diagram of the data migration without staging tables&lt;/em>&lt;/p>
&lt;p>The following example shows how to migrate items without staging tables:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">trigger&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnRun&lt;span style="color:#ce5c00;font-weight:bold">()&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Item Data Migration Facade&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemNumber&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemJson&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// loop on items retrieved through a web service for example
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">for&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemNumber&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">to&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ExternalWebService&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetItemCount&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">do&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ExternalWebService&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetItem&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemNumber&lt;span style="color:#000;font-weight:bold">,&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// create item using the facade
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">not&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>CreateItemIfNeeded&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemNumber&lt;span style="color:#000;font-weight:bold">,&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemName1&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemName2&lt;span style="color:#000;font-weight:bold">,&lt;/span>ConvertItemType&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemType&lt;span style="color:#ce5c00;font-weight:bold">)) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">exit&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// item already exists
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// set some fields using the facade
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetVendorItemNo&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>VendItemNumber&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetUnitVolume&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Volume&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetAlternativeItemNo&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>AltItemNumber&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>PrimaryVendor&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetVendorNo&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>PrimaryVendor&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// migrate dependencies
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MigrateItemUnitOfMeasure&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemDataMigrationFacade&lt;span style="color:#000;font-weight:bold">,&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// modify the item (+run trigger) to save the changes made by setters
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ModifyItem&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// update the status in the migration dashboard
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DataMigrationStatusFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>IncrementMigratedRecordCount&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;My Migration Type&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Database&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>Item&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">procedure&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MigrateItemUnitOfMeasure&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemDataMigrationFacade&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Item Data Migration Facade&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemJson&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyUnitCodeStagingTable&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;My Unit Code Staging Table&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DataMigrationStatusFacade&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Data Migration Status Facade&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DescriptionToSet&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">10&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>UnitCodeJson&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// log an error using the Data migration façade
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DataMigrationStatusFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RegisterErrorNoStagingTablesCase&lt;span style="color:#ce5c00;font-weight:bold">(
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;My Migration Type&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Database&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>Item&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;Unit of measure is empty.&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ExternalWebService&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetUnitCode&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>UnitCodeJson&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DescriptionToSet&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>UnitCodeJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Description&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>CreateUnitOfMeasureIfNeeded&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DescriptionToSet&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// set the unit of measure on the item
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ItemDataMigrationFacade&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetBaseUnitOfMeasure&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ItemJson&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;em>Figure 2: Example of Item and Item Unit of Measure migration without staging tables&lt;/em>&lt;/p>
&lt;h3 id="usage-with-staging-tables">Usage with staging tables:&lt;/h3>
&lt;p>The overall workflow is:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Integrate your extension in the Data Migration Wizard by subscribing to the events exposed by the &lt;strong>Data Migration Façade&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>From there, initialize the status of the migration so it can be displayed in the &lt;strong>Data Migration Overview: &amp;ldquo;Data Migration Status Façade&amp;rdquo;.InitStatusLine(&amp;lsquo;My Migration Type&amp;rsquo;,Database::Item,42000,Database::&amp;ldquo;My extension Staging table for items&amp;rdquo;,0)&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>You can either fill the staging tables from the wizard events, or in a subscriber to the event dedicated to filling staging tables (&lt;strong>&amp;lsquo;OnFillStagingTables&amp;rsquo;&lt;/strong> in codeunit 6100): in this case, the import of data from the files to the staging tables will be done in the background.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Launch the migration: &lt;strong>&amp;ldquo;Data Migration Façade&amp;rdquo;.StartMigration(&amp;lsquo;My Migration Type&amp;rsquo;,false)&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Subscribe to the events to migrate entities and their dependencies.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>From the event subscribers, call the façade procedures to create entities and set their field values:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&amp;ldquo;Item Data Migration Façade&amp;rdquo;.CreateItemIfNeeded(&amp;lsquo;ITEM042&amp;rsquo;,&amp;lsquo;My Item Description&amp;rsquo;;&amp;lsquo;My Item Description 2&amp;rsquo;;ItemTypeToSet::Inventory)&lt;/strong>&lt;/li>
&lt;li>&lt;strong>&amp;ldquo;Item Data Migration Façade&amp;rdquo;.SetBaseUnitOfMeasure(&amp;lsquo;BOX&amp;rsquo;)&lt;/strong>&lt;/li>
&lt;li>&lt;strong>&amp;ldquo;Item Data Migration Façade&amp;rdquo;.ModifyItem(true)&lt;/strong>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="StagingTableNew2.png">&lt;img src="StagingTableNew2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 3: Simplified sequence diagram of the data migration with staging tables&lt;/em>&lt;/p>
&lt;p>Below is a simplified example showing how to create an item:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">[EventSubscriber&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ObjectType&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Item Data Migration Facade&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;OnMigrateItem&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">procedure&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnMigrateItem&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Item Data Migration Facade&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>RecordIdToMigrate&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordId&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyItemStagingTable&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;My Item Staging Table&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// handle the event if it targets this extension&amp;#39;s staging table
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RecordIdToMigrate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TableNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Database&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;My Item Staging Table&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">exit&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Get&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecordIdToMigrate&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// create item using the facade
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">not&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>CreateItemIfNeeded&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemNumber&lt;span style="color:#000;font-weight:bold">,&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemName1&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemName2&lt;span style="color:#000;font-weight:bold">,&lt;/span>ConvertItemType&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ItemType&lt;span style="color:#ce5c00;font-weight:bold">)) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">exit&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// item already exists
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// set some fields using the facade
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetVendorItemNo&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>VendItemNumber&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetUnitVolume&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Volume&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetAlternativeItemNo&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>AltItemNumber&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>PrimaryVendor&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetVendorNo&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>PrimaryVendor&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// modify the item (+run trigger) to save the changes made by setters
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ModifyItem&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;em>Figure 4: Example of event subscriber for Item migration&lt;/em>&lt;/p>
&lt;p>Below is another example showing how to use additional events to set fields that reference other tables, here the unit of measure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">[EventSubscriber&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ObjectType&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Item Data Migration Facade&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;OnMigrateItemUnitOfMeasure&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">procedure&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnMigrateItemUnitOfMeasure&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Item Data Migration Facade&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>RecordIdToMigrate&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordId&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyItemStagingTable&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;My Item Staging Table&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyUnitCodeStagingTable&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;My Unit Code Staging Table&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DescriptionToSet&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">10&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// handle the event if it targets this extension&amp;#39;s staging table
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RecordIdToMigrate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TableNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Database&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;My Item Staging Table&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">exit&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Get&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecordIdToMigrate&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>error&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;Unit of measure is empty.&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyUnitCodeStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetRange&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>UnitCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyUnitCodeStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FindFirst&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DescriptionToSet&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MyUnitCodeStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Description&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// create the unit of measure through the facade
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>CreateUnitOfMeasureIfNeeded&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DescriptionToSet&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// set the unit of measure on the item
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetBaseUnitOfMeasure&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MyItemStagingTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UnitCode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// modify the item to save the changes made by setter
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Sender&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ModifyItem&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>false&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;em>Figure 5: Example of event subscriber for Item Unit of Measure migration&lt;/em>&lt;/p>
&lt;h3 id="combining-both-approaches">Combining both approaches:&lt;/h3>
&lt;p>If you want to migrate additional entities, the &lt;strong>Data Migration&lt;/strong> framework lets you initialize the migration with entities other than master data. In this case, the &lt;strong>Data Migration Overview&lt;/strong> page will show additional lines. Item, vendor, customer, an general ledger accounts are migrated with an event driven approach, and the additional entities are migrated by calling an extension codeunit &lt;strong>OnRun&lt;/strong> method.&lt;/p>
&lt;h2 id="error-handling-with-staging-tables">Error handling with staging tables:&lt;/h2>
&lt;p>The migration starts by calling &lt;strong>RUN&lt;/strong> on the façade codeunit. Errors thrown during the call are captured by &lt;strong>GETLASTERRORTEXT&lt;/strong> and displayed when you choose the &lt;strong>Show Errors&lt;/strong> action on the &lt;strong>Data Migration Overview&lt;/strong> page.&lt;/p>
&lt;p>&lt;a href="errorhandling1.png">&lt;img src="errorhandling1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 6: List of errors shown when clicking &lt;strong>Show Errors&lt;/strong> on the &lt;strong>Data Migration Overview&lt;/strong> page&lt;/em>&lt;/p>
&lt;p>The &lt;strong>Edit Record&lt;/strong> action opens a view of the staging table, where you can edit fields to fix errors. Figure 4 shows an example of a page for the vendor staging table in a migration from C5.&lt;/p>
&lt;p>&lt;a href="errorhandling2.png">&lt;img src="errorhandling2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 7: Edit a staging table record&lt;/em>&lt;/p>
&lt;p>The &lt;strong>Staging Table ID&lt;/strong> determines the page to open, so it is important that the page ID is equal to the &lt;strong>Staging Table ID&lt;/strong>, at least for the master data staging tables, for example, for &lt;strong>G/L Accounts, Items, Customers&lt;/strong> and &lt;strong>Vendor&lt;/strong>. You should ensure that pages to edit related entities are linked on this page by means of new actions. For example, Figure 4 uses the &lt;strong>C5 Purchaser&lt;/strong> action.&lt;/p>
&lt;p>After you fix the staging table record, you can choose the &lt;strong>Migrate&lt;/strong> action to mark the selected records as records to retry, and then run &lt;strong>StartMigration&lt;/strong> with the &lt;strong>Retry&lt;/strong> flag set to true. This is the only place where the retry flag should be set to true in the &lt;strong>StartMigration&lt;/strong> procedure.&lt;/p>
&lt;p>Error handling without staging tables&lt;/p>
&lt;p>When migrating data without staging tables, errors can be registered manually by the extension using &lt;strong>DataMigrationStatusFacade.RegisterErrorNoStagingTablesCase&lt;/strong>. Otherwise they can be registered automatically if the codeunits fail when called on their &lt;strong>OnRun&lt;/strong> procedure.&lt;/p>
&lt;p>Errors will be displayed in the error list, but you cannot open and edit records because there is no staging table. The Edit action will not be available.&lt;/p>
&lt;h2 id="limitations">Limitations:&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>Data migration will fail if there are customers, vendors, items in the database and if these entities are selected for migration. For example, if you choose to migrate items and your company already contains items, you will get an error. This should not be an issue if you migrate your data from another tool to NAV, in which case you will most likely start on a fresh empty company. However, if you just want to import additional items to a company with existing items, then it is not supported by the framework. however, you can still use the different functions provided by the different codeunits (such as &lt;strong>Item Data Migration Facade&lt;/strong>) to create the entities without strong coupling on the NAV data model.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>G/L entries&lt;/strong> are deleted automatically.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>There is no automated rollback in case of failure: data that is successfully migrated will be commited, and data that is not successfully migrated with be shown in the errors list. The retry feature (in case of staging tables) then makes it possible for you to retry individual entities or ignore them.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="usages-in-nav">Usages in NAV:&lt;/h2>
&lt;p>The Data Migration Façade is available starting from version 2018.&lt;/p>
&lt;p>The following Façade codeunits for data migration management are available:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>COD6100 (&lt;strong>Data Migration Facade&lt;/strong>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>COD6101 (&lt;strong>Data Migration Status Facade&lt;/strong>)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>The following Entity data migration façade codeunits are available:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>COD6110 (&lt;strong>GL Acc. Data Migration Facade&lt;/strong>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>COD6111 (&lt;strong>Vendor Data Migration Facade&lt;/strong>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>COD6112 (&lt;strong>Customer Data Migration Facade&lt;/strong>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>COD6113 (&lt;strong>Item Data Migration Facade&lt;/strong>)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>COD6114 (&lt;strong>Ex. Rate Data Migration Facade&lt;/strong>)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="references">References:&lt;/h2>
&lt;p>Façade pattern on Wikipedia: &lt;a href="https://en.wikipedia.org/wiki/Facade_pattern">https://en.wikipedia.org/wiki/Facade_pattern&lt;/a>&lt;/p></description></item><item><title>Docs: Discovery Event</title><link>https://alguidelines.dev/docs/navpatterns/patterns/discovery-event/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/discovery-event/</guid><description>
&lt;p>&lt;em>by waldo&lt;/em>&lt;/p>
&lt;h1 id="abstract">Abstract&lt;/h1>
&lt;p>The &amp;ldquo;Discovery Event&amp;rdquo; pattern is a way for a generic functionality, to call out to other functionalities that want to make use of it, by raising an event, so that they have an event to subscribe to. This is usually done to set itself up within the generic app.&lt;/p>
&lt;h1 id="the-problem">The problem&lt;/h1>
&lt;p>Let&amp;rsquo;s suppose you have a generic piece of functionality, that hooks into lots of places (modules) in your application. To set this up, you might have to hook into all these parts of the application. Well, this pattern turns this setup around: let all the different modules set itself up in the generic app by raising a &amp;ldquo;discovery event&amp;rdquo;.&lt;/p>
&lt;h1 id="usage">Usage&lt;/h1>
&lt;p>The pattern is most easily described when you look at an example. This example is an actual usage of the pattern within the application, in page &lt;strong>Service Connections.&lt;/strong>&lt;/p>
&lt;p>&lt;a href="ServiceConnections.jpg">&lt;img src="ServiceConnections.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>The goal of this functionality is to:&lt;/p>
&lt;ul>
&lt;li>List all the different connections to external services,&lt;/li>
&lt;li>Have a central place to navigate to the corresponding setup of the service.&lt;/li>
&lt;/ul>
&lt;p>The functionality (&lt;strong>Service Connections&lt;/strong>) itself, is not aware of the state nor setup nor any context of all the different services in the list. All it does is:&lt;/p>
&lt;ul>
&lt;li>It raises an event as an opportunity for all services within the NAV application to subscribe to,&lt;/li>
&lt;li>It has a public function &lt;strong>InsertServiceConnection&lt;/strong> that the subscribers can use to register itself at the Service Connection.&lt;/li>
&lt;/ul>
&lt;p>The event &lt;strong>OnRegisterServiceConnection&lt;/strong> is raised when the page (1279 - &lt;strong>Service Connections&lt;/strong>) is opened.&lt;/p>
&lt;p>One example of a subscription is the SMTP setup. In Codeunit 400 you&amp;rsquo;ll find the subscriber function &lt;strong>HandleSMTPRegisterServiceConnection&lt;/strong> which subscribes to this discovery event, and calls the &lt;strong>InsertServiceConnection&lt;/strong> to register itself.&lt;/p>
&lt;h1 id="description">Description&lt;/h1>
&lt;p>The main idea of this pattern is: &amp;ldquo;Discover the settings, the context, the records, &amp;hellip; which I need for my functionality&amp;rdquo; or &amp;ldquo;Discover the configuration for my functionality&amp;rdquo;. In any case, &amp;ldquo;discover&amp;rdquo; is the main idea. It&amp;rsquo;s a pattern where using both publishers and subscribers in one application makes a lot of sense.&lt;br>
Let&amp;rsquo;s break down to the steps that are needed to implement the pattern.&lt;/p>
&lt;h2 id="step-1-publish-the-event">Step 1: Publish the event&lt;/h2>
&lt;p>In the below example, I create a table &lt;strong>Module Status&lt;/strong> with a published event &lt;strong>OnDiscoverModuleStatuses&lt;/strong>.&lt;/p>
&lt;p>&lt;a href="Pic2.jpg">&lt;img src="Pic2.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>You see that I also include the sender. This way, I will be able to access the methods on my table (which I use as a class). Obviously, other patterns can be applied here as well, like the Argument Table pattern.&lt;/p>
&lt;h2 id="step-2-raise-the-event-on-the-right-place">Step 2: Raise the event on the right place&lt;/h2>
&lt;p>When you publish an event, it should obviously be raised somewhere in the code as well. In the below example, I want to raise the event simply by a method which I want to call from a page. So I create a global function where I raise the event:&lt;/p>
&lt;p>&lt;a href="Pic2b.jpg">&lt;img src="Pic2b.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="step-3-create-one-or-more-global-functions-so-that-your-subscriber-can-call-into-your-functionality-to-configure-set-up-or-do-whatever-it-needs-to-do-to-make-itself-discoverable">Step 3: Create one or more global functions, so that your subscriber can call into your functionality to configure, set up, or do whatever it needs to do to make itself discoverable&lt;/h2>
&lt;p>The generic functionality that I want to call, should be part of the main class - in this case the &lt;strong>Module Discovery&lt;/strong> class, or better, the table (&lt;strong>Module Status&lt;/strong>). In this table, I create this global function, because I want to make it available for the subscribers:&lt;/p>
&lt;p>&lt;a href="Pic3.jpg">&lt;img src="Pic3.jpg" alt=" ">&lt;/a>&lt;br>
The business logic doesn&amp;rsquo;t really matter for this pattern. This is obviously dependent on the functionality where you would like to implement the pattern.&lt;/p>
&lt;h2 id="step-4-subscribe-from-the-places-in-the-app-to-this-event-use-the-global-functions">Step 4: subscribe from the places in the app to this event, use the global function(s)&lt;/h2>
&lt;p>This could be anywhere. Any module within your vertical, of within the main application, can subscribe to the event. In the example below, I create the subscriber in Codeunit80, as I was interested in the status of the Sales-module in default NAV.&lt;br>
The exact place of the subscriber is up to you. The main message is that it&amp;rsquo;s part of the module that wants to subscribe, and not part of the &lt;strong>Module Status&lt;/strong> module in the application.&lt;br>
Here is the subscriber (and one small helper function):&lt;/p>
&lt;p>&lt;a href="Pic4.jpg">&lt;img src="Pic4.jpg" alt=" ">&lt;/a>&lt;br>
You see I can use the &amp;ldquo;sender&amp;rdquo; as a normal Record-variable. I access the previously created global function to &amp;ldquo;register&amp;rdquo; this sales-module.&lt;/p>
&lt;h1 id="microsoft-dynamics-nav-versions">Microsoft Dynamics NAV Versions&lt;/h1>
&lt;p>This pattern only works with Microsoft Dynamics &lt;strong>NAV 2016 and up.&lt;/strong>&lt;/p></description></item><item><title>Docs: Document</title><link>https://alguidelines.dev/docs/navpatterns/patterns/document/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/document/</guid><description>
&lt;p>&lt;em>By Xavier Garonnat, knk Ingénierie (France), xgaronnat@knk.fr&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>A document structure contains a header and a set of lines. Each line is linked to the header and could have common data with header.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>This pattern should be used as a basis to build any document, showing a header and multiple lines in the same page. Basically, a document is at least composed of two tables and three pages, as shown below:&lt;/p>
&lt;p>&lt;a href="0005.Document-Pattern-UML-Class-Diagram.jpg">&lt;img src="0005.Document-Pattern-UML-Class-Diagram.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>You should use it any time you have to capture and store a document.&lt;/p>
&lt;h2 id="example">Example&lt;/h2>
&lt;p>To build this example from scratch, you will need:&lt;/p>
&lt;ul>
&lt;li>Two tables, one for the header (called &amp;ldquo;Document Header&amp;rdquo;), and one for the document lines (called &amp;ldquo;Document Line&amp;rdquo;). Each document will be composed of &amp;ldquo;1 to N&amp;rdquo; line(s).&lt;/li>
&lt;li>Three pages, one for the header, one for the subpage (lines), and the last for the document list obviously.Table &amp;ldquo;Document Header&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Table &amp;ldquo;Document Header&amp;rdquo;&lt;/strong>: Is the &amp;ldquo;header&amp;rdquo; table of your document (like Sales Header, Purchase Header, Transfer Header &amp;hellip;)&lt;/p>
&lt;ul>
&lt;li>Add a field &amp;ldquo;No.&amp;rdquo; (Code 20): Should be the first field and primary key of your documents, to be driven by Serial No. (See corresponding design pattern)&lt;/li>
&lt;/ul>
&lt;p>For this sample, I just added a &amp;ldquo;Sell-to Customer No.&amp;rdquo; to this table. Don&amp;rsquo;t forget to manage deletion of lines with trigger OnDelete().&lt;/p>
&lt;p>&lt;strong>Table &amp;ldquo;Document Line&amp;rdquo;&lt;/strong>: will store the lines of the document&lt;/p>
&lt;ul>
&lt;li>Add a field &amp;ldquo;Document No.&amp;rdquo; (Code 20): Should be the first field and is related to table &amp;ldquo;Document Header&amp;rdquo;: set TableRelation to your &amp;ldquo;Document Header&amp;rdquo; table&lt;/li>
&lt;li>Add a field &amp;ldquo;Line No.&amp;rdquo; (Integer): this field will be populated automatically by the subpage Page (see AutoSplitKey)&lt;/li>
&lt;/ul>
&lt;p>First (Primary) Key must be &amp;ldquo;Document No.,Line No.&amp;rdquo;. On table properties, set PasteIsValid to No (to avoid copying/pasting lines, will be implemented by &amp;ldquo;Copy document&amp;rdquo;, another pattern).&lt;/p>
&lt;p>For my sample, I just add a couple of fields: &amp;ldquo;Item No.&amp;rdquo; and &amp;ldquo;Quantity&amp;rdquo; to this table (just copy/paste standard fields from &amp;ldquo;Sales Line&amp;rdquo; table and delete trigger code, this will insure that each field will be well designed)&lt;/p>
&lt;p>&lt;strong>Page &amp;ldquo;Document Subpage&amp;rdquo;&lt;/strong>: will display the lines in the main form, and will be in charge of assigning line number automatically.&lt;/p>
&lt;p>Create the page for table &amp;ldquo;Document Line&amp;rdquo; with the wizard by selecting the ListPart template, add all yours fields except the primary key (&amp;ldquo;Document No.&amp;rdquo; and &amp;ldquo;Line No.&amp;quot;).&lt;/p>
&lt;p>Then edit the properties:&lt;/p>
&lt;ul>
&lt;li>Set AutoSplitKey, DelayedInsert and MultipleNewLines to Yes: this combination will make your subpage work as required.&lt;/li>
&lt;li>AutoSplitKey is used to set NAV calculate the last field of the key (&amp;ldquo;Line No.&amp;quot;) with proper numbers (10000, 20000&amp;hellip;).&lt;/li>
&lt;/ul>
&lt;p>Set caption to &amp;ldquo;Lines&amp;rdquo;. Save your page, we will use it on the next step.&lt;/p>
&lt;p>&lt;strong>Page &amp;ldquo;Document&amp;rdquo;&lt;/strong>: will display the document, and the lines with subpage.&lt;/p>
&lt;p>Create the page for &amp;ldquo;Document Header&amp;rdquo; Table with the wizard by selecting the Document template:&lt;/p>
&lt;ul>
&lt;li>Add a General FastTab&lt;/li>
&lt;li>Add all the revelant fields for the user (or at least &amp;ldquo;No.&amp;quot;)&lt;/li>
&lt;li>Click Finish to close the wizard&lt;/li>
&lt;/ul>
&lt;p>Then simply add your subpage as new line in the designer, and adjust the property &amp;ldquo;SubFormPerLink&amp;rdquo; with &amp;ldquo;Document No.=FIELD(No.)&amp;rdquo; to link header and lines :&lt;/p>
&lt;p>&lt;a href="2086.Design-Pattern-Document-SubPage-Properties.png">&lt;img src="2086.Design-Pattern-Document-SubPage-Properties.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Page &amp;ldquo;Document List&amp;rdquo;:&lt;/strong> Use the Page wizard to create a List page based on the Document table and add fields, FactBox (RecordLinks, Notes&amp;hellip;), etc.&lt;/p>
&lt;p>Once created:&lt;/p>
&lt;ul>
&lt;li>Set Editable to No on the List&lt;/li>
&lt;li>CardPageID to Page &amp;ldquo;Document&amp;rdquo; to enable New/Edit/&amp;hellip; Pane actions.&lt;/li>
&lt;/ul>
&lt;p>Save our page and add it to the Role Page &amp;ldquo;Order Processor Role Center&amp;rdquo; for example.&lt;/p>
&lt;p>Now, observe how &amp;ldquo;Line No.&amp;rdquo; is calculated on the first line, and when inserting a new line between the first and second one.&lt;/p>
&lt;p>Code sample (copy link to your browser) : &lt;a href="https://knk1fr-my.sharepoint.com/personal/xgaronnat_knk_fr/_layouts/15/guestaccess.aspx?guestaccesstoken=hL0P%2fyQ1ZreY5KlSPc%2b8dHrO4zjUkqQbg8DnGSbgd1Y%3d&amp;amp;docid=02b3cb93e1ff1459380891795fb8441fc">https://knk1fr-my.sharepoint.com/personal/xgaronnat_knk_fr/_layouts/15/guestaccess.aspx?guestaccesstoken=hL0P%2fyQ1ZreY5KlSPc%2b8dHrO4zjUkqQbg8DnGSbgd1Y%3d&amp;amp;docid=02b3cb93e1ff1459380891795fb8441fc&lt;/a>&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>So many: Sales Order, Purchase Order, Transfer Order, Assembly Order&amp;hellip;&lt;/p>
&lt;p>For posted document, it&amp;rsquo;s quite similar, but you don&amp;rsquo;t have to setup subpage properties like AutoSplitKey, used for data entry purpose only (and your pages content should be mainly read-only / non editable).&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;ul>
&lt;li>A new property like &amp;ldquo;AutoSplitStartNumber&amp;rdquo;, enabled if AutoSplitKey=Yes, default value with &amp;lt;10000&amp;gt;. Allow to change the numbers of created line.&lt;/li>
&lt;li>Be able to copy/paste header AND lines or import header and line from an Excel file.&lt;/li>
&lt;/ul>
&lt;h2 id="when-it-should-not-be-used">When it should not be used&lt;/h2>
&lt;p>This pattern is mainly used for Documents, and may not be used directly for Master data or any other table (Setup, Supplemental, etc&amp;hellip;).&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>Use Series No. Pattern for your documents, and Copy Document to implement document duplication.&lt;/p>
&lt;h2 id="references">References&lt;/h2>
&lt;p>Walkthrough: Creating a Document Page : &lt;a href="http://msdn.microsoft.com/en-us/library/dd338599(v=nav.71).aspx" title="http://msdn.microsoft.com/en-us/library/dd338599(v=nav.71).aspx">http://msdn.microsoft.com/en-us/library/dd338599(v=nav.71).aspx&lt;/a>&lt;br>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/S9cRD2D4c0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;/p></description></item><item><title>Docs: Easy Update Of Setup Or Supplementary Information</title><link>https://alguidelines.dev/docs/navpatterns/patterns/easy-update-of-setup-or-supplementary-information/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/easy-update-of-setup-or-supplementary-information/</guid><description>
&lt;p>&lt;em>Originally by Anders Larsen at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>Users or the administrator must regularly update setup or supplementary information in the day-to-day business, such as setting up a new type of customer. This setup task often arrives when their focus is on registration and execution instead of setup.&lt;/p>
&lt;p>The navigation experience around these extra steps is often quite troublesome and time-consuming. To enable users to easily perform the needed update, a guide often gives the best support.&lt;/p>
&lt;p>To guide users, we can prompt them with a dialog on which they can update the setup or supplementary information instantly and easily, so that they can proceed with the business task without being side-tracked.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>Define two functions in the setup or supplementary table: One for verifying if the needed information is available, and another for exposing the page that contains the fields that the user must update.&lt;/p>
&lt;p>Call the code. For example:&lt;/p>
&lt;pre tabindex="0">&lt;code>Local IsXAvailable : Boolean
If field X &amp;lt;&amp;gt; '' then
Exit(True)
Exit(false)
VerifyAndSetX
If IsXAvailable then
Exit;
If Confirm('Field X is missing a value. Do you want to update it now?') then
Open the card page in edit mode
If not IsXAvailable then
Error(Field X is missing a value. Please correct it.)
&lt;/code>&lt;/pre>&lt;p>The calling code&lt;/p>
&lt;pre tabindex="0">&lt;code>..
SetupTable.VerifyAndSetX
..
&lt;/code>&lt;/pre>&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;p>In the &lt;strong>Sales &amp;amp; Receivables Setup&lt;/strong> table (311) for the DK version, the following procedures have been added:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">Local&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Procedure&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>IsOIOUBLPathAvailable&lt;span style="color:#ce5c00;font-weight:bold">(...)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Procedure&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VerifyAndSetOIOUBLPath&lt;span style="color:#ce5c00;font-weight:bold">(...)
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The code in the &lt;strong>Sales &amp;amp; Receivables Setup&lt;/strong> table can now be called directly from the related processing codeunit, such as the &lt;strong>Sales-Post + Print&lt;/strong> codeunit (82).&lt;/p>
&lt;p>Were the code is called:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;EAN No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>VerifyAndSetOIOUBLPathSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If the setup is not updated properly, the user is prompted to update it as follows.&lt;/p>
&lt;p>&lt;a href="0654.easy-update-1.png">&lt;img src="0654.easy-update-1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Choosing &lt;strong>Yes&lt;/strong> opens the related setup page.&lt;/p>
&lt;p>&lt;a href="4024.easy-update-2.png">&lt;img src="4024.easy-update-2.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;ul>
&lt;li>Report 206, &lt;strong>Sales invoice&lt;/strong>&lt;/li>
&lt;li>Table 79, &lt;strong>Company Information&lt;/strong>&lt;/li>
&lt;li>In OIOUBL fields (DK version) during posting/printing of a sales invoice.&lt;/li>
&lt;/ul>
&lt;h2 id="ideas-for-improvement">Ideas for Improvement&lt;/h2>
&lt;p>Make a more generic platform implementation that launches the corresponding card page for Rec on Rec.testfield with an asterisk mark for the field that needs a proper value.&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>The anti-pattern is to do a testfield on a field that is not in the table that you are currently updating.&lt;/p>
&lt;p>The test field message can often be confusing because the pages are often named differently than the tables, which can lead to misunderstanding and context-switching.&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/oeASJN-zqTo" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Error Message Processing</title><link>https://alguidelines.dev/docs/navpatterns/patterns/error-message-processing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/error-message-processing/</guid><description>
&lt;p>&lt;em>By Jesper Schulz at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;p>Note: This pattern describes new functionality which makes it possible to generalize the &lt;a href="https://alguidelines.dev/navpatterns/1-patterns/journal-error-processing/">Journal Error Processing&lt;/a> pattern.&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>Missing, invalid or incomplete data is a common issue during data processing in NAV. This article describes how to collect all error messages during processing using the error message component and present them to the user in a unified way, which enables the user to correct the errors efficiently. By leveraging the integrated error message logging functions, you can log a message with a single line of code and present it to the user with another one-liner.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>This article describes how to use the Error Message component in NAV, which in short gives you the possibility to:&lt;/p>
&lt;ol>
&lt;li>Link an error message to the page which enables you to resolve the problem.&lt;/li>
&lt;li>Assemble all error messages in one central view instead of having to encounter them one by one.&lt;/li>
&lt;/ol>
&lt;p>Validating data is a common task during data processing in NAV. Unfortunately, validation is often done using NAV&amp;rsquo;s integrated ERROR and TESTFIELD functions, which halt execution of the process. The user will then have to locate the invalid / missing data, correct it and reinitiate the process, possibly running into the next error, making the cycle repeat itself. This can be a very tedious, time-consuming and frustrating process. The error message component aims at improving this experience by providing a lightweight framework for error message logging and this article will explain how to leverage this functionality in your code. By doing so, all error messages are gathered during (pre-)processing and are finally presented to the user. The user then has the possibility to click on the error message, which will open the record where the invalid / missing data is located, thereby enabling the user to correct all mistakes efficiently, from one central place and in one go.&lt;/p>
&lt;p>The example below comes from a Mexican localization, where the user has to export financial balances and transactions into an XML file for government audit purposes. In order to generate valid files, some mandatory data needs to be entered in the system. By leveraging the error message component, the user will be presented with the following page, if missing or invalid data was discovered:&lt;/p>
&lt;p>&lt;a href="image001.png">&lt;img src="image001.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>By clicking on the error message, the user will be presented with the entity, where the invalid / missing data should be corrected / added. This is done by applying the related pattern &lt;a href="https://alguidelines.dev/navpatterns/1-patterns/easy-update-of-setup-or-supplementary-information/">Easy Update of Setup or Supplementary Information&lt;/a>.&lt;/p>
&lt;p>&lt;a href="image003.png">&lt;img src="image003.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>In the processing function, define a temporary record of type &amp;ldquo;Error Message&amp;rdquo;. Use the functions on that record to populate the record with error message, a few of them being:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>LogIfEmpty&lt;/strong>&lt;/li>
&lt;li>&lt;strong>LogIfLengthExceeded&lt;/strong>&lt;/li>
&lt;li>&lt;strong>LogIfInvalidCharacters&lt;/strong>&lt;/li>
&lt;li>&lt;strong>LogIfOutsideRange&lt;/strong>&lt;/li>
&lt;li>&lt;strong>LogIfGreaterThan&lt;/strong>&lt;/li>
&lt;li>&lt;strong>LogIfEqualTo&lt;/strong>&lt;/li>
&lt;li>&lt;strong>LogMessage&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>The following parameters must be provided to these functions:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Record:&lt;/strong> The record which you want to check&lt;/li>
&lt;li>&lt;strong>Field Number:&lt;/strong> The field number of the field you want to verify the value of&lt;/li>
&lt;li>&lt;strong>Condition:&lt;/strong> The condition the field must meet (e.g. length, range, valid characters)&lt;/li>
&lt;li>&lt;strong>Message Type:&lt;/strong> The type of message, which can be Error, Warning or Message&lt;/li>
&lt;/ul>
&lt;p>When the processing is complete, you can check if any error messages of type &amp;ldquo;Error&amp;rdquo; were logged by calling the &lt;strong>HasErrors&lt;/strong> function and you can show the list or error messages by calling the &lt;strong>ShowErrorMessages&lt;/strong> function. You can also integrate the error messages list as a FactBox, but that is not part of this example.&lt;/p>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;p>The code below is an example of how the error message component was used in one part of the before mentioned Mexican feature. This code iterates over all G/L Accounts and pipes information out into an XML file. While doing so, it is validated that all mandatory fields have values and meet certain conditions. And only if that is the case, is the XML document actually exported. Also notice, that an error message is logged, in case no G/L Accounts are found given the provided filters. That way, the user can be guided to setup the system correctly.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ExportChartOfAccounts@&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Year@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>Month@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempErrorMessage@&lt;span style="color:#0000cf;font-weight:bold">1003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TEMPORARY&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">700&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ClearLog&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// only necessary if variable is global
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">...
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>CreateXMLHeader&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Document&lt;span style="color:#000;font-weight:bold">,&lt;/span>RootNode&lt;span style="color:#000;font-weight:bold">,&lt;/span>CatalogoNodeTxt&lt;span style="color:#000;font-weight:bold">,&lt;/span>Namespace&lt;span style="color:#000;font-weight:bold">,&lt;/span>Year&lt;span style="color:#000;font-weight:bold">,&lt;/span>Month&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;1.1&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>LogIfEmpty&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GLAccount&lt;span style="color:#000;font-weight:bold">,&lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FIELDNO&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Name&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Message Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Error&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XMLDOMManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>AddElement&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RootNode&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;Ctas&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>Namespace&lt;span style="color:#000;font-weight:bold">,&lt;/span>Node&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XMLDOMManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>AddAttribute&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Node&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;CodAgrup&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;SAT Account Code&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">...
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">CASE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Debit/Credit&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Debit/Credit&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Debit&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XMLDOMManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>AddAttribute&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Node&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;Natur&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;D&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Debit/Credit&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Credit&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XMLDOMManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>AddAttribute&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Node&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;Natur&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;A&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>LogMessage&lt;span style="color:#ce5c00;font-weight:bold">(
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>GLAccount&lt;span style="color:#000;font-weight:bold">,&lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FIELDNO&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Debit/Credit&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Message Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Error&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>STRSUBSTNO&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GLAccountTypeErr&lt;span style="color:#000;font-weight:bold">,&lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Debit/Credit&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">RECORDID&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GLAccount&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>LogSimpleMessage&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Message Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Error&lt;span style="color:#000;font-weight:bold">,&lt;/span>NoSATAccountDefinedErr&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>HasErrors&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SaveXMLToClient&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Document&lt;span style="color:#000;font-weight:bold">,&lt;/span>Year&lt;span style="color:#000;font-weight:bold">,&lt;/span>Month&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;CT&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempErrorMessage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ShowErrorMessages&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FALSE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>One could also do pre-processing in a function of its own, and only if the pre-processing results in no error messages of type &amp;ldquo;Error&amp;rdquo; would the processing continue.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>By using this easy to use component, we have the possibility to extend this functionality going forward. A nice addition to the error message component would be the possibility to log the error messages persistently in a grouped manner, thereby allowing 3rd parties to see the issues the users bump into the most, or allowing 3rd parties to get an detailed insight into what happened, thereby enabling them to provide better support.&lt;/p></description></item><item><title>Docs: Extending the Role Center Headlines</title><link>https://alguidelines.dev/docs/navpatterns/patterns/extending-the-role-center-headlines/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/extending-the-role-center-headlines/</guid><description>
&lt;p>&lt;em>By David Bastide at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;p>&lt;a href="3733.logo.png">&lt;img src="3733.logo.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="context">Context&lt;/h2>
&lt;p>Headlines are designed as a page of type HeadlinePart containing at least one text field. The part is added to the top of Role Center pages.&lt;br>
This document provides an elegant and extensible pattern about how to extend the Role Center headlines to add your own business headlines based on your data, and display them only if relevant.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>The Dynamics 365 Business Central release (April 2018) introduces a new HeadlinePart page type. This page type defines a page that rotates a display of several headlines after another, in the web client. A user can also click to switch to another headline. Headlines can also include a drilldown action that will be invoked when the user clicks the headline Text of the payload can be emphasized.&lt;br>
Headlines are divided in 2 parts: the qualifier, and the payload as you can see in the figure below.&lt;/p>
&lt;p>&lt;a href="Headline.png">&lt;img src="Headline.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 1: Qualifier, Payload and emphasized text.&lt;/em>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>A page part has been added to each major Role Center:&lt;/p>
&lt;ul>
&lt;li>Page 9006 Order Processor Role Center, contains Page 1441 Headline RC Order Processor&lt;/li>
&lt;li>Page 9015 Job Project Manager RC, contains Page 1443 Headline RC Project Manager&lt;/li>
&lt;li>Page 9022 Business Manager Role Center, contains Page 1440 Headline RC Business Manager&lt;/li>
&lt;li>Page 9024 Security Admin Role Center, contains Page 1445 Headline RC Administrator&lt;/li>
&lt;li>Page 9026 Sales &amp;amp; Relationship Mgr. RC, contains Page 1444 Headline RC Relationship Mgt.&lt;/li>
&lt;li>Page 9027 Accountant Role Center, contains Page 1442 Headline RC Accountant&lt;/li>
&lt;li>Page 9028 Team Member Role Center, contains Page 1446 Headline RC Team Member&lt;/li>
&lt;li>Page 9010 Production Planner Role Center, contains Page 1447 Headline RC Prod. Planner&lt;/li>
&lt;li>Page 9016 Service Dispatcher Role Center, contains Page 1448 Headline RC Serv. Dispatcher&lt;/li>
&lt;/ul>
&lt;p>You can create extensions that extend these pages to add your own headlines.&lt;br>
If no headline is added on these pages, fallback headlines will be displayed.&lt;/p>
&lt;p>The process to extend the headlines of a Role Center is simple:&lt;/p>
&lt;ol>
&lt;li>In a V2 extension, extend the pages (PAG1440 to 1446) with one or more fields you want to add as headlines. The field and its visibility should be variables that are populated in OnAfterGetRecord.&lt;/li>
&lt;li>Subscribe to the OnComputeHeadlines event from the codeunits associated with the page (same ID and name as the page). Here you can compute your headlines. You should store the result in a table in your extension, so you can quickly get the results in step 3. The computation is done in a background task, not to decrease the performance of the role center pages.&lt;/li>
&lt;li>Subscribe to the OnIsAnyExtensionHeadlineVisible event from the page. This event is used to determine if any extension has visible headlines, and if so, hide the fallback headlines. You should set the ExtensionHeadlinesVisible variable to true if your extension has headlines to display at the time of the event. Otherwise, do nothing.&lt;/li>
&lt;li>In the page, in the OnAfterGetRecord trigger, get the headline text and visibility values and copy them to your added fields.&lt;/li>
&lt;/ol>
&lt;p>To format headlines, you should use Codeunit 1439 Headline Management functions:&lt;/p>
&lt;ul>
&lt;li>Truncate: to truncate a text gracefully when possible with &amp;ldquo;&amp;hellip;&amp;rdquo;. For example, HeadlineManagement.Truncate(&amp;lsquo;the text&amp;rsquo;,6) returns &amp;ldquo;the&amp;hellip;&amp;rdquo;.&lt;/li>
&lt;li>Emphasize: to emphasize part of the headline payload. Emphasized text is shown with a different style.&lt;/li>
&lt;li>GetHeadlineText: to build the headline text. You provide the headline qualifier and payload, and you get the headline in a format that will be interpreted and formatted correctly by the client. It returns false if the qualifier exceeds its maximum length (50 characters) or payload exceeds its maximum length (75 characters). In that case it will not return the headline. If the qualifier you specify is empty, the default text &amp;ldquo;HEADLINE&amp;rdquo; will be displayed in the qualifier area. The payload must not be empty.&lt;/li>
&lt;/ul>
&lt;h3 id="examples">Examples:&lt;/h3>
&lt;h4 id="1-extending-the-page-with-a-new-headline">1. Extending the page with a new headline:&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">group&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>LargestSale&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>{&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Visible&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>LargestSaleVisible&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ShowCaption=false&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Editable=false&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">field&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>LargestSaleText&lt;span style="color:#000;font-weight:bold">;&lt;/span>LargestSaleText&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>{&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ApplicationArea&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Basic&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Suite&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DrillDown=true&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">trigger&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDrillDown&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusHeadlineMgt&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Essential Bus. Headline Mgt.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusHeadlineMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>OnDrillDownLargestSale&lt;span style="color:#ce5c00;font-weight:bold">()&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="2-subscribing-to-the-oncomputeheadlines-event-and-computing-headlines">2. Subscribing to the OnComputeHeadlines event, and computing headlines&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">[EventSubscriber&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ObjectType&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Headline RC Business Manager&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;OnComputeHeadlines&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">procedure&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnComputeHeadlinesBusinessManager&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// [...] compute headline, and init the EssentialBusinessHeadline record
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">not&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ShowHeadline&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">exit&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// not enough data to compute headline
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">not&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HeadlineManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetHeadlineText&lt;span style="color:#ce5c00;font-weight:bold">(
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;Insight from last week&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>StrSubstNo&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;The largest posted sales invoice was for %1&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HeadlineManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Emphasize&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Format&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>CustomerLedgerEntry&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Amount&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TypeHelper&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetAmountFormatWithUserLocale&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;$&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">))))
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Text&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">exit&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Validate&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Headline Visible&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Modify&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">()&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="3-subscribing-to-the-onisanyextensionheadlinevisible-event">3. Subscribing to the OnIsAnyExtensionHeadlineVisible event&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">[EventSubscriber&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ObjectType&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Page&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Page&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Headline RC Business Manager&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;OnIsAnyExtensionHeadlineVisible&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">procedure&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnIsAnyExtensionHeadlineVisible&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ExtensionHeadlinesVisible&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Essential Business Headline&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>AtLeastOneHeadlineVisible&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetRange&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Headline Visible&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetFilter&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;%1|%2|%3|%4|%5&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>LargestOrder&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>LargestSale&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>BusiestResource&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>MostPopularItem&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>SalesIncrease&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>TopCustomer&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>AtLeastOneHeadlineVisible&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">not&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>IsEmpty&lt;span style="color:#ce5c00;font-weight:bold">()&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// only modify the var if this extension is making some headlines visible, setting to false could override some other extensions setting the value to true
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">if&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>AtLeastOneHeadlineVisible&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">then&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ExtensionHeadlinesVisible&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>true&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="heading">&lt;/h4>
&lt;h4 id="4-setting-the-headline-text-on-the-page">4. Setting the headline text on the page&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">trigger&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnAfterGetRecord&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">begin&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetHeadline&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Name&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>LargestSale&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>LargestSaleVisible&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Visible&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>LargestSaleText&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>EssentialBusinessHeadline&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Headline Text&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">end&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;a href="0724.Headline-sequence-diagram-v2.png">&lt;img src="0724.Headline-sequence-diagram-v2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 2: Sequence diagram of headline usage&lt;/em>&lt;/p>
&lt;h2 id="usages-in-nav">Usages in NAV:&lt;/h2>
&lt;ul>
&lt;li>Essential Business Headlines extension&lt;/li>
&lt;/ul></description></item><item><title>Docs: Feature Localization For Data Structures</title><link>https://alguidelines.dev/docs/navpatterns/patterns/feature-localization-for-data-structures/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/feature-localization-for-data-structures/</guid><description>
&lt;p>&lt;em>Originally by Bogdan Sturzoiu at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>This pattern shows a solution for integrating W1 features to pre-existing country features that use different tables to achieve similar functionality.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>It sometimes happens that certain features are requested in a NAV-supported country, but they are not initially considered generic enough to be included in the W1 build. This is how local features, such as Subcontracting in Italy and India, were created or specific banking and payments functionality in Italy, France, Spain, and others.&lt;/p>
&lt;p>Then, at some point in time, a decision is made to create a W1 feature that is closely related to the local functionality but uses a completely different set of tables, pages, etc. The developers now face the following problem: How to enable the newly-developed W1 feature into a country, such that the customers who are accustomed to their local structures can seamlessly continue working without completely (or immediately) switching to the W1 objects.&lt;/p>
&lt;p>This was the issue that was tackled in the NAV 2013 R2, in relation to the SEPA Credit Transfers functionality.&lt;/p>
&lt;h3 id="using-a-proxy">Using a Proxy&lt;/h3>
&lt;p>The generic Proxy pattern is &amp;ldquo;a class functioning as an interface to something else&amp;rdquo; (&lt;a href="http://en.wikipedia.org/wiki/Proxy_pattern">Wikipedia&lt;/a>).&lt;/p>
&lt;p>&lt;a href="5123.Feature-localization-for-data-structures-1.png">&lt;img src="5123.Feature-localization-for-data-structures-1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Figure 1. Proxy in UML&lt;/p>
&lt;h3 id="pattern-elements">Pattern Elements&lt;/h3>
&lt;p>The NAV data model translation of the proxy pattern can be used as explained below.&lt;/p>
&lt;p>The RealSubject is the NAV data model. Variations in table structures, relationships, and numbers are particular to each country. The W1 model is the base for the country-localized data models. However, some countries have heavy localizations which cannot be directly processed by the W1 core objects.&lt;/p>
&lt;p>The proxy is a codeunit that gathers data from wherever it is stored and transforms it to fit into a standard table, which is later used across all localizations.&lt;/p>
&lt;p>The interface is the fixed form in which the data is presented to be consumed by the client.&lt;/p>
&lt;p>The client can be an XML port that is fed from the common data interface. It can also be any other data processor (a codeunit fed to another table, etc.) or data display object (page or report).&lt;/p>
&lt;h3 id="pattern-steps">Pattern Steps&lt;/h3>
&lt;ol>
&lt;li>
&lt;p>The user creates records in the local tables.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The user invokes an action that must be processed using the W1 feature code.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The proxy codeunit moves the data from the local tables to the W1 tables, either into a temporary or persistent set of records, as needed.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The W1 code now performs the action on the W1 table data.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>In NAV 2013 R2, we released the SEPA Credit Transfer functionality. It involves exporting vendor payments to an XML file that is subsequently processed by the customer&amp;rsquo;s bank. The payments are exported from the Payment Journal page through a configurable XMLport. Therefore, the data source for these payment lines is the Gen. Journal Line table (81).&lt;/p>
&lt;p>In various countries, we already had payment export functionality, usually into flat bank files. However, the files are generated from different tables than in W1. For example, in Italy, vendor payments are handled through the Vendor Bill Header table (12181) and the Vendor Bill Line table (12182). They are the RealSubject.&lt;/p>
&lt;p>The W1 feature flow is as follows:&lt;/p>
&lt;p>&lt;a href="6052.Feature-localization-for-data-structures-2.png">&lt;img src="6052.Feature-localization-for-data-structures-2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Figure 2. W1 object call sequence&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong> CT = Credit Transfers, pain = payments initiation (the XML format used for SEPA Credit Transfers and SEPA Direct Debit).&lt;/p>
&lt;p>The key question is: Where to tap into this flow when using a local data structure. For this purpose, a proxy codeunit has been added in W1, called 1222 &amp;ndash; SEPA CT-Prepare Source. This codeunit feeds the client (XML1000) data in a standard format (the interface is the Gen. Journal Line table (81)).&lt;/p>
&lt;p>In W1, the codeunit simply outputs the same set of general journal lines that it receives as an input:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">OnRun&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Rec&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>COPYFILTERS&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CopyJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CopyJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TEMPORARY&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>GenJnlBatch&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Journal Template Name&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Journal Batch Name&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>TempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CreateTempJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FromGenJnlLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>TempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CreateTempJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TEMPORARY&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#8f5902;font-style:italic">// To fill TempGenJnlLine from the source identified by filters set on FromGenJnlLine
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In a country, such as Italy, the codeunit will have the following functions:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Gets an empty set of general journal lines that carry the local payment document key as a filter on the Document No. field (as opposed to W1 that gets the real set of records to be exported). This is done so that the local data can be extracted at runtime.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Selects the local payment data, for example in Italy, in the Vendor Bill Header and Vendor Bill Lines tables.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Transforms the local payment data into temporary records of the Gen. Journal Line table.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Outputs the temporary general journal lines that will be further processed and exported, exactly as in W1.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">OnRun&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Rec&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>COPYFILTERS&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CopyJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CopyJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TEMPORARY&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>GenJnlBatch&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Journal Template Name&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Journal Batch Name&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>TempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CreateTempJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FromGenJnlLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>TempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CreateTempJnlLines&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TEMPORARY&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>PaymentDocNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GETFILTER&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Document No.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>PaymentDocNo&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RESET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETCURRENTKEY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Vendor Bill List No.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;Vendor No.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;Due Date&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;Vendor Bank Acc. No.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;Cumulative Transfers&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Vendor Bill List No.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Cumulative Transfers&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CumulativeAmount&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>PrevVendorBillLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">TESTFIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Invoice&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">((&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Vendor No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PrevVendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Vendor No.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Vendor Bank Acc. No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PrevVendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Vendor Bank Acc. No.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>InsertTempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TempGenJnlLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>PrevVendorBillLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>CumulativeAmount&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CumulativeAmount&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Amount to Pay&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>CumulativeAmount&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">+=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Amount to Pay&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>PrevVendorBillLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>InsertTempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TempGenJnlLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>PrevVendorBillLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>CumulativeAmount&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Cumulative Transfers&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>FALSE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDSET&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">TESTFIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Invoice&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>InsertTempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TempGenJnlLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillLine&lt;span style="color:#000;font-weight:bold">,&lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Amount to Pay&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>InsertTempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TEMPORARY&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>VendorBillHeader&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Vendor Bill Header&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>VendorBillLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Vendor Bill Line&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>AmountToPay&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Decimal&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>INIT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Journal Template Name&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Journal Batch Name&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Payment&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Document No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Vendor Bill List No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Line No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Line No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Account No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Vendor No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Account Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Account Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Vendor&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Bal. Account Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempGenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Bal. Account Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Bank Account&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Bal. Account No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Bank Account No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Applies-to Ext. Doc. No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;External Document No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Amount&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>AmountToPay&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Applies-to Doc. Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Applies-to Doc. No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Currency Code&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Currency Code&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Due Date&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Due Date&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Posting Date&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Posting Date&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Recipient Bank Account&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Vendor Bank Acc. No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Description&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Description&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Message to Recipient&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VendorBillLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Description 2&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The derived local feature flow is as follows:&lt;/p>
&lt;p>&lt;a href="3058.Feature-localization-for-data-structures-3.png">&lt;img src="3058.Feature-localization-for-data-structures-3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Figure 3. The local country object flow&lt;/p>
&lt;p>As we can see from the diagram, this solution allows integration of the local and W1 features with a minimum amount of changes in W1 code. The only two differences are:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>The entry point of the flow is the local table/page.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Codeunit 1222 is overloaded to prepare general journal lines from the local records.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>The data mapping technique has been used for the SEPA Credit Transfer feature, and will be used in subsequent local integration projects.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>A weak point for this pattern is the need to set a filter on the empty journal line in order to retrieve the local data when exporting from a local page. This can cause problems if the size of the local table document number is larger than the Document No. field (ID 20) in the Gen. Journal line table (81).&lt;/p>
&lt;p>Also, there is a strong need for thorough testing when using this pattern, because there might be differences in the behavior of the local table and table 81. Whatever is acceptable for the local table may not be acceptable for the W1 table. A deep functional analysis is needed to see if the local export feature uses the same constraints as the W1 feature.&lt;/p></description></item><item><title>Docs: Hooks</title><link>https://alguidelines.dev/docs/navpatterns/patterns/hooks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/hooks/</guid><description>
&lt;p>&lt;em>By Eric Wauters (&lt;a href="http://www.waldo.be" title="waldo's blog">waldo&lt;/a>), Partner-Ready-Software&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>As a partner, adding new code to NAV means interfering with code shipped by Microsoft. Minimize your footprint of changes in Microsoft code, so that, when a new NAV version is shipped, you avoid conflicts and upgrade impact. The core NAV code is the &amp;ldquo;danger zone&amp;rdquo; - the less you touch it, the happier your upgrade will be.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>When doing development over years, by different developers with different mindsets, the standard codebase gets changed a lot, adding multiple lines of code, adding local and global variants, adding or changing keys, changing existing business logic, &amp;hellip; . In other terms, the standard text objects are being changed all over the place.. .&lt;/p>
&lt;p>After years, it&amp;rsquo;s not clear why a change was done, and what was the place where the change was intended to be done. And the latter is quite important in an upgrade process, when code in the base product is being refactored: if the exact place of the posting of the Customer Entry is being redesigned to a separate number, the first thing I need to know, is that I did a certain change at the place: &amp;ldquo;where the posting of the Customer Entry starts&amp;rdquo;. The definition of that place, we call a &amp;ldquo;Hook&amp;rdquo;.&lt;/p>
&lt;p>By minimizing the code in already existing application objects, you will make the upgrade process much easier, and all customization business logic will be grouped in new objects. When using atomic coding, it will be very readable what is being customized on a certain place in an existing part of the application.&lt;/p>
&lt;p>To minimize the impact of customizations, the idea of hooks is:&lt;/p>
&lt;ul>
&lt;li>First of all, name the places in the already existing code where customization is needed;&lt;/li>
&lt;li>Second, place your business logic completely outside the already existing application code.&lt;/li>
&lt;/ul>
&lt;p>I recommend to use this concept on:&lt;/p>
&lt;ul>
&lt;li>All objects of the default applications that need to be changed&lt;/li>
&lt;li>On objects that should not hold any business logic (like tables, pages, XMLPorts)&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>&lt;strong>Step 1&lt;/strong> - if it doesn&amp;rsquo;t exist yet - you create your Hook Codeunit. As the name assumes .. this is always a codeunit. We apply the following rules to it:&lt;/p>
&lt;ul>
&lt;li>One Hook always hooks into one object. Which basically means that I will only declare this new codeunit in one other object (which is its parent object)&lt;/li>
&lt;li>The naming convention is: &amp;ldquo;The_Original_Object_Name Hook&amp;rdquo;. Naming conventions are important, just to find your mapped object, and also to be able to group the Hooks.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Step 2&lt;/strong>, you create the hook, which is basically a method (function) in your codeunit. The naming is important:&lt;/p>
&lt;ul>
&lt;li>The naming of the hook should NOT describe what it is going to do (So, examples like &amp;ldquo;CheckMandatoryFields&amp;rdquo;, &amp;ldquo;FillCustomFields&amp;rdquo; should not be used as a hook)&lt;/li>
&lt;li>The naming of the hook should describe WHERE the hook is placed, not what the hook will be doing (as nobody is able to look into the future .. :-))&lt;/li>
&lt;li>To help with the naming, it is a good convention to use the &amp;ldquo;On&amp;rdquo;-prefix for these triggers. This way, it&amp;rsquo;s very clear what are hooks, and what aren&amp;rsquo;t..&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Step 3&lt;/strong>, it&amp;rsquo;s time to hook it to its corresponding object and right place in the business logic of that object. You do this by declaring your codeunit as a global in your object, and using the created hook function on its place in the business logic. This way, these one-liners apply:&lt;/p>
&lt;ul>
&lt;li>A Hook Codeunit is only used once in one object only (its corresponding object)&lt;/li>
&lt;li>A Hook (function) is used only once in that object. As a consequence, changing the parameters has no consequence: you only need to change one function-call&lt;/li>
&lt;li>The codeunit is declared as a global. That exact global is the only custom declaration in the existing object .. Everything else is pushed to the hook-codeunit.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Step 4&lt;/strong>, implement your business logic in the hook. Do this in the most atomic way, as there is a good chance that this same hook is going to be used for other business logic as well. Best is to use a one-line-function-call to business logic, so that the Hook Function itself stays readable.&lt;/p>
&lt;h2 id="example">Example&lt;/h2>
&lt;p>Suppose, we want to add business logic just before posting a sales document. In that case, we have to look for the most relevant place, which is somewhere in the &amp;ldquo;Sales-Post&amp;rdquo; codeunit. So:&lt;/p>
&lt;p>&lt;strong>Step 1&lt;/strong>: create codeunit &amp;ldquo;Sales-Post Hook&amp;rdquo;&lt;/p>
&lt;p>&lt;a href="5383.HookPattern1.png">&lt;img src="5383.HookPattern1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Step 2&lt;/strong>: create the hook function &amp;ldquo;OnBeforePostDocument&amp;rdquo;&lt;/p>
&lt;p>&lt;a href="6378.HookPattern2.png">&lt;img src="6378.HookPattern2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Step 3&lt;/strong>: declare a global in the &amp;ldquo;Sales-Post&amp;rdquo;-codeunit, called &amp;ldquo;SalesPostHook&amp;rdquo;. Then, call the Hook Function that you created in Step 2 in the right place.&lt;/p>
&lt;p>&lt;a href="8156.HookPattern3.png">&lt;img src="8156.HookPattern3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Step 4&lt;/strong>: implement the business logic, by calling out to a new function. And implement the test-codeunit.&lt;/p>
&lt;p>&lt;a href="8875.HookPattern4.png">&lt;img src="8875.HookPattern4.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;p>This pattern can be used in all cases to put business logic. But I see three possible approaches&lt;/p>
&lt;ol>
&lt;li>You only declare the most important and most used hooks
&lt;ul>
&lt;li>This way, you limit the amount of objects and hooks to only a few in the default product&lt;/li>
&lt;li>For example, only the OnBeforePostSalesHeader, OnBeforeReleaseSalesDocument, .. And no field validation or such&amp;hellip;&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Only at objects of the default application which you are customizing.
&lt;ul>
&lt;li>This way, you don&amp;rsquo;t want to create hooks for your own objects, only default existing objects.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>(recommended) You create hooks on all places you don&amp;rsquo;t want to write business logic, and on all existing objects which you would like to customize.
&lt;ul>
&lt;li>This is a very consistent way of working, as in any case, your business logic ends up in either a hook, or in its corresponding objects from a specific design pattern. But you know that the entry point is always a hook.&lt;/li>
&lt;li>You know what to expect in any case, both changed business logic in existing code and business logic in newly created code is entered from a hook.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>Atomic coding: It&amp;rsquo;s important that the hook function is readable in the most extreme way. For this, we recommend to use the &amp;ldquo;Atomic Coding&amp;rdquo; concept.&lt;/p>
&lt;p>See here a comparison / extension of hooks : &lt;a href="http://www.waldo.be/2016/02/29/nav-2016-hooks-or-events/">http://www.waldo.be/2016/02/29/nav-2016-hooks-or-events/&lt;/a>&lt;/p></description></item><item><title>Docs: Surrogate keys using Autoincrement Pattern</title><link>https://alguidelines.dev/docs/navpatterns/patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/</guid><description>
&lt;p>&lt;em>By &lt;a href="http://mvp.microsoft.com/en-us/mvp/Soren%20Klemmensen-5001002" title="Soren Klemmensen">Soren Klemmensen&lt;/a>, &lt;a href="http://partner-ready-software.com/" title="Partner-Ready-Software">&lt;em>Partner-Ready-Software&lt;/em> &lt;/a> &amp;amp; &lt;a href="http://www.360visibility.com/" title="360 Visibility">360 Visibility&lt;/a>&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>This Pattern is meant to create generic &amp;amp; reusable links between tables. The goal is to have an easy generic way to link a generically designed sub table to a record on a main table which can be used for other links too.&lt;/p>
&lt;p>To minimize the impact of customizations and to keep modules as generic and reusable as possible the idea of the Implementation of surrogate keys using AutoIncrement pattern is:&lt;/p>
&lt;ul>
&lt;li>To create a generic and reusable auto generated link (A Surrogate Key), Immune to natural key data &amp;amp; requirement changes, on a main table with minimum impact on the table.&lt;/li>
&lt;li>To create generic and reusable sub tables that effortless can be reused anywhere in the application.&lt;/li>
&lt;/ul>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Over years of development many things are repeated across different implementation and even inside the same application. A typical example could be adding comments to an area just as it is done in Microsoft Dynamics NAV multiple times. There can be reasons for doing this again and again, but not only does this need to be maintained and upgraded over the years, but all the implementations of comments also needs to be tested separately. If a standard and generic comment could be developed and a generic way of connecting it to a main table this could be resolved. This is exactly what this pattern is trying accomplish.&lt;/p>
&lt;p>&lt;a href="0458.Figure-1.PNG">&lt;img src="0458.Figure-1.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 1: Table structure for linking a Document Header and Line Table with a Document Comment Table.&lt;/em>&lt;/p>
&lt;p>&lt;a href="0638.Figure-2.PNG">&lt;img src="0638.Figure-2.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 2: Table Structure for linking a Master Data Table with a Master Data Comment Table&lt;/em>&lt;/p>
&lt;p>A typical way of linking a table to master data or to a document has been to use the primary key of the table being linked to. This causes some issues as the linked table now is designed specifically for the main table and it functionality cannot be reused. In case of renames the linked table needs to be renamed too which is costly in processing. Code also needs to be added on the delete trigger of the table to ensure that the attached records get removed if needed which increases the over all footprint of any change.&lt;/p>
&lt;p>&lt;a href="0333.Figure-3.PNG">&lt;img src="0333.Figure-3.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;em>Figure 3: A Generic Way of creating a Comment table and linking it in a generic way to the main table no matter what this table might be. The Unique Record Identifier on the main tables is an Integer with AutoIncrement set to yes.&lt;/em>&lt;/p>
&lt;p>It is recommended using this pattern in all tables which need sub tables unless specific reasons exists for not doing this.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>&lt;strong>Step 1&lt;/strong>: Create a generic Unique Record Identifier in the main table&lt;/p>
&lt;p>The Pattern is implemented by adding a Field (I have called it Unique Record Identifier for this article) in a table (the main Table) where links are needed to be established to. Set the Property Data Type to Integer, Editable to No &amp;amp; AutoIncrement to Yes.&lt;/p>
&lt;p>&lt;strong>Step 2&lt;/strong>: Create a generic link-able sub table.&lt;/p>
&lt;p>Create a new table (Sub Table) which you would like to be reusable with a primary key containing&lt;/p>
&lt;ul>
&lt;li>Table No. of Data Type Integer&lt;/li>
&lt;li>Unique Record Identifier of Data Type Integer&lt;/li>
&lt;li>A 3 field for allowing multiple entries to exist per record in the main table if so needed. This could be a Line No. of Data Type Integer or a Code field of Data Type Code(10) and so on.&lt;/li>
&lt;/ul>
&lt;p>The important part here is that the 2 or 3 first fields in the tables primary key is the Table No. and the Unique Record Identifier. If a 3rd field was added to allow for multiple entries to exist per record in the main table this should also be included in the primary key.&lt;/p>
&lt;p>Make sure to also add any other fields containing the information you wish to store as needed to the table.&lt;/p>
&lt;p>The sub table will be immune to renames from the main table as the main tables primary key is not used in the primary key of the sub table. The Insert, Modify and Rename triggers are not causing any issues and only the delete trigger will need to be considered. This can be dealt with generically from the OnDatabaseDelete trigger in Codeunit 1. I would recommend to use a Hook Pattern for this.&lt;/p>
&lt;p>&lt;strong>Step 3&lt;/strong>: Create a page showing the sub table information.&lt;/p>
&lt;p>Now create a page showing the data in the sub table.&lt;/p>
&lt;p>&lt;strong>Step 4&lt;/strong>: Add an Action or factbox.&lt;/p>
&lt;p>Create an action or factbox on the pages showing the main table data linking to the subpage with Table ID filtered to a constant of the Table No. of the main table and the Unique Record Identifier of the sub table filtering to the Unique Record Identifier of the main table.&lt;/p>
&lt;p>&lt;strong>Step 5&lt;/strong>: Create a Hook for Function OnDatabaseDelete in Codeunit 1 ApplicationManagement if one doesn&amp;rsquo;t already exist. See the Hook pattern.&lt;/p>
&lt;p>&lt;strong>Step 6&lt;/strong>: Create a code to delete records in the Sub table if a main table record is deleted if this is required. This function needs to be called from the Hook created in Step 5.&lt;/p>
&lt;h2 id="nav-specific-example">&lt;strong>NAV Specific Example&lt;/strong>&lt;/h2>
&lt;p>Let&amp;rsquo;s assume we would like to create comment for a larger number of very different tables in the system.&lt;/p>
&lt;p>&lt;strong>Update the Customer table (Step 1)&lt;/strong>: Go to table 18 Customer and add Field 50000 Unique Record Identifier. Set the Property Data Type to Integer, Editable to No &amp;amp; AutoIncrement to Yes. Save the changes.&lt;/p>
&lt;p>&lt;a href="1488.Example-Figure-1.png">&lt;img src="1488.Example-Figure-1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>_&lt;a href="4682.Example-Figure-2.png">&lt;img src="4682.Example-Figure-2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Create Comment table (Step 2)&lt;/strong>: Create a new table called Comment. Add 3 fields Table No., Unique Record Identifier &amp;amp; Line No. all of Data Type Integer. Make these 3 fields into the primary key for the table. Add a 4 field called Comment with Data Type Text(80). Save the changes.&lt;/p>
&lt;p>&lt;a href="4532.Example-Figure-3.png">&lt;img src="4532.Example-Figure-3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Create the Comments page (Step 3)&lt;/strong>: Start the page wizard and create a Page based on table comment created above as a List only showing the Comment field. Set AutoSplitKey property to Yes on the page.&lt;/p>
&lt;p>_&lt;a href="2068.Example-Figure-4.png">&lt;img src="2068.Example-Figure-4.png" alt=" ">&lt;/a>_&lt;/p>
&lt;p>&lt;strong>Update the Customer Card (Step 4)&lt;/strong>: Add an action to the Customer Card to open the Comments. Go to Actions and create an action called Smart Comment. Populate the properties RunObject, RunPageView and RunPageLink as see in the picture below.&lt;/p>
&lt;p>&lt;a href="https://alguidelines.dev/cfs-file.ashx/__key/communityserver-wikis-components-files/00-00-00-00-42/0552.Example-Figure-5.png">&lt;img src="0552.Example-Figure-5.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Create a hook OnDatabaseDelete (Step 5)&lt;/strong>:&lt;/p>
&lt;p>Create a codeunit 50000 called &amp;ldquo;ApplicationManagement Hook&amp;rdquo; with one function called OnAfterOnDatabaseDelete taking the parameter RecRef of Data Type RecordRef. Add it as a global variable to Codeunit 1 ApplicationManagement and call the function as the last line in OnDatabaseDelete. Please read about the hook pattern before implementing it.&lt;/p>
&lt;p>&lt;a href="https://alguidelines.dev/cfs-file.ashx/__key/communityserver-wikis-components-files/00-00-00-00-42/4477.Example-Figure-6.png">&lt;img src="4477.Example-Figure-6.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Create the code needed to delete comments linked to a deleted record (Step6)&lt;/strong>:&lt;/p>
&lt;p>Create a DeleteComments function taking the RecRef of Data Type RecordRef and add the code as shown blow.&lt;/p>
&lt;p>&lt;a href="https://alguidelines.dev/cfs-file.ashx/__key/communityserver-wikis-components-files/00-00-00-00-42/1884.Example-Figure-7.png">&lt;img src="1884.Example-Figure-7.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>It is assumed in this example for simplicity that the Field 50000 is reserved across the entire application for the Unique Record Identifier as defined in Step 1.&lt;/p>
&lt;p>The comments are now fully working if we look away from the fact that we did not deal with a few things specific to Sales orders like RecreateSalesLines function, Archiving and Copy Document. All of which can easily be dealt with.&lt;/p>
&lt;p>These comments are now completely reusable everywhere else in the system. Sales Document is a perfect example as the primary keys of the Sales Header and the Sales line are both different from the customer and normally we would not be able to use the comments header or the line. All that needs to be done is adding the Field 50000 Unique Record Identifier to the Sales Header &amp;amp; Sales Line (Disregarding the posted documents in this example) and creating the actions on the Page Actions with the needed filters. Deletion is already handled of comments no matter what the main table might be.&lt;/p>
&lt;p>Looking at the main table the Unique Record Identifier is also completely reusable for any other linking needed.&lt;/p>
&lt;p>Other ideas for use of this pattern could be. An Error table, Tags, Dynamically defined fields and Generic fact boxes. Only the imagination sets limits for its use.&lt;/p>
&lt;p>Upgrade wise there can be an impact if data is moved out of tables to be reinserted again because of a change to a database structure. This will cause the Unique Record Identifier to change, unless steps are taken to avoid this, and the links will need to be reestablished.&lt;/p>
&lt;p>Other risks could be if Transfer Fields are used and data is being copied unintentionally.&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>This is a new pattern not currently used in Microsoft Dynamics NAV.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>The reason for doing it this way is that you now can reuse your code again and again with only creating the same link on other tables instead of building it from scratch each time reducing testing needed and improving the quality of the overall product.&lt;/p>
&lt;h2 id="consequences-when-it-should-not-be-used">Consequences (When it should not be used)&lt;/h2>
&lt;p>This can be used on any table when linking anything to it that can be considered a generic module which can be reused. That said it should not be used in cases where there is a risk of tables growing so much that performance could be impacted. There are ways to reduce performance impact when using high volume tables, but that is outside the scope of this pattern.&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>This is related to the hook pattern as far as they both try to reduce the footprint changes have on the standard application, by creating reusable ways to interact with the standard code. That said the hook pattern is more about hooking the functionality to existing while this pattern is more about creating reusable ways of creating functionality.&lt;/p></description></item><item><title>Docs: Instructions in the UI</title><link>https://alguidelines.dev/docs/navpatterns/patterns/instructions-in-the-ui/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/instructions-in-the-ui/</guid><description>
&lt;p>&lt;em>Originally by Nikola Kukrika at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>To mitigate usability problems with learnability or discoverability of NAV functionality, it is possible to embed instructions in the UI in connection with the task that the user is performing. The goal is to explain how to use the product or feature without impairing the user&amp;rsquo;s productivity after user has learned how to use a feature.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Users must often go through a few days of training to learn how to use NAV, and even then, many users rely on super users to help them mitigate difficulties using NAV. In addition, because of low discoverability and learnability, many useful features are not being used at all.&lt;/p>
&lt;p>Users' expectations are changing. They expect the software to be usable out-of-the-box because this is the trend in software generally.&lt;/p>
&lt;p>One of the cheapest and most effective methods to solve usability issues is to embed instructional messages in the product. From a user-experience point of view, &lt;strong>this should be used as a last resort&lt;/strong>. UI should be self-explanatory, efficient, and simple to use. Accordingly, you should only implement this pattern if simplifying and improving a scenario is not possible or is too expensive.&lt;/p>
&lt;p>In this connection, the most important requirement is not to impair productivity of the users. One of the biggest and most common UX mistakes that developers make is to &amp;ldquo;optimize for new users&amp;rdquo;. After the user has learned how to use the product, all the instruction texts and dialogs that we added to the UI will clutter the page and make information less visible. Instructional dialogs on routine tasks will become annoying. Therefore, we must make all instructions dismissible.&lt;/p>
&lt;p>In the Mini App solution we have used following elements:&lt;/p>
&lt;ol>
&lt;li>Dismissible dialogs&lt;/li>
&lt;li>FastTabs with instructional text&lt;/li>
&lt;li>Help tiles on a Role Center&lt;/li>
&lt;li>Tooltips on actions and fields&lt;/li>
&lt;li>Task-oriented page Help&lt;/li>
&lt;/ol>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The following pattern applies to dismissible parts in the UI.&lt;/p>
&lt;p>We have a table that stores the instructional code ID and the UserID, so that we can track which user has turned off which instruction. All the logic handling is done from a codeunit. It is the responsibility of the codeunit to show/hide dialogs if needed.&lt;/p>
&lt;p>&lt;a href="6215.picture-1.png">&lt;img src="6215.picture-1.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="dismissible-dialogs">Dismissible Dialogs&lt;/h2>
&lt;p>Dismissible dialogs show the instructional message about the functionality, with the user option to select &amp;ldquo;Don&amp;rsquo;t show this again&amp;rdquo;. This is a good solution to problems where users enter text in the wrong place, or to explain behavior of a somewhat hidden feature.&lt;/p>
&lt;p>&lt;a href="2804.Picture-2.png">&lt;img src="2804.Picture-2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>On a recent usability study of the &lt;strong>Description&lt;/strong> field on sales or purchase lines, most users ignored the &lt;strong>No.&lt;/strong> field and started entering text in the description field before proceeded to enter a quantity. In the solution in question, text only is treated as a line comment if the &lt;strong>No.&lt;/strong> field is blank. The fix was to update the field name to &lt;strong>Description/Comment&lt;/strong> and to provide a message that typing in the field creates a comment only. Users that often use comments can then choose &amp;ldquo;Do not show again&amp;rdquo; to get rid of the instructional text.&lt;/p>
&lt;p>&lt;strong>When to use:&lt;/strong> Recommendation is to use only when many users are entering data in the wrong way and modifying the code is costly. This is an interrupting dialog, but the benefits are that it is very hard to overlook this dialog.&lt;/p>
&lt;h2 id="fasttabs-with-instructional-text">FastTabs with Instructional Text&lt;/h2>
&lt;p>Instructional text on FastTabs is ideal for showing larger amounts of text in the UI.&lt;/p>
&lt;p>&lt;a href="6685.picture-3.png">&lt;img src="6685.picture-3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>When a user changes a filter in the &lt;strong>Navigate&lt;/strong> page, we blank the grid. This may confuse the users as to how to proceed. The &lt;strong>Notification&lt;/strong> FastTab provides information on what has happened and gives instructions on how to proceed.&lt;/p>
&lt;p>Similar implementation is to have the FastTab always visible with the &lt;strong>Do not show again&lt;/strong> check box present, so that users can dismiss it after they have read the message. This is less intrusive than using a dialog, and it has the benefit of being always visible compared to the dialog. The drawback is that users may not read it or may not dismiss it.&lt;/p>
&lt;h2 id="information-tiles-on-role-centers">Information Tiles on Role Centers&lt;/h2>
&lt;p>On the &lt;strong>Small Business Role Center&lt;/strong> page (9022), we have implemented a &lt;strong>Getting Started&lt;/strong> group containing action tiles. Clicking on the first two tiles will play instructional videos. Clicking on the third tile launches a dedicated help topic. Since these tiles will get in the way of the experienced users, an option to hide the entire group is provided.&lt;/p>
&lt;p>&lt;a href="5707.Picture-4.png">&lt;img src="5707.Picture-4.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Note&lt;/strong>: in NAV 2013 R2, actions appear as tiles in the web client only. In the win client, they appear as links. In the web client, the actions only appear if they are in a group for themselves (without Stack Queues &amp;ndash; empty group with only actins defined).&lt;/p>
&lt;h3 id="to-implement-tiles-for-instructional-videos">To implement tiles for instructional videos&lt;/h3>
&lt;ol>
&lt;li>Upload a video to a video hosting service (check if licensing is allowing you to use if for this usage. Examples of video hosting services are: YouTube, Vimeo, Yahoo Video.)&lt;/li>
&lt;li>Get the code to embed the video (select option embed).&lt;/li>
&lt;li>You can reuse the code on the &lt;strong>Mini Video Player Page&lt;/strong> page (1395) or implement a custom one.&lt;/li>
&lt;/ol>
&lt;p>Important parts:&lt;br>
&lt;strong>VideoPlayerAddIn.SetFrameAttribute&lt;/strong> function is used to set an attribute to the iframe that will be playing the video.&lt;/p>
&lt;p>Example of the embed code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-js" data-lang="js">&lt;span style="color:#ce5c00;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#000">iframe&lt;/span> &lt;span style="color:#000">width&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;560&amp;#34;&lt;/span> &lt;span style="color:#000">height&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;315&amp;#34;&lt;/span> &lt;span style="color:#000">src&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;//www.youtube.com/embed/7SGp9pA9cAY&amp;#34;&lt;/span> &lt;span style="color:#000">frameborder&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;0&amp;#34;&lt;/span> &lt;span style="color:#000">allowfullscreen&lt;/span>&lt;span style="color:#a40000">\&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&amp;gt;&amp;lt;&lt;/span>&lt;span style="color:#a40000">/iframe\&amp;gt;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>You must assign &lt;strong>src attribute&lt;/strong> to src of the embed code, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VideoPlayer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetFrameAttribute&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;src&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;https://www.youtube.com/embed/7SGp9pA9cAY&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Without this, the video will not play. You can use the same function to assign other attributes, for example to remove frame border use:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VideoPlayer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetFrameAttribute&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39; frameborder&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;0&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Height and width should be set by using the following functions, since they ensure that the video will be centered on the page.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VideoPlayerAddIn&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetHeight&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Height&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">and&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>VideoPlayerAddIn&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetWidth&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Width&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you would like to reuse the &lt;strong>Mini Video Player Page&lt;/strong> page (1395), then use:&lt;/p>
&lt;pre>&lt;code>SetParameters(Height,Width,Src,Caption), which uses the functions described above.
&lt;/code>&lt;/pre>
&lt;p>4. As a last step you need to implement the action on the group and assign a video icon&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong>&lt;/p>
&lt;p>Videos are implemented to be Web Client only. This is done because Flash player control that is used by most of the providers is not working well with WebBrowser control that the Windows Client is using.&lt;/p>
&lt;p>For displaying the videos on the Windows client, the simplest option is to provide an action with a link that opens a video page in a browser or a page hosting all of the instructional videos you have provided. Optionally you can implement a .NET add-in control that would be able to play the video from selected provider.&lt;/p>
&lt;h3 id="to-implement-tiles-for-help-topics">To implement tiles for help topics&lt;/h3>
&lt;p>You only need to add an empty action with a &lt;strong>TileHelp&lt;/strong> icon. Platform will render the action and will generate the logic to trigger a help call when user clicks on the icon. On the Help Server create an help topic that matches the URL.&lt;/p>
&lt;h2 id="tooltips-on-actions-and-fields">Tooltips on actions and fields&lt;/h2>
&lt;p>Platform improvements in NAV 2013 R2 provide ability to create tooltips for actions and all kinds of fields in the web client simply by filling the &lt;strong>TooltipML&lt;/strong> property on the page object.&lt;/p>
&lt;p>&lt;a href="7217.picture-1.png">&lt;img src="7217.picture-1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Note&lt;/strong>: In NAV 2013 R2, tooltips (in the 1330-range pages only) are extracted from intro paragraphs in the related field topic and inserted build-time using an infrastructure system.&lt;/p>
&lt;h2 id="task-oriented-page-help">Task-oriented page Help&lt;/h2>
&lt;p>Every page in NAV 2013 R2 has a help icon in top right corner that should open a Task-oriented help topic that should be related to this page. We recommend providing help topics for new task pages that you provide with your solutions.&lt;/p>
&lt;p>&lt;a href="7245.Picture-2.png">&lt;img src="7245.Picture-2.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>Dismissible dialogs - Used in the &lt;strong>Description&lt;/strong> field in pages 1305, 1325, 1355, 1373, &amp;hellip;.&lt;/p>
&lt;p>FastTabs with instructional text &amp;ndash; &lt;strong>Navigate&lt;/strong> page (344).&lt;/p>
&lt;p>Help Tiles on Role Center &amp;ndash; &lt;strong>Small Business Role Center&lt;/strong> page (9022) and &lt;strong>Mini Activities&lt;/strong> page (1310).&lt;/p>
&lt;p>Tooltips &amp;ndash; All pages in the 1300 number range.&lt;/p>
&lt;p>Task-oriented page help &amp;ndash; all task pages in 1300 number range&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for Improvement&lt;/h2>
&lt;p>Provide the support for the invoking any Help topics (URL on the Help Server from C/AL code. Then we would be able to promote help actions anywhere or launch them from C/AL code if needed.&lt;/p>
&lt;p>Implement tooltips across the application and in all country versions. (Requires a run-time infrastructure system.)&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/loobQ1TVO3o" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Integration of Addresses</title><link>https://alguidelines.dev/docs/navpatterns/patterns/integration-of-addresses/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/integration-of-addresses/</guid><description>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/60Wrx9N-gfY" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Journal Error Processing</title><link>https://alguidelines.dev/docs/navpatterns/patterns/journal-error-processing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/journal-error-processing/</guid><description>
&lt;p>&lt;em>Originally by Bogdana Botez at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>This pattern describes an optimized way to handle invalid, incomplete, or inconsistent data that users enter in journals.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Scenario: A user has entered data on a journal line and proceeds to invoke a processing action on it, such as posting or exporting to electronic payments. NAV validates the data before it is committed. If any validation errors are found, the user must be informed of validation errors in the most optimal way.&lt;/p>
&lt;p>One design is that when an error is found, stop execution and prompt the user to correct the error. After correcting the error, the user restarts processing and is stopped again at the next error, and so on. Stopping and showing each error is time-consuming and frustrating for the user.&lt;/p>
&lt;p>Another design is that processing does not stop when an error is found. Instead, all errors are gathered in a table and displayed all at once at the end of processing. This way, the processing is ideally invoked only once, reducing the time and effort spent by the user to expose and correct all data validation errors.&lt;/p>
&lt;p>In both designs, the processing is not finalized if any errors are found (for example, exporting to electronic payments is not done, until the data error is resolved).&lt;/p>
&lt;p>This document describes how to implement the second error-handling design: Showing all errors at the end.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The example below comes from the implementation of SEPA Credit Transfer.&lt;/p>
&lt;p>After setting up SEPA-specific configurations, the user can start entering vendor payments that will later be exported to the payment file. (The setup depends on the country, but generally involves choosing number series for SEPA export files, choosing the export format, and enabling SEPA Credit Transfer.)&lt;/p>
&lt;p>In the W1 solution (and most of the countries), payment lines are created in the Payment Journal page, from where the user can invoke the Export Payments to File action, which will attempt to create a SEPA-compliant XML file containing the description of the journal payments that are to be made by the bank.&lt;/p>
&lt;p>When the Export Payments to File function is invoked, NAV validates the journal line data. If the data must be completed or updated, then no file will be created and the user sees the following message:&lt;/p>
&lt;p>&lt;a href="5518.Journal-Error-Processing-1.jpg">&lt;img src="5518.Journal-Error-Processing-1.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>To give a visual overview, the lines that need corrections are highlighted in red. The factbox is context-sensitive, meaning that it shows only the errors that relate to the currently selected line.&lt;/p>
&lt;p>When the first payment journal line is selected, the FactBox show errors for the first line.&lt;/p>
&lt;p>&lt;a href="0005.Journal-Error-Processing-2.jpg">&lt;img src="0005.Journal-Error-Processing-2.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>When the second payment journal line is selected, the FactBox shows errors for the second line.&lt;/p>
&lt;p>&lt;a href="8640.Journal-Error-Processing-3.jpg">&lt;img src="8640.Journal-Error-Processing-3.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="application-objects">Application Objects&lt;/h2>
&lt;p>In the following table, the Generic Object column contains the objects that you can use as a base for your implementation.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Generic Object&lt;/th>
&lt;th>Description&lt;/th>
&lt;th>Sample W1 implementation of SEPA Credit Transfer&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Journal Page&lt;/td>
&lt;td>This is the journal list page where the user invokes the processing action.&lt;/td>
&lt;td>Payment Journal&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Action on Page&lt;/td>
&lt;td>The processing action invoked by the user on the journal list page.&lt;/td>
&lt;td>Export Payments to File&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Errors Page List Part&lt;/td>
&lt;td>A FactBox that displays any journal line validation errors.&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>To improve user experience, the developer can highlight the lines with errors in red and conveniently sort the lines with errors at the top.&lt;/td>
&lt;td>Payment Journal Errors Part&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Validation codeunit&lt;/td>
&lt;td>Contains code that checks that the journal line contains correct, complete, and coherent data and that the line is ready for whatever process must be done next.&lt;/td>
&lt;td>SEPA CT-Check Line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Processing codeunit&lt;/td>
&lt;td>Executes the processing of the journal lines.&lt;/td>
&lt;td>SEPA CT-Export File&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Generic Object:&lt;/strong> Journal Error Text Table&lt;/p>
&lt;p>&lt;strong>Description:&lt;/strong>&lt;/p>
&lt;p>Contains:&lt;/p>
&lt;ul>
&lt;li>The error messages&lt;/li>
&lt;li>Link information about where the error messages belong. For example, in table 1228, Payment Jnl. Export Error Text, the error is linked uniquely to a journal line by the following fields:&lt;/li>
&lt;li>Journal Template Name, with TableRelation=&amp;ldquo;Gen. Journal Template&amp;rdquo;&lt;/li>
&lt;li>Journal Batch Name, with TableRelation=&amp;ldquo;Gen. Journal Batch&amp;rdquo;.Name WHERE (Journal Template Name=FIELD(Journal Template Name))&lt;/li>
&lt;li>Journal Line No.&lt;/li>
&lt;/ul>
&lt;p>Other related information can be added, such as document number of the original source document, if the current journal line originates from a document.&lt;/p>
&lt;p>An extra improvement would be to add a drilldown or a link to the page where the user can fix the error. This would significantly simplify the scenario by excluding manual navigation and investigation by the user to find the page where the error can be fixed.&lt;/p>
&lt;p>&lt;strong>Sample W1 implementation of SEPA Credit Transfer:&lt;/strong> Payment Jnl. Export Error Text&lt;/p>
&lt;p>* The W1 implementation of file export for SEPA Credit Transfer contains the generic SEPA functionality. However, due to differences in data models and user scenarios in various country implementations, the selected local versions contain adaptations of the generic functionality.&lt;/p>
&lt;h2 id="flow">Flow&lt;/h2>
&lt;p>Find below a diagram describing the flow between the objects involved in the journal error processing.&lt;/p>
&lt;p>&lt;a href="0777.Journal-Error-Processing.jpg">&lt;img src="0777.Journal-Error-Processing.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="code">Code&lt;/h2>
&lt;p>Following the flow above, the code (in the SEPA Credit Transfer example) is as follows.&lt;/p>
&lt;p>&lt;a href="5661.Journal-Error-Processing-8.jpg">&lt;img src="5661.Journal-Error-Processing-8.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>The public interface of this table contains simple functionality for adding/deleting errors and for interrogation on if any errors are associated with the current journal template and batch.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-AL" data-lang="AL">CreateNew&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>NewText&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>SetLineFilters&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FINDLAST&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Journal Template Name&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Journal Template Name&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Journal Batch Name&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Journal Batch Name&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Document No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Journal Line No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Line No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Line No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">+=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Error Text&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>COPYSTR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>NewText&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>MAXSTRLEN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Error Text&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>INSERT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>JnlLineHasErrors&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>SetLineFilters&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ISEMPTY&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>JnlBatchHasErrors&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>SetBatchFilters&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ISEMPTY&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>DeleteJnlLineErrors&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>JnlLineHasErrors&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>DELETEALL&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>DeleteJnlBatchErrors&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Gen. Journal Line&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>JnlBatchHasErrors&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GenJnlLine&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>DELETEALL&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>SEPA Credit Transfer feature - for export of vendor payments&lt;/p>
&lt;/li>
&lt;li>
&lt;p>SEPA Direct Debit feature for export of customer payment instructions&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>The same concept of storing error messages (but with a different flow) is also present in:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Planning Error Log table (5430) - Supply Planning feature&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Costing table (5890) - Costing feature&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="ideas-for-improvement">Ideas for Improvement&lt;/h2>
&lt;p>Older code in NAV does not use this pattern yet. It would be good for consistency reasons, and also for overall user experience, to extend this pattern to replace the error processing in more areas.&lt;/p>
&lt;p>We can also improve by helping users find the place where they must fix the error by providing auto-navigation to the required page.&lt;/p></description></item><item><title>Docs: Journal Template Batch Line</title><link>https://alguidelines.dev/docs/navpatterns/patterns/journal-template-batch-line/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/journal-template-batch-line/</guid><description>
&lt;p>&lt;em>Originally by Bogdana Botez at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The role of a journal line is to temporarily hold transaction data until the transaction is posted. Before posting, the entries are in a draft state, which means that they are available for corrections and/or deletion. As soon as the entries are posted, they are converted to ledger entries.&lt;/p>
&lt;p>Journal templates are used to specify the underlying journal structure and to provide the default information for the journal batches. Journal batches usually serve to group journal lines, such as lines created by two different users.&lt;/p>
&lt;p>&lt;a href="2438.Journal-Template-Batch-Line-1.jpg">&lt;img src="2438.Journal-Template-Batch-Line-1.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Journal templates and journal batches are used if there is a need to create and post one or more entries. They are implemented in multiple areas of the application, like Sales, Purchases, Cash Receipts, Payments, Fixed Assets1.&lt;/p>
&lt;h3 id="journal-templates">Journal Templates&lt;/h3>
&lt;p>The journal templates are located on the Journal Template page. A Journal Template definition contains a series of attributes, such as:&lt;/p>
&lt;ul>
&lt;li>Name&lt;/li>
&lt;li>Description&lt;/li>
&lt;li>Type&lt;/li>
&lt;li>Recurring&lt;/li>
&lt;li>No. Series&lt;/li>
&lt;/ul>
&lt;p>The Journal Template table stores the relevant attributes that define the nature and behavior of the journal templates, for example:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Journal Template Table Field&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Test Report ID&lt;/td>
&lt;td>The journals offer the possibility of running test reports3. The role of a test report is to simulate the posting process. The verification criteria for the journal lines is ran, and the report can be displayed, all without doing the actual posting. This helps finding and correcting any errors that might exist in the data. The name of the test report is the same with the name of the corresponding journal, plus the suffix &amp;quot; - Test&amp;quot;. For example, the General Journal has the associated test report named General Journal - Test.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Posting Report ID&lt;/td>
&lt;td>This report is printed when a user selects Post and Print4.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Page ID&lt;/td>
&lt;td>For some journals, more UI objects are required. For example, the General Journals have a special page for bank and cash.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Source Code&lt;/td>
&lt;td>Here you can enter a Trail Code for all the postings done through this Journal4.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Recurring&lt;/td>
&lt;td>Whenever you post lines from a recurring journal, new lines are automatically created with a posting date defined in the recurring date formula.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Each journal template defines a default value of those attributes. The values that are defined in a template will be inherited by the journal batches, which will be created from a journal template.&lt;/p>
&lt;p>Microsoft Dynamics NAV is released with a number of standard journal templates predefined in the Journal Templates page. More templates can be defined by the users.&lt;/p>
&lt;h3 id="journal-batches">Journal Batches&lt;/h3>
&lt;p>Journal batches are created with the help of the journal templates.&lt;/p>
&lt;p>A journal batch is typically used to make a distinction between collections of logically grouped journal lines. A typical design is to have a journal batch for each user who enters lines. The batches are used during the posting process, in order to post one or multiple lines at once.&lt;/p>
&lt;h3 id="journal-lines">Journal Lines&lt;/h3>
&lt;p>Journal lines contain the actual business data (posting dates, account numbers, amounts) that will be posted as ledger entries.&lt;/p>
&lt;p>During posting, only the information from the journal lines is needed. However, the information has been created with the help of the journal templates and grouped together using the journal batches.&lt;/p>
&lt;p>Posting creates ledger entries from the temporary content that is stored in the journal lines. Ledger entries are not created directly. Instead, they are posted from journal lines.&lt;/p>
&lt;p>&lt;a href="8103.Journal-Template-Batch-Line-2.jpg">&lt;img src="8103.Journal-Template-Batch-Line-2.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="aggregation">Aggregation&lt;/h3>
&lt;p>There is a 1:n aggregation relationship between journal templates and journal batches, as well as between journal batches and journal lines. Deleting a template will cascade deletion of the related batches and lines. Deleting a batch will cascade into deletion of related lines.&lt;/p>
&lt;h3 id="recurring-journals">Recurring Journals&lt;/h3>
&lt;p>A recurring journal is used to post transactions that repeat periodically. In a recurring journal, the user enters only the variable data, such as posting date, amounts, and accounts to be used for posting.&lt;/p>
&lt;p>After posting a recurring journal, new journal lines are created containing the posting date for the next recurring period. The posting date recurrence pattern is previously defined in the Recurring Frequency field (for example, monthly recurrences are defined with the date formula 1M).&lt;/p>
&lt;p>A boolean field named Recurring is placed on both the journal templates and journal batches, giving the possibility of defining the type of the journal to be used.&lt;/p>
&lt;h3 id="consistent-user-experience">Consistent User Experience&lt;/h3>
&lt;p>To keep a consistent user interface experience, it is recommended that the the following guidelines are taken respected concerning navigation:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Journal template to journal batches:&lt;/p>
&lt;/li>
&lt;li>
&lt;p>On the Journal Templates page, create an action called &amp;ldquo;Batches&amp;rdquo; and place it in the Navigate tab of the ribbon. Link the action to the batches list page.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Journal batch to journal lines:&lt;/p>
&lt;/li>
&lt;li>
&lt;p>On the Batch page, create an action called &amp;ldquo;Edit Journal&amp;rdquo; in the Home ribbon tab. Link the action to the journal lines list page.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>To keep a consistent user interface experience, it is recommended that the the following guidelines are taken respected concerning posting:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Posting multiple batches&lt;/p>
&lt;/li>
&lt;li>
&lt;p>On the Journal Batches page, posting actions (Post, Post and Print) are available. When invoked, the batch posting will iterate through all related journal lines and trigger the posting routine for all of the lines.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="general-journals">General Journals&lt;/h3>
&lt;p>The General Journal Templates page (101) uses the Gen. Journal Template table (80).&lt;/p>
&lt;p>Various template types are defined: General,Sales,Purchases,Cash Receipts,Payments,Assets,Intercompany,Jobs. Based on the journal type, two other attributes are automatically set on the template lines as follows:&lt;/p>
&lt;ul>
&lt;li>Page ID: Defines which journal page relates to the current journal template&lt;/li>
&lt;li>Source Code: Filled with the default codes that are defined in Source Code Setup table (242).&lt;/li>
&lt;/ul>
&lt;p>The General Journals Batches page (251) is linked to the Gen. Journal Batch source table (232), which has a multiple-to-1 relationship with Gen. Journal Template table, based on the Journal Template Name field.&lt;/p>
&lt;p>Some of the fields in the Gen. Journal Batch table are not editable. Instead, their value is automatically calculated from the parent Gen. Journal Template table. For example, the Recurring field (22) is a FlowField with the following calculation formula:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">Lookup&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Gen. Journal Template&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Recurring&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">WHERE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Name=&lt;span style="color:#204a87;font-weight:bold">FIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Journal&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Template&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Name&lt;span style="color:#ce5c00;font-weight:bold">)))
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Similarly, the Template Type field is a FlowField that gets its value from the parent table:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">Lookup&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Gen. Journal Template&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">WHERE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Name=&lt;span style="color:#204a87;font-weight:bold">FIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Journal&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Template&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Name&lt;span style="color:#ce5c00;font-weight:bold">)))
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="setting-up-a-new-batch">Setting up a New Batch&lt;/h3>
&lt;p>When the user creates a new batch, the following field values are transferred from the Gen. Journal Template table to the Gen. Journal Batch table:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&amp;#34;Bal. Account Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Bal. Account Type&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Bal. Account No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Bal. Account No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Posting No. Series&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Posting No. Series&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Reason Code&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Reason Code&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Copy VAT Setup to Jnl. Lines&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Copy VAT Setup to Jnl. Lines&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&amp;#34;Allow VAT Difference&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GenJnlTemplate&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Allow VAT Difference&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="cascade-record-deletion">Cascade record deletion&lt;/h3>
&lt;p>When a record from the Gen. Journal Template table is deleted, the corresponding Gen. Journal Batch and Gen. Journal Line records are also deleted.&lt;/p>
&lt;h3 id="cascade-updates">Cascade updates&lt;/h3>
&lt;p>When the reason code or the posting number series change in the current batch, all linked Gen. Journal Line records are updated (see ModifyLines function on the Gen. Journal Batch table).&lt;/p>
&lt;p>The Gen. Journal Line table (814) stores a relation with the Journal Batch Name field (51) in the Gen. Journal Batch table. The Gen. Journal Line table also inherits the table relation with the Journal Template Name field (1) in the Gen. Journal Template table.&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>Implementations of this pattern in NAV include:&lt;/p>
&lt;ul>
&lt;li>General Journal (see &amp;ldquo;Use the Pattern&amp;rdquo; above)&lt;/li>
&lt;li>Item Journal&lt;/li>
&lt;li>Resource Journal&lt;/li>
&lt;li>Job Journal&lt;/li>
&lt;/ul>
&lt;p>References&lt;/p>
&lt;ol>
&lt;li>&lt;a href="https://mbs.microsoft.com/partnersource/communities/training/trainingmaterials/student/course80534.htm?printpage=false">NAV Course 50534&lt;/a> Finance Essentials in Microsoft Dynamics NAV 2013, Chapter 3: &amp;ldquo;General Journals&amp;rdquo;.&lt;/li>
&lt;li>&lt;a href="https://mbs.microsoft.com/partnersource/communities/training/trainingmaterials/student/course80435.htm?printpage=false">NAV Course 50435&lt;/a> Application Setup in Microsoft Dynamics NAV 2013, Chapter 5: &amp;ldquo;Set up Journal Templates and Batches&amp;rdquo;&lt;/li>
&lt;li>&lt;a href="http://msdn.microsoft.com/en-us/library/dd338776.aspx">Test reports&lt;/a> Definition on MSDN.&lt;/li>
&lt;li>&lt;a href="http://www.packtpub.com/article/microsoft-dynamics-nav-2009-using-journals-and-entries-custom-application">Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application&lt;/a> Blog article by Mark Brummel&lt;/li>
&lt;li>&lt;a href="http://social.msdn.microsoft.com/Search/en-US?query=journals%20nav&amp;amp;ac=3">Search result for &amp;ldquo;Journal+NAV&amp;rdquo; &lt;/a>Various topics on MSDN&lt;/li>
&lt;/ol>
&lt;h2 id="related-pattern-standard-journal">Related Pattern: Standard Journal&lt;/h2>
&lt;p>For cases when most of the journal data can be used later (like monthly electricity payments, for example), the user has the possibility to save the current transaction details for later use. See the related pattern, Standard Journal.&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/xtsZ5beNdZg" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Master Data</title><link>https://alguidelines.dev/docs/navpatterns/patterns/master-data/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/master-data/</guid><description>
&lt;p>&lt;em>By &lt;a href="http://mvp.microsoft.com/en-us/mvp/Soren%20Klemmensen-5001002" title="Soren Klemmensen">Soren Klemmensen&lt;/a>, &lt;a href="http://partner-ready-software.com/" title="Partner-Ready-Software">&lt;em>Partner-Ready-Software&lt;/em> &lt;/a> &amp;amp; &lt;a href="http://www.360visibility.com/" title="360 Visibility">360 Visibility&lt;/a>&lt;/em>&lt;/p>
&lt;h1 id="abstract">Abstract&lt;/h1>
&lt;p>The goal of this design pattern is to outline a standard way of creating master data, such as customers, vendors or items, in NAV.&lt;/p>
&lt;h1 id="description">Description&lt;/h1>
&lt;p>This pattern creates a standard master data entity, listing all necessary prerequisites, attributes and methods to generate a basic version of the data entity.&lt;/p>
&lt;p>It is being used for creating a master data entity and can roughly be divided into 2 categories: Business and Product&lt;/p>
&lt;p>Examples of Master Data tables are:&lt;/p>
&lt;p>Business Data:&lt;/p>
&lt;ul>
&lt;li>Table 18: Customer&lt;/li>
&lt;li>Table 23: Vendor&lt;/li>
&lt;li>Table 270: Bank Account&lt;/li>
&lt;li>Table 5050: Contact&lt;/li>
&lt;/ul>
&lt;p>Product Data:&lt;/p>
&lt;ul>
&lt;li>Table 15 G/L Account&lt;/li>
&lt;li>Table 27: Item&lt;/li>
&lt;li>Table 156: Resource&lt;/li>
&lt;li>Table 5600: Fixed Asset&lt;/li>
&lt;li>Table 5718: Nonstock Item&lt;/li>
&lt;li>Table 5913: Loaner&lt;/li>
&lt;/ul>
&lt;p>Master Data has attributes such as Location, Countries &amp;amp; Item Vendors. These tables are closely related to Master Data tables and are called Supplemental and Subsidiary tables.&lt;/p>
&lt;p>Supplemental:&lt;/p>
&lt;ul>
&lt;li>Table 9: Country/Region&lt;/li>
&lt;li>Table 14: Location&lt;/li>
&lt;/ul>
&lt;p>Subsidiary:&lt;/p>
&lt;ul>
&lt;li>Table 99: Item Vendor&lt;/li>
&lt;/ul>
&lt;p>Master Data is among other used in journals, posting routines and historic data like ledger entries.&lt;/p>
&lt;p>&lt;strong>Naming &amp;amp; Conventions&lt;/strong>&lt;/p>
&lt;p>Table &amp;amp; Card Page&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Singular&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Examples: Customer, Vendor &amp;amp; Item&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>List Page&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Plural if Editable = TRUE.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Singular + &amp;ldquo;List&amp;rdquo; if Editable = FALSE.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h1 id="example">Example&lt;/h1>
&lt;p>The data entity has a single primary key field with the following properties:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Field No.&lt;/td>
&lt;td>1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Name&lt;/td>
&lt;td>&amp;ldquo;No.&amp;rdquo;&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Date Type&lt;/td>
&lt;td>Code 20&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Each master data entity has a field which gives a name tag to the data entity carrying the natural name of the entity. This field is called Name if the data entity refers to a living person or an organization, such as a customer or a vendor; it is called Description instead if the data entity does not refer to a person or organization, such as an item. The field has the following properties:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Name&lt;/td>
&lt;td>Name or Description&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Date Type&lt;/td>
&lt;td>Text 50&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>An added benefit of using the Name or Description field naming is that this will be part of the dropdown when looking up based on the table relation.&lt;/p>
&lt;p>The table properties of a master data table contain the following entries:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>LookupPageID&lt;/td>
&lt;td>A ListType Page referring to the table which is not editable.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>DrillDownPageID&lt;/td>
&lt;td>The same page as defined in the LookupPageID&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>DataCaptionFields&lt;/td>
&lt;td>The primary key plus the field which provides the primary name tag for the record. This will typically be the Name or Description field defined earlier.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h1 id="nav-specific-example">NAV Specific Example&lt;/h1>
&lt;p>We will create an Example table here with a Card and List Page as described above.&lt;/p>
&lt;p>First we create the Table with No. as the primary key.&lt;/p>
&lt;p>&lt;a href="Table.PNG">&lt;img src="Table.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>Than we create a non-editable Page called Example List&lt;/p>
&lt;p>&lt;a href="PageListDefinition.PNG">&lt;img src="PageListDefinition.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>Than we create an Example Card Page with the following definition&lt;/p>
&lt;p>&lt;a href="PageCardDefinition.PNG">&lt;img src="PageCardDefinition.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>Now we can set the properties of the 2 pages.&lt;/p>
&lt;p>First the Example Card Page Properties&lt;/p>
&lt;p>&lt;a href="PageCardPropertiesV2.PNG">&lt;img src="PageCardPropertiesV2.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>Than the Example List Page Properties&lt;/p>
&lt;p>&lt;a href="PageListPropertiesV2.PNG">&lt;img src="PageListPropertiesV2.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>Last but not least we set the Table Properties&lt;/p>
&lt;p>&lt;a href="TablePropertiesV2.PNG">&lt;img src="TablePropertiesV2.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;h1 id="nav-usages">NAV Usages&lt;/h1>
&lt;p>You can see this pattern used in the following tables &amp;amp; pages:&lt;/p>
&lt;p>Business Data:&lt;/p>
&lt;ul>
&lt;li>Table 18: Customer, Page 21 Customer Card &amp;amp; Page 22 Customer List&lt;/li>
&lt;li>Table 23: Vendor, Page 26 Vendor Card &amp;amp; Page 27 Vendor List&lt;/li>
&lt;li>Table 270: Bank Account, Page 370 Bank Account Card &amp;amp; Page 371 Bank Account List&lt;/li>
&lt;li>Table 5050: Contact, Page 5050 Contact Card &amp;amp; Page 5052 Contact List&lt;/li>
&lt;/ul>
&lt;p>Product Data:&lt;/p>
&lt;ul>
&lt;li>Table 15 G/L Account, Page 17 G/L Account Card &amp;amp; Page 18 G/L Account List&lt;/li>
&lt;li>Table 27: Item, Page 30 Item Card &amp;amp; Page 31 Item List&lt;/li>
&lt;li>Table 156: Resource, Page 76 Resource Card &amp;amp; Page 77 Resource List&lt;/li>
&lt;li>Table 5600: Fixed Asset, Page 5600 Fixed Asset Card &amp;amp; Page 5601 Fixed Asset List&lt;/li>
&lt;li>Table 5718: Nonstock Item, Page 5725 Nonstock Item Card &amp;amp; Page 5726 Nonstock Item List&lt;/li>
&lt;li>Table 5913: Loaner, Page 5922 Loaner Card &amp;amp; Page 5923 Loaner List&lt;/li>
&lt;/ul>
&lt;h1 id="consequences">Consequences&lt;/h1>
&lt;p>This pattern should not be used when this is not Master Data.&lt;/p>
&lt;h1 id="references">References&lt;/h1>
&lt;p>Patterns that are typically used in connection with the Master Data Pattern could be the &lt;strong>&amp;ldquo;No. Series&amp;rdquo;, &amp;ldquo;Address Integration&amp;rdquo;&lt;/strong> and/or the &lt;strong>&amp;ldquo;Entity State&amp;rdquo;&lt;/strong> design patterns., Master Data are central to almost everything we do, so most patterns connect in one way or another to the Master Data Pattern.&lt;/p></description></item><item><title>Docs: Multi-file Download</title><link>https://alguidelines.dev/docs/navpatterns/patterns/multi-file-download/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/multi-file-download/</guid><description>
&lt;p>&lt;em>By Martin Dam at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The goal of this pattern is to enable the users to download multiple files as a zip file instead of downloading one by one. On the Web Client this is preferred way of delivering multiple files since it is one of the web patterns and we cannot use File Management code unit to place files silently on the machine.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>When generating reports that consists of multiple, and usually an unknown number of files, the developer will have to handle the download which also depends on the client the user is on. The problem is that the WinClient has access to the user&amp;rsquo;s file system, whereas the web client does not. Following web guidelines, and the fact that client side .NET is not available in Web client, you can&amp;rsquo;t initiate multiple downloads which requires the developer respond to the type of client. In some browsers it is possible to download files one-by-one in the Web client by using a confirm dialog, however this is a hack and should not be used.&lt;/p>
&lt;p>To solve this problem, a generic download mechanism is used that is client dependent event when multiple files need to be downloaded. For Web client the files are compressed using ZIP and for WinClient the files are downloaded directly to the file system.&lt;/p>
&lt;p>The pattern is usable for all objects that output multiple files and is available in both WinClient and Web client.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The pattern consists of two steps: 1) Gathering the files and 2) downloading the file(s)&lt;/p>
&lt;p>For first step consists of a loop that goes through the files that needs to be downloaded. If it is on the Web client, the files are added to a ZIP archive server-side using a naming convention defined by the integration function GetSeriesFileName. This function takes a filename and number, and transforms it to unique names following a meaningful deterministic pattern e.g. prepend an integer before the file extension. The same function is used when the temporary files are created server side, so the files can be found deterministically later. This removes the need for storing filenames and consequently allows an arbitrary number of files. The second integration function: GetTotalNumberOfFiles, returns the total number of files generated during the data processing and makes the pattern able to handle an arbitrary number of files.&lt;/p>
&lt;p>The second step is the actually download of file(s). For the Web client this consists of closing the ZIP achieve and downloading via the standard download handler that works in the Web client. For the Win client, the files are saved directly to the client during the first step.&lt;/p>
&lt;p>Code 1: File loop shows an example implementation of this pattern. ServerFileName is generated at the beginning of the report/codeunit, and is the base for GetSeriesFilename. The file that is actually written to during data processing is stored in another variable which holds the output from GetSeriesFilename on the current file number. Note; the example code will only create a ZIP file if there in fact are multiple files to be downloaded.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileName&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SupplyFileNameErr&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ZipMultipleFiles&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AND&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GetTotalNumberOfFiles&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>\&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AND&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>IsWebClient&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Basename&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetFileName&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ZipFileName&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>CreateZipArchiveObject&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">FOR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetTotalNumberOfFiles&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>AddFileToZipArchive&lt;span style="color:#ce5c00;font-weight:bold">(
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>GetSeriesFilename&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ServerFileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>FileNo&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>GetSeriesFilename&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Basename&lt;span style="color:#000;font-weight:bold">,&lt;/span>FileNo&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>DownloadHandler&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ZipFileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>STRSUBSTNO&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;%1.zip&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetFileNameWithoutExtension&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#ce5c00;font-weight:bold">)))
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>IsWebClient&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetTotalNumberOfFile&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>MultipleFilesWebClientErr&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagementDownloadHandler&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GetSeriesFilename&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ServerFileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetFileName&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">FOR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">TO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetTotalNumberOfFiles&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>DownloadToFile&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>GetSeriesFilieName&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ServerFileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>FileNo&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetSeriesFilename&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>FileNo&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;em>Code 1: File loop&lt;/em>&lt;/p>
&lt;p>The following code is an example implementation of the GetSeriesFilename function. It needs to support the case where no directory is given, only a filename, in order to add files to the root of the ZIP archive. The example will add a file number right before the extension, e.g. C:\directory\file.txt will become C:\directory\file1.txt etc.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetSeriesFilename&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>FileNo&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>STRPOS&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;\\&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Directory&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetDirectoryName&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>+&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;\\&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Directory&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>+&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetFileNameWithoutExtension&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>+&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FORMAT&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileNo&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>+&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;.&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>+&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetExtension&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FileName&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="_code-2-getseriesfilename_">&lt;em>Code 2: GetSeriesFilename&lt;/em>&lt;/h4>
&lt;p>The pattern depends on .NET library System.IO.Compression.ZipFile, which from NAV 2015 is implemented in Codeunit 419 (File management). It consists of three functions:&lt;/p>
&lt;ul>
&lt;li>CreateZipArchiveObject: Which creates a System.IO.Compression.ZipArchive on a server side file&lt;/li>
&lt;li>AddFileToZipArchive: Which adds a server side file to the archive using System.IO.Compression.ZipFileExtensions.CreateEntryFromFile(). This function allows to use arbitrary naming and does not require to create a server directory before creating the ZIP achieve.&lt;/li>
&lt;li>CloseZipArchive: Which simply closes the ZIP file and saves it to disk.&lt;/li>
&lt;/ul>
&lt;p>The pattern is integrated into the report/codeunit in question by providing a filename field on the request page if it is on WinClient but hidden if it is in Web client. On the Web client, a meaningful default filename is used for the file to download, e.g. in Code 1, Filename is set by the user on the request page if it is WinClient, and set to a default value in Web client.&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>This pattern is used by VAT Report and Blacklist communication in the Italian localization in NAV 2015. The ZIP archive functions are available on all localization from NAV 2015.&lt;/p>
&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;p>This pattern can be used whenever you need to ZIP one or more files. The above example downloads the file, but it could have been transmitted, saved to a persistent storage etc. It could also be used to improve download speed between server and client where the WinClient would unzip the files locally and save individually to disk. This follows the normal procedure in NAV in the WinClient, which is to download files directly to disk, so a ZIP file should only be created when the user specifically needs it or the Web client is invoking the report/codeunit.&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>File Management&lt;/p>
&lt;h2 id="references">References&lt;/h2>
&lt;p>&lt;a href="http://msdn.microsoft.com/en-us/library/vstudio/system.io.compression.zipfile">System.IO.Compression.ZipFile&lt;/a>&lt;/p></description></item><item><title>Docs: Multi-Page List</title><link>https://alguidelines.dev/docs/navpatterns/patterns/multi-page-list/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/multi-page-list/</guid><description>
&lt;p>&lt;em>By Bogdana Botez at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h3 id="abstract">Abstract&lt;/h3>
&lt;p>This pattern describes how to open a related document (or card) page from a list page, for the case when there can be more than one pages associated to the rows of the list page.&lt;/p>
&lt;h3 id="description">Description&lt;/h3>
&lt;p>The example below illustrates the connection of a List Page with multiple Document Pages, while the second example links the List Page with Card Pages.&lt;/p>
&lt;p>&lt;a href="Multi-page-list-img-1.jpg">&lt;img src="Multi-page-list-img-1.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>The records contained in a list page have an associated page, which is specified in the CardPageID property of the list page. The NAV infrastructure assures the following scenarios are in place, without the need to add any explicit C/AL code:&lt;/p>
&lt;ol>
&lt;li>From the selected record in the list page, the user can double-click in order to open the related card page.&lt;/li>
&lt;li>The &amp;ldquo;Edit&amp;rdquo; action is available on the ribbon as well as in the right-click context menu of the list page rows. Invoking this action, opens the related card page.&lt;/li>
&lt;/ol>
&lt;p>However, there are situations when rows of the list page can correspond to different pages each (either cards or documents). For example, consider a list page containing 3 rows, requiring the following behaviour:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Row1&lt;/td>
&lt;td>Opens page ID 1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Row2&lt;/td>
&lt;td>Opens page ID 2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Row3&lt;/td>
&lt;td>Opens page ID 3&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>This situation is not handled automatically by NAV. There is no possibility to specify more than one CardPageID in the list page properties. Furthermore, there is no possibility to specify one or more document page IDs on the list page. Therefore, those cases need to be handled explicitly by the C/AL developer.&lt;/p>
&lt;h3 id="usage">Usage&lt;/h3>
&lt;p>The solution used in NAV implementations is at the list page level, as following:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>The property CardPageID of the list page remains undefined.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>An action named &amp;ldquo;Show Document&amp;rdquo; or &amp;ldquo;Card&amp;rdquo; is created on the Navigate tab, with the properties:&lt;/p>
&lt;ul>
&lt;li>Image = EditLines&lt;/li>
&lt;li>Promoted = Yes&lt;/li>
&lt;li>ShortCutKey = Shift+F7&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>The OnAction trigger for the Card action, contains explicit logic to run the targeted card page. It can, for example, be a CASE statement, which invokes PAGE.RUN(&amp;hellip;) based on an enumeration field of the current row.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="nav-specific-example">NAV Specific Example&lt;/h3>
&lt;p>For example, the NAV page Sales List (page ID 45), which displays the Sales Header Table (table ID 36), chooses which card to open, based on the Document Type field. This is an option field, which can have the following values: Quote, Order, Invoice, Credit Memo, Blanket Order, Return Order. For each document type, the related card page must be opened.&lt;/p>
&lt;p>&lt;a href="Multi-page-list-img-2.jpg">&lt;img src="Multi-page-list-img-2.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>For this purpose, a new action (&amp;ldquo;Card&amp;rdquo;) is added to the Sales List page. The OnAction trigger of this new action contains the page selection logic:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">CASE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Quote&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Quote&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Order&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Order&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Invoice&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Invoice&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Return Order&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Return Order&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Credit Memo&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Credit Memo&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Blanket Order&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">PAGE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Blanket Sales Order&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>Rec&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="nav-usages">NAV Usages&lt;/h3>
&lt;p>Some of the NAV implementations of this pattern can be found in the following pages:&lt;/p>
&lt;ol>
&lt;li>Sales List (45) and Sales List Archive (5159)&lt;/li>
&lt;li>Purchase List (53) and Purchase List Archive (5166)&lt;/li>
&lt;li>Available - Sales Lines (499)&lt;/li>
&lt;li>Sales Lines (516)&lt;/li>
&lt;li>Purchase Lines (518)&lt;/li>
&lt;/ol></description></item><item><title>Docs: Multilanguage Application Data</title><link>https://alguidelines.dev/docs/navpatterns/patterns/multilanguage-application-data/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/multilanguage-application-data/</guid><description>
&lt;p>&lt;em>Originally by Bogdana Botez at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>Generally, NAV translation refers to the translation of UI elements like captions and user texts (messages on dialogs, warnings, error messages). This translation is done by the Microsoft Dynamics NAV team before releasing the localized version of the product.&lt;/p>
&lt;p>But there is one more scenario. In this scenario, Cronus International Ltd., wants to sell a &amp;ldquo;Fiets&amp;rdquo; to a Dutch customer, a&amp;quot;Cykel&amp;quot; to a Danish one, and a &amp;ldquo;Bicicletta&amp;rdquo; to an Italian customer. All 3 are the same inventory item - and its default name is &amp;ldquo;Bicycle&amp;rdquo;. But for reporting, Cronus International Ltd. wants to use the customer language preferences for translating the bicycle&amp;rsquo;s name.&lt;/p>
&lt;p>Sometimes there&amp;rsquo;s a need to support multiple languages for domestic transactions, too. For example, &lt;a href="http://en.wikipedia.org/wiki/Languages_of_Switzerland" title="Switzerland has 4 official languages">Switzerland has 4 official languages&lt;/a>: German, French, Italian and Romansh, the first 3 of them being supported by NAV.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>The example below uses the Item Translation feature of NAV, however, implementations of the same pattern exist for other application areas.&lt;/p>
&lt;h3 id="how-to-use-the-pattern">How to use the pattern&lt;/h3>
&lt;p>&lt;strong>Enter translations for &amp;ldquo;Bicycle&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>In the Windows client, on the bicycle Item card, on the Home ribbon tab, choose Translations.&lt;/p>
&lt;p>&lt;a href="5670.1.png">&lt;img src="5670.1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>On the opened page, enter the Danish (language code DAN), the Italian (ITA), and the Dutch (NLD) translations for &amp;ldquo;Bicycle&amp;rdquo;.&lt;/p>
&lt;p>&lt;a href="6746.2.png">&lt;img src="6746.2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Set the desired language for the Dutch, Danish, and Italian customers&lt;/strong>&lt;/p>
&lt;p>On the customer card for your 3 customers, in the Foreign Trade FastTab, choose the preferred language for each customer. If no language is specified, then the default item description will be used for items sold or anyhow associated to that customer. If for example, the DAN (Danish) language is specified for the customer, and the &amp;ldquo;Bicycle&amp;rdquo; has a translation in Danish, then this translation &amp;ldquo;Cykel&amp;rdquo; will be used instead of the default name &amp;ldquo;Bicycle&amp;rdquo;.&lt;/p>
&lt;p>&lt;a href="2746.3.png">&lt;img src="2746.3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>See the result&lt;/strong>&lt;/p>
&lt;p>After those changes, when the customer (in this case the Danish &amp;ldquo;Lauritzen Kontormøbler A/S&amp;rdquo;) transactions a bicycle, the translated description &amp;ldquo;Cykel&amp;rdquo; will be displayed on the documents and reports. For example, creating a sales order for this customer with 1 item No. 1000, shows:&lt;/p>
&lt;p>&lt;a href="4812.4.png">&lt;img src="4812.4.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>&lt;strong>Create the translation table&lt;/strong>&lt;/p>
&lt;p>Named &amp;ldquo;&amp;lt;Entity&amp;gt; Translation&amp;rdquo; table, where &amp;lt;Entity&amp;gt; is replaced with the name of the actual object being translated. For the Item example above, this table will be named &amp;ldquo;Item Translation&amp;rdquo;.&lt;/p>
&lt;p>The table definition contains at a minimum:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Field&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Entity ID field&lt;/td>
&lt;td>For example, Item No.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Language Code&lt;/td>
&lt;td>Identifies the language of this translation string (for example, &amp;ldquo;DAN&amp;rdquo; (Danish), &amp;ldquo;BGR&amp;rdquo;(Bulgarian). This is one of the language codes defined in the Languages table.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Translation&lt;/td>
&lt;td>The translated string.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The table above has a key composed of the first two fields.&lt;/p>
&lt;p>&lt;strong>Create the user interface for entering new translations of &amp;lt;Entity&amp;gt;&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Create a Translations page to present the table created above&lt;/li>
&lt;li>On the Entity card - add a Translations menu option which will open the Translations page&lt;/li>
&lt;/ul>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>Some of the NAV implementations of this pattern are:&lt;/p>
&lt;ol>
&lt;li>Item Translation&lt;/li>
&lt;li>Payment Term Translation&lt;/li>
&lt;li>Shipment Method Translation&lt;/li>
&lt;li>Unit of Measure Translation&lt;/li>
&lt;/ol>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>The &lt;strong>Extended Text&lt;/strong> pattern is a more powerful version of the &lt;strong>Multilanguage application data&lt;/strong> pattern presented in this section. The main differences are:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Pattern&lt;/th>
&lt;th>Multilanguage Application Data&lt;/th>
&lt;th>Extended Text&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Supports translation of application data&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Format&lt;/td>
&lt;td>Single- or multi-line&lt;/td>
&lt;td>Single-line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Applies to document type&lt;/td>
&lt;td>Can choose which document types are affected.&lt;/td>
&lt;td>All document types are affected.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table></description></item><item><title>Docs: NET Exception Handling in CAL</title><link>https://alguidelines.dev/docs/navpatterns/patterns/net-exception-handling-in-cal/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/net-exception-handling-in-cal/</guid><description>
&lt;p>&lt;em>Originally by Mostafa Balat, Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>When there is a need to use .NET classes within C/AL, one of the main challenges is to handle the exceptions the methods of these .NET classes may throw. Eventually, if not handled, they will basically bubble up as runtime errors, halting the current operation a user is doing without having a chance to properly display errors in a user-friendly format.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Using the .NET classes in order to extend NAV&amp;rsquo;s functionality usually triggers the need to create an add-on assembly. This is a pretty powerful approach and opens the door for empowering NAV with new and extra functionality while harnessing the full power of .NET.&lt;/p>
&lt;p>For example, integration with a Web service into NAV can be done to extend NAV&amp;rsquo;s functionality or benefit from a service model offered through a 3rd party. To do so, it is possible to write a .NET add-in to handle the required bi-directional communication between NAV and the Web service. Alternatively, the implementation itself can be done in C/AL, with no add-in dependency. The latter option simplifies customization, deployment and upgradeability. Additionally, it builds up on the knowledge NAV developers have with C/AL programming.&lt;/p>
&lt;p>On the other hand, not using an add-in exposes NAV to runtime errors due to unhandled exceptions that get thrown at different levels. The first is the communication layer, in which HTTP requests and responses are exchanged. The second is the business logic layer, at which the content of the requests and response is being prepared and groomed using XML Elements and being retrieved or edited based on the respective XPaths.&lt;/p>
&lt;h3 id="when-to-use-it">When to Use It&lt;/h3>
&lt;p>When .NET classes are used, they may throw exceptions upon failure. Some of these exceptions cannot pre-checked (e.g. like existence of a file on disk) and will only be figured out at runtime. Eventually, to present the error reason to a user and explain what needs to be done to address it, the exception needs to be handled gracefully. This also protects the client for unexpected crashes that may deteriorate the user experience.&lt;/p>
&lt;h3 id="diagram">Diagram&lt;/h3>
&lt;p>&lt;a href="1856.DotNet_5F00_Exception_5F00_Handling_5F00_in_5F00_CAL_5F00_Diagram.png">&lt;img src="1856.DotNet_5F00_Exception_5F00_Handling_5F00_in_5F00_CAL_5F00_Diagram.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>A Try-Catch-Finally statement does not exist in C/AL. The alternative is to run the code consuming .NET objects within a codeunit, and handle the runtime errors, as follows:&lt;/p>
&lt;ol>
&lt;li>Write the code that uses the .NET classes in a codeunit.&lt;/li>
&lt;li>Run the codeunit using &lt;strong>CODEUNIT.RUN&lt;/strong> or the Run function on a codeunit variable.&lt;/li>
&lt;li>Handle the return value of the &lt;strong>OnRun&lt;/strong> trigger for the codeunit within an &lt;strong>IF&lt;/strong> statement.&lt;/li>
&lt;li>Write the exception handling code in a function, and call it when the return value for &lt;strong>OnRun&lt;/strong> is &lt;strong>FALSE&lt;/strong>.&lt;/li>
&lt;li>The exception handling function should determine which exception to handle, and pass this over to &lt;strong>COD1291 DotNet Exception Handler&lt;/strong> codeunit.&lt;/li>
&lt;/ol>
&lt;p>When an exception is thrown, it is already wrapped up within an NAV exception. This means the real exception to look for is retrievable through the &lt;strong>InnerException&lt;/strong> property of the NAV exception. Then, next step would be to properly determine the type of that exception, and act accordingly. The &lt;strong>COD1291 DotNet Exception Handler&lt;/strong> codeunit takes care of looping through the nested levels of inner exceptions, digging for an exception with the expected type. If found, it is retrieved; otherwise, the main (outer) exception&amp;rsquo;s message is retrieved.&lt;/p>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;h3 id="overview">Overview&lt;/h3>
&lt;p>The exception handling pattern is implemented in the integration with a web service for bank file format conversion. Within the respective &amp;ldquo;External Data Handling Codeunit&amp;rdquo; for that web service, communication through SOAP requests is required. Eventually, the HTTP web request and response .NET classes are used for that purpose.&lt;/p>
&lt;p>For instance, if a failure to establish a connection to the web service due to lack of Internet access, a &lt;strong>WebException&lt;/strong> is thrown with the relevant error details. &lt;strong>COD1290 Web Service Mgt.&lt;/strong> codeunit wraps up the required functionality to interact with a web service in C/AL, handling all the required plumping work to send web requests, receive web responses, and extract valid and error details from the web response.&lt;/p>
&lt;h3 id="code-sample">Code Sample&lt;/h3>
&lt;p>The &amp;ldquo;External Data Handling Codeunit&amp;rdquo; is a consumer of &lt;strong>COD1290 Web Service Mgt.&lt;/strong> codeunit. If a runtime exception occurs, it gets handled as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SendDataToConversionService@&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PaymentFileTempBlob@&lt;span style="color:#0000cf;font-weight:bold">1003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">99008535&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>BodyTempBlob@&lt;span style="color:#0000cf;font-weight:bold">1004&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">99008535&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>PostingExch@&lt;span style="color:#0000cf;font-weight:bold">1007&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1220&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvServiceSetup@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1260&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebServiceRequestMgt@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1290&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BodyInStream@&lt;span style="color:#0000cf;font-weight:bold">1005&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">InStream&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ResponseInStream@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">InStream&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BodyTempBlob&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Blob&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>HASVALUE&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>NoRequestBodyErr&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PrepareSOAPRequestBody&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>BodyTempBlob&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>COMMIT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvServiceSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BodyTempBlob&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Blob&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>CREATEINSTREAM&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>BodyInStream&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebServiceRequestMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetGlobals&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>BodyInStream&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>BankDataConvServiceSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Service URL&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>BankDataConvServiceSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;User Name&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>BankDataConvServiceSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetPassword&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebServiceRequestMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebServiceRequestMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ProcessFaultResponse&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebServiceRequestMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetResponseContent&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ResponseInStream&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CheckIfErrorsOccurred&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ResponseInStream&lt;span style="color:#000;font-weight:bold">,&lt;/span>PostingExch&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ReadContentFromResponse&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>PaymentFileTempBlob&lt;span style="color:#000;font-weight:bold">,&lt;/span>ResponseInStream&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ProcessFaultResponse@&lt;span style="color:#0000cf;font-weight:bold">15&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">()&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XMLDOMMgt@&lt;span style="color:#0000cf;font-weight:bold">1006&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">6224&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DotNetExceptionHandler@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1291&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebException@&lt;span style="color:#0000cf;font-weight:bold">1005&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;#39;.System.Net.WebException&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebExceptionStatus@&lt;span style="color:#0000cf;font-weight:bold">1004&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;#39;.System.Net.WebExceptionStatus&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XmlDoc@&lt;span style="color:#0000cf;font-weight:bold">1003&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;#39;.System.Xml.XmlDocument&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HttpWebResponseError@&lt;span style="color:#0000cf;font-weight:bold">1007&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;#39;.System.Net.HttpWebResponse&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HttpStatusCode@&lt;span style="color:#0000cf;font-weight:bold">1008&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;#39;.System.Net.HttpStatusCode&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ResponseInputStream@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">InStream&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DotNetExceptionHandler&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Collect&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DotNetExceptionHandler&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>CastToType&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>WebException&lt;span style="color:#000;font-weight:bold">,&lt;/span>GETDOTNETTYPE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>WebException&lt;span style="color:#ce5c00;font-weight:bold">)) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DotNetExceptionHandler&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Rethrow&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Status&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Equals&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>WebExceptionStatus&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ProtocolError&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>WebException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Message&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ResponseInputStream&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Response&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetResponseStream&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DebugLogStreamToTempFile&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ResponseInputStream&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;WebExceptionResponse&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>TempDebugLogTempBlob&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HttpWebResponseError&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>WebException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Response&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>HttpWebResponseError&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>StatusCode&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Equals&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>HttpStatusCode&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Found&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>HttpWebResponseError&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>StatusCode&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Equals&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>HttpStatusCode&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InternalServerError&lt;span style="color:#ce5c00;font-weight:bold">))
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>WebException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Message&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XmlDoc&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XmlDoc&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">XmlDocument&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>XmlDoc&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Load&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ResponseInputStream&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>XMLDOMMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FindNodeTextWithNamespace&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>XmlDoc&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>DocumentElement&lt;span style="color:#000;font-weight:bold">,&lt;/span>FaultStringXmlPathTxt&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;soap&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>SoapNamespaceTxt&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">OBJECT&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1291&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Exception&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Handler&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>{&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OBJECT&lt;span style="color:#ce5c00;font-weight:bold">-&lt;/span>PROPERTIES&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>{&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Date&lt;/span>=&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Time&lt;/span>=&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Version&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">List&lt;/span>=&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PROPERTIES&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>{&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnRun=&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">CODE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>{&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OuterException@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;mscorlib&amp;#39;.System.Exception&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Catch@&lt;span style="color:#0000cf;font-weight:bold">3&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Exception@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;mscorlib&amp;#39;.System.FormatException&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>@&lt;span style="color:#0000cf;font-weight:bold">1007&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;mscorlib&amp;#39;.System.Type&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Collect&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CastToType&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Exception&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Rethrow&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Collect@&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">()&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OuterException&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GETLASTERROROBJECT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TryCastToType@&lt;span style="color:#0000cf;font-weight:bold">5&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;mscorlib&amp;#39;.System.Type&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Exception@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;mscorlib&amp;#39;.System.FormatException&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>CastToType&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Exception&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">))&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CastToType@&lt;span style="color:#0000cf;font-weight:bold">2&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Exception@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;mscorlib&amp;#39;.System.FormatException&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>@&lt;span style="color:#0000cf;font-weight:bold">1007&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DotNet&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;&amp;#39;mscorlib&amp;#39;.System.Type&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Exception&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OuterException&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPEAT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Type&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Equals&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Exception&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetType&lt;span style="color:#ce5c00;font-weight:bold">()) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Exception&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Exception&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InnerException&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">UNTIL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ISNULL&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Exception&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FALSE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Rethrow@&lt;span style="color:#0000cf;font-weight:bold">4&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">()&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ISNULL&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>OuterException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InnerException&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>OuterException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InnerException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Message&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>OuterException&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Message&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>The DotNet Exception Handler codeunit has been used for the Web service integration required for:&lt;/p>
&lt;ol>
&lt;li>Payment Export from the Payment Journal for creating bank-specific payment files.&lt;/li>
&lt;li>Bank Statement Import on the Bank Acc. Reconciliation card for importing the content of bank-specific statements.&lt;/li>
&lt;li>Bank name lookup on the Bank Account card for dynamically identifying the format to use to generate a bank-specific payment file.&lt;/li>
&lt;/ol>
&lt;h2 id="ideas-for-improvement">Ideas for Improvement&lt;/h2>
&lt;p>Extend the language support in C/AL to provide a built-in Try-Catch-Finally statement, similar to .NET languages.&lt;/p>
&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;p>When this pattern should not be used: avoid nesting of codeunits. To properly handle the exceptions, you need to use the codeunit as an atomic piece of functionality that may pass or fail without using Codeunit.Run internally.&lt;/p></description></item><item><title>Docs: No Series</title><link>https://alguidelines.dev/docs/navpatterns/patterns/no-series/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/no-series/</guid><description>
&lt;p>&lt;em>By Bogdana Botez, at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>Number series assignment is widely used in Microsoft Dynamics NAV to automatically assign unique numbers to data entries.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Documents and entities of any type (invoices, orders, customers, inventory items etc) are usually assigned an unique number, which can be later referenced whenever that particular entry needs to be consulted. When a new data entry is created, NAV implements the possibility to auto-assign a new number for this entry. For example, whenever a new sales order is created, it can be auto-numbered. This number has a specific format which is set up previously by the NAV administrator. For example, sales orders could have numbers between SO00001 and SO99999. When all the numbers in this series have been used, NAV will show an error and the administrator has to either extend the current number series, or create a new series to be used.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The number series is implemented at the table level. Each time a new record is inserted, the user can either:&lt;/p>
&lt;ul>
&lt;li>type a new number (if allowed by the setup), or&lt;/li>
&lt;li>have an auto-generated number created.&lt;/li>
&lt;/ul>
&lt;h3 id="number-series-definition">Number Series definition&lt;/h3>
&lt;p>From the implementation point of view, a number series is a record in the table 308 - &amp;ldquo;No. Series&amp;rdquo;.&lt;/p>
&lt;p>&lt;a href="5661.1.png">&lt;img src="5661.1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The most relevant fields are:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Code&lt;/td>
&lt;td>Code 10&lt;/td>
&lt;td>Used to identify the number series in further places where it will be used.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Default Nos.&lt;/td>
&lt;td>Boolean&lt;/td>
&lt;td>The boolean &lt;strong>Default Nos.&lt;/strong> decides whether this number series can use automatic numbering. If false, then the user is expected to manually look up the No. field and select it from the number series.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Manual Nos.&lt;/td>
&lt;td>Boolean&lt;/td>
&lt;td>If the &lt;strong>Manual Nos.&lt;/strong> is Yes, then the used will be allowed to manually type the value of the next number (&amp;ldquo;No.&amp;quot;) field.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Date Order&lt;/td>
&lt;td>Boolean&lt;/td>
&lt;td>&lt;strong>Date Order&lt;/strong> is used to decide whether or not the numbers from the range are assigned chronologically.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="number-series-sequence">Number Series sequence&lt;/h3>
&lt;p>The sequence definition is found in table 309 - No. Series Line. Contains the explicit definition of the series, for example a series called BANK, could start with BANK001 and increase incrementally by one, in the sequence BANK001, BANK002, BANK003, &amp;hellip;. Until the last number BANK999. When hitting the number BANK990, the user will receive a warning that the series is about to be exhausted and it must either be increased, or a new series should be assigned.&lt;/p>
&lt;p>&lt;a href="1452.2.png">&lt;img src="1452.2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="3527.3.png">&lt;img src="3527.3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The most relevant fields are:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Series Code&lt;/td>
&lt;td>Code 10&lt;/td>
&lt;td>Links it to the number series defined in table 308.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Starting No.&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>This is the first number in the sequence, for a book indexing application it can be BOOK0001.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Ending No.&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>The last number in the sequence, for example BOOK5000.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Warning No.&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>When this number is reached, the user will see a warning message stating that the number series is running out of assignable numbers.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Increment-by No.&lt;/td>
&lt;td>Integer&lt;/td>
&lt;td>The value for incrementing the numeric part of the series.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Last No. Used&lt;/td>
&lt;td>Code 20&lt;/td>
&lt;td>The last number from the sequence that was assigned.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Last Date Used&lt;/td>
&lt;td>Date&lt;/td>
&lt;td>Stating when the last number was assigned.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="add-the-default-number-series-to-the-setup">Add the default number series to the setup&lt;/h3>
&lt;p>Various series of numbers can be defined as seen above. For example, a library can have a number series for indexing rental of each of the following: books, movies, music, video. The books series can be split by domain, for example a series BOOKSCIFI can have BOOK0001&amp;hellip;BOOK1500, then BOOKTECH can use the sequence BOOK1501&amp;hellip;BOOK4000 and so on.&lt;/p>
&lt;p>The default number series for a certain application area is typically stored in the domain setup table. For example, NAV Demo Database stores the default Item number series in the Inventory Setup table 313. This means that you will need to add the Number Series fields in your setup table and ensure that before the customer starts using the solution, the number series is created and added to the setup defaults.&lt;/p>
&lt;h3 id="how-to-use-the-number-series">How to use the Number Series&lt;/h3>
&lt;p>The table which will host the number from the number series, needs the following fields:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>No.&lt;/td>
&lt;td>Code 20&lt;/td>
&lt;td>Contains the auto-generated sequential number.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>No. Series&lt;/td>
&lt;td>Code 10&lt;/td>
&lt;td>The number series definition, which decides what the next No. will be.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>And the code to make the number series alive:&lt;/p>
&lt;p>&lt;strong>OnInsert&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">OnInsert&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NoSeriesMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InitSeries&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>DefaultNoSeriesCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>OldNoSeriesCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>NewDate&lt;span style="color:#000;font-weight:bold">,&lt;/span>NewNo&lt;span style="color:#000;font-weight:bold">,&lt;/span>NewNoSeriesCode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Field &amp;ldquo;No.&amp;quot;&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">No&lt;span style="color:#ce5c00;font-weight:bold">. &lt;/span>-&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnValidate&lt;span style="color:#ce5c00;font-weight:bold">()
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>xRec&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">// Validate that &amp;#34;No.&amp;#34; corresponds to the current No. Series rules
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NoSeriesMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TestManual&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>DefaultNoSeriesCode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>AssistEdit&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">AssistEdit&lt;span style="color:#ce5c00;font-weight:bold">() &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NoSeriesMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InitSeries&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>DefaultNoSeriesCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>OldNoSeriesCode&lt;span style="color:#000;font-weight:bold">,&lt;/span>NewDate&lt;span style="color:#000;font-weight:bold">,&lt;/span>NewNo&lt;span style="color:#000;font-weight:bold">,&lt;/span>NewNoSeriesCode&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Where:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>DefaultNoSeriesCode&lt;/strong> is typically found in the application domain setup table.&lt;/li>
&lt;li>&lt;strong>OldNoSeriesCode&lt;/strong> is typically the previous value of the &amp;ldquo;No. Series&amp;rdquo; code, which is found in &lt;strong>xRec.&amp;ldquo;No. Series&amp;rdquo;&lt;/strong>&lt;/li>
&lt;li>&lt;strong>NewDate&lt;/strong> is typically 0D (empty date)&lt;/li>
&lt;li>NewNo and &lt;strong>NewNoSeriesCode&lt;/strong> are the current values found in &lt;strong>&amp;ldquo;No.&amp;quot;&lt;/strong> and &lt;strong>&amp;ldquo;No. Series&amp;rdquo;&lt;/strong>&lt;/li>
&lt;/ul>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>See below an example of how NAV implements the number series pattern.&lt;/p>
&lt;h3 id="sales-and-receivables">Sales and Receivables&lt;/h3>
&lt;p>The setup table 311 (Sales &amp;amp; Receivables Setup) contains the default number series to be used in the whole application domain. In the demo data, some of the series defined here are: Customer Nos., Quote Nos., Order Nos., Invoice Nos., Posted Invoice Nos., Credit Memo Nos., Posted Credit Memo Nos., etc. Those number series are dimensioned for the needs of a typical small to medium sized company, however, various business have different patterns (for example, posting an unusual high number of invoices). In this case, the number series should be adjusted accordingly to make space for the customized company needs.&lt;/p>
&lt;p>The default number series defined in the setup is then used in the individual tables. For example, table 18 - Customer, has&lt;/p>
&lt;h3 id="field-no">Field &amp;ldquo;No.&amp;rdquo;&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">{&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>No&lt;span style="color:#ce5c00;font-weight:bold">. &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>Code20&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>AltSearchField=Search&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Name&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>OnValidate=&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;lt;&amp;gt;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>xRec&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NoSeriesMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TestManual&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Customer Nos.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Invoice Disc. Code&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Invoice Disc. Code&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="field-no-series">Field &amp;ldquo;No. Series&amp;rdquo;&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">{&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">107&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>No&lt;span style="color:#ce5c00;font-weight:bold">. &lt;/span>Series&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>Code10&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>TableRelation=&amp;#34;No. Series&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Editable=No&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>}&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="assistedit">AssistEdit&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>AssistEdit@&lt;span style="color:#0000cf;font-weight:bold">2&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>OldCust@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">18&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Cust@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Record&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">18&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">WITH&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Cust&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DO&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Cust&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Rec&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">TESTFIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Customer Nos.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NoSeriesMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SelectSeries&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Customer Nos.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>OldCust&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NoSeriesMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SetSeries&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Rec&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Cust&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TRUE&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="oninsert">OnInsert&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">OnInsert=&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">TESTFIELD&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Customer Nos.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>NoSeriesMgt&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>InitSeries&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Customer Nos.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>xRec&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>0D&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&amp;#34;No. Series&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">...
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To run the AssistEdit procedure, include this code on the No. - OnAssistEdit() trigger of the Page:&lt;/p>
&lt;h3 id="no---onassistedit">No. - OnAssistEdit()&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>AssistEdit&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>xRec&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>CurrPage&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>UPDATE&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/1lG9rY_dmM4" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Notifications</title><link>https://alguidelines.dev/docs/navpatterns/patterns/notifications/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/notifications/</guid><description>
&lt;p>A collection of patterns about notifications.&lt;/p></description></item><item><title>Docs: Observer</title><link>https://alguidelines.dev/docs/navpatterns/patterns/observer/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/observer/</guid><description>
&lt;p>&lt;em>By Nikolai L&amp;rsquo;Estrange, from TVision Technology Ltd. in the UK&lt;/em>&lt;/p>
&lt;h3 id="abstract">Abstract&lt;/h3>
&lt;p>Track all record changes against a defined table or set of tables.&lt;/p>
&lt;h3 id="problem">Problem&lt;/h3>
&lt;p>Microsoft Dynamics NAV has the built in ability to track all record changes against any table, however it does not always fire the triggers for every table.&lt;/p>
&lt;h3 id="solution">Solution&lt;/h3>
&lt;p>Create a setup table to define which other tables you want to track changes for, and optionally what triggers you want to fire, then link this up to the standard triggers in Codeunit 1.&lt;/p>
&lt;p>Codeunit 1 Application Management contains the triggers OnDatabaseInsert, OnDatabaseModify, OnDatabaseDelete and OnDatabaseRename which are what we need to subscribe to in order to track record changes. However these triggers are only fired sometimes. This is determined by the parameters set in the function GetTableTriggerSetup, which is called once per table per session.&lt;/p>
&lt;p>In order to define which tables we are interested in we can create a new table with the following fields:&lt;/p>
&lt;p>&lt;strong>Observable Table:&lt;/strong>&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&amp;ldquo;Table ID&amp;rdquo;&lt;/th>
&lt;th>Integer&lt;/th>
&lt;th>Object.ID WHERE (Type=CONST(Table))&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>TrackInsert&lt;/td>
&lt;td>Boolean&lt;/td>
&lt;td>[optional]&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>TrackModify&lt;/td>
&lt;td>Boolean&lt;/td>
&lt;td>[optional]&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>TrackDelete&lt;/td>
&lt;td>Boolean&lt;/td>
&lt;td>[optional]&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>TrackRename&lt;/td>
&lt;td>Boolean&lt;/td>
&lt;td>[optional]&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Then we can create a Codeunit that will set the Table Trigger Setup parameters and also subscribe to the OnDatabase triggers.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[EventSubscriber]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetTableTriggerSetup&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TableId&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Integer&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseInsert&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseModify&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseDelete&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseRename&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Boolean&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TableId&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackInsert&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseInsert&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TRUE&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackModify&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseModify&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TRUE&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackDelete&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseDelete&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TRUE&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackRename&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseRename&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TRUE&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[EventSubscriber]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseInsert&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Get&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NUMBER&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AND&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackInsert&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">//do something
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[EventSubscriber]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseModify&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Get&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NUMBER&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AND&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackModify&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">//do something
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[EventSubscriber]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseDelete&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Get&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NUMBER&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AND&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackDelete&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">//do something
&lt;/span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LOCAL&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[EventSubscriber]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>OnDatabaseRename&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>xRecRef&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Get&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecRef&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NUMBER&lt;span style="color:#ce5c00;font-weight:bold">) &lt;/span>&lt;span style="color:#204a87;font-weight:bold">AND&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Observable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>TrackRename&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic">//do something
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;em>&lt;strong>Note:&lt;/strong>&lt;/em> In NAV2016 all these functions can be EventSubscribers that subscribe to the functions in Codeunit 1 as per above, in earlier versions of NAV these functions will need to be Global and called explicitly from within the Codeunit 1 functions.&lt;/p>
&lt;h3 id="nav-usages">NAV Usages&lt;/h3>
&lt;p>Variations of this pattern exists in the standard product in:&lt;/p>
&lt;ul>
&lt;li>Codeunit 423 Change Log Management&lt;/li>
&lt;li>Codeunit 5150 Integration Management. In this Codeunit the tables that fire triggers are hardcoded in C/AL.&lt;/li>
&lt;/ul>
&lt;h3 id="consequences">Consequences&lt;/h3>
&lt;p>It is important that in our GetTableTriggerSetup function we only ever set the parameters to &lt;strong>TRUE&lt;/strong>, and &lt;strong>never&lt;/strong> set them to &lt;strong>FALSE&lt;/strong>. This is because there may be other Codeunits listening to the triggers for that table, e.g. Change Log. This is also why we check the setup again within each trigger.&lt;/p>
&lt;h3 id="related-topics">Related Topics&lt;/h3>
&lt;p>This pattern was originally described in the following blog:&lt;/p>
&lt;p>&lt;a href="https://geeknikolai.wordpress.com/2015/10/30/observer-pattern-in-dynamics-nav-2016/">https://geeknikolai.wordpress.com/2015/10/30/observer-pattern-in-dynamics-nav-2016/&lt;/a>&lt;/p>
&lt;h3 id="nav-versions">NAV Versions&lt;/h3>
&lt;ul>
&lt;li>From NAV 2016 use the code as shown&lt;/li>
&lt;li>For earlier versions see &lt;em>Note&lt;/em> above&lt;/li>
&lt;/ul></description></item><item><title>Docs: Posting Routine - Select Behavior</title><link>https://alguidelines.dev/docs/navpatterns/patterns/posting-routine-select-behavior/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/posting-routine-select-behavior/</guid><description>
&lt;p>&lt;em>By waldo&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>Send information (parameters) to a processing framework/routine so that it knows what to do, how to behave.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>For a processing routine to behave correctly, it needs sometimes input of a user to know what it has to do, check or avoid doing. To do this, usually a piece of UI is getting called (STRMENU) with the question what to do. These input needs to get to the routine.&lt;/p>
&lt;ol>
&lt;li>The user selects the option on how he wants the process to behave&lt;/li>
&lt;li>There are extra fields on the processing table, that are used internally and act like parameters. These Fields get filled according to the selections that the user has made&lt;/li>
&lt;li>The processing codeunit receives the processing table, and therefor also the parameters&lt;/li>
&lt;/ol>
&lt;p>&lt;a href="7585.PostingRoutineSelectBehaviour1.png">&lt;img src="7585.PostingRoutineSelectBehaviour1.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>Example: Sales Post.&lt;/p>
&lt;p>On Sales Header, there were fields created which act like internal parameter-fields for the &amp;ldquo;Sales Post&amp;rdquo; routine:&lt;/p>
&lt;p>&lt;a href="1563.PostingRoutineSelectBehaviour2.png">&lt;img src="1563.PostingRoutineSelectBehaviour2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>When pressing &amp;ldquo;Post&amp;rdquo;, the Selection Codeunit is getting called:&lt;/p>
&lt;p>&lt;a href="5428.PostingRoutineSelectBehaviour3.png">&lt;img src="5428.PostingRoutineSelectBehaviour3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Or in case of the Post&amp;amp;Print, the selection codeunit is different:&lt;/p>
&lt;p>&lt;a href="6170.PostingRoutineSelectBehaviour4.png">&lt;img src="6170.PostingRoutineSelectBehaviour4.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Next, the user is able to select the options with an STRMENU, which results in filling in the fields above, like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">Selection&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>STRMENU&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Text000&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">3&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Selection&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Ship&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Selection&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">3&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>Invoice&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Selection&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>[&lt;span style="color:#0000cf;font-weight:bold">2&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">3&lt;/span>]&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The processing codeunit is being called after these options were set.&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>This is also being used in the Purchase Post.&lt;/p>
&lt;p>However, the Service Post works different. In Short:&lt;/p>
&lt;ul>
&lt;li>There were no parameter fields added to the processing table (Service Header)&lt;/li>
&lt;li>The processing routine isn&amp;rsquo;t called by CODEUNIT.RUN, but a function in a declared codeunit, where you pass the Invoice and Ship parameter separately.&lt;/li>
&lt;/ul>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>Implement it consequently. There is (in my knowledge) no reason to do Service Posting differently from Sales and Purchase.&lt;/p>
&lt;p>Furthermore, one might argue if adding fields to a table (which also means adding fields to the SQL Table) is the right solution to pass parameters to processing methods.&lt;/p>
&lt;p>On the other hand, as we are handling tables as being &amp;ldquo;classes&amp;rdquo; in many cases, it does make sense to add &amp;ldquo;properties&amp;rdquo; to those &amp;ldquo;classes&amp;rdquo; to change the behavior of the method (SalesHeader.Post).&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>I would like to add a pattern like &amp;ldquo;Using Argument tables&amp;rdquo; (as a sub-pattern for the facade-pattern). It somewhat is related to this way of handling parameters: using tablefields to pass a flexible amount of parameters to functions/codeunits.&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/SxywT2XSpcI" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Product Name</title><link>https://alguidelines.dev/docs/navpatterns/patterns/product-name/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/product-name/</guid><description>
&lt;h4 id="abstract">&lt;strong>Abstract&lt;/strong>&lt;/h4>
&lt;p>On many occasions, it&amp;rsquo;s needed to refer to the product name in messages or errors. It&amp;rsquo;s not a good practice to hardcode the brand name like Dynamics NAV 2017, and change this value with each rebranding. You can use client &lt;strong>ProductName&lt;/strong> System Object instead to refer to the product name.&lt;/p>
&lt;p>&lt;a href="ProductName-Logo.png">&lt;img src="ProductName-Logo.png" alt=" ">&lt;/a>&lt;/p>
&lt;h4 id="problem">&lt;strong>Problem&lt;/strong>&lt;/h4>
&lt;p>When you want to refer to product name in informational messages or errors, it&amp;rsquo;s not a good practice to hardcode the brand name, as this requires changing this text when a rebranding happens.&lt;/p>
&lt;h4 id="solution">&lt;strong>Solution&lt;/strong>&lt;/h4>
&lt;p>Instead of hardcoding the product name like &amp;ldquo;Dynamics NAV 2017&amp;rdquo;, it&amp;rsquo;s recommended to use &lt;strong>ProductName&lt;/strong> System Object that platform provides.&lt;/p>
&lt;p>You can use &lt;strong>ProductName&lt;/strong> to refer to the product name, this you can use in text messages. &lt;strong>ProductName&lt;/strong> has 3 values &lt;strong>ProductName.Short&lt;/strong>, &lt;strong>ProductName.Full&lt;/strong>, and &lt;strong>ProductName.Marketing&lt;/strong>, each one should be used according to the context of your message.&lt;/p>
&lt;p>It&amp;rsquo;s recommended to use &lt;strong>ProductName.Short&lt;/strong> for most in-product texts , &lt;strong>ProductName.Full&lt;/strong> when other dynamics apps are present in the message context (like CRM), and &lt;strong>ProductName.Marketing&lt;/strong> only when absolutely necessary.&lt;/p>
&lt;p>&lt;strong>Usage&lt;/strong>: You should make a placeholder in your text constant and substitute this placeholder with &lt;strong>ProductName&lt;/strong> as shown below.&lt;/p>
&lt;p>&lt;a href="ProductName-Sample.PNG">&lt;img src="ProductName-Sample.PNG" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Output&lt;/strong>&lt;/p>
&lt;p>&lt;a href="ProductName-output.png">&lt;img src="ProductName-output.png" alt=" ">&lt;/a>&lt;/p>
&lt;h4 id="benefits">&lt;strong>Benefits&lt;/strong>&lt;/h4>
&lt;ul>
&lt;li>This decouples your messages from the application name&lt;/li>
&lt;li>This removes the effort of maintaining these messages and keeping them up to date with the brand name.&lt;/li>
&lt;/ul>
&lt;h4 id="limitations">&lt;strong>Limitations&lt;/strong>&lt;/h4>
&lt;ul>
&lt;li>&lt;strong>ProductName&lt;/strong> can&amp;rsquo;t be used for tooltips and captions, it can only be used for text constants (Labels).&lt;/li>
&lt;li>&lt;strong>ProductName&lt;/strong> System object doesn&amp;rsquo;t exist in NAV 2016 and earlier version.&lt;/li>
&lt;/ul></description></item><item><title>Docs: Queries</title><link>https://alguidelines.dev/docs/navpatterns/patterns/queries/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/queries/</guid><description>
&lt;p>Expand to see NAV design patterns which use queries.&lt;/p></description></item><item><title>Docs: Read-once Initialization and Validation</title><link>https://alguidelines.dev/docs/navpatterns/patterns/read-once-initialization-and-validation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/read-once-initialization-and-validation/</guid><description>
&lt;p>&lt;em>By Tim Grant&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>One time query and validation of a setup table.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Firstly identifies if a setup table record is in memory, removing the need to execute and validate the re-query again within a code unit. (From NAV 2013+ service tier database caching exists).&lt;/p>
&lt;p>If you need to query a setup table, but not sure if the table is yet in memory from earlier code, this helps to determine this call (see Singleton Table pattern).&lt;/p>
&lt;p>Allows a central function to validate critical fields before processing automated code. &lt;strong>TESTFIELD&lt;/strong> calls are added to the function and not the INIT call in order to ensure that critical functions do not run without this human check in place as these may rely on key configuration. If you have a design where specific field values are critical (custom or standard) for integrity, then INIT INSERT is a dangerous default which could result in the corruption of processes. This is separate automated INIT INSERT from a setup page.&lt;/p>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;p>A global variable record and a global status indicator, but within the context of a local function.&lt;/p>
&lt;p>&lt;a href="6332.1.png">&lt;img src="6332.1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="5025.2.png">&lt;img src="5025.2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;img src="5672.8.png" alt=" ">&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>A similar example of this is in Codeunit 80, but without any validation.&lt;/p>
&lt;p>&lt;a href="4.png">&lt;img src="4.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>E.g. If there is a bespoke change, then this existing &lt;strong>GetGLSetup&lt;/strong> can be called earlier to accommodate for an earlier bespoke change:&lt;/p>
&lt;p>&lt;a href="5.png">&lt;/a>&lt;a href="2465.5.png">&lt;img src="2465.5.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>This means that by the time the code reaches the original &lt;strong>GetGLSetup&lt;/strong> code requirement, this record is already in memory as the status flag is set to True, eliminating another check. For such Patterns the setup record should never be cleared, it should be called once globally, initiated and left in memory for future checks. It should &lt;strong>not&lt;/strong> be declared locally at the same time, review your code for matching local variable usage before implementing this.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>Merge &lt;strong>Singleton Table&lt;/strong> with dynamic validation field meta configuration. This removes the coding of &lt;strong>TESTFIELD&lt;/strong> to a central setup check.&lt;/p>
&lt;p>Example with the &lt;strong>Sales &amp;amp; Receivables Setup&lt;/strong>&lt;/p>
&lt;p>&lt;a href="5857.1.png">&lt;img src="5857.1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="4477.2.png">&lt;img src="4477.2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="4314.3.png">&lt;img src="4314.3.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;p>If in the circumstance that a field value in the setup table is expected to change within the life of the code component instance. e.g. If a CHANGECOMPANY is required to cross reference another Setup table, use a separate variable.&lt;/p>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>This is related to the &lt;strong>Singleton Table&lt;/strong> pattern.&lt;/p></description></item><item><title>Docs: Released Entity</title><link>https://alguidelines.dev/docs/navpatterns/patterns/released-entity/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/released-entity/</guid><description>
&lt;p>&lt;em>Authors: Henrik Langbak and Kim Ginnerup, Bording Data&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>This pattern prevent data from being used elsewhere before it is in a system consistent state.&lt;br>
NAV inserts a record as soon as the primary key has been set. But the record may not be in a valid state at this point in time. How do you know if a newly inserted record is ready for use?&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Whenever you need to stall the release of data, you can use this pattern.&lt;/p>
&lt;p>Because NAV decides when a record is written to the database, it may not be in a system consistent state. Nobody should use the record before everything is in place and the record is valid. An inserted record may even have data in other tables that needs to be inserted and in a valid state before other parts of the system can use the data without running into a problem.&lt;/p>
&lt;p>Data entered into the system may have to be approved by a second person before it can be used.&lt;/p>
&lt;p>Data requires different parties (e.g. Departments) to add information before data is valid.&lt;/p>
&lt;p>The solution is an Option Field with two or three values:&lt;br>
(Open, Released) or (Open, Pending, Released)&lt;/p>
&lt;p>The states should be interpreted as:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>State&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Open&lt;/td>
&lt;td>Not all data is in place. The record is system inconsistent. The record or record hierarchy is invisible for all other parts of the system.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Pending&lt;/td>
&lt;td>The record is system consistent. But is awaiting someone to manually raise the state to Released. The record is still invisible.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Released&lt;/td>
&lt;td>All data is in place and the record is system consistent, and ready for use. It is now visible for the rest of the system. The state can never be reversed.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The option field name: Release State.&lt;/p>
&lt;p>This pattern is very similar to the Blocked Entity pattern, but it has one significant difference.&lt;br>
The record is not visible to any part of the system, before it is in the Released state.&lt;br>
There is no going back. When the Released state is reached, it will stay that way for the life of the record. In case of a tri-state, it is ok to bypass Pending seen from a system state perspective.&lt;/p>
&lt;p>If there is a hierarchy, e.g. Header and Lines, then the Release State field resides on the Header. As long as the Header remains unreleased, the lines are considered inconsistent and must not be used.&lt;/p>
&lt;p>The important and critical part of this pattern is that the whole application needs to obey the &amp;ldquo;Release State&amp;rdquo;-contract or the system will fail.&lt;/p>
&lt;h2 id="usage">&lt;strong>Usage&lt;/strong>&lt;/h2>
&lt;p>To use this pattern you need to create an Option Field named: &amp;ldquo;Release State&amp;rdquo; with at least the two states: Open, Released.&lt;/p>
&lt;h3 id="automatic-pending-or-release">Automatic pending or release&lt;/h3>
&lt;p>If it is feasible to set the Release State automatically, create a local function named: &amp;ldquo;CheckAndSetReleaseState&amp;rdquo; that validates the record and sets Release State to Pending or Released, when all system requirements are met.&lt;/p>
&lt;p>The function only works one way. It can only increase the state. If the function is called when release state is Pending or Release, the function will do nothing.&lt;/p>
&lt;p>If the function is implemented, then the user should not be able to change the value from Open to Pending or Released, only the function can do that.&lt;/p>
&lt;p>The function should be called on every change, this way it will be visible to the end user immediately when all requirements are met.&lt;br>
If the Pattern is implemented without this function, then field is maintained by the end user.&lt;/p>
&lt;h2 id="nav-specific-example">&lt;strong>NAV Specific Example&lt;/strong>&lt;/h2>
&lt;p>NAV has Table 36 Sales Header, Field 120 Status.&lt;br>
In this example, it is called: Status.&lt;br>
Status has 4 values: Open, Released, Pending Approval, Pending Prepayment.&lt;/p>
&lt;h2 id="nav-usages">&lt;strong>NAV Usages&lt;/strong>&lt;/h2>
&lt;p>The example above, taken from NAV, shows similarity with this pattern, but in the Sales Header example it is possible to modify the Release state to an earlier state, through a function in NAV. This is not recommended in the pattern.&lt;/p>
&lt;h2 id="ideas-for-improvement">&lt;strong>Ideas for improvement&lt;/strong>&lt;/h2>
&lt;p>In case of a Pending State, you may need an Approved Date and Approved By. Depending on how formal it needs to be.&lt;/p>
&lt;h2 id="consequences">&lt;strong>Consequences&lt;/strong>&lt;/h2>
&lt;p>This pattern is only used on data creation.&lt;br>
If there is a need for shuffling between states back and forth, then this is not the pattern to use.&lt;/p>
&lt;h2 id="related-topics">&lt;strong>Related Topics&lt;/strong>&lt;/h2>
&lt;p>Blocked Entity is a variant of this pattern but Blocked Entity is used later in the life-cycle.&lt;/p>
&lt;p>An alternative to the pattern is temporary tables. But the temporary table is an all or nothing approach. If all data in the Record is valid, the temporary record can update the real data. If not, abandon the process. The Release State pattern is simpler and requires less code.&lt;/p>
&lt;h2 id="references">&lt;strong>References&lt;/strong>&lt;/h2>
&lt;p>There is a term called: Long Term Lock. This pattern has some resemblance.&lt;br>
When talking about hierarchical data structures and the Release State is held on the root node, there is a pattern called Hierarchical Locking that has some resemblance.&lt;/p></description></item><item><title>Docs: Report Selection</title><link>https://alguidelines.dev/docs/navpatterns/patterns/report-selection/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/report-selection/</guid><description>
&lt;p>From the PRS workshop at NAVTechDays 2013, this pattern was written by 2 work groups&lt;/p>
&lt;p>Group 1: Dale Gauci &amp;amp; Kimberly Congleton&lt;/p>
&lt;p>Group 2: Jens Winberg, Tim Grant, Alen Tot&lt;/p>
&lt;p>Thanks to Tim Grant who had merged the two patterns, corrected, sent for review and finalized them.&lt;/p>
&lt;h2 id="meet-the-pattern">Meet the Pattern&lt;/h2>
&lt;p>It should be possible to change which document report object should be used when printing. This configuration can be stored in one place (Report Selection) and available at configuration time. In this situation, the code for printing records can remain the same.&lt;/p>
&lt;p>The purpose of this pattern is to describe the process to implement a reports selection by retrieving the specific &lt;strong>Document Header&lt;/strong>, determining which type of document is related to it in the &lt;strong>Report Selection Screen&lt;/strong>, and call the report which needs to be printed by passing the specific document header. This specifies the reports that you can print when you work with the various documents for sales and purchases, such as orders, quotes, invoices, and credit memos.&lt;/p>
&lt;h2 id="know-the-pattern">Know the Pattern&lt;/h2>
&lt;p>The program can preselect which report will be printed when you print from various types of purchase and sales headers. For example, on an order, the &lt;strong>Order Confirmation&lt;/strong> report is automatically printed.&lt;/p>
&lt;p>The &lt;strong>Report Selection&lt;/strong> table contains the specification of which report will be printed in different situations. The &lt;strong>Report Selection&lt;/strong> table also contains the report ID and report name for the report that will be printed when the user works with a given document type.&lt;/p>
&lt;p>The user can, of course, choose to have the program print a different report than the preselected one. You can also add reports to the &lt;strong>Report Selection&lt;/strong> table to have the program print more than one report per document type.&lt;/p>
&lt;p>This pattern should be used when the user needs to print a new type of document which can have different report layouts, or when the user needs to print several different reports in sequence. This can also be used during a new post and print routine, a test report for journal posting or for re-printing a posted document. Using this pattern will minimize code by allowing a flexible means of specifying different reports to print, instead of hard-coding a report id when printing a document.&lt;/p>
&lt;h2 id="use-the-pattern">Use the Pattern&lt;/h2>
&lt;p>The Report Selection Pattern involves the &lt;strong>Report Selection&lt;/strong> table as the central configuration element also with the &lt;strong>Report Selection&lt;/strong> Page. The table is used in 4 generic functional workflows:&lt;/p>
&lt;ol>
&lt;li>Test Print un-posted&lt;/li>
&lt;/ol>
&lt;p>If the Report Selection is related to a Test Report relating to a Document:&lt;/p>
&lt;ul>
&lt;li>The Document&amp;rsquo;s Page including Printing Actions&lt;/li>
&lt;li>Test Report-Print Codeunit 228&lt;/li>
&lt;/ul>
&lt;ol start="2">
&lt;li>Print un-posted. If the Report Selection is related to an existing Document (un-posted):&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>The Document&amp;rsquo;s Page (Document / List) including the Printing Actions&lt;/li>
&lt;li>The Document-Print Codeunit 229 is used atomically to use the document type in the generic Sales Header table before the report selection is found.&lt;/li>
&lt;/ul>
&lt;ol start="3">
&lt;li>Print while posting. If the Document is printed at the point of posting then:&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>The Document&amp;rsquo;s Post + Print Codeunit (82 or 92), with the related &lt;strong>GetReport&lt;/strong> and &lt;strong>PrintReport&lt;/strong> functions.&lt;/li>
&lt;/ul>
&lt;ol start="4">
&lt;li>Print after posting. If the Report Selection is related to an existing Document (posted):&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>The specific document related posted header table is used along with a typical function: &lt;strong>PrintRecords&lt;/strong> within the respective table.&lt;/li>
&lt;/ul>
&lt;h2 id="example">Example&lt;/h2>
&lt;p>Sales Document (Invoice)&lt;/p>
&lt;p>Pre-conditions&lt;/p>
&lt;ul>
&lt;li>The document header/lines table is present and there is a report which has a parent DataItem linked to this document.&lt;/li>
&lt;li>A document and list page is present and related to the document.&lt;/li>
&lt;li>A post and print Codeunit exists for the document.&lt;/li>
&lt;/ul>
&lt;p>Implementation:&lt;/p>
&lt;ul>
&lt;li>Add a new &lt;strong>Option String&lt;/strong> to the &lt;strong>Report Selection&lt;/strong> table, &lt;strong>Usage&lt;/strong> field (including any ML Captions).&lt;/li>
&lt;li>Calling of &lt;strong>GetReport&lt;/strong> function, passing the document header.&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GET&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Post &amp;amp; Print with ob Queue&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesPostViaobQueue&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>EnqueueSalesDoc&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">CODEUNIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">CODEUNIT&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales-Post&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>GetReport&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>COMMIT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>Implementing the new document type within the &lt;strong>GetReport&lt;/strong> Function, and calling &lt;strong>PrintReport&lt;/strong> with the New OptionString&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Invoice&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Last Posting No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#39;&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesInvHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesInvHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;No.&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&amp;#34;Last Posting No.&amp;#34;&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesInvHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRECFILTER&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PrintReport&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelection&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Invoice&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>Implement the new Document Type and calling the associated report ID, passing the document header&lt;/li>
&lt;/ul>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;ul>
&lt;li>Codeunits 82, 92, for post and printing purchase and sales documents&lt;/li>
&lt;li>Codeunit 229 for Document printing&lt;/li>
&lt;li>Header Tables 110, 112, 114, 120, 122, 124, 295, 297, 302, 304. 5744, 5746, 6650, 6660&lt;/li>
&lt;/ul>
&lt;p>This pattern is already used for printing documents like sales invoices, proforma, waybills, Finance Charge Memos, Receipt Documents.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for improvement&lt;/h2>
&lt;p>The &amp;ldquo;Usage&amp;rdquo; Field could be more dynamic through a setup field linked to a document type table mapped to the document header Table ID.&lt;/p>
&lt;p>Report Selection table is currently based on the Usage of the report to be defined. A more generic way could be to only select what record id the printing selection is based on could also be implemented. (I think this means Recordref and Table Number could be used to identify the posted tables)&lt;/p>
&lt;p>The Report Selection matrix could be evolved to accommodate the Journal post &amp;amp; print configuration. This setup currently resides in the Gen. Journal Template table.&lt;/p>
&lt;p>Merge the &lt;strong>PrintReport&lt;/strong> functions in the purchase and sales post printing functions (82, 92) into a more atomic print selection component.&lt;/p>
&lt;p>Merge the &lt;strong>PrintRecords&lt;/strong> functions in the separate posted header tables into a more atomic print selection component.&lt;/p>
&lt;h2 id="related-patterns">Related Patterns&lt;/h2>
&lt;ul>
&lt;li>Posting Routine Pattern (Journal/Document)&lt;/li>
&lt;li>Post Batch Routine Pattern&lt;/li>
&lt;/ul></description></item><item><title>Docs: Security</title><link>https://alguidelines.dev/docs/navpatterns/patterns/security/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/security/</guid><description>
&lt;p>&lt;em>By Bogdana Botez at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="security-patterns-for-nav">&lt;strong>Security patterns for NAV&lt;/strong>&lt;/h2>
&lt;h3 id="problem-statement">&lt;strong>Problem statement&lt;/strong>&lt;/h3>
&lt;p>When sensitive data is stored inside the Dynamics NAV database, if negligently handled, it can become vulnerable. Particularly, the location, access and the state of the data are critical.&lt;/p>
&lt;p>Use the following patterns to enhance security on your NAV system.&lt;/p>
&lt;ol>
&lt;li>&lt;a href="https://alguidelines.dev/navpatterns/1-patterns/security/1-sensitive-data-encapsulation/">Sensitive Data Encapsulation&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://alguidelines.dev/navpatterns/1-patterns/security/2-data-encryption/">Data Encryption&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://alguidelines.dev/navpatterns/1-patterns/security/3-single-point-of-access/">Single Point of Access&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://alguidelines.dev/navpatterns/1-patterns/security/4-masked-text/">Masked Text&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://alguidelines.dev/navpatterns/1-patterns/security/5-ssl-in-nav/">SSL in NAV&lt;/a>&lt;/li>
&lt;/ol></description></item><item><title>Docs: Setup Specificity Fallback</title><link>https://alguidelines.dev/docs/navpatterns/patterns/setup-specificity-fallback/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/setup-specificity-fallback/</guid><description>
&lt;p>&lt;em>By Jan Hoek at IDYN&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The Setup Specificity Fallback pattern allows users to efficiently define a potentially complex setup in terms of rules and exceptions to these rules, exceptions to the exceptions, etc.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>The pattern involves a setup table with a compound (i.e. consisting of more than one field) primary key, where each record in the table maps a combination of primary key values to a particular setup value. However, setting up and maintaining each and every combination could prove to be rather labour-intensive.&lt;/p>
&lt;p>With the Setup Specificity Pattern in place, primary key fields in the setup table can have a special value (typically: zero or an empty string) that acts as a wildcard, meaning that the setup record in question applies to a combination of primary key fields with any value in the field containing that wildcard. According to the pattern, when querying the setup table, the application attempts to find the appropriate setup record by searching less and less specific, starting with only specified primary key values, and possibly ending with only wildcard values, replacing specific values with wildcards in a predefined order until a setup record is found, e.g.:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Step 1.&lt;/td>
&lt;td>Try to find record with: Field A = value &amp;ldquo;a&amp;rdquo; and Field B = value &amp;ldquo;b&amp;rdquo;&lt;/td>
&lt;td>If found, return record; if not, go to step 2.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Step 2.&lt;/td>
&lt;td>Try to find record with: Field A = value &amp;ldquo;a&amp;rdquo; and Field B = wildcard value&lt;/td>
&lt;td>If found, return record; if not, go to step 3.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Step 3.&lt;/td>
&lt;td>Try to find record with: Field A = wildcard value and Field B = value &amp;ldquo;b&amp;rdquo;&lt;/td>
&lt;td>If found, return record; if not, go to step 4.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Step 4.&lt;/td>
&lt;td>Try to find record with: Field A = wildcard value and Field B = wildcard value&lt;/td>
&lt;td>If found, return record; if not, optionally return hard-coded value&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The least specific record can be thought of as the general rule, and each of the subsequent records is an exception to that rule. By defining only exceptions to the rule, instead of each and every combination, the burden of setting up and maintaining the setup records is strongly reduced, and the overall setup is much easier to read and understand.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;ol>
&lt;li>Create your setup table. Remember that this pattern applies only to setup tables with a compound primary key;&lt;/li>
&lt;li>Create a function that will return the required value from the setup;&lt;/li>
&lt;li>For each level of specificity, the function should test if the corresponding record exists. If it does, the setup value should be returned. If it doesn&amp;rsquo;t, the logic should fall-back to a lower level of specificity.&lt;/li>
&lt;li>(Optional) If even the least specific setup record can not be found, the function may return a blank value or hard-coded default value.&lt;/li>
&lt;/ol>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>The Printer Selection table in NAV is an example of the Setup Specificity Fallback pattern. Its primary key consists of two fields. A blank value in either field means that the record applies to any user or report respectively.&lt;/p>
&lt;p>&lt;a href="0724.Printer-Selection.png">&lt;img src="0724.Printer-Selection.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The FindPrinter function in codeunit 1 searches for the printer to use, with a decreasing level of specificity.&lt;/p>
&lt;p>&lt;a href="2335.FindPrinter.png">&lt;img src="2335.FindPrinter.png" alt=" ">&lt;/a>&lt;/p></description></item><item><title>Docs: Silent File Upload and Download</title><link>https://alguidelines.dev/docs/navpatterns/patterns/silent-file-upload-and-download/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/silent-file-upload-and-download/</guid><description>
&lt;p>&lt;em>By Bogdana Botez, at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>This pattern is about silently handing file transfers between NAV Service Tier and the NAV client. By &amp;ldquo;silently&amp;rdquo; we mean: without showing a dialog box at upload or download time.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>As a terminology clarification [1], note that both &amp;ldquo;upload&amp;rdquo; and &amp;ldquo;download&amp;rdquo; are named as seen from the client&amp;rsquo;s point of view:&lt;/p>
&lt;ul>
&lt;li>Download&amp;quot; defines transferring a file from the server to the client.&lt;/li>
&lt;li>&amp;ldquo;Upload&amp;rdquo; transfers the file from the client to the server.&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="8688.Silent-file-upload-and-download-NAV-design-pattern.png">&lt;img src="8688.Silent-file-upload-and-download-NAV-design-pattern.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Sometimes, files must be transferred to or from known locations without triggering file-save or file-load dialogs.&lt;/p>
&lt;p>In the following, both the historical and the recommended ways of silently transferring files are described. Since we keep both implementations possible for the sake of backward compatibility, we strongly recommend that you use the file-transfer API provided that is provided with the File Management codeunit (419).&lt;/p>
&lt;p>The legacy API for file transfers [2]:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">[Ok&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>UPLOAD&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>DialogTitle&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromFolder&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromFilter&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromFile&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToFile&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>[Ok&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DOWNLOAD&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FromFile&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DialogTitle&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToFolder&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToFilter&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToFile&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As you can see, this historical API leaves no place for turning off the functionality for showing a dialog. Historically, NAV offered a remedy to this, namely by using the &amp;ldquo;Magicpath&amp;rdquo; string, which is the constant &amp;lsquo;&amp;lt;TEMP&amp;gt;&amp;rsquo;. Under this condition, the way to invoke silent file upload or download becomes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">[Ok&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>UPLOAD&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>DialogTitle&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Magicpath&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromFilter&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FromFile&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToFile&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">&lt;/span>[Ok&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>]&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DOWNLOAD&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>FromFile&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DialogTitle&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Magicpath&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToFilter&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ToFile&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This remedy introduced an issue: If we use &amp;ldquo;Magicpath&amp;rdquo; instead of &lt;strong>FromFolder&lt;/strong> and &lt;strong>ToFolder&lt;/strong> specifications, then where do we upload from and where do we download to? The answer is that they are uploaded to and downloaded from the NAV server&amp;rsquo;s temporary folder. The path to the temporary file can be obtained when this file is created, by using the following function in &lt;strong>File Management: &amp;lt;tempFileName&amp;gt; := ServerTempFileName(&amp;lt;fileExtension&amp;gt;)&lt;/strong>.&lt;/p>
&lt;p>The new API for file transfers in the &lt;strong>File Management&lt;/strong> codeunit:&lt;/p>
&lt;p>[Text :=] UploadFileSilent(ClientFilePath)&lt;/p>
&lt;p>[Text :=] DownloadTempFile(ServerFileName)&lt;/p>
&lt;p>Using the API in the &lt;strong>File Management&lt;/strong> codeunit instead of the historical API is recommended for all file transferring and file management in NAV implementations.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The following describes a scenario for the silent file upload/download pattern, both from the user&amp;rsquo;s point of view and from the NAV developer&amp;rsquo;s point of view.&lt;/p>
&lt;h3 id="the-nav-user">The NAV User&lt;/h3>
&lt;p>The production manager at CRONUS needs an XML file in a specific format containing his latest product list with description, prices, and quantities. He wants to import the list into his web shop to keep product information updated with data in NAV.&lt;/p>
&lt;p>&lt;a href="6428.Silent-File-download-design-pattern.png">&lt;img src="6428.Silent-File-download-design-pattern.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The production manager wants to have the file in a predefined location on his hard drive. The location has been defined in a NAV setup table.&lt;/p>
&lt;h3 id="the-nav-developer">The NAV Developer&lt;/h3>
&lt;p>The NAV developer has written a module to query the CRONUS database and to export the product list in the pre-described XML format required by the web shop. He saves the data in a temporary server file created with this code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">ServerFileName&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ServerTempFileName&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#39;xml&amp;#39;&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When the file has been populated with the latest product data, the NAV developer uses the following call to download the file from the temporary location on the server to the predefined location on the client:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">FileManagement&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>DownloadToFile&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ServerFileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>ClientFileName&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The call to &lt;strong>DownloadToFile&lt;/strong> is part of the &lt;strong>File Management&lt;/strong> codeunit, and it embeds the silent download offered by &lt;strong>DownloadTempFile&lt;/strong>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">PROCEDURE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DownloadToFile@&lt;span style="color:#0000cf;font-weight:bold">13&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ServerFileName@&lt;span style="color:#0000cf;font-weight:bold">1002&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>ClientFileName@&lt;span style="color:#0000cf;font-weight:bold">1000&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">VAR&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempClientFileName@&lt;span style="color:#0000cf;font-weight:bold">1001&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">Text&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ValidateFileNames&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ServerFileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>ClientFileName&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>TempClientFileName&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>DownloadTempFile&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ServerFileName&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>MoveFile&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>TempClientFileName&lt;span style="color:#000;font-weight:bold">,&lt;/span>ClientFileName&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;ol>
&lt;li>Even today, there is no fully silent up or download. The user will get a warning stating the system is trying to run a client side .NET component. However when dismissing this warning, the user can show to not see it again.&lt;/li>
&lt;li>Due to client side .NET interop and of security concerns, silently downloading/uploading files on the web is disabled. Therefore, this pattern is recommended for implementation with Windows clients only.&lt;/li>
&lt;/ol></description></item><item><title>Docs: Singleton</title><link>https://alguidelines.dev/docs/navpatterns/patterns/singleton/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/singleton/</guid><description>
&lt;p>&lt;em>By Bogdana Botez at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;p>&lt;a href="0535.Singleton.png">&lt;img src="0535.Singleton.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Context:&lt;/strong> The pattern described in this article applies to Dynamics NAV only. For the general definition of the &lt;strong>Singleton&lt;/strong> pattern, see for example &lt;a href="https://en.wikipedia.org/wiki/Singleton_pattern">this link&lt;/a>.&lt;/p>
&lt;p>&lt;strong>Problem&lt;/strong>: As a C/AL developer, you need to coordinate action (through a codeunit) or store information (in a table) that is unique across the system.&lt;/p>
&lt;p>&lt;strong>Forces:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Lost reference to centralizer:&lt;/strong> An instance of a relevant object could attempt to centralize control or data in the system. However, once this object is no longer in scope, the reference to it is lost and cannot be retrieved for later coordination&lt;/li>
&lt;li>&lt;strong>Cannot rebuild the initial state:&lt;/strong> A new instance of the same object could be created, however the last known state of the lost instance cannot be known anymore.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Solution:&lt;/strong> create an object which resides in memory in a single copy (instance). Have a way to retrieve this unique object from code. This object can either be a &lt;a href="https://alguidelines.dev/navpatterns/1-patterns/singleton/singleton-table/">&lt;strong>Singleton Table&lt;/strong>&lt;/a>, or a &lt;a href="https://alguidelines.dev/navpatterns/1-patterns/singleton/singleton-codeunit/">&lt;strong>Singleton Codeunit&lt;/strong>&lt;/a>.&lt;/p>
&lt;p>The implementation varies depending on the technology and language used. In object-oriented (OO) languages like C#, C++ or Java, the &lt;strong>Singleton&lt;/strong> uses static classes and class members to instantiate. There is a mechanism to ensure only one instance of the object can exist. This mechanism is many times explicit (like in OO languages) and sometimes implicit as part of the compiler or platform (as it is in NAV).&lt;/p>
&lt;p>&lt;strong>Benefits:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Centralization&lt;/strong>: the setup information is stored in a single well-known place and easily retrievable from anywhere in the application code, by invoking a Record.GET. In case of a single-instance codeunit, any reference to it will retrieve the same instance, so the context will be preserved.&lt;/li>
&lt;li>&lt;strong>Persistence&lt;/strong>: information remains even after the instance goes out of scope, because it continues to live in memory.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Limitation:&lt;/strong> The generic object-oriented &lt;strong>Singleton&lt;/strong> pattern permits instantiation of a limited number n of objects (where usually n=1, but it can have other positive values too). However, in Dynamics NAV, the Singleton patterns are limited: n is always 1.&lt;/p></description></item><item><title>Docs: Standard Journal</title><link>https://alguidelines.dev/docs/navpatterns/patterns/standard-journal/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/standard-journal/</guid><description>
&lt;p>&lt;em>By Bogdana Botez, at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;p>Meet the &lt;strong>Standard Journal&lt;/strong> pattern, which gives the NAV user the advantage of storing transaction details and reusing them multiple times at later dates. For example, this is how to pay a monthly bill.&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>If the journal data can be reused later, the user has the possibility to save the current temporary transaction details. One example can be the case of monthly electricity payments. The user will manually enter the details for the first payment, of the current month. Next month, a part of the data will be the same, such as the vendor and transaction details. If the user has saved the initial monthly payment as a standard journal, then they can now reuse it to create the draft of the next monthly payment. Once the draft journal lines are created, they can be updated with the current month information.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>When a journal is created, the user can invoke the Save as Standard Journal action to save the current journal for later use. When saving the journal as a standard journal, the user is required to choose a code, which is later used to identify the saved journal. The journal lines are stored in a separate table. There can be one standard journal saved per journal type and code.&lt;/p>
&lt;p>Later, the user can create new journal lines by using the Get Standard Journals action. This action restores the saved journal into the new journal lines.&lt;/p>
&lt;h3 id="scenario">Scenario&lt;/h3>
&lt;p>&lt;strong>Step 1&lt;/strong>: The data entered by the user through the Journal page is stored temporarily in the Journal Line table. The data is available for editing or deleting. The journal line data will be stored in this table until it is either deleted or posted.&lt;/p>
&lt;p>&lt;strong>Step 2&lt;/strong>: The user decides to save the current journal line entries for later use. If this is the monthly rent, the user may want to use similar entries next month when a new payment is due. On the Journal page, the user invokes the Save as Standard Journal action. This triggers the Save as Standard Journal report, which copies the entries from the Journal Line table to the Standard Journal Line table. When saving, the user will be asked for an identifier, a code, which will be used to later uniquely identify the saved entries.&lt;/p>
&lt;p>&lt;strong>Step 3&lt;/strong>: When the user invokes the Get Standard Journal action, a list of codes are presented to the user so that they can decide which standard journal to restore and copy in the Journal Line table.&lt;/p>
&lt;p>&lt;a href="3201.NAVPatternStdJournal1.png">&lt;/a>&lt;a href="0820.Standard-Document-Pattern-1.png">&lt;img src="0820.Standard-Document-Pattern-1.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="0143.Standard-Document-Pattern-2.png">&lt;img src="0143.Standard-Document-Pattern-2.png" alt=" ">&lt;/a>&lt;a href="6521.NAVPatternStdJournal2.png">&lt;/a>&lt;/p>
&lt;p>The sequence flow of the three steps is described in the following diagram.&lt;/p>
&lt;p>&lt;a href="5327.Standard-Document-Pattern-3.png">&lt;img src="5327.Standard-Document-Pattern-3.png" alt=" ">&lt;/a>&lt;a href="3618.Standard-Document-Pattern-3.png">&lt;/a>&lt;a href="1104.NAVPatternStdJournal3.png">&lt;/a>&lt;/p>
&lt;h2 id="nav-specific-example">NAV Specific Example&lt;/h2>
&lt;p>In the standard version of NAV, the Standard Journal functionality is implemented in the following journals:&lt;/p>
&lt;ul>
&lt;li>Item Journal, which saves data to the Standard Item Journal&lt;/li>
&lt;li>General Journal, which saves data to the Standard General Journal&lt;/li>
&lt;/ul>
&lt;h3 id="general-journal">General Journal&lt;/h3>
&lt;p>The user enters data in the General Journal page (39) and invokes the Save/Get actions as illustrated in the following screenshot:&lt;/p>
&lt;p>&lt;a href="8585.NAVPatternStdJournal3.jpg">&lt;/a>&lt;a href="0456.Standard-Journal.png">&lt;img src="0456.Standard-Journal.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>When saving the journal lines, the Save as Standard Gen. Journal report (750) is invoked. The report saves the entries in the Standard General Journal Line table (751).&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;ol>
&lt;li>Standard General Journal&lt;/li>
&lt;li>Standard Item Journal&lt;/li>
&lt;/ol>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/XeTKmO2Eqgw" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Temporary Dataset Report</title><link>https://alguidelines.dev/docs/navpatterns/patterns/temporary-dataset-report/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/temporary-dataset-report/</guid><description>
&lt;p>&lt;em>Originally by Abhishek Ghosh, at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>This pattern generates the data to be displayed dynamically by combing/processing several data sources. It then displays the resulting dataset without writing to the database.&lt;/p>
&lt;p>&lt;a href="0250.Temporary-Dataset-Report-1.png">&lt;img src="0250.Temporary-Dataset-Report-1.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>While writing reports in NAV, we have the luxury of using a built-in iterator. So, once we define the dataitem and the ordering, the runtime takes care of the iteration.&lt;/p>
&lt;p>The iterator has one shortcoming: It can only run through records written into the database. There are situations, however, where we want to display temporary datasets created at runtime by processing data from different sources. That is where the Temporary Dataset Report pattern can be used.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>This pattern takes a two-step approach to displaying the data:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Parse the data sources to create a record buffer in a temporary record variable.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Iterate through a dataitem of the Integer table and display one record from the temporary recordset in each iteration.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h4 id="step-1-combining-data-sources-to-create-a-dataset">Step 1: Combining data sources to create a dataset&lt;/h4>
&lt;p>In this step, we would process the existing data to create a temporary recordset. The three most common techniques to do this are discussed in the following paragraphs.&lt;/p>
&lt;p>The first technique is mostly used when we want to build the report based on one or more source tables. A lot of processing is required, and we therefore want to store and display information from a temporary recordset. With this technique, we create a dataitem of the source record and then iterate through this dataitem to create the temporary recordset. An advantage of this technique is that it allows the user to perform additional filtering on the data source tables since they are added as additional dataitems and therefore will have their tabs on the request page by default.&lt;/p>
&lt;p>&lt;a href="2376.Temporary-Dataset-Report-2.png">&lt;img src="2376.Temporary-Dataset-Report-2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The second technique was made available with NAV 2013 when queries were introduced as a tool to help us combine data from different sources. Instead of writing data into a temporary record variable, we can create a query to combine the data from different sources. This offers better performance than the first technique in almost every situation. However, with a query, we sacrifice the luxury of getting a flexible filtering on the request page for the source dataitem.&lt;/p>
&lt;p>The third technique is to write a function (or a codeunit, if the complexity demands so) that will crunch the data and create the temporary record variable. This function must be invoked from the OnPreReport trigger (or the OnPreDataItem trigger of the Integer dataitem).&lt;/p>
&lt;p>&lt;a href="7607.Temporary-Dataset-Report-3.png">&lt;img src="7607.Temporary-Dataset-Report-3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>The following table summarizes when to use each of the three techniques:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Technique&lt;/th>
&lt;th>When to Use&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Source Record DataItem&lt;/td>
&lt;td>When it is important to offer flexible filtering possibilities on the source data.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Query&lt;/td>
&lt;td>When performance is critical.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Populating temporary table in a function&lt;/td>
&lt;td>Only when the source dataset is too complex to use either of the other techniques.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h4 id="step-2-iterating-through-the-integer-dataitem">Step 2: Iterating through the Integer dataitem&lt;/h4>
&lt;p>When you have created the dataset as a temporary record variable or a query, the next step is to iterate through them to display the information. However, the report controller in NAV cannot iterate through temporary records or through the results of a query. This is where the Integer table comes into use.&lt;/p>
&lt;p>The Integer table is a virtual table with only one field, Number, which is an integer field. For all practical purposes, we can assume that this table has pre-inserted records with value of Number, starting from 1 and ending with the highest integer value. So, if we keep iterating through this dataitem, the value of the Number field will be 1 for the first iteration and will keep increasing by 1 for every iteration.&lt;/p>
&lt;p>There are two ways to use the Integer dataitem to iterate through the temporary recordset:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Loop for an indeterminate number of times until you reach the end of the recordset.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Calculate the number of records in the temporary recordset in advance and then iterate that many number of times.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>With the first approach, in the Integer-OnAfterGetRecord trigger, you must make the temporary record variable move to the next record, follow that up with a check if you have reached the end of the recordset, and then use CurrReport.BREAK if you have reached the end.&lt;/p>
&lt;p>With the second approach, you must limit the number of times the report iterates through the Integer dataitem. The Number field in the Integer table will have a value of 1 in the first iteration and will increment automatically by 1 on every subsequent iteration. To ensure that the report iterates through the Integer dataitem &amp;ldquo;n&amp;rdquo; times, you must, therefore, filter the Integer dataitem on Number = 1..n. You must also move the temporary record variable to the next record in every iteration of the Integer-OnAfterGetRecord trigger. NOTE: This technique cannot be used if you use queries as the temporary data source, since queries do not (in NAV 2013) return the number of records.&lt;/p>
&lt;h2 id="example">Example&lt;/h2>
&lt;p>&lt;strong>Goal:&lt;/strong> To print a report that lists all contacts that have open documents (both sales and purchase) and displays those documents in chronological order&lt;/p>
&lt;p>A contact can be connected to a vendor or a customer using the Create As Customer/Vendor function on the Contact Card. When a sales/purchase document is created for this customer/vendor, the Contact No. is stored in the Sell-to Contact No. or Buy-from Contact No. fields of the sales and purchase documents. The obvious choice would be to display the data directly from the Sales Header and Purchase Header records. However, the requirement is to display all of them together chronologically, which means they will need to be stored in, and be read from, one common dataset.&lt;/p>
&lt;p>&lt;strong>Step 1: Design a new table that will hold the temporary dataset.&lt;/strong>&lt;/p>
&lt;p>The UI must display the Document Type, Document No., Document Date, Amount Incl. VAT and the name of the salesperson or purchaser. The table is designed as follows.&lt;/p>
&lt;p>&lt;a href="6523.Temporary-Dataset-Report-4.jpg">&lt;img src="6523.Temporary-Dataset-Report-4.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>Since this table is used to sort the data by Document Date, a &amp;ldquo;Document Date&amp;rdquo; key is added to the table.&lt;/p>
&lt;p>&lt;a href="4118.Temporary-Dataset-Report-5.jpg">&lt;img src="4118.Temporary-Dataset-Report-5.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>Some additional properties to note:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Sales Header dataitem should be linked to the Contact dataitem through the DataItemLink property &amp;ndash; &amp;ldquo;Sell-to Contact No.=FIELD(No.)&amp;rdquo;&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Purchase Header dataitem should be linked to the Contact dataitem through the DataItemLink property &amp;ndash; &amp;ldquo;Buy-from Contact No.=FIELD(No.)&amp;rdquo;&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Step 2: In the Sales Header&lt;/strong> &amp;ndash; OnAfterGetRecord, write the following code to populate the data buffer:&lt;/p>
&lt;p>&lt;a href="4010.Temporary-Dataset-Report-6.jpg">&lt;img src="4010.Temporary-Dataset-Report-6.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Where:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>ContactDocumentBuffer is a temporary global variable of the buffer table created.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>SalesPerson is a local record variable for table 13.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>SalesTxt is a text constant denoting &amp;ldquo;Sales&amp;rdquo; in ENU.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Similar code must be written in Purchase Header &amp;ndash; OnAfterGetRecord to store data from the purchase documents into the buffer.&lt;/p>
&lt;p>&lt;strong>Step 3:&lt;/strong> Iterate through the temporary records in the Integer dataitem.&lt;/p>
&lt;p>Since the requirement is to sort the data by Document Date, we must sort the ContactDocumentBuffer table by this key. Also, by the time the execution of Integer &amp;ndash; OnPreDataItem begins, the number of records in the temporary buffer should be known already. Therefore, we can limit the number of times to repeat the Integer dataitem to the number of records in the buffer.&lt;/p>
&lt;p>We meet both requirements with the following lines of code in Integer - OnPreDataItem:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">ContactDocumentBuffer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETCURRENTKEY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Document Date&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Number&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>ContactDocumentBuffer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&lt;span style="color:#204a87;font-weight:bold">COUNT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Lastly, we must move the record pointer by 1 record every time we loop through the Integer dataitem. So, in Integer &amp;ndash; OnAfterGetRecord, we add the following lines of code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>Number&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>=&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ContactDocumentBuffer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDFIRST&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ELSE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ContactDocumentBuffer&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NEXT&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, the only task that remains is to design the RDLC layout. (Not part of this application pattern description.)&lt;/p>
&lt;p>NAV Usages&lt;/p>
&lt;p>This is a commonly used pattern in several reports, such as:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Report 204 &amp;ndash; Sales &amp;ndash; Quote&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Report 205 &amp;ndash; Order Confirmation&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Report 206 &amp;ndash; Sales &amp;ndash; Invoice&lt;/p>
&lt;/li>
&lt;/ul>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/QHn5oEOJv0Q" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Totals and Discounts on Subpages Sales and Purchases</title><link>https://alguidelines.dev/docs/navpatterns/patterns/totals-and-discounts-on-subpages-sales-and-purchases/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/totals-and-discounts-on-subpages-sales-and-purchases/</guid><description>
&lt;p>&lt;em>By Nikola Kukrika at Microsoft Development Center Copenhagen&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>To increase discoverability and productivity, critical information, such as statistics, can be moved from separate pages onto the document where it is needed.&lt;/p>
&lt;p>For example, documents should clearly display totals and discounts information to provide quick overview, make it easy to relate the amounts to the document currency, and to allow the user to see and apply discounts directly on the document.&lt;/p>
&lt;h2 id="description">Description&lt;/h2>
&lt;p>Before Microsoft Dynamics NAV 2015, totals and discount information was scattered between the document and the Statistics page, which made it less discover-able and less usable for new users. It was difficult to see the discount amounts, relate the amounts to the currency of the invoice, and it was not-intuitive that you had to update the Statistics page to see updates on the document. In addition, the result of the update was not visible on the main document, which added to the confusion.&lt;/p>
&lt;p>Totals and discount information logically belongs on the document, as is the case on many competitor products.&lt;/p>
&lt;p>The Statistics page contains too much information for most common scenarios, and only a part of the information is visible on the related document. See the following example for sales order statistics.&lt;/p>
&lt;p>&lt;a href="4300.Fig-1.jpg">&lt;img src="4300.Fig-1.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>With the pattern implemented, selected statistics fields are placed on the sales order, as in the following example.&lt;/p>
&lt;p>&lt;a href="Fig-2.jpg">&lt;img src="Fig-2.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>This new layout gives precise and complete information about totals and discounts, with discounts on the left side and totals on the right side. The currency is clearly shown, and the layout resembles a printed document. The values are always updated (with some exceptions that are explained in the next following sections), and the user can apply a discount directly on the document.&lt;/p>
&lt;p>Options considered when deciding on the layout:&lt;/p>
&lt;ul>
&lt;li>A new FactBox&lt;/li>
&lt;li>A new FastTab&lt;/li>
&lt;li>On the Lines subpage&lt;/li>
&lt;/ul>
&lt;p>The Lines subpage option was chosen because:&lt;/p>
&lt;ul>
&lt;li>Can be made with cleaner code&lt;/li>
&lt;li>Is always visible, not collapsible, as opposed to FactBox and FastTab options&lt;/li>
&lt;li>Less chrome in the UI&lt;/li>
&lt;/ul>
&lt;h2 id="usages">Usages&lt;/h2>
&lt;p>Concerning update of totals and discounts, the following were considered:&lt;/p>
&lt;ul>
&lt;li>All code should be in one place&lt;/li>
&lt;li>Existing VAT, invoice discount calculation, etc. should be reused and not re-implemented.&lt;/li>
&lt;li>The presentation layer should be separated from the logic.&lt;/li>
&lt;li>Presentation layer should have simple (one liner) calls to the logic&lt;/li>
&lt;li>System responsiveness should not be significantly affected&lt;/li>
&lt;li>Totals and discounts should be updated &amp;ldquo;on-the-fly&amp;rdquo; on any change that affects amounts&lt;/li>
&lt;/ul>
&lt;p>The following artifacts were implemented to achieve the desired functionality.&lt;/p>
&lt;h3 id="flags-that-totals-are-not-updated">Flags That Totals Are Not Updated&lt;/h3>
&lt;p>In order to always update the totals, the system must have a way to mark that a specific change should trigger a recalculation of the totals. To achieve this, the following was implemented.&lt;/p>
&lt;ul>
&lt;li>On the lines:
&lt;ul>
&lt;li>A new field, Recalculate Invoice Discount, was added and set to FALSE by default.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>The &lt;em>UpdateAmounts&lt;/em> function sets the new field to TRUE for any execution. This function was chosen as it is a central entry point for any amount-related change.&lt;/p>
&lt;p>&lt;a href="Fig-3.jpg">&lt;img src="Fig-3.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;ul>
&lt;li>On the header:
&lt;ul>
&lt;li>A new FlowField, Recalculate Invoice Discount was added. This field is TRUE if at least one line (that relates to the header) has been marked as &amp;ldquo;dirty&amp;rdquo;, meaning that totals must be recalculated.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="6305.Fig-4.jpg">&lt;img src="6305.Fig-4.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>Update diagram&lt;/p>
&lt;p>&lt;a href="Fig-5.jpg">&lt;img src="Fig-5.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="total-calculation-and-update-logic">Total Calculation and Update Logic&lt;/h3>
&lt;p>The following new codeunits were added:&lt;/p>
&lt;ul>
&lt;li>COD56 and COD66 (one for sales and one for purchase) are responsible for the &amp;ldquo;heavy&amp;rdquo; tasks of calculating/applying totals and discounts by calling into existing code, similarly to how the Statistics page works.&lt;/li>
&lt;li>After recalculation, the flag field is reset on all the lines related to a specific header.&lt;/li>
&lt;li>These calculations, in the existing implementation, are triggered ONLY in case of UI scenarios. Non-UI scenarios are not affected.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Note:&lt;/strong> In case of web-service implementations that do not use the existing pages, the total calculation and the invoice discount logic should be called specifically to display similar functionality.&lt;/p>
&lt;h3 id="ui-related-updates">UI-Related Updates&lt;/h3>
&lt;p>A new CU, COD57 has been added and it contains the logic used to update the fields that will, in the end, be displayed in the UI. Decision was to merge both the sales and purchase functionality into one place.&lt;/p>
&lt;h3 id="update-controls">Update Controls&lt;/h3>
&lt;p>The pattern is applied to both non-posted documents (orders, invoices, etc.) and posted documents (posted Invoice, etc.). Because the posted document is a document that does not change, the implementation is simplified as follows.&lt;/p>
&lt;h4 id="subpage---non-posted-documents">Subpage - Non-posted documents&lt;/h4>
&lt;p>The &lt;em>OnAfterGetCurrRecord&lt;/em> function call is responsible for updating the totals- and discount-related controls.&lt;/p>
&lt;p>To avoid duplicating lots of code in many places, a single function with more parameters &amp;ldquo;pattern&amp;rdquo; was chosen. The function returns all the controls updated in a single call, as follows.&lt;/p>
&lt;p>&lt;a href="Fig-6.jpg">&lt;img src="Fig-6.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>Manual invoice discount. One function call when applying a manual invoice discount, as follows.&lt;/p>
&lt;p>&lt;a href="Fig-7.jpg">&lt;img src="Fig-7.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong> After applying the manual discount, the lines should be refreshed as they will be changed in batch mode.&lt;/p>
&lt;p>The following &amp;ldquo;decorators&amp;rdquo; were added to recalculate amounts on the fly:&lt;/p>
&lt;ul>
&lt;li>Totals should always be updated as soon as the user leaves the field.&lt;/li>
&lt;/ul>
&lt;p>Code should be added to the validate triggers of the controls that are changing the amounts in order to refresh the total controls.&lt;a href="Fig-8.jpg">&lt;img src="Fig-8.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong> Amounts will not always be up to date because of the following:&lt;/p>
&lt;ul>
&lt;li>Performance. The update must be triggered manually if the number of lines is above 100. (100 was chosen because performance measurements have demonstrated that with more than 100 lines, the performance was worse than 0.5-1s in update time.)&lt;/li>
&lt;li>Missed/customized triggers or header changes - cannot trigger lines update from header. Likewise, lines cannot trigger the header to update.&lt;/li>
&lt;li>In the above cases, a link next to the totals will be displayed informing user that totals/discounts might not be updated and they can be updated by selecting the link&lt;/li>
&lt;/ul>
&lt;h4 id="subpage----posted-documents">Subpage &amp;ndash; Posted Documents&lt;/h4>
&lt;p>Only the _OnAfterGetCurrRecord _function will have code because posted documents cannot be changed. Therefore, totals do not need to be updated.&lt;/p>
&lt;p>&lt;a href="Fig-9.jpg">&lt;img src="Fig-9.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="ui----presentation-layer">UI &amp;ndash; Presentation Layer:&lt;/h3>
&lt;p>After Platform added support for this specific case, the layout is very simple, as follows.&lt;/p>
&lt;p>&lt;a href="Fig-10.jpg">&lt;img src="Fig-10.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;p>This will produce the layout we wanted:&lt;/p>
&lt;p>&lt;a href="Fig-11.jpg">&lt;img src="Fig-11.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h3 id="ui----manual-totals-update">UI &amp;ndash; Manual Totals Update&lt;/h3>
&lt;p>As mentioned before, there are cases when the user is informed that totals/discounts might not be up to date and that it should select a link in order to get the updated values.&lt;/p>
&lt;p>The link is part of the sub-part where totals and discounts are added. The visibility is controlled by actually controlling the text (message, or empty), because Platform does not support making only one visible/invisible (it must be a group). When the link is displayed, the styling is also changed for the total/discount controls, and the values are set to 0.&lt;/p>
&lt;p>&lt;a href="Fig-12.jpg">&lt;img src="Fig-12.jpg" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="nav-usages">NAV Usages&lt;/h2>
&lt;p>We have implemented these scenarios for sales and purchase documents (order, invoice, quote, credit memos, return orders, including posted documents). Note that the implementation in NAV 2015 is a bit different than the one in NAV 2014 C5 objects (1300 range). It was decided not to merge the two implementations, among other reasons because the NAV 2014 C5 implementation does not fit the full application.&lt;/p>
&lt;p>The pattern can easily be extended to new sales and purchase documents. If the pattern is followed, it can also be extended to other types of documents, such as in services, jobs, etc.&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong> This new pattern is not implemented in the North America and India versions. This is due to special local features in the two versions regions and the multitude of sales tax/vat options that would make the solution non-user friendly and not optimized for performance.&lt;/p>
&lt;h2 id="ideas-for-improvement">Ideas for Improvement&lt;/h2>
&lt;p>Platform support to be able to trigger full-page update from the lines. Support does exist today, but it is not programmatically controlled at design time. This means that it cannot be used in all cases.&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/U3noU-WT8Xk" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Transfer Custom Fields</title><link>https://alguidelines.dev/docs/navpatterns/patterns/transfer-custom-fields/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/transfer-custom-fields/</guid><description>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/cGaBqwfGCws" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>Docs: Variant Facade</title><link>https://alguidelines.dev/docs/navpatterns/patterns/variant-facade/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/navpatterns/patterns/variant-facade/</guid><description>
&lt;p>&lt;em>By Nikola Kukrika, waldo and Gary Winter&lt;/em>&lt;/p>
&lt;h2 id="abstract">Abstract&lt;/h2>
&lt;p>The Variant façade provides a single interface that can take any Record, RecordRef or RecordID as an argument. With this pattern the code is encapsulated within the single object, with clear separation between common and table specific code.&lt;/p>
&lt;p>&lt;a href="picture1.png">&lt;img src="picture1.png" alt=" ">&lt;/a>&lt;/p>
&lt;h2 id="problem">Problem&lt;/h2>
&lt;p>Since NAV is strongly typed, developers often need to duplicate functionality in order to add support for a new table. The developer would typically start by duplicating the function, changing the record type and implement slight modifications to the code if needed.&lt;/p>
&lt;p>The problem with this approach is that code duplication is one of the worst things in software development &amp;ndash; it makes code harder to understand, maintain, extend and test.&lt;/p>
&lt;p>One of the good examples of this approach and the resulting duplication is codeunit 229, Document-Print:&lt;/p>
&lt;p>&lt;a href="Picture2.png">&lt;img src="Picture2.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="Picture3.png">&lt;img src="Picture3.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>After reading the code from the two code snippets above, it is very hard to see the differences. The most of the code is duplicated (more than 95%). To make the matters worse the codeunit itself has 10 additional methods that are used to print different records, some are similar to the ones above while others are completely different.&lt;/p>
&lt;p>&lt;a href="Picture4.png">&lt;img src="Picture4.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="Picture5.png">&lt;img src="Picture5.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Figure: the entire code of the codeunit 229, Document Print, 12 methods&lt;/p>
&lt;p>&lt;a href="Picture6.png">&lt;img src="Picture6.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>Figure: Visualization how it would look like with 20 methods&lt;/p>
&lt;p>Problems arising from this way of implementing code are:&lt;/p>
&lt;p>&lt;strong>Understanding of the code&lt;/strong> is very hard, since the developer needs to read blocks of code that look similar and try to understand what exactly the differences are.&lt;/p>
&lt;p>&lt;strong>Maintaining and Extending&lt;/strong> the code is hard, since every fix or a new behavior that needs to be implemented multiple times (in this case probably 12 times).&lt;/p>
&lt;p>&lt;strong>Upgradability is low&lt;/strong> &amp;ndash; each conflict needs to be resolved many times. The hook pattern is hard to implement since it needs to be implemented for every function. Evening suffers the same problem - cannot use the evening easily since it needs to be raised from multiple places in the code.&lt;/p>
&lt;p>&lt;strong>Testing the code&lt;/strong> is hard since the tests need to be replicated.&lt;/p>
&lt;p>&lt;strong>Constant cost of adding support for new tables&lt;/strong> &amp;ndash; when the new record type needs to be supported, it has a constant cost. Adding a support for a new record will increase the Maintenance tax and it will make the code harder to understand and extend.&lt;/p>
&lt;p>&lt;strong>Conclusion&lt;/strong> - &lt;strong>If the functionality needs to be used for many records the approach of duplicating the functions should be avoided.&lt;/strong>&lt;/p>
&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>The Variant façade pattern provides a single interface that would not need to be changed in the future. It will be able to take any record as a parameter. Common code should be kept separately from record specific code and both must be very visible so the developers can easily see what the differences are.&lt;/p>
&lt;p>The Key components of the pattern are:&lt;/p>
&lt;h3 id="signature">Signature&lt;/h3>
&lt;p>Instead of hardcoding a record type a variant is used as an argument. A Variant Façade function can receive three types of data: Record, RecordID, or RecordRef. This way, it can be reused anywhere in the product and the code will still work.&lt;/p>
&lt;p>A good practice is to combine this pattern with the Argument Table pattern to make sure that the signature does not change (Additional parameters can be added to the argument table without impacting existing code.). If the Argument Table is not needed, it should not be placed in the signature - it is always possible to add it at a latter point and have two public functions (one with and one without arguments).&lt;/p>
&lt;p>Example - For codeunit 229, Document-Print all of the public methods can be simply replaced with a single public method like this:&lt;/p>
&lt;p>With this approach the façade function can serve all of the record types and will not need to change in the future.&lt;/p>
&lt;h3 id="casting-to-a-record-ref">Casting to a record ref&lt;/h3>
&lt;p>After the signature it is necessary to decide if the function will support passing of the Record ID and the RecordRef. Code tends to be easier to understand and maintain if only the records are passed as the arguments, however in some cases it is needed to support the other two types.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Support for Record, Record ID and RecordRef:&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>After the signature if the function supports passing of the RecordID or RecordRef as a parameter it is a good practice to cast them to a RecordRef. Codeunit Data Type Management is used to do this:&lt;/p>
&lt;p>DataTypeManagement.GetRecordRef(RecRelatedVariant,RecordRef)&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Support Records only&lt;/strong> - If the function supports only passing in the record, it is a good practice to check if the variant is a record:&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">IF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">NOT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>RecordVariant&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>ISRECORD&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">THEN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ERROR&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>NotARecordErr&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="using-the-variant">Using the variant&lt;/h3>
&lt;p>The variant can be passed instead of record when calling the Page.RUN, Codeunit.RUN or Report.RUN statically:&lt;/p>
&lt;p>For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">Page&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>PageID&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Variant&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Codeunit&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>CodeunitID&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Variant&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Report&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportID&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Variant&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>These calls are identical to using an actual instance of the record, since the variant will be casted to the record automatically, with all filters, markings and values preserved.&lt;/p>
&lt;p>In case the variant was casted to the RecordRef (by using DataTypeManagement.GetRecordRef(RecRelatedVariant,RecordRef)), it is still possible to invoke the functions statically.&lt;/p>
&lt;p>The RecordRef simply needs to be casted into a variant and passed as a parameter, for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">VariantArgument&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Page&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>PageID&lt;span style="color:#000;font-weight:bold">,&lt;/span>VariantArgument&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Variant can always casted back to the original record in the table specific code, exact process is described below.&lt;/p>
&lt;h3 id="table-specific-code">Table specific code&lt;/h3>
&lt;p>To do table-specific processing, it is necessary to get the RecordRef first, since NUMBER parameter will tell us which table it is. In the table-specific code, it is possible to cast the variant back to the original record type, so data is accessible and it is possible to invoke functions.&lt;/p>
&lt;p>To do this, the best practice is to use the COPY function to preserve filters:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>COPY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecordVariant&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Assigning directly such as SalesHeader := RecordVariant, is possible, however all filters will be lost.&lt;/p>
&lt;p>Example of table specific code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">CASE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NUMBER&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Header&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>COPY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecordVariant&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>PrintDocument&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Purchase Header&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>PurchaseHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>COPY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecordVariant&lt;span style="color:#ce5c00;font-weight:bold">)
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> ...
&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">....
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It is a good practice to try to avoid the table specific code if possible.&lt;/p>
&lt;p>One of the issues with table specific code is that the CASE statement can easily explode when large number of records are supported.&lt;/p>
&lt;p>There are two possible solutions:&lt;/p>
&lt;ol>
&lt;li>Move the calculations outside of the façade code unit and pass it in as part of the argument table.&lt;/li>
&lt;/ol>
&lt;p>For example, instead of having a case like this within DocumentPrint codeunit:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">CASE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NUMBER&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">DATABASE&lt;/span>&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Sales Header&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">BEGIN&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>COPY&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>RecordVariant&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">CASE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Quote&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">,&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Quote&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Blanket Order&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">,&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Blanket&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Order&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">,&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Order&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Return Order&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">,&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Return&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Invoice&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">,&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Invoice&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Credit Memo&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">,&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Cr.Memo&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">END&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If the ReportSelections.Usage is simply passed into the function from outside, then the case statement is not needed at all. For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">PrintDocumentArguments&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Report Selection Usage&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">:=&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>GetReportSelectionUsage&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>DocumentPrint&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>PrintDocument&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>SalesHeader&lt;span style="color:#000;font-weight:bold">,&lt;/span>PrintDocumentArguments&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Where GetReportSelection usage is coded like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">&lt;span style="color:#204a87;font-weight:bold">CASE&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OF&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Quote&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Quote&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Blanket Order&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Blanket&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&lt;span style="color:#204a87;font-weight:bold">Order&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Order&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Return Order&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Return&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>Invoice&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Invoice&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>SalesHeader&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Document Type&amp;#34;&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;Credit Memo&amp;#34;&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EXIT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelections&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>Usage&lt;span style="color:#000;font-weight:bold">::&lt;/span>&amp;#34;S.Cr.Memo&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This way the code is much more reusable and simpler to read.&lt;/p>
&lt;ol>
&lt;li>Use Rules Table to replace the code with data-driven approach.&lt;/li>
&lt;/ol>
&lt;p>Setup table would contain the list of the reports and their usages. Based on Table ID and usage it is possible to set filters on the setup table and run the object ID from the result.&lt;/p>
&lt;p>For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-al" data-lang="al">ReportSelectionSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Table ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>NUMBER&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>ReportSelectionSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>SETRANGE&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>&amp;#34;Usage Type&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">RecordRef&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FieldValue&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ArgumentTable&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Usage Type&amp;#34;&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>ReportSelectionSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>FINDFIRST&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">REPORT&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>RUN&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>ReportSelectionSetup&lt;span style="color:#ce5c00;font-weight:bold">.&lt;/span>&amp;#34;Report ID&amp;#34;&lt;span style="color:#000;font-weight:bold">,&lt;/span>VariantRecord&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="example">Example&lt;/h2>
&lt;p>The following code illustrates how the Variant Façade pattern can be used to implement the Document-Print Codeunit.&lt;/p>
&lt;p>&lt;a href="Picture7.png">&lt;img src="Picture7.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>&lt;a href="Picture8.png">&lt;img src="Picture8.png" alt=" ">&lt;/a>&lt;/p>
&lt;p>From the PrintDocument signature it is clear that it will not need to be changed in the future.&lt;/p>
&lt;p>Code duplication is avoided, specific code is isolated in the PrepareRecord function, there is clear extension point to add support for new records in the future. Since code is not duplicated and there is a single flow through the method, inserting hooks and events in the future will be straightforward.&lt;/p>
&lt;p>When adding the support for new records in most cases it is not need to change any code within the method, thus the cost of extending the usage is minimal.&lt;/p>
&lt;p>Note - PrepareRecord function is placed for the illustrational purposes. An improvement would be to move all of the code from the PrepareRecord function before calling the function. So for the SalesHeader and PurchaseHeaders discounts should be calculated before invoking the function. For passing of the argument it should be one of the fields in the Argument Table, thus the entire specific code would be eliminated.&lt;/p>
&lt;h2 id="consequences">Consequences&lt;/h2>
&lt;ul>
&lt;li>Not needed if the functionality needs to support few tables. Don&amp;rsquo;t use it as a hammer&lt;/li>
&lt;li>Strongly typing the records has it benefits since it is easier to find usages, errors will be visible at the compilation time.&lt;/li>
&lt;li>Code becomes harder to debug within the variant façade&lt;/li>
&lt;li>Be careful with filters and marks, if the function needs to support multiple records. Test these cases thoughtfully because with bad placement of code the filters can easily be lost.&lt;/li>
&lt;li>Case statements can explode if there are too many tables that require specific processing. Then it is a must to find a way to keep the number of options in the CASE statement low. The Rules Table pattern and adding specifics to the Argument Table before invoking the code could help with keep the list shorter.&lt;/li>
&lt;/ul>
&lt;h2 id="nav-usages">NAV usages&lt;/h2>
&lt;ul>
&lt;li>Codeunit 452 - Report Distribution Management&lt;/li>
&lt;li>Codeunit 700 - Page Management&lt;/li>
&lt;li>Codeunit 701 - Data Type Management&lt;/li>
&lt;li>Codeunit 1268 - Export Launcher&lt;/li>
&lt;li>Codeunit 1410 - Doc. Exch. Service Mgt.&lt;/li>
&lt;li>Codeunit 1501 - Workflow Management&lt;/li>
&lt;li>Codeunit 1521 - Workflow Response Handling&lt;/li>
&lt;li>Codeunit 1531 - Workflow Change Rec Mgt.&lt;/li>
&lt;li>Codeunit 1535 - Approvals Mgmt.&lt;/li>
&lt;/ul>
&lt;h2 id="related-topics">Related Topics&lt;/h2>
&lt;p>OO Facade &lt;a href="https://en.wikipedia.org/wiki/Facade_pattern">https://en.wikipedia.org/wiki/Facade_pattern&lt;/a>&lt;/p>
&lt;p>Argument Table pattern - &lt;a href="https://alguidelines.dev/nav/w/designpatterns/245.argument-table-pattern">https://community.dynamics.com/nav/w/designpatterns/245.argument-table-pattern&lt;/a>&lt;/p>
&lt;p>Rules Table pattern&lt;/p></description></item></channel></rss>