formatted nav patterns
This commit is contained in:
parent
38a19d75d8
commit
2fad891a77
59 changed files with 1403 additions and 1970 deletions
|
|
@ -30,8 +30,8 @@ The implementation varies depending on the technology and language used. In obje
|
|||
|
||||
[anchor0]: 0535.Singleton.png
|
||||
[anchor1]: https://en.wikipedia.org/wiki/Singleton_pattern
|
||||
[anchor2]: /nav/w/designpatterns/151.singleton-table
|
||||
[anchor3]: /nav/w/designpatterns/283.singleton-codeunit
|
||||
[anchor2]: /navpatterns/1-patterns/singleton/singleton-table/
|
||||
[anchor3]: /navpatterns/1-patterns/singleton/singleton-codeunit/
|
||||
|
||||
|
||||
[image0]: 0535.Singleton.png
|
||||
|
|
|
|||
|
|
@ -22,23 +22,27 @@ Context: Azure Machine Learning services are paid. However, Dynamics NAV include
|
|||
|
||||
The test below checks that, when the monthly quota is exceeded, then the function IsAzureMLLimitReached returns TRUE.
|
||||
|
||||
\[Test\]
|
||||
PROCEDURE AzureMLProcessingTimeExceedsLimit@11();
|
||||
VAR
|
||||
```al
|
||||
[Test]
|
||||
PROCEDURE AzureMLProcessingTimeExceedsLimit@11();
|
||||
VAR
|
||||
AzureMachineLearningUsage@1004 : Record 2002;
|
||||
ProcessingTime@1000 : Decimal;
|
||||
BEGIN
|
||||
// \[SCENARIO\] Azure Machine Learning Processing time exceeds AzureML limit
|
||||
// \[GIVEN\] AzureMachineLearningUsage \> 0
|
||||
BEGIN
|
||||
// [SCENARIO] Azure Machine Learning Processing time exceeds AzureML limit
|
||||
|
||||
// [GIVEN] AzureMachineLearningUsage > 0
|
||||
Initialize; // calls PermissionManager.SetTestabilitySoftwareAsAService(TRUE);
|
||||
ProcessingTime := LibraryRandom.RandDec(1000,2);
|
||||
AzureMachineLearningUsage.IncrementTotalProcessingTime(ProcessingTime);
|
||||
// \[WHEN\] When IsAzureMLLimitReached is invoked with Limit more than Processing time
|
||||
// \[THEN\] HasAzureLimitReached returns TRUE
|
||||
AzureMachineLearningUsage.IncrementTotalProcessingTime(ProcessingTime);
|
||||
|
||||
// [WHEN] When IsAzureMLLimitReached is invoked with Limit more than Processing time
|
||||
// [THEN] HasAzureLimitReached returns TRUE
|
||||
Assert.IsTrue(AzureMachineLearningUsage.IsAzureMLLimitReached(ProcessingTime - 1),
|
||||
'HasAzureLimitReached returns wrong value when Processing time exceeds Limit.');
|
||||
'HasAzureLimitReached returns wrong value when Processing time exceeds Limit.');
|
||||
PermissionManager.SetTestabilitySoftwareAsAService(FALSE);
|
||||
END;
|
||||
END;
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
|
|
@ -50,8 +54,6 @@ The figure below explains what happens when the Permission Manager is not a sing
|
|||
|
||||
[![ ][image1]][anchor1]
|
||||
|
||||
****
|
||||
|
||||
**Solution:** restrict the number of instantiations of a codeunit to only one, by setting the codeunit property **SingleInstance** to **Yes**.
|
||||
|
||||
Returning to the previous example, let's analyze the case when the codeunit Permission Manager is a singleton codeunit:
|
||||
|
|
@ -60,8 +62,7 @@ Returning to the previous example, let's analyze the case when the codeunit Perm
|
|||
|
||||
When the codeunit Permission Manager is a singleton, then no matter from where it is invoked, the same instance will be reached. Therefore, the status set by the test (SaaS = TRUE) will be reachable from the production code, and the test will pass, as seen in the figure below.
|
||||
|
||||
**[![ ][image3]][anchor3]
|
||||
**
|
||||
[![ ][image3]][anchor3]
|
||||
|
||||
**Consequences**
|
||||
|
||||
|
|
@ -84,9 +85,8 @@ Most of the usages in NAV refer to the so-called "management codeunits". The man
|
|||
* Codeunit 9002 Permission Manager
|
||||
* Etc.
|
||||
|
||||
**Note:** while the object-oriented **Singleton** pattern can restrict the number of instantiations of the singleton to an integer n \> 0, in Dynamics NAV the **Singleton Codeunit** can only have n=1\.
|
||||
**Note:** while the object-oriented **Singleton** pattern can restrict the number of instantiations of the singleton to an integer n > 0, in Dynamics NAV the **Singleton Codeunit** can only have n=1\.
|
||||
|
||||
__
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,15 +6,10 @@ weight = 1110
|
|||
|
||||
_By Elly Nkya at Microsoft Development Center Copenhagen_
|
||||
|
||||
## [![ ][image0]][anchor0]
|
||||
|
||||
_
|
||||
_
|
||||
[![ ][image0]][anchor0]
|
||||
|
||||
**Problem**: The developer needs to define a single record that can contain a set of rules and behavior (optional, mandatory, or defaulting mechanisms), that apply to a functionality, and can be configured by a user.
|
||||
|
||||
****
|
||||
|
||||
**Forces**
|
||||
|
||||
* You want a central place to define the address and logo of your company (see Company Information table).
|
||||
|
|
@ -36,8 +31,6 @@ In a functionality that is large enough (such as sales, inventory, fixed) you ma
|
|||
|
||||
**4\. Use:** Access the rule in code and use it
|
||||
|
||||
****
|
||||
|
||||
**NAV Usages**
|
||||
|
||||
Rounding rules for Unit-Amounts and Amounts are implemented using the Singleton pattern.
|
||||
|
|
@ -46,35 +39,43 @@ Rounding rules for Unit-Amounts and Amounts are implemented using the Singleton
|
|||
|
||||
**2\. Instantiate:** In codeunit 2, the following code is invoked
|
||||
|
||||
WITH GLSetup DO
|
||||
```al
|
||||
WITH GLSetup DO
|
||||
IF NOT FINDFIRST THEN BEGIN
|
||||
INIT;
|
||||
INSERT;
|
||||
INIT;
|
||||
INSERT;
|
||||
END;
|
||||
```
|
||||
|
||||
**3\. Enforce:** On the General Ledger Setup. The following properties are setup:
|
||||
|
||||
```al
|
||||
DeleteAllowed=false,
|
||||
InsertAllowed=false
|
||||
```
|
||||
|
||||
**4\. Use:** Access the rounding rules are used
|
||||
|
||||
...
|
||||
GLSetup.GET;
|
||||
UnitCostCurrency := ROUND(...,GLSetup."Unit-Amount Rounding Precision");
|
||||
...
|
||||
```al
|
||||
...
|
||||
GLSetup.GET;
|
||||
UnitCostCurrency := ROUND(...,GLSetup."Unit-Amount Rounding Precision");
|
||||
...
|
||||
```
|
||||
|
||||
Or if accessing the rule multiple times and performance is a consideration, use lazy instantiation:
|
||||
|
||||
...
|
||||
GetGLSetup;
|
||||
UnitCostCurrency := ROUND(...,GLSetup."Unit-Amount Rounding Precision");
|
||||
...
|
||||
```al
|
||||
...
|
||||
GetGLSetup;
|
||||
UnitCostCurrency := ROUND(...,GLSetup."Unit-Amount Rounding Precision");
|
||||
...
|
||||
|
||||
LOCAL GetGLSetup()
|
||||
IF NOT GLSetupRead THEN
|
||||
LOCAL GetGLSetup()
|
||||
IF NOT GLSetupRead THEN
|
||||
GLSetup.GET;
|
||||
GLSetupRead := TRUE;
|
||||
GLSetupRead := TRUE;
|
||||
```
|
||||
|
||||
**Related topics**
|
||||
|
||||
|
|
@ -93,7 +94,7 @@ YouTube Video of NAV Singleton:
|
|||
|
||||
[anchor0]: 5554.Singleton-Table.png
|
||||
[anchor1]: https://en.wikipedia.org/wiki/Singleton_pattern
|
||||
[anchor2]: /nav/w/designpatterns/76.setup-table
|
||||
[anchor2]: /navpatterns/1-patterns/singleton/singleton-table/setup-table/
|
||||
[anchor3]: https://www.youtube.com/watch?v=aQPu-s9FkYI&list=PLhZ3P-LY7CqmVszuvtJLujFyHpsVN0U_w&index=13
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,20 +19,15 @@ The overview information consists of summed-up numbers, calculated from business
|
|||
|
||||
**Problem**: NAV stores data in tables. By definition, a table is a repetitive structure containing multiple lines, each line having a different piece of the information. But sometimes this repetitive information needs to be summed-up or otherwise synthetized, and presented as an overview.
|
||||
|
||||
|
||||
**Solution:** Store overview information in a singleton table.
|
||||
|
||||
****
|
||||
|
||||
There are two ways of calculating overview information in NAV.
|
||||
|
||||
1. By using a FlowField. This applies for simpler calculations, like filtered or unfiltered counts, sums etc.
|
||||
2. By writing C/AL code to perform custom calculations. Use this when:
|
||||
|
||||
* * The way to calculate the overview is too complex for flow fields, or
|
||||
* The data needs to be pulled from an external system (like Dynamics CRM, QuickBooks or any external integration).
|
||||
|
||||
****
|
||||
* The way to calculate the overview is too complex for flow fields, or
|
||||
* The data needs to be pulled from an external system (like Dynamics CRM, QuickBooks or any external integration).
|
||||
|
||||
The implementation of Cues is already described in detail on MSDN, in [Creating and Customizing Cues][anchor4] and in [Walkthrough: Creating a Cue Based on a FlowField][anchor5].
|
||||
|
||||
|
|
@ -40,92 +35,34 @@ The implementation of Cues is already described in detail on MSDN, in [Creating
|
|||
|
||||
_Table 1 - Cue tables in Dynamics NAV_ shows some examples of singleton tables used for creating Cues.
|
||||
|
||||
Table ID
|
||||
|
||||
Table Name
|
||||
|
||||
1313
|
||||
|
||||
Activities Cue
|
||||
|
||||
5370
|
||||
|
||||
CRM Synch. Job Status Cue
|
||||
|
||||
9042
|
||||
|
||||
Team Member Cue
|
||||
|
||||
9050
|
||||
|
||||
Warehouse Basic Cue
|
||||
|
||||
9051
|
||||
|
||||
Warehouse WMS Cue
|
||||
|
||||
9052
|
||||
|
||||
Service Cue
|
||||
|
||||
9053
|
||||
|
||||
Sales Cue
|
||||
|
||||
9054
|
||||
|
||||
Finance Cue
|
||||
|
||||
9055
|
||||
|
||||
Purchase Cue
|
||||
|
||||
9056
|
||||
|
||||
Manufacturing Cue
|
||||
|
||||
9057
|
||||
|
||||
Job Cue
|
||||
|
||||
9058
|
||||
|
||||
Warehouse Worker WMS Cue
|
||||
|
||||
9059
|
||||
|
||||
Administration Cue
|
||||
|
||||
9060
|
||||
|
||||
SB Owner Cue
|
||||
|
||||
9061
|
||||
|
||||
RapidStart Services Cue
|
||||
|
||||
9063
|
||||
|
||||
Relationship Mgmt. Cue
|
||||
|
||||
9069
|
||||
|
||||
O365 Sales Cue
|
||||
|
||||
9070
|
||||
|
||||
Accounting Services Cue
|
||||
Table ID | Table Name
|
||||
---------|-----------
|
||||
1313 | Activities Cue
|
||||
5370 | CRM Synch. Job Status Cue
|
||||
9042 | Team Member Cue
|
||||
9050 | Warehouse Basic Cue
|
||||
9051 | Warehouse WMS Cue
|
||||
9052 | Service Cue
|
||||
9053 | Sales Cue
|
||||
9054 | Finance Cue
|
||||
9055 | Purchase Cue
|
||||
9056 | Manufacturing Cue
|
||||
9057 | Job Cue
|
||||
9058 | Warehouse Worker WMS Cue
|
||||
9059 | Administration Cue
|
||||
9060 | SB Owner Cue
|
||||
9061 | RapidStart Services Cue
|
||||
9063 | Relationship Mgmt. Cue
|
||||
9069 | O365 Sales Cue
|
||||
9070 | Accounting Services Cue
|
||||
|
||||
Table 1 - Cue tables in Dynamics NAV
|
||||
|
||||
___
|
||||
_
|
||||
|
||||
|
||||
|
||||
[anchor0]: Cue-Table.png
|
||||
[anchor1]: /nav/w/designpatterns/151.singleton-table
|
||||
[anchor2]: /nav/w/designpatterns/76.setup-table
|
||||
[anchor1]: /navpatterns/1-patterns/singleton/singleton-table/
|
||||
[anchor2]: /navpatterns/1-patterns/singleton/singleton-table/setup-table/
|
||||
[anchor3]: Cue-Table-Figure-1.JPG
|
||||
[anchor4]: https://msdn.microsoft.com/en-us/library/dn789553(v=nav.90).aspx
|
||||
[anchor5]: https://msdn.microsoft.com/en-us/library/ff477101(v=nav.90).aspx
|
||||
|
|
|
|||
|
|
@ -31,12 +31,14 @@ The **CardPage** type is most suitable for representing this kind of tables. In
|
|||
|
||||
In the **OnOpenPage** trigger, the following code should be added to insert a record when the user opens the page for the first time, if a record does not exist already.
|
||||
|
||||
OnOpenPage()
|
||||
```al
|
||||
OnOpenPage()
|
||||
RESET;
|
||||
IF NOT GET THEN BEGIN
|
||||
INIT;
|
||||
INSERT;
|
||||
INIT;
|
||||
INSERT;
|
||||
END;
|
||||
```
|
||||
|
||||
The following diagram describes the flow of the program, once the user tries to access the setup information. The user opens the page. If the record containing setup information already exists, then the page opens on the existing record. Else, a new empty record is created and the page opens on it.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue