1184 lines
No EOL
347 KiB
XML
1184 lines
No EOL
347 KiB
XML
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>alguidelines.dev - Business Central Design Patterns – Design Patterns</title><link>https://alguidelines.dev/docs/patterns/</link><description>Recent content in Design 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/patterns/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: API Register Fieldset</title><link>https://alguidelines.dev/docs/patterns/api-register-fieldset/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/api-register-fieldset/</guid><description>
|
||
<p><em>Created by Arend-Jan Kauffmann, Described by Arend-Jan Kauffmann</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>The goal of this pattern is to register the fields that are part of the request body of an API call.</p>
|
||
<h2 id="context">Context</h2>
|
||
<p>A request to an API page to insert or modify a record requires a JSON body with the fields and values. It is not required to specify all fields that are exposed by the API page. Only those fields that are specified in the JSON body will be validated with a value. A call to insert a record (http POST) will leave the unspecified fields at their default value. A call to modify a record (http PATCH) will only update the specified fields and leave the other fields to their current value.</p>
|
||
<h2 id="problem">Problem</h2>
|
||
<p>The standard behavior can result in a number of challenges:</p>
|
||
<ul>
|
||
<li>It&rsquo;s not possible to implement mandatory fields. Especially for fields with an initial value like integers, decimals and booleans the code doesn&rsquo;t know if they are their initial value or were included in the API request.</li>
|
||
<li>In the OnValidate trigger of a field it&rsquo;s not possible to verify if the API request is an insert or modify operation. Fields can&rsquo;t be protected to be modified during a specific operation, e.g. do not allow to modify during an insert.</li>
|
||
<li>When implementing the Delegated API Operation pattern, for example to implement a template with default values, the template values should not overwrite the provided values in the API request while non-specified fields should get a value from the template.</li>
|
||
</ul>
|
||
<h2 id="description">Description</h2>
|
||
<p>To mitigate these problems, we can register the fields during the OnValidate trigger in a temporary table. During the delayed insert or modify operation the code knows which fields were part of the API request.</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">field</span><span style="color:#ce5c00;font-weight:bold">(</span>displayName<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Rec<span style="color:#ce5c00;font-weight:bold">.</span>Description<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnValidate<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>RegisterFieldSet<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#ce5c00;font-weight:bold">.</span>FieldNo<span style="color:#ce5c00;font-weight:bold">(</span>Description<span style="color:#ce5c00;font-weight:bold">))</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">....
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Field</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">temporary</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>RegisterFieldSet<span style="color:#ce5c00;font-weight:bold">(</span>FieldNumber<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Integer</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">Database</span><span style="color:#000;font-weight:bold">::</span>Item<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>FieldNumber<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#ce5c00;font-weight:bold">.</span>Init<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#ce5c00;font-weight:bold">.</span>TableNo<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Database</span><span style="color:#000;font-weight:bold">::</span>Item<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No.&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>FieldNumber<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#ce5c00;font-weight:bold">.</span>Insert<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>Now that we have the list of fields that are part of the request, they can be checked during the insert or modify operation. Or they can be handed over to a delegated operation.</p>
|
||
<p>Some examples to work with the list of fields:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnInsertRecord<span style="color:#ce5c00;font-weight:bold">(</span>BelowxRec<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">Database</span><span style="color:#000;font-weight:bold">::</span>Item<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Rec<span style="color:#ce5c00;font-weight:bold">.</span>FieldNo<span style="color:#ce5c00;font-weight:bold">(</span>Inventory<span style="color:#ce5c00;font-weight:bold">)) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Error<span style="color:#ce5c00;font-weight:bold">(</span>InventoryCannotBeChangedInAPostRequestErr<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ItemAPIOperations<span style="color:#ce5c00;font-weight:bold">.</span>InsertItem<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnModifyRecord<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ItemAPIOperations<span style="color:#ce5c00;font-weight:bold">.</span>ModifyItem<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnDeleteRecord<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ItemAPIOperations<span style="color:#ce5c00;font-weight:bold">.</span>DeleteItem<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>The example code combines this with the Delegated API Operation pattern. The codeunit for the delegated operation can use the fieldset to apply a template while keeping the original values from the request.</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50000</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Item API Operations&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>InsertItem<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Field&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ModifiedDateTime<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">DateTime</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfigTemplateHeader<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Config. Template Header&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfigTemplateManagement<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Config. Template Management&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>RecRef<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">RecordRef</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>FindConfigTemplateHeader<span style="color:#ce5c00;font-weight:bold">(</span>Item<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfigTemplateHeader<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>RecRef<span style="color:#ce5c00;font-weight:bold">.</span>GetTable<span style="color:#ce5c00;font-weight:bold">(</span>Item<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfigTemplateManagement<span style="color:#ce5c00;font-weight:bold">.</span>ApplyTemplate<span style="color:#ce5c00;font-weight:bold">(</span>RecRef<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempFieldSet<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>RecRef<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfigTemplateHeader<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>RecRef<span style="color:#ce5c00;font-weight:bold">.</span>SetTable<span style="color:#ce5c00;font-weight:bold">(</span>Item<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ModifyItem<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>DeleteItem<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><h2 id="benefits">Benefits</h2>
|
||
<p>Having a list of fields that are part of the API request provides more information during to the insert or modify operation. This helps to implement specific behavior, based on which fields were specified in the API request.</p></description></item><item><title>Docs: Command Queue</title><link>https://alguidelines.dev/docs/patterns/command-queue/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/command-queue/</guid><description>
|
||
<p><em>Created by Patrick Schiefer, Described by Patrick Schiefer</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>The goal of this pattern is to control the flow of multiple processes</p>
|
||
<h2 id="problem">Problem</h2>
|
||
<p>Sometimes its neccassary to perform multiple processes in Business Central, for example you want to post more than one order or before you post an Order you also have to post a purchase order this often leads to spaghetti code with big if else structures, which is not easy to read</p>
|
||
<h2 id="description">Description</h2>
|
||
<p>The pattern is ideal for executing several independent processes in succession. Since the processes are independent, each process must take care of error handling itself.
|
||
The command queue should not be used to control a single process. Also it is important to know that the queue is just in the memory so if the service gets restarted the queue is gone and has to be rebuilt.</p>
|
||
<h2 id="the-pattern">The Pattern</h2>
|
||
<p>To structure this problem we can use the &ldquo;Command Queue&rdquo; pattern. The pattern consist of two main parts the queue and the command interface</p>
|
||
<p><img src="queue.png" alt="image"></p>
|
||
<p>First the command interface, it only has one procedure to execute the command</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Execute<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>And then the Queue which consist of two codeunits, the Queue itself and a Queue Entry</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50100</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Queue&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Push<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Entry<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>QueueEntry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Entry<span style="color:#ce5c00;font-weight:bold">.</span>SetValue<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">count</span><span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>first<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Entry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>last<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Entry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">else</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>last<span style="color:#ce5c00;font-weight:bold">.</span>SetNextEntry<span style="color:#ce5c00;font-weight:bold">(</span>Entry<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>last<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Entry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">count</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">+=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Pop<span style="color:#ce5c00;font-weight:bold">() </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">count</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&gt;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>first<span style="color:#ce5c00;font-weight:bold">.</span>GetValue<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>first<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>first<span style="color:#ce5c00;font-weight:bold">.</span>GetNextEntry<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">count</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">-=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">else</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Error<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#4e9a06">&#39;The Queue is empty!&#39;</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetSize<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Integer</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">count</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>first<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>QueueEntry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>last<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>QueueEntry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">count</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Integer</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50102</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;QueueEntry&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SetValue<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>v<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>v<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetValue<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetNextEntry<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>QueueEntry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>NextEntry<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SetNextEntry<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Entry<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>QueueEntry<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NextEntry<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Entry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NextEntry<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>QueueEntry<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>As we see the queue entry stores a command, since the command is an interface we can hide each business logic behind.</p>
|
||
<h2 id="benefits">Benefits</h2>
|
||
<p>The logical flow is very easy to adopt, it is even possible to add entries to the queue while it is processed.</p>
|
||
<h2 id="example">Example</h2>
|
||
<p>In this short example I show you how to post multiple sales orders and display message after finishing the last post.</p>
|
||
<p>We have two commands in this example, the &ldquo;SalesOrderPostCommander&rdquo; is used to post a sales order and the &ldquo;MessageCommander&rdquo; displays a message.</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50104</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;SalesOrderPostCommander&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SetSalesOrderNumber<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>No<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Execute<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// TODO Post Sales Header
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>No<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50103</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;MessageCommander&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SetText<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Text</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>t<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">value</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Execute<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Message<span style="color:#ce5c00;font-weight:bold">(</span>t<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>t<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Text</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>Using this two codeunits we can now implement a patch posting</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50105</span><span style="color:#f8f8f8;text-decoration:underline"> </span>PatchPostQueue<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>PatchPost<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>FilterSalesOrdersToPost<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesOrders<span style="color:#ce5c00;font-weight:bold">.</span>Findset<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// Nothing to post
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">repeat</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>AddSalesOrderToQueue<span style="color:#ce5c00;font-weight:bold">(</span>SalesOrder<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No.&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">until</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesOrders<span style="color:#ce5c00;font-weight:bold">.</span>Next<span style="color:#ce5c00;font-weight:bold">() </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>AddMessageToQueue<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#4e9a06">&#39;Posting Complete&#39;</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExecuteQueue<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExecuteQueue<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>object<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;ICommand&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">repeat</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>object<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>queue<span style="color:#ce5c00;font-weight:bold">.</span>Pop<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>object<span style="color:#ce5c00;font-weight:bold">.</span>Execute<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">until</span><span style="color:#f8f8f8;text-decoration:underline"> </span>queue<span style="color:#ce5c00;font-weight:bold">.</span>GetSize<span style="color:#ce5c00;font-weight:bold">() </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>FilterSalesOrdersToPost<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// Filter Sales Orders here
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>AddMessageToQueue<span style="color:#ce5c00;font-weight:bold">(</span>message<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Text</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>t<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>MessageCommander<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>object<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>t<span style="color:#ce5c00;font-weight:bold">.</span>SetText<span style="color:#ce5c00;font-weight:bold">(</span>message<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>object<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>t<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>queue<span style="color:#ce5c00;font-weight:bold">.</span>Push<span style="color:#ce5c00;font-weight:bold">(</span>object<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>AddSalesOrderToQueue<span style="color:#ce5c00;font-weight:bold">(</span>No<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Text</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SaleOrderCommander<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesOrderPostCommander<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>object<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ICommand<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SaleOrderCommander<span style="color:#ce5c00;font-weight:bold">.</span>SetSalesOrderNumber<span style="color:#ce5c00;font-weight:bold">(</span>No<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>object<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SaleOrderCommander<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>queue<span style="color:#ce5c00;font-weight:bold">.</span>Push<span style="color:#ce5c00;font-weight:bold">(</span>object<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesOrders<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Sales Header&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>queue<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Queue<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><h2 id="references">References</h2>
|
||
<p><a href="https://patrickschiefer.wordpress.com/2022/02/24/part-2-how-to-implement-a-command-queue-in-pure-al/">Detailed Explanation of the pattern</a></p></description></item><item><title>Docs: Delegate API Operation</title><link>https://alguidelines.dev/docs/patterns/api-delegate-operation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/api-delegate-operation/</guid><description>
|
||
<p><em>Created by Arend-Jan Kauffmann, Described by Arend-Jan Kauffmann</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>The goal of this pattern is to delegate data operations from the API page to a codeunit. The codeunit can implement its own logic for inserting, modifying or deleting data.</p>
|
||
<h2 id="context">Context</h2>
|
||
<p>API pages implement a specific pattern for insert, modify and delete operations. An API page uses delayed insert behavior, which means that all fields will be validated before the record is inserted or modified.
|
||
This is different from the standard behavior on a UI card page, where a record is first inserted, followed by a modify when field values are updated.</p>
|
||
<h2 id="problem">Problem</h2>
|
||
<p>The standard behavior can result in a number of challenges:</p>
|
||
<ul>
|
||
<li>Code behind the OnValidate triggers and its event subscribers may expect that a record already exists when a field is being validated.</li>
|
||
<li>Usage of temporary buffer tables can become really complex when fully handled from the API page.</li>
|
||
<li>Applying default data to records before they are created does not work well with delayed inserts.</li>
|
||
</ul>
|
||
<h2 id="description">Description</h2>
|
||
<p>To mitigate these problems, we can delegate the data operation to a codeunit while canceling the data operation inside the API page.</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50000</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Item API Operations&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>InsertItem<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ModifyItem<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>DeleteItem<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Item<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>It is important that the record parameter is updated with the final result. This allows the API page to return the result of the API operation to the caller.</p>
|
||
<p>The API page implements this in the page triggers as follows:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ItemAPIOperations<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Item API Operations&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnInsertRecord<span style="color:#ce5c00;font-weight:bold">(</span>BelowxRec<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ItemAPIOperations<span style="color:#ce5c00;font-weight:bold">.</span>InsertItem<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnModifyRecord<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ItemAPIOperations<span style="color:#ce5c00;font-weight:bold">.</span>ModifyItem<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnDeleteRecord<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ItemAPIOperations<span style="color:#ce5c00;font-weight:bold">.</span>DeleteItem<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>The triggers must return false in order to cancel the operation in the page.</p>
|
||
<h2 id="benefits">Benefits</h2>
|
||
<p>Inside the functions in the codeunit you have full control over the steps that are performed for the specific operation.</p></description></item><item><title>Docs: Event Bridge</title><link>https://alguidelines.dev/docs/patterns/event-bridge-pattern/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/event-bridge-pattern/</guid><description>
|
||
<p><em>Created by waldo &amp; Arend-Jan Kauffmann, Described by waldo</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>In the world of interfaces, it is important to preserve (certain) events over multiple implementation of the interface.</p>
|
||
<h2 id="context">Context</h2>
|
||
<p>An app can have interfaces.
|
||
It makes it possible for other apps to extend/change the implementations of a certain part of the business logic.</p>
|
||
<p>Like in this example, we have an interface, to implement different ways for getting weights from scales:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;IScale&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetWeight<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Decimal</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Tare<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><h2 id="problem">Problem</h2>
|
||
<p>Multiple apps can subscribe to certain events of the app.
|
||
When a new implementation is created, we need to make sure that these events are raised at the right times. If those events were published on the implementation codeunit, it might very well be that those events will not be raised, hard to find, or whatever.</p>
|
||
<p>So, if we would implement it like this, it isn&rsquo;t really extensible, as a different implemention would implement different events .. and it&rsquo;s not possible to subscribe to all of them (including future implementations)</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50407</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Scale Wrong&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IScale<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetWeight<span style="color:#ce5c00;font-weight:bold">() </span>Result<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Decimal</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">//TODO: Implement Bar GetWeight
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterGetWeight<span style="color:#ce5c00;font-weight:bold">(</span>Result<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Tare<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">//TODO: Implement Bar Tare
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterTare<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterGetWeight<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Result<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Decimal</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterTare<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><h2 id="description">Description</h2>
|
||
<p>To mitigate this problem, we can work with a new, dedicated and isolated codeunit, with publisher events to be able to raise them from different places.</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50406</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;IScale Triggers&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterGetWeight<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Result<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Decimal</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterTare<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>This way, it&rsquo;s possible to raise the events in all the implementations:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50405</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Scale Bar&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IScale<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IScaleTriggers<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;IScale Triggers&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetWeight<span style="color:#ce5c00;font-weight:bold">() </span>Result<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Decimal</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">//TODO: Implement Bar GetWeight
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>IScaleTriggers<span style="color:#ce5c00;font-weight:bold">.</span>OnAfterGetWeight<span style="color:#ce5c00;font-weight:bold">(</span>Result<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Tare<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">//TODO: Implement Bar Tare
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>IScaleTriggers<span style="color:#ce5c00;font-weight:bold">.</span>OnAfterTare<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><h2 id="benefits">Benefits</h2>
|
||
<p>This new codeunit, with public events, makes the events accessible from all places, including new apps that are dependent from this app.</p>
|
||
<p>The naming convention (both starting with &ldquo;IScale&rdquo;) also makes it very easy to find that corresponding events for the interface.</p>
|
||
<h2 id="when-not-to-use">When not to use</h2>
|
||
<p>Obviously, the events should be carefully considered: only the events that make sense to &ldquo;share&rdquo; over all implementations, need this approach.</p></description></item><item><title>Docs: Façade</title><link>https://alguidelines.dev/docs/patterns/facade-pattern/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/facade-pattern/</guid><description>
|
||
<p><em>Created by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (Gang of Four), Described by Jesper Schulz-Wedde (Microsoft)</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>The intent of this pattern is to provide a unified API to a single or a collection of potentially complex subsystems. If you apply this pattern as a general pattern, you will ensure improved:</p>
|
||
<ul>
|
||
<li>Decoupling</li>
|
||
<li>Encapsulation</li>
|
||
<li>Readability</li>
|
||
<li>Testability</li>
|
||
<li>Maintainability</li>
|
||
</ul>
|
||
<h2 id="context">Context</h2>
|
||
<p>Whenever you want to write an isolated piece of business logic, from now on referred to as subsystem, this pattern should be applicable.</p>
|
||
<h2 id="problem">Problem</h2>
|
||
<p>The facade pattern addresses two main problems:</p>
|
||
<ul>
|
||
<li>Over time as systems grow, they tend to become complex and harder to comprehend. By adding a facade on top of the subsystem, that complexity is hidden, and a clear API is defined.</li>
|
||
<li>Any object or method which is publicly accessible, may not receive breaking changes in future releases without announced deprecation. This complicates maintainability of the system. By adding a facade, you ensure that the subsystem is inaccessible to the outside systems, enabling you to change the implementation details of the subsystem at will.</li>
|
||
</ul>
|
||
<h2 id="description">Description</h2>
|
||
<p>The facade pattern is one of the most commonly used and known patterns, first described the book <a href="https://archive.org/details/designpatternsel00gamm/page/185">Design Patterns: Elements of Reusable Object-Oriented Software</a>. It is classified as a structural pattern. While it originates from the object-oriented world, it for sure also applies to AL. The power of a facade is that it:</p>
|
||
<ul>
|
||
<li>Improves the readability of your subsystem&rsquo;s API, as it acts as an entry point to your subsystem. This also allows for easier documentation of your API, as you can focus it to a few public objects.</li>
|
||
<li>Improves the maintainability of your subsystem, as the internal subsystem can be modified or even completely replaced freely, without risking to break the public API - as long as the facade remains intact.</li>
|
||
<li>Ensures that your code remains loosely coupled and encapsulated, as no other subsystem can take dependencies on your internal implementation details. This also fosters the reusability of your code.</li>
|
||
<li>Suggests what needs most attention in your tests, as you would want to make sure that your subsystem&rsquo;s public API behaves as designed.</li>
|
||
</ul>
|
||
<p>Whenever you develop a functional group or an independent system, which has a clear API, you should add a facade to achieve the above-mentioned benefits.</p>
|
||
<h3 id="what-is-a-subsystem">What is a subsystem?</h3>
|
||
<p>A subsystem is a group of objects, which together provide a set of capabilities. Libraries are excellent examples of such subsystems.
|
||
In Business Central, all modules in the System Application are subsystems. Examples are hence every module you will find in the system application, such as:</p>
|
||
<ul>
|
||
<li>Azure Blob Services API</li>
|
||
<li>Barcode</li>
|
||
<li>Cryptography Management</li>
|
||
<li>Encoding</li>
|
||
<li>Image</li>
|
||
<li>RegEx</li>
|
||
<li>&hellip;</li>
|
||
</ul>
|
||
<p>If you can describe a set of capabilities out of context of the rest of the system, chances are you are looking at a subsystem.</p>
|
||
<h3 id="the-pattern">The Pattern</h3>
|
||
<p>This is arguably one of easiest patterns to understand and implement. Loosely speaking, you simply need to smack a wrapper on top of your implementation and hide away your implementation details from the outside world.</p>
|
||
<p><img src="diagram.jpg" alt="image"></p>
|
||
<p>To achieve this, we are using <a href="https://docs.microsoft.com/bs-cyrl-ba/dynamics365/business-central/dev-itpro/developer/devenv-using-access-modifiers">access modifiers</a>. Let&rsquo;s try to take a look at an example, taken from the system application: <a href="https://github.com/microsoft/ALAppExtensions/tree/main/Modules/System/Image">the Image module</a>. I&rsquo;m using this very simplified example for illustration purposes. Notice, that even the full subsystem at time of writing isn&rsquo;t complex - it merely has a single codeunit containing the implementation details. However, as it is expected that the complexity will increase over time or that the implementation details can change, the subsystem is already equipped with a facade from the beginning.</p>
|
||
<p><em>The Facade</em></p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">3971</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Image<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Access<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span>Public<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ImageImpl<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Image Impl.&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// &lt;summary&gt;
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// Creates an image from the specified data stream.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// &lt;/summary&gt;
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// &lt;param name=&#34;InStream&#34;&gt;A Stream that contains the image data.&lt;/param&gt;
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>FromStream<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ImageImpl<span style="color:#ce5c00;font-weight:bold">.</span>FromStream<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// &lt;summary&gt;
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// Gets the width in pixels.
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// &lt;/summary&gt;
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">/// &lt;returns&gt;The width in pixels.&lt;/returns&gt;
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetWidth<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Integer</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>ImageImpl<span style="color:#ce5c00;font-weight:bold">.</span>GetWidth<span style="color:#ce5c00;font-weight:bold">())</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>The facade codeunit above has some characteristics:</p>
|
||
<ul>
|
||
<li>Access is explicitly set to Public, to underline that this is a facade.</li>
|
||
<li>All methods are public.</li>
|
||
<li>All methods are documented.</li>
|
||
<li>No methods contain any logic. They merely point to implementation details.</li>
|
||
<li>The object naming suggests that it will get referenced from the outside.</li>
|
||
</ul>
|
||
<p>Anyone who wants to access the subsystem, will only have to take a dependency on the facade; the implementation details are not needed nor accessible.</p>
|
||
<p>Anyone who wants to access the subsystem, will only have to relate to this one public facade; the documentation makes it easy-to-understand the subsystem&rsquo;s capabilities.</p>
|
||
<p>Test of the subsystem can be limited to testing the facade - it is strictly speaking the only thing that needs verification, that it functions as designed. It is the contract of the subsystem.</p>
|
||
<p><em>The Subsystem</em></p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">3970</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Image Impl.&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Access<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Internal</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempBlob<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Temp Blob&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>FromStream<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">OutStream</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">OutStream</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempBlob<span style="color:#ce5c00;font-weight:bold">.</span>CreateOutStream<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">OutStream</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>CopyStream<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">OutStream</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetWidth<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Integer</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Image<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">DotNet</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Image<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TempBlob<span style="color:#ce5c00;font-weight:bold">.</span>CreateInStream<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Image<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Image<span style="color:#ce5c00;font-weight:bold">.</span>FromStream<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">InStream</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>Image<span style="color:#ce5c00;font-weight:bold">.</span>Width<span style="color:#ce5c00;font-weight:bold">())</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>There are no rules for the subsystem, except that access needs to be <strong>internal</strong>. How you implement, how much you document, how you test, is entirely up to you and not the business of the outside caller. Of course, you should apply all of the best practices and patterns anyway, as you and possibly other developers will have to understand, extend and maintain the subsystem too. But from the view of this pattern, the complexity of the subsystem is irrelevant - just as long as it&rsquo;s not accessible.</p>
|
||
<h2 id="usage">Usage</h2>
|
||
<p>The facade pattern is one of the most prominent patterns in the <a href="https://github.com/microsoft/ALAppExtensions/tree/main/Modules/System">system application</a>. You will find plenty of examples here.</p>
|
||
<h2 id="benefits">Benefits</h2>
|
||
<p>The benefits of this rather simple pattern should be abundantly clear by now. But let&rsquo;s go over them once more, structured by the advantages this patterns brings:</p>
|
||
<h3 id="decoupling">Decoupling</h3>
|
||
<p>As the entire subsystem is inaccessible to outside systems, no dependencies can be taken. Hence this patterns strongly promotes the decoupling of objects.</p>
|
||
<h3 id="encapsulation">Encapsulation</h3>
|
||
<p>The entire purpose of this very pattern is to encapsulate complexity; you hide away the implementation details behind an easy to understand facade.</p>
|
||
<h3 id="readability">Readability</h3>
|
||
<p>If done right, the developer doesn&rsquo;t need to be able to understand the details of the subsystem. Everything relevant to using the subsystem is described in the facade.</p>
|
||
<h3 id="testability">Testability</h3>
|
||
<p>Ensuring the correct behaviour of the subsystem can be done by testing the facade. The facade defines the contract of your subsystem - what does it expose and how should it behave. That contract should be covered with adequate tests, which will ensure that it is upheld, even if you decide to change the implementation of the subsystem.</p>
|
||
<h3 id="maintainability">Maintainability</h3>
|
||
<p>The one thing you may not change freely, is the facade and the test of the facade. It can be extended, but you should not break any existing APIs. But that leaves the entire subsystem to be completely rewritten, if you desire to do so. As no external dependencies can exist, there is no risk of introducing any syntactical breaking changes to the outside world. And as the tests of the public facade remain, there is no risk of introducing semantical breaking changes either - the contract is upheld, as long as your tests pass.</p>
|
||
<h2 id="when-not-to-use">When not to use</h2>
|
||
<p>This is a very applicable pattern, which can be used in most cases. While it may appear to be overkill at the beginning of the design of your subsystem, chances are your subsystem will evolve in complexity over time. The pattern may complicate implementation of extensibility, as you hide away all implementation details and hence also take away the opportunity to extend those, but that does not mean that extensibility cannot be achieved - but it requires more careful designing for extensibility. Extensibility with facades could be a topic of its own, which for now isn&rsquo;t covered by this pattern description. As always, use your common sense when to use and when not to use this pattern.</p>
|
||
<h2 id="snippets">Snippets</h2>
|
||
<p>Given the simplicity of this pattern, there are no snippets available at the moment.</p>
|
||
<h2 id="list-of-references">List of references</h2>
|
||
<p>This is one of the most commonly used and discussed, initially described here:</p>
|
||
<p><a href="https://archive.org/details/designpatternsel00gamm/page/185">Design Patterns: Elements of Reusable Object-Oriented Software</a>. Addison Wesley. pp. 185ff. ISBN 0-201-63361-2.</p>
|
||
<p>It is also a key pattern in the design of our system application modules, which is described here:</p>
|
||
<p><a href="https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-blueprint">Module Architecture</a></p></description></item><item><title>Docs: Generic Method</title><link>https://alguidelines.dev/docs/patterns/generic-method-pattern/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/generic-method-pattern/</guid><description>
|
||
<p><em>Created by Gary Winter (Cloud Ready Software), Described by waldo (iFacto Business Solutions | Dynex)</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>The goal of this pattern is to facilitate a lot of things in one single awesome way of writing code. If you apply this pattern as a general pattern, you&rsquo;ll implement:</p>
|
||
<ul>
|
||
<li>Extensibility</li>
|
||
<li>Decoupling</li>
|
||
<li>Readability</li>
|
||
<li>Testability</li>
|
||
<li>Encapsulation</li>
|
||
</ul>
|
||
<h2 id="context">Context</h2>
|
||
<p>Whenever you have to write an isolated piece of business logic, this pattern should be applicable.</p>
|
||
<h2 id="problem">Problem</h2>
|
||
<p>Usually, when you ask people where to place code, they all have their own opinion: on a table or page, or in some kind of codeunit library where lots of functions will be placed, or .. . In fact, does it matter? It sure does, because in many cases, the code simply isn&rsquo;t maintainable, let alone extendable or testable.</p>
|
||
<h2 id="description">Description</h2>
|
||
<p>What if we have some kind of &ldquo;standard way&rdquo; to always write our code. The <em>Generic Method Pattern</em> is kind of like what it says: a generic way to implement a method.</p>
|
||
<h3 id="what-is-a-method">What is a method?</h3>
|
||
<p>Well, a method is <em>a significant piece of business logic</em> - maybe best explained by some examples:</p>
|
||
<ul>
|
||
<li>Posting a document</li>
|
||
<li>Any button on a page that executes business logic</li>
|
||
<li>a batch run to send emails</li>
|
||
<li>&hellip;</li>
|
||
</ul>
|
||
<p>In a way, except &ldquo;data validation&rdquo;, most of the things we write in our daily life, are methods.</p>
|
||
<h3 id="the-pattern">The Pattern</h3>
|
||
<p><strong>One method, one codeunit</strong>
|
||
The idea is to put the code in one <em>encapsulated</em> codeunit with the purpose to have all the code in that one codeunit function for that one method. This way, the codeunit will stay relatively small and readable.</p>
|
||
<p>Let me start by showing an example, so you can refer to this complete example during the rest of the article:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">53100</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;WLD BlockCustomer Meth&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnBeforeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>Cust<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>DoBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>Cust<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>Cust<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>AcknowledgeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>DoBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#ce5c00;font-weight:bold">.</span>Blocked<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#ce5c00;font-weight:bold">.</span>Blocked<span style="color:#000;font-weight:bold">::</span>All<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#ce5c00;font-weight:bold">.</span><span style="color:#204a87;font-weight:bold">Modify</span><span style="color:#ce5c00;font-weight:bold">(</span>true<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmManagement<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Confirm Management&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmQst<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Label</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;Are you sure?&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>DefaultAnswer<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>DefaultAnswer<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>true<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>DefaultAnswer<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>ConfirmManagement<span style="color:#ce5c00;font-weight:bold">.</span>GetResponseOrDefault<span style="color:#ce5c00;font-weight:bold">(</span>ConfirmQst<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>DefaultAnswer<span style="color:#ce5c00;font-weight:bold">))</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>AcknowledgeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>AcknowledgeMsg<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Label</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;You successfully executed &#34;BlockCustomer&#34;&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GuiAllowed<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">or</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Message<span style="color:#ce5c00;font-weight:bold">(</span>AcknowledgeMsg<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnBeforeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>Within that codeunit, the pattern is always the same:</p>
|
||
<ul>
|
||
<li>One public (internal) procedure</li>
|
||
<li>The rest is always local</li>
|
||
</ul>
|
||
<p>So, from outside the codeunit, there is only one clear entrypoint: that one (public) internal function with its parameters.</p>
|
||
<p>The <strong>pattern</strong> within the codeunit exists of a few layers:</p>
|
||
<ul>
|
||
<li>The UI layer</li>
|
||
<li>The Event layer</li>
|
||
<li>The method layer</li>
|
||
</ul>
|
||
<p><em>The UI layer</em>
|
||
The UI layer takes care of the UI, obviously. What is important in this case, is that you always make sure that there is a &ldquo;HideDialog&rdquo; parameter that the business logic can use to still decide whether to use the dialog or not.</p>
|
||
<p>These are the UI Layer parts, where you see the public function gets the HideDialog, and passes it to the UI-related procedures, where the business logic for showing the UI takes place. Also, the default answer of the confirmation is handled there as well (what if the business logic calls this method with HideDialog to &ldquo;true&rdquo;).</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">53100</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;WLD BlockCustomer Meth&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span>AcknowledgeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmManagement<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Confirm Management&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>ConfirmQst<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Label</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;Are you sure?&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>DefaultAnswer<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>DefaultAnswer<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>true<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>DefaultAnswer<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>ConfirmManagement<span style="color:#ce5c00;font-weight:bold">.</span>GetResponseOrDefault<span style="color:#ce5c00;font-weight:bold">(</span>ConfirmQst<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>DefaultAnswer<span style="color:#ce5c00;font-weight:bold">))</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>AcknowledgeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>AcknowledgeMsg<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Label</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;You successfully executed &#34;BlockCustomer&#34;&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GuiAllowed<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">or</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Message<span style="color:#ce5c00;font-weight:bold">(</span>AcknowledgeMsg<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p><em>The Event layer</em>
|
||
This layer is going to add flexibility to any app that has a dependency on this app. By default, the pattern always foresees an <code>OnBefore</code> and an <code>OnAfter</code> event.</p>
|
||
<p>This is the relevant code for the event layer:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">53100</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;WLD BlockCustomer Meth&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span>OnBeforeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>Cust<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span>OnAfterBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>Cust<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnBeforeBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[IntegrationEvent<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#ce5c00;font-weight:bold">)</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p><em>The method layer</em>
|
||
The last layer is obviously where the business logic will be written.</p>
|
||
<p>The relevant part is:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">53100</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;WLD BlockCustomer Meth&#34;<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">internal</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span>DoBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>Cust<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">local</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>DoBlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#ce5c00;font-weight:bold">.</span>Blocked<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#ce5c00;font-weight:bold">.</span>Blocked<span style="color:#000;font-weight:bold">::</span>All<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#ce5c00;font-weight:bold">.</span><span style="color:#204a87;font-weight:bold">Modify</span><span style="color:#ce5c00;font-weight:bold">(</span>true<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#ce5c00;font-weight:bold">...
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>Usually indicated with a &ldquo;do&rdquo;-function, the business logic takes place in that procedure. Obviously, when you have a decent amount of code, it&rsquo;s recommended that you make it readable by applying all the Best Practices in terms of readability in the codeunit. Though, a few pointers here:</p>
|
||
<ul>
|
||
<li>keep the <a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a> low
|
||
<ul>
|
||
<li>one line (function call) after an IF-clause</li>
|
||
<li>one line (function call) after a repeat</li>
|
||
</ul>
|
||
</li>
|
||
<li>readable function calls</li>
|
||
<li>&hellip;</li>
|
||
</ul>
|
||
<p><strong>Call out to the method from a table</strong></p>
|
||
<p>Now, there is a reason that the one global procedure in the method-codeunit is <code>internal</code>. We shouldn&rsquo;t be calling this procedure directly. We should be calling it through it&rsquo;s &ldquo;class&rdquo; (usually, a table can be seen as a class). That means, we would have to create a public (not internal) procedure on table-level, which can be used in the business logic.</p>
|
||
<p>In our example above, this could be that table extension:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">tableextension</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">53100</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Customer Ext BASE&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">extends</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>HideDialog<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>WLDBlockCustomerMeth<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;WLD BlockCustomer Meth&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>WLDBlockCustomerMeth<span style="color:#ce5c00;font-weight:bold">.</span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>HideDialog<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>BlockCustomer<span style="color:#ce5c00;font-weight:bold">(</span>false<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>This practice improves readability. In fact, by doing this, you just extended the suggestions-list in VSCode (IntelliSense) indicating a new method that your class can do. This is very convenient for the developer that might need your new method.</p>
|
||
<p><em>Note - it could very well be that there simply isn&rsquo;t any table that can act as a class for our method. In that case, you could use a codeunit as well.</em></p>
|
||
<p><strong>Naming Conventions</strong></p>
|
||
<p>You might have noticed that the naming of our method is quite strict:</p>
|
||
<ul>
|
||
<li>codeunit name: <code>WLD BlockCustomer Meth</code></li>
|
||
<li>internal proc: <code>BlockCustomer</code></li>
|
||
<li>do-procedure: <code>DoBlockCustomer</code></li>
|
||
</ul>
|
||
<p>It is important to align these namings. It indicates that the codeunit only does one thing (remember: encapsulation), and it improves searchability from outside the codeunit (for example when you&rsquo;re searching symbols or something).</p>
|
||
<h2 id="usage">Usage</h2>
|
||
<p>Currently, there is no usage of this pattern in the BaseApp.</p>
|
||
<p>The pattern has a main advantage in an ISV product, just because of the decoupling and extensibility. Although, I have seen many occasions where parts of the pattern was useful on PTE&rsquo;s as well. You simply never know if ever at the customer site, there is going to be another partner that needs to create its own PTE, and has to depend on yours. So I&rsquo;d say, this pattern is everywhere applicable, no matter the type of the app.</p>
|
||
<h2 id="benefits">Benefits</h2>
|
||
<p>As I said, it will facilitate a lot of advantages. Let&rsquo;s explain a bit more in depth:</p>
|
||
<h3 id="extensibility">Extensibility</h3>
|
||
<p>Thanks to the <em>event layer</em>, by applying this pattern for all methods, we will automatically have the bare minimum of events that we need to hook into a method: the <code>OnBefore-</code> and the <code>OnAfter</code>. Of course it would make sense to even add more events to the method when appropriate (eg, when you&rsquo;re inserting a record in a table, it might be interesting to also raise an event just before you call the insert).</p>
|
||
<h3 id="decoupling">Decoupling</h3>
|
||
<p>Thanks to these same events, and the fact the pattern foresees a handler as well, we are able to &ldquo;decouple&rdquo; our method as well. What do I mean with that? Well, we can simply subscribe to the <code>OnBefore</code>event, and set <code>IsHandled</code> to <code>true</code>. This means it will never execute the do-procedure, which means, the original procedure/method/business logic is &ldquo;decoupled&rdquo;.</p>
|
||
<p>We can use this obviously for implementing our own method (a new way to accomplish this method), or to disable the method by simply subscribing to it, and only providing the <code>IsHandled := true</code> in our subscriber. However, there are many more usages where we can use this for.</p>
|
||
<p>Maybe one more example:
|
||
if you would apply this pattern to your product, at the customer, you&rsquo;ll be able to hotfix your methods simply by decoupling them and fixing the method instead of waiting for a hotfix from the hotfix-departement.</p>
|
||
<p>This gives a lot of flexibility.</p>
|
||
<h3 id="readability">Readability</h3>
|
||
<p>When we talk about readability, we actually talk about the part where we expose our method on the class. The rule is: never call the codeunit, but only from one place: from its &ldquo;class&rdquo; - or in BC terms: its table (or codeunit).</p>
|
||
<p>In terms of readability, that means that intellisense comes into play. In stead of:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#ce5c00;font-weight:bold">.</span>Run<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#000;font-weight:bold">::</span>&#34;Sales-Post&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>you simply get</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span>Post<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>THAT is readable. The previous is not! That is just something we got used to.</p>
|
||
<h3 id="testability">Testability</h3>
|
||
<p>There are two things in terms of testability where this pattern helps a lot.</p>
|
||
<p><em>Unit testing</em>
|
||
You can interpret &ldquo;unit testing&rdquo; very broadly. But just imagine: when you&rsquo;re building your software entirely out of &ldquo;methods&rdquo; - which means: when you&rsquo;d build your software entirely with this &ldquo;Generic Method Pattern&rdquo;. Now, the list of methods, are all the units that you need to test: if you test all your methods, you kind of like test the majority of your software, right?</p>
|
||
<p>So you could simply set up rules in your company like: EVERY method needs a test-codeunit. And even more: since every method only has one global function - it&rsquo;s pretty easy to know the context, and all the flavors to test your method.</p>
|
||
<p>The pattern describes the tests that needs to be written.</p>
|
||
<p><em>Disabling methods</em>
|
||
Coming back to the &ldquo;decoupling&rdquo; part - in tests, you actually might need it more than you realize. Just imagine: you want to test method 1, but method 2 comes in the way by interfering with configurations that you need to do, or UI that is popping up, while it could be completely pointless.<br>
|
||
Solution: simply - within your test-codeunit - subscribe (with a manual subscriber) to method 2, set <code>IsHandled</code> to <code>false</code> - done!</p>
|
||
<h3 id="encapsulation">Encapsulation</h3>
|
||
<p>Don&rsquo;t underestimate the power of the encapsulation part of this pattern. One of the first questions that people ask themselves when reading into this pattern is: &ldquo;<em>isn&rsquo;t it going to consume all my codeunit-id&rsquo;s</em>&rdquo; or &ldquo;<em>so many codeunits, that can&rsquo;t be readable, right?</em>&rdquo;.<br>
|
||
The fact that the functionality of one method is encapsulated in one codeunit is very powerful. You&rsquo;ll avoid <a href="https://sourcemaking.com/antipatterns/boat-anchor">Boat anchors</a> simply because because, thanks to the encapsulation, there is a limited amount of code in the codeunit, of course.<br>
|
||
And because of that, it so much more maintainable, upgradable, readable, .. . Only advantages.</p>
|
||
<h2 id="when-not-to-use">When not to use</h2>
|
||
<p>However, there are occasions where you can&rsquo;t use this pattern. Just imagine if you&rsquo;d put EVERY SINGE LINE of code in a method, including the simple validation code on a table, or library-functions like in helper codeunits. That would obviously not make any sense.</p>
|
||
<p>So all I can say is: use your common sense.</p>
|
||
<p>One example: set the bar at &ldquo;validation code&rdquo;: any code that is solely there to facilitate data integrity doesn&rsquo;t belong in method codeunits.</p>
|
||
<p>Another tip might be: don&rsquo;t let the amount of codelines trick you in deciding to <em>not</em> use this pattern: when it&rsquo;s a method, it&rsquo;s a method. When it makes sense to be able to extend, decouple, .. then this pattern can help.</p>
|
||
<h2 id="snippets">Snippets</h2>
|
||
<p><a href="https://marketplace.visualstudio.com/items?itemName=waldo.crs-al-language-extension">waldo&rsquo;s CRS AL Language Extension</a> contains snippets that help you in setting up the boiler plate code in a matter of seconds.</p>
|
||
<p>The snippets are:</p>
|
||
<ul>
|
||
<li><code>tcodeunitMethodWithoutUIwaldo</code></li>
|
||
<li><code>tcodeunitMethodWithUIwaldo</code></li>
|
||
</ul>
|
||
<h2 id="list-of-references">List of references</h2>
|
||
<p>There have been a number of occasions where people have been sharing this pattern. Here is one:</p>
|
||
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
|
||
<iframe src="https://www.youtube.com/embed/CWpaD9RUa6U" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video"></iframe>
|
||
</div></description></item><item><title>Docs: No. Series</title><link>https://alguidelines.dev/docs/patterns/no-series/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/no-series/</guid><description>
|
||
<p><em>Created by Microsoft, Described by Jeremy Vyska (Spare Brained Ideas)</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>The &ldquo;Number Series&rdquo; system is used extensively to provide numbers to master records, documents, and other transactions through Microsoft Dynamics 365 Business Central.</p>
|
||
<h2 id="description">Description</h2>
|
||
<p>At the heart of things, the Number Series engine allows users to define structure for a sequential numeric or alphanumeric string (collectively referred to as a &rsquo;number series&rsquo;), then assign that structure to different parts of the system.</p>
|
||
<p>Typically, one creates a single number series for each <em>type</em> of data entity. For example, Customers or Sales Orders each could have a series defined so that all new Customers or Sales Orders get a new number automatically.</p>
|
||
<p>The Number Series system serves a few ancillary roles:</p>
|
||
<ul>
|
||
<li>maintains the usage information to know when the last number was generated and on which date</li>
|
||
<li>allows for date driven structures, so that different periods may have different structures</li>
|
||
<li>allows control of if manual entries are or are not permitted</li>
|
||
<li>allow for incrementing in different steps (+1 each time or +1000 each time)</li>
|
||
<li>warn users as a series is running out of numbers</li>
|
||
<li>control if any gaps in a series are permitted (as some regional laws do not allow skipping)</li>
|
||
</ul>
|
||
<p>This is many roles, features, and controls for generation of a single field so the implementation of this can seem difficult at first.</p>
|
||
<div class="alert alert-info" role="alert">
|
||
<h4 class="alert-heading">Note</h4>
|
||
One additional (and somewhat optional) feature in the Number Series engine allows multiple sequences per type, called <strong>Relationships</strong>. For example, different numbers for Items that are finished goods versus raw materials. This requires additional hooks on the Page.
|
||
</div>
|
||
<h2 id="usage-in-data-entities">Usage in Data Entities</h2>
|
||
<p>To understand an example use in the Base App, the Customer data entity is a good choice.</p>
|
||
<p>Implementation to connect the Customer <strong><code>No.</code></strong> field to the Number Series engine is done at the table level. The Customer table contains:</p>
|
||
<p>A field to contain the number (typically the primary key), which will be of type <strong><code>Code</code></strong>, length of <strong>20</strong>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">field</span><span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No.&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Caption<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;No.&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnValidate<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[<span style="color:#ce5c00;font-weight:bold">...</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>A field to contain the unique ID of the Number Series, typically called &ldquo;No. Series&rdquo;</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">field</span><span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">107</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No. Series&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Caption<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;No. Series&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Editable<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>TableRelation<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No. Series&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div>
|
||
<div class="alert alert-warning" role="alert">
|
||
<h4 class="alert-heading">Note</h4>
|
||
The <strong><code>TableRelation</code></strong> is important, and the <strong><code>Editable</code></strong> being false is advised.
|
||
</div>
|
||
<p>And on the <strong><code>OnInsert</code></strong> trigger, code populates the <strong><code>No. Series</code></strong> and <strong><code>No.</code></strong> field.</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnInsert<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnBeforeInsert<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No.&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;&#39;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span><span style="color:#204a87;font-weight:bold">TestField</span><span style="color:#ce5c00;font-weight:bold">(</span>&#34;Customer Nos.&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">.</span>InitSeries<span style="color:#ce5c00;font-weight:bold">(</span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Customer Nos.&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>xRec<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No. Series&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>0D<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No.&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No. Series&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[<span style="color:#ce5c00;font-weight:bold">...</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAfterOnInsert<span style="color:#ce5c00;font-weight:bold">(</span>Rec<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>xRec<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>In the case of Customer, this is a Data Entity within the Sales module of the system. The Sales module has a <strong>Sales Setup</strong> table where the user can specify a <strong>No. Series</strong> to use for Customers by default.</p>
|
||
<p><code>SalesSetup.Get();</code> fetches the sole setup table record.</p>
|
||
<p><code>SalesSetup.TestField(&quot;Customer Nos.&quot;);</code> is the basic validation that the <strong>Sales Setup</strong> table has a non-empty <strong>Customer Nos.</strong> field. If the setup field isn&rsquo;t populated, when the user attempts to create a new Customer, they will receive an error message.</p>
|
||
<p><code>NoSeriesMgt.InitSeries(SalesSetup.&quot;Customer Nos.&quot;, xRec.&quot;No. Series&quot;, 0D, &quot;No.&quot;, &quot;No. Series&quot;);</code> is more parameters to a function than most expect.</p>
|
||
<p>The function call takes the following parameters:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>InitSeries<span style="color:#ce5c00;font-weight:bold">(
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span>DefaultNoSeriesCode<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OldNoSeriesCode<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NewDate<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Date</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NewNo<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NewNoSeriesCode<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span></code></pre></div><p>The <strong>DefaultNoSeriesCode</strong> parameter is typically from a setup table. In the Customer example, this comes from the <strong>Sales Setup</strong> <strong>Customer Nos.</strong> setting.</p>
|
||
<p>The <strong>OldNoSeriesCode</strong> is used to verify when changing from one No Series to another that they are related.</p>
|
||
<p>The <strong>NewDate</strong> parameter is used to drive numbering based on Dates. This is typically used on Documents. For master entities, like Customer, an empty date <code>0D</code> can be passed in.</p>
|
||
<div class="alert alert-info" role="alert">
|
||
<h4 class="alert-heading">Note</h4>
|
||
Many parts of the NoSeriesManagement codeunit predate method overloading, so if the system was created today, some parameters like NewDate would likely be optional.
|
||
</div>
|
||
<p>The <strong>NewNo</strong> is a <code>var</code> parameter, and is how the new value comes back from the engine. This also serves two other purposes:</p>
|
||
<ul>
|
||
<li>if passed in blank, the Number Series used must be configured to have <strong>Default Nos.</strong> enabled</li>
|
||
<li>if passed in with a value, the Number Series used must be configured to have <strong>Manual Nos</strong> enabled.</li>
|
||
</ul>
|
||
<p>The <strong>NewNoSeriesCode</strong> is more often used to switch between related number series, but is a required parameter, and is also passed back from the engine, so it is also a <code>var</code>.</p>
|
||
<p>Additionally, it is a good idea to have <code>OnValidate</code> functionality on the <strong><code>No.</code></strong> field. The complete code for the Customer <strong><code>No.</code></strong> field:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">field</span><span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No.&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Caption<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;No.&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnValidate<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No.&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span>&lt;&gt;<span style="color:#f8f8f8;text-decoration:underline"> </span>xRec<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No.&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">.</span>TestManual<span style="color:#ce5c00;font-weight:bold">(</span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Customer Nos.&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No. Series&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;&#39;</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Invoice Disc. Code&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;&#39;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Invoice Disc. Code&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No.&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>If the user has changed the <strong><code>No.</code></strong> field (<code>&quot;No.&quot; &lt;&gt; xRec.&quot;No.&quot;</code>), then:</p>
|
||
<ul>
|
||
<li>the Number Series is checked if manually setting a new value is allowed via the <code>TestManual</code> function</li>
|
||
<li>The <code>No. Series</code> is cleared on the record, as it has no longer been given a value from that Series.</li>
|
||
</ul>
|
||
<p>Since the Customer data entity supports the <strong>No. Series Relationship</strong> functionality, there are additional components. On the table, there is a function called <code>AssistEdit</code>:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>AssistEdit<span style="color:#ce5c00;font-weight:bold">(</span>OldCust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Customer<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">with</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">do</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Rec<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span><span style="color:#204a87;font-weight:bold">TestField</span><span style="color:#ce5c00;font-weight:bold">(</span>&#34;Customer Nos.&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">.</span>SelectSeries<span style="color:#ce5c00;font-weight:bold">(</span>SalesSetup<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Customer Nos.&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OldCust<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No. Series&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No. Series&#34;<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">.</span>SetSeries<span style="color:#ce5c00;font-weight:bold">(</span>&#34;No.&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Rec<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Cust<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAssistEditOnBeforeExit<span style="color:#ce5c00;font-weight:bold">(</span>Cust<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>true<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div>
|
||
<div class="alert alert-warning" role="alert">
|
||
<h4 class="alert-heading">Note</h4>
|
||
The use of <strong><code>WITH</code></strong> is deprecated. While this code block represents the current state of the Base App, the use of <strong><code>WTIH</code></strong> should not be copied.
|
||
</div>
|
||
<p>Similar to the <strong><code>OnInsert</code></strong> trigger, some setup fields are checked.</p>
|
||
<p>Then, the <code>SelectSeries</code> function is called. This will present a List to the user of available and relevant <strong>No. Series</strong> that are connected to the <code>SalesSetup.&quot;Customer Nos.&quot;</code> by a Number Series Relationship.</p>
|
||
<p>From the <strong><code>Customer Page</code></strong> (a Card type page), the <strong>No.</strong> field has an <strong><code>AssistEdit</code></strong> trigger:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">trigger</span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnAssistEdit<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>AssistEdit<span style="color:#ce5c00;font-weight:bold">(</span>xRec<span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>CurrPage<span style="color:#ce5c00;font-weight:bold">.</span>Update<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><h2 id="usage-in-journals">Usage in Journals</h2>
|
||
<p>Journals utilize a <strong><code>Document No.</code></strong> as a non-primary key field and use a different strategy for use of the Number Series engine. For each Journal Batch, a different <strong><code>No. Series</code></strong> can be set.</p>
|
||
<p>For example, on the <strong><code>General Journal</code></strong> Page, in the <strong><code>OnNewRecord</code></strong>, the <strong><code>SetUpNewLine</code></strong> function on the <strong><code>Gen. Journal Line</code></strong> Table is called:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SetUpNewLine<span style="color:#ce5c00;font-weight:bold">(</span>LastGenJnlLine<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Gen. Journal Line&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Balance<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Decimal</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BottomLine<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>false<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnBeforeSetUpNewLine<span style="color:#ce5c00;font-weight:bold">(</span>GenJnlTemplate<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlBatch<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlLine<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastGenJnlLine<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GLSetupRead<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Balance<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BottomLine<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IsHandled<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlTemplate<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">(</span>&#34;Journal Template Name&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlBatch<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">(</span>&#34;Journal Template Name&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Journal Batch Name&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>SetRange<span style="color:#ce5c00;font-weight:bold">(</span>&#34;Journal Template Name&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Journal Template Name&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>SetRange<span style="color:#ce5c00;font-weight:bold">(</span>&#34;Journal Batch Name&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Journal Batch Name&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>FindFirst<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Posting Date&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastGenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Posting Date&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Document Date&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastGenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Posting Date&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Document No.&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastGenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Document No.&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>OnSetUpNewLineOnBeforeIncrDocNo<span style="color:#ce5c00;font-weight:bold">(</span>GenJnlLine<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastGenJnlLine<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Balance<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BottomLine<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>BottomLine<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">and</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">(</span>Balance<span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>LastGenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Balance (LCY)&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#ce5c00;font-weight:bold">) </span><span style="color:#204a87;font-weight:bold">and</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastGenJnlLine<span style="color:#ce5c00;font-weight:bold">.</span>EmptyLine<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>IncrementDocumentNo<span style="color:#ce5c00;font-weight:bold">(</span>GenJnlBatch<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Document No.&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">else</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Posting Date&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>WorkDate<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Document Date&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>WorkDate<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlBatch<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No. Series&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span>&lt;&gt;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;&#39;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>Clear<span style="color:#ce5c00;font-weight:bold">(</span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Document No.&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">.</span>TryGetNextNo<span style="color:#ce5c00;font-weight:bold">(</span>GenJnlBatch<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No. Series&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Posting Date&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>[<span style="color:#ce5c00;font-weight:bold">...</span>]<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>If the Batch is empty, and if the <strong><code>Gen. Journal Batch</code></strong> has a <strong><code>No. Series</code></strong> set, the <strong><code>Document No.</code></strong> is set from the number series via the <strong><code>NoSeriesManagement</code></strong> codeunit&rsquo;s <strong><code>TryGetNextNo</code></strong> function. This takes two parameters:</p>
|
||
<ul>
|
||
<li>Which <strong><code>No. Series</code></strong> to get the next number from</li>
|
||
<li>Which date to fetch for</li>
|
||
</ul>
|
||
<p>This function does <em>not</em> update the <strong><code>Last No. Used</code></strong> and <strong><code>Last Date Used</code></strong> fields on the number series. Those will be updated during the Posting process.</p>
|
||
<p>If the Batch is not empty <em>and</em> the sum of the existing lines totals to zero (in balance), the General Journal assumes the user wants to start a new set of lines under a new <strong><code>Document No.</code></strong>. The table level procedure <strong><code>IncrementDocumentNo</code></strong> function is called:</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-AL" data-lang="AL"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IncrementDocumentNo<span style="color:#ce5c00;font-weight:bold">(</span>GenJnlBatch<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Gen. Journal Batch&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastDocNumber<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">20</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesLine<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;No. Series Line&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlBatch<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No. Series&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span>&lt;&gt;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#39;&#39;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">.</span>SetNoSeriesLineFilter<span style="color:#ce5c00;font-weight:bold">(</span>NoSeriesLine<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenJnlBatch<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No. Series&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Posting Date&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesLine<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Increment-by No.&#34;<span style="color:#f8f8f8;text-decoration:underline"> </span>&gt;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">1</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesMgt<span style="color:#ce5c00;font-weight:bold">.</span>IncrementNoText<span style="color:#ce5c00;font-weight:bold">(</span>LastDocNumber<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NoSeriesLine<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Increment-by No.&#34;<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">else</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastDocNumber<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IncStr<span style="color:#ce5c00;font-weight:bold">(</span>LastDocNumber<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">else</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>LastDocNumber<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IncStr<span style="color:#ce5c00;font-weight:bold">(</span>LastDocNumber<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>If the batch&rsquo;s <strong><code>No. Series</code></strong> is set, it is checked if the <strong><code>Increment-By No.</code></strong> setting is anything besides <code>1</code>. If so, use the special <strong><code>IncrementNoText</code></strong> function.</p>
|
||
<p>If neither of those cases is true, then the line&rsquo;s <strong><code>Document No.</code></strong> is updated with the language function <strong><code>IncStr</code></strong>.</p>
|
||
<h2 id="objects-to-inspect">Objects to Inspect</h2>
|
||
<p>Business Central objects in the Base App to review to find out more:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Object Type</th>
|
||
<th>Object ID</th>
|
||
<th>Object Name</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Table</td>
|
||
<td>308</td>
|
||
<td>No. Series</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Table</td>
|
||
<td>309</td>
|
||
<td>No. Series Line</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Table</td>
|
||
<td>310</td>
|
||
<td>No. Series Relationship</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Page</td>
|
||
<td>456</td>
|
||
<td>No. Series</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Page</td>
|
||
<td>457</td>
|
||
<td>No. Series Lines</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Page</td>
|
||
<td>458</td>
|
||
<td>No. Series Relationships</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Page</td>
|
||
<td>571</td>
|
||
<td>No. Series List</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Codeunit</td>
|
||
<td>396</td>
|
||
<td>NoSeriesManagement</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h2 id="when-not-to-use">When not to use</h2>
|
||
<p>Typically, this pattern is used for unique Data Entities. It is not recommended for use in parts of the system where entries are created permanently (such as an <strong><code>Entry No.</code></strong> for ledgers) or highly mutable / working line data (such as <strong><code>Line No.</code></strong> for journals or document lines).</p>
|
||
<h2 id="list-of-references">List of references</h2>
|
||
<p>For usage of number series, there is more information available on:</p>
|
||
<ul>
|
||
<li><a href="https://docs.microsoft.com/en-us/dynamics365/business-central/ui-create-number-series">Microsoft Docs: Create Number Series</a></li>
|
||
<li><a href="https://docs.microsoft.com/en-us/learn/modules/number-series-trail-codes-dynamics-365-business-central/">Microsoft Learn: Set up number series and trail codes</a></li>
|
||
</ul>
|
||
<p>For more programming details, there is more information on <a href="https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-number-sequences">Microsoft Docs: Number Sequences in Business Central</a>.</p></description></item><item><title>Docs: Template Method Pattern</title><link>https://alguidelines.dev/docs/patterns/template-method-pattern/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/docs/patterns/template-method-pattern/</guid><description>
|
||
<p><em>Created by Patrick Schiefer, Described by Patrick Schiefer</em></p>
|
||
<h2 id="abstract">Abstract</h2>
|
||
<p>The goal of this pattern is to simplify the solution of similar problems and make your code more readable.</p>
|
||
<h2 id="problem">Problem</h2>
|
||
<p>In nearly every app you sometimes have to solve similar problems for different cases. Mostly not the same developer will solve every case. This results in different solutions.</p>
|
||
<h2 id="description">Description</h2>
|
||
<p>The pattern is used when you have problems which are independent but require the same logical flow. Examples which occur very often are: <em>Posting Documents</em>, <em>Printing Reports</em> or <em>Exporting Data</em>.</p>
|
||
<h2 id="bad-code-example">Bad Code Example</h2>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50010</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportSalesLines<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportData<span style="color:#ce5c00;font-weight:bold">(</span>SalesHeader<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Sales Header&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesLine<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Sales Line&#34;<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span>CheckData<span style="color:#ce5c00;font-weight:bold">() </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">repeat</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">case</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span>ExportType<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">of</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Enum</span><span style="color:#000;font-weight:bold">::</span>ExportType<span style="color:#000;font-weight:bold">::</span>A<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenerateLineTypeA<span style="color:#ce5c00;font-weight:bold">(</span>SalesLine<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Enum</span><span style="color:#000;font-weight:bold">::</span>ExportType<span style="color:#000;font-weight:bold">::</span>B<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>GenerateLineTypeB<span style="color:#ce5c00;font-weight:bold">(</span>SalesLine<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">until</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesLine<span style="color:#ce5c00;font-weight:bold">.</span>Next<span style="color:#ce5c00;font-weight:bold">() </span>=<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">case</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span>ExportType<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">of</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Enum</span><span style="color:#000;font-weight:bold">::</span>ExportType<span style="color:#000;font-weight:bold">::</span>A<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>WriteToFile<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Enum</span><span style="color:#000;font-weight:bold">::</span>ExportType<span style="color:#000;font-weight:bold">::</span>B<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SendToWebService<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">//TODO Implementation of procedures used in example
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>As you can see in this example the readability gets worse with every new case.</p>
|
||
<h2 id="the-pattern">The Pattern</h2>
|
||
<p>To implement the Pattern you need at least 3 objects:</p>
|
||
<ul>
|
||
<li>A template codeunit</li>
|
||
<li>An Interface which provides the needed procedures</li>
|
||
<li>A codeunit which Implements the interrface</li>
|
||
</ul>
|
||
<p>In my example I show how to implement a data export with templating.</p>
|
||
<p>We start with the template</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50000</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportTemplate<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportData<span style="color:#ce5c00;font-weight:bold">(</span>export<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IDataExport<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>export<span style="color:#ce5c00;font-weight:bold">.</span>CheckData<span style="color:#ce5c00;font-weight:bold">() </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span>export<span style="color:#ce5c00;font-weight:bold">.</span>GetLinesToExport<span style="color:#ce5c00;font-weight:bold">() </span><span style="color:#204a87;font-weight:bold">then</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">repeat</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>export<span style="color:#ce5c00;font-weight:bold">.</span>ExportLine<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">until</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">not</span><span style="color:#f8f8f8;text-decoration:underline"> </span>export<span style="color:#ce5c00;font-weight:bold">.</span>NextLine<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>export<span style="color:#ce5c00;font-weight:bold">.</span>Finish<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>As you can see the template just calls procedures via an interface and just defines the flow of the export without really implementing it.</p>
|
||
<p>As the second part we need an interface for the export functions</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IDataExport<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>CheckData<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetLinesToExport<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportLine<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NextLine<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Finish<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>And now we need an implementation. For my example I wrote a export Codeunit for Sales Headers</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50001</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeaderExport<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">implements</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IDataExport<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SetSalesHeader<span style="color:#ce5c00;font-weight:bold">(</span>DocType<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Enum</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Sales Document Type&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>No<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">10</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span>Get<span style="color:#ce5c00;font-weight:bold">(</span>DocType<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>No<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>CheckData<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span><span style="color:#204a87;font-weight:bold">TestField</span><span style="color:#ce5c00;font-weight:bold">(</span>Status<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Enum</span><span style="color:#000;font-weight:bold">::</span>&#34;Sales Document Status&#34;<span style="color:#000;font-weight:bold">::</span>Released<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GetLinesToExport<span style="color:#ce5c00;font-weight:bold">()</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesLines<span style="color:#ce5c00;font-weight:bold">.</span>SetRange<span style="color:#ce5c00;font-weight:bold">(</span>&#34;Document Type&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span>&#34;Document Type&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesLines<span style="color:#ce5c00;font-weight:bold">.</span>SetRange<span style="color:#ce5c00;font-weight:bold">(</span>&#34;Document No.&#34;<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#ce5c00;font-weight:bold">.</span>&#34;No.&#34;<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>SalesLines<span style="color:#ce5c00;font-weight:bold">.</span>FindSet<span style="color:#ce5c00;font-weight:bold">())</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportLine<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">//Generate Exportdata here
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>NextLine<span style="color:#ce5c00;font-weight:bold">(</span>Steps<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">integer</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Boolean</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">exit</span><span style="color:#ce5c00;font-weight:bold">(</span>SalesLines<span style="color:#ce5c00;font-weight:bold">.</span>Next<span style="color:#ce5c00;font-weight:bold">(</span>Steps<span style="color:#ce5c00;font-weight:bold">) </span>&lt;&gt;<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">0</span><span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>Finish<span style="color:#ce5c00;font-weight:bold">()
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// Send or Save data here
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeader<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Sales Header&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesLines<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Sales Line&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><p>Now lets have a look how to use the pattern</p>
|
||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-al" data-lang="al"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">50002</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportOrders<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>{<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">procedure</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportOrder<span style="color:#ce5c00;font-weight:bold">(</span>DocType<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Enum</span><span style="color:#f8f8f8;text-decoration:underline"> </span>&#34;Sales Document Type&#34;<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span>No<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Code</span>[<span style="color:#0000cf;font-weight:bold">10</span>]<span style="color:#ce5c00;font-weight:bold">)
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"> </span><span style="color:#204a87;font-weight:bold">var</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>export<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ExportTemplate<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>exportImpl<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Codeunit</span><span style="color:#f8f8f8;text-decoration:underline"> </span>SalesHeaderExport<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>exportInt<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">Interface</span><span style="color:#f8f8f8;text-decoration:underline"> </span>IDataExport<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">begin</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>exportImpl<span style="color:#ce5c00;font-weight:bold">.</span>SetSalesHeader<span style="color:#ce5c00;font-weight:bold">(</span>DocType<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span>No<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>exportInt<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>exportImpl<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>export<span style="color:#ce5c00;font-weight:bold">.</span>ExportData<span style="color:#ce5c00;font-weight:bold">(</span>exportInt<span style="color:#ce5c00;font-weight:bold">)</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">end</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>}<span style="color:#f8f8f8;text-decoration:underline">
|
||
</span></span></span></code></pre></div><h2 id="benefits">Benefits</h2>
|
||
<p>Your code gains readability and it is very easy to add new cases for the template. You don&rsquo;t always have to think about the whole logic. You just have to implement the details.</p>
|
||
<h2 id="when-not-to-use">When not to use</h2>
|
||
<p>The Pattern should not be used for problems which differ too much. For example, if you have two data exports in your app, one is exporting header and lines and the second one only export header. In this case I would suggest to not use the pattern or to make two templates out of it.</p>
|
||
<h2 id="references">References</h2>
|
||
<p><a href="https://patrickschiefer.com/2022/04/08/template-method-pattern/">Detailed Explanation of the pattern</a></p></description></item></channel></rss> |