This commit is contained in:
waldo1001 2022-02-28 21:41:22 +00:00
parent d5790b8abb
commit 7e9d4c18d3
232 changed files with 25544 additions and 58300 deletions

View file

@ -11,26 +11,26 @@
<p>Take for example the following test of Azure ML (Azure Machine Learning) integration with NAV.</p>
<p>Context: Azure Machine Learning services are paid. However, Dynamics NAV includes a monthly pre-paid quota of Azure ML, which can be used for free by the users. There is an upper limit to this quota, and when it is reached, Azure ML services are turned off until the next month starts and a new quota becomes available for consumption.</p>
<p>The test below checks that, when the monthly quota is exceeded, then the function IsAzureMLLimitReached returns TRUE.</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">[Test]<span style="color:#f8f8f8;text-decoration:underline">
</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>AzureMLProcessingTimeExceedsLimit@<span style="color:#0000cf;font-weight:bold">11</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:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">VAR</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>AzureMachineLearningUsage@<span style="color:#0000cf;font-weight:bold">1004</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">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2002</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ProcessingTime@<span style="color:#0000cf;font-weight:bold">1000</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">Decimal</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</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 style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// [SCENARIO] Azure Machine Learning Processing time exceeds AzureML limit
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// [GIVEN] AzureMachineLearningUsage > 0
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>Initialize<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// calls PermissionManager.SetTestabilitySoftwareAsAService(TRUE);
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>ProcessingTime<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LibraryRandom<span style="color:#ce5c00;font-weight:bold">.</span>RandDec<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1000</span><span style="color:#000;font-weight:bold">,</span><span style="color:#0000cf;font-weight:bold">2</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:#f8f8f8;text-decoration:underline"> </span>AzureMachineLearningUsage<span style="color:#ce5c00;font-weight:bold">.</span>IncrementTotalProcessingTime<span style="color:#ce5c00;font-weight:bold">(</span>ProcessingTime<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:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// [WHEN] When IsAzureMLLimitReached is invoked with Limit more than Processing time
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// [THEN] HasAzureLimitReached returns TRUE
</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>Assert<span style="color:#ce5c00;font-weight:bold">.</span>IsTrue<span style="color:#ce5c00;font-weight:bold">(</span>AzureMachineLearningUsage<span style="color:#ce5c00;font-weight:bold">.</span>IsAzureMLLimitReached<span style="color:#ce5c00;font-weight:bold">(</span>ProcessingTime<span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">1</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:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">'HasAzureLimitReached returns wrong value when Processing time exceeds Limit.'</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:#f8f8f8;text-decoration:underline"> </span>PermissionManager<span style="color:#ce5c00;font-weight:bold">.</span>SetTestabilitySoftwareAsAService<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 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></code></pre></div><p>The figure below explains what happens when the Permission Manager is not a singleton. When it is invoked from different places (first from the test, second from the production code), then different instances of the Permission Manager will fire up and answer. In detail:</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>[Test]<span style="color:#f8f8f8;text-decoration: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>AzureMLProcessingTimeExceedsLimit@<span style="color:#0000cf;font-weight:bold">11</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>AzureMachineLearningUsage@<span style="color:#0000cf;font-weight:bold">1004</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">Record</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">2002</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>ProcessingTime@<span style="color:#0000cf;font-weight:bold">1000</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">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">// [SCENARIO] Azure Machine Learning Processing time exceeds AzureML limit
</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:#8f5902;font-style:italic">// [GIVEN] AzureMachineLearningUsage > 0
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>Initialize<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic">// calls PermissionManager.SetTestabilitySoftwareAsAService(TRUE);
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>ProcessingTime<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>LibraryRandom<span style="color:#ce5c00;font-weight:bold">.</span>RandDec<span style="color:#ce5c00;font-weight:bold">(</span><span style="color:#0000cf;font-weight:bold">1000</span><span style="color:#000;font-weight:bold">,</span><span style="color:#0000cf;font-weight:bold">2</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>AzureMachineLearningUsage<span style="color:#ce5c00;font-weight:bold">.</span>IncrementTotalProcessingTime<span style="color:#ce5c00;font-weight:bold">(</span>ProcessingTime<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:#8f5902;font-style:italic">// [WHEN] When IsAzureMLLimitReached is invoked with Limit more than Processing time
</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">// [THEN] HasAzureLimitReached returns TRUE
</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span><span style="color:#f8f8f8;text-decoration:underline"> </span>Assert<span style="color:#ce5c00;font-weight:bold">.</span>IsTrue<span style="color:#ce5c00;font-weight:bold">(</span>AzureMachineLearningUsage<span style="color:#ce5c00;font-weight:bold">.</span>IsAzureMLLimitReached<span style="color:#ce5c00;font-weight:bold">(</span>ProcessingTime<span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#0000cf;font-weight:bold">1</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:#4e9a06">'HasAzureLimitReached returns wrong value when Processing time exceeds Limit.'</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>PermissionManager<span style="color:#ce5c00;font-weight:bold">.</span>SetTestabilitySoftwareAsAService<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 figure below explains what happens when the Permission Manager is not a singleton. When it is invoked from different places (first from the test, second from the production code), then different instances of the Permission Manager will fire up and answer. In detail:</p>
<ol>
<li>The test calls Initialize which sets SaaS=TRUE in codeunit Permission Manager</li>
<li>The test calls into production code to validate it works as expected. It calls AzureMachineLearningUsage codeunit to find out if the monthly quota has been reached. The function IsAzureMLLimitReached in AzureMachineLearningUsage codeunit is designed only for SaaS. If the code doesn’t run in SaaS, then it always returns FALSE.</li>
@ -83,30 +83,30 @@
<p>Rounding rules for Unit-Amounts and Amounts are implemented using the Singleton pattern.</p>
<p><strong>1. Define:</strong> The General Ledger Setup is used for this.</p>
<p><strong>2. Instantiate:</strong> In codeunit 2, the following code is invoked</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="color:#204a87;font-weight:bold">WITH</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GLSetup<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:#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>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 style="color:#f8f8f8;text-decoration:underline"> </span>INIT<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>INSERT<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</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></code></pre></div><p><strong>3. Enforce:</strong> On the General Ledger Setup. The following properties are setup:</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="color:#f8f8f8;text-decoration:underline"> </span>DeleteAllowed=false<span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>InsertAllowed=false<span style="color:#f8f8f8;text-decoration:underline">
</span></code></pre></div><p><strong>4. Use:</strong> Access the rounding rules are used</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="color:#ce5c00;font-weight:bold">...
</span><span style="color:#ce5c00;font-weight:bold"></span>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>GET<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"></span>UnitCostCurrency<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ROUND<span style="color:#ce5c00;font-weight:bold">(...</span><span style="color:#000;font-weight:bold">,</span>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>"Unit-Amount Rounding Precision"<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:#f8f8f8;text-decoration:underline"></span><span style="color:#ce5c00;font-weight:bold">...
</span></code></pre></div><p>Or if accessing the rule multiple times and performance is a consideration, use lazy instantiation:</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="color:#ce5c00;font-weight:bold">...
</span><span style="color:#ce5c00;font-weight:bold"></span>GetGLSetup<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"></span>UnitCostCurrency<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ROUND<span style="color:#ce5c00;font-weight:bold">(...</span><span style="color:#000;font-weight:bold">,</span>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>"Unit-Amount Rounding Precision"<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:#f8f8f8;text-decoration:underline"></span><span style="color:#ce5c00;font-weight:bold">...
</span><span style="color:#ce5c00;font-weight:bold">
</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>GetGLSetup<span style="color:#ce5c00;font-weight:bold">()
</span><span style="color:#ce5c00;font-weight:bold"></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>GLSetupRead<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:#f8f8f8;text-decoration:underline"> </span>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>GET<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"></span>GLSetupRead<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></code></pre></div><p><strong>Related topics</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">WITH</span><span style="color:#f8f8f8;text-decoration:underline"> </span>GLSetup<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></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>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>INIT<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"> </span>INSERT<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration: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><strong>3. Enforce:</strong> On the General Ledger Setup. The following properties are setup:</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>DeleteAllowed=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>InsertAllowed=false<span style="color:#f8f8f8;text-decoration:underline">
</span></span></span></code></pre></div><p><strong>4. Use:</strong> Access the rounding rules are used</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:#ce5c00;font-weight:bold">...
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>GET<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>UnitCostCurrency<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ROUND<span style="color:#ce5c00;font-weight:bold">(...</span><span style="color:#000;font-weight:bold">,</span>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>"Unit-Amount Rounding Precision"<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></code></pre></div><p>Or if accessing the rule multiple times and performance is a consideration, use lazy instantiation:</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:#ce5c00;font-weight:bold">...
</span></span></span><span style="display:flex;"><span><span style="color:#ce5c00;font-weight:bold"></span>GetGLSetup<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>UnitCostCurrency<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">:=</span><span style="color:#f8f8f8;text-decoration:underline"> </span>ROUND<span style="color:#ce5c00;font-weight:bold">(...</span><span style="color:#000;font-weight:bold">,</span>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>"Unit-Amount Rounding Precision"<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></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>GetGLSetup<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">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>GLSetupRead<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>GLSetup<span style="color:#ce5c00;font-weight:bold">.</span>GET<span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
</span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span>GLSetupRead<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></code></pre></div><p><strong>Related topics</strong></p>
<p><a href="https://en.wikipedia.org/wiki/Singleton_pattern">Singleton design pattern</a>.</p>
<p>The <strong>Singleton Table</strong> has two established applications in Dynamics NAV:</p>
<ol>