From 7e4e21d22342a69a595f8beedc25121e3236ea77 Mon Sep 17 00:00:00 2001 From: christianbraeunlich Date: Sun, 5 Dec 2021 19:02:27 +0100 Subject: [PATCH] change nav 1-patterns formatting --- .../1-patterns/argument-table/index.md | 2 - .../1-patterns/blocked-entity/_index.md | 5 +- .../conditional-cascading-update/index.md | 2 +- .../1-patterns/copy-document/index.md | 2 +- .../create-data-from-templates/index.md | 2 +- .../creating-custom-charts/index.md | 6 +- .../1-patterns/cross-session-events/index.md | 4 +- .../currently-active-record/index.md | 10 +-- .../1-patterns/data-migration-facade/index.md | 14 ++-- .../1-patterns/discovery-event/index.md | 4 +- .../NAVPatterns/1-patterns/document/index.md | 8 +-- .../index.md | 9 +-- .../error-message-processing/index.md | 72 ++++++++++--------- .../index.md | 9 +-- .../index.md | 4 ++ content/NAVPatterns/1-patterns/hooks/index.md | 18 ++--- .../index.md | 4 +- .../instructions-in-the-ui/index.md | 14 ++-- .../integration-of-addresses/index.md | 2 +- .../journal-error-processing/index.md | 2 + .../journal-template-batch-line/index.md | 21 +++--- .../1-patterns/master-data/index.md | 2 +- .../1-patterns/multi-file-download/index.md | 2 +- .../1-patterns/multi-page-list/index.md | 33 +++++---- .../multilanguage-application-data/index.md | 2 +- .../NAVPatterns/1-patterns/no-series/index.md | 4 +- .../in-context-notifications/index.md | 2 +- .../index.md | 14 ++-- .../NAVPatterns/1-patterns/observer/index.md | 2 +- .../posting-routine-select-behavior/index.md | 4 +- .../1-patterns/product-name/index.md | 2 +- .../select-distinct-with-queries/index.md | 6 +- .../index.md | 11 ++- .../index.md | 6 +- .../index.md | 8 +-- .../1-patterns/released-entity/index.md | 4 +- .../1-patterns/report-selection/index.md | 2 +- .../1-sensitive-data-encapsulation/index.md | 14 ++-- .../security/2-data-encryption/index.md | 12 ++-- .../3-single-point-of-access/index.md | 16 ++--- .../security/4-masked-text/index.md | 10 ++- .../1-patterns/security/5-ssl-in-nav/index.md | 9 +-- .../security/{index.md => _index.md} | 5 +- .../setup-specificity-fallback/index.md | 3 +- .../1-patterns/singleton/_index.md | 10 ++- .../singleton/singleton-codeunit/index.md | 7 +- .../singleton/singleton-table/_index.md | 10 +-- .../singleton-table/cue-table/index.md | 14 ++-- .../singleton-table/setup-table/index.md | 6 +- .../1-patterns/standard-journal/index.md | 2 +- .../temporary-dataset-report/index.md | 11 ++- .../index.md | 4 +- .../transfer-custom-fields/index.md | 2 +- .../1-patterns/variant-facade/index.md | 8 +-- 54 files changed, 211 insertions(+), 250 deletions(-) rename content/NAVPatterns/1-patterns/security/{index.md => _index.md} (94%) diff --git a/content/NAVPatterns/1-patterns/argument-table/index.md b/content/NAVPatterns/1-patterns/argument-table/index.md index 3ac7fe4e..8bb49298 100644 --- a/content/NAVPatterns/1-patterns/argument-table/index.md +++ b/content/NAVPatterns/1-patterns/argument-table/index.md @@ -2,8 +2,6 @@ title = "Argument Table" weight = 220 +++ -## Argument table pattern - _Originally By Nikola Kukrika and waldo_ ### Abstract diff --git a/content/NAVPatterns/1-patterns/blocked-entity/_index.md b/content/NAVPatterns/1-patterns/blocked-entity/_index.md index 0cd631d1..1d3f2770 100644 --- a/content/NAVPatterns/1-patterns/blocked-entity/_index.md +++ b/content/NAVPatterns/1-patterns/blocked-entity/_index.md @@ -90,16 +90,13 @@ Entities where the Blocked Entity has been implemented include: The [Released Entity][anchor4]. -[watch?v=O2R fTSup1o&list=PLhZ3P LY7CqmVszuvtJLujFyHpsVN0Uw&index=16][anchor5] - - +{{< youtube O2R-fTSup1o >}} [anchor0]: 2260.BlockedEntityPattern.png [anchor1]: /nav/w/designpatterns/247.data-driven-blocked-entity/edit [anchor2]: 8637.BlockedEntityPattern_5F00_5F00_5F00_Boolean.png [anchor3]: 3056.BlockedEntityPattern_5F00_5F00_5F00_Option.png [anchor4]: /nav/w/designpatterns/115.released-entity.aspx -[anchor5]: https://www.youtube.com/watch?v=O2R-fTSup1o&list=PLhZ3P-LY7CqmVszuvtJLujFyHpsVN0U_w&index=16 [image0]: 2260.BlockedEntityPattern.png diff --git a/content/NAVPatterns/1-patterns/conditional-cascading-update/index.md b/content/NAVPatterns/1-patterns/conditional-cascading-update/index.md index 05c23717..a690d1ff 100644 --- a/content/NAVPatterns/1-patterns/conditional-cascading-update/index.md +++ b/content/NAVPatterns/1-patterns/conditional-cascading-update/index.md @@ -2,7 +2,7 @@ title = "Conditional Cascading Update" weight = 370 +++ -_Originally by Jan Hoek at IDYN _ +_Originally by Jan Hoek at IDYN_ ## Abstract diff --git a/content/NAVPatterns/1-patterns/copy-document/index.md b/content/NAVPatterns/1-patterns/copy-document/index.md index d134de6c..8086821d 100644 --- a/content/NAVPatterns/1-patterns/copy-document/index.md +++ b/content/NAVPatterns/1-patterns/copy-document/index.md @@ -100,7 +100,7 @@ In the standard version of Microsoft Dynamics NAV, the Copy Document functionali 3. Copy Service Document (REP5979) 4. Copy Assembly Document (REP901) -[watch?v=aTiwroXwW0&list=PLhZ3P LY7CqmVszuvtJLujFyHpsVN0Uw&index=17][anchor5] +{{< youtube aTiwroXwW0 >}} diff --git a/content/NAVPatterns/1-patterns/create-data-from-templates/index.md b/content/NAVPatterns/1-patterns/create-data-from-templates/index.md index 94319b52..f58dee98 100644 --- a/content/NAVPatterns/1-patterns/create-data-from-templates/index.md +++ b/content/NAVPatterns/1-patterns/create-data-from-templates/index.md @@ -189,7 +189,7 @@ Implement the solution in the standard version of Microsoft Dynamics NAV and ext It is possible that users end up with a large number of templates if they need many different data combinations. An improvement could be to split templates into smaller groups, grouping only part of the fields that are related, and then apply only these. -[watch?v=F0CTvoyKSmI&list=PLhZ3P LY7CqmVszuvtJLujFyHpsVN0Uw&index=20][anchor6] +{{< youtube F0CTvoyKSmI >}} diff --git a/content/NAVPatterns/1-patterns/creating-custom-charts/index.md b/content/NAVPatterns/1-patterns/creating-custom-charts/index.md index 44b5a1ff..f8a35c77 100644 --- a/content/NAVPatterns/1-patterns/creating-custom-charts/index.md +++ b/content/NAVPatterns/1-patterns/creating-custom-charts/index.md @@ -125,7 +125,7 @@ BusinessChart::DataPointClicked(point : DotNet "Microsoft.Dynamics.Nav.Client.Bu SetDrillDownindexes is a method from the **Business Chart Buffer** table that maps the DotNet point variable to C/AL data, so it must be used. The next method that you must implement is the action to be performed on Drilldown. -The **DataPointDoubleClicked **trigger has the same implementation logic as the DataPointClicked trigger. +The **DataPointDoubleClicked** trigger has the same implementation logic as the DataPointClicked trigger. ### NAV Specific Example 2 @@ -133,11 +133,11 @@ Implementation of chart part 1390 on the **Small Business Role Center** page (90 [![ ][image5]][anchor5] -This chart part contains data from multiple charts within a single part. The **Status Text** field shows the name of the chart and the current period. Users can browse through the charts with **Next Chart **and**Previous Chart** or use **Select Chart** to choose from a list of available charts. +This chart part contains data from multiple charts within a single part. The **Status Text** field shows the name of the chart and the current period. Users can browse through the charts with **Next Chart** and **Previous Chart** or use **Select Chart** to choose from a list of available charts. [![ ][image6]][anchor6] -On this dialog, users can choose if a chart should be enabled or disabled. If the chart is not enabled, it will be skipped on the **Previous Chart **and **Next Chart** actions. Charts used by this part use different codeunits and setup records. If the user changes the selected chart, this option will be saved and applied next time role center is opened. +On this dialog, users can choose if a chart should be enabled or disabled. If the chart is not enabled, it will be skipped on the **Previous Chart** and **Next Chart** actions. Charts used by this part use different codeunits and setup records. If the user changes the selected chart, this option will be saved and applied next time role center is opened. Users can also change the period length. diff --git a/content/NAVPatterns/1-patterns/cross-session-events/index.md b/content/NAVPatterns/1-patterns/cross-session-events/index.md index 61325c2f..79f66ced 100644 --- a/content/NAVPatterns/1-patterns/cross-session-events/index.md +++ b/content/NAVPatterns/1-patterns/cross-session-events/index.md @@ -54,7 +54,7 @@ The Change Observer table identifies the Subscriber using Server ID and Session The Change Notification table then has the same three fields plus an Entry No. as its Primary Key, and in this example borrows heavily from the Change Log code to fill in the rest of the message. -_**Note:** _Other examples of the pattern could have very different fields to identify the Subscriber, Filters and then whatever fields needed for content of the Message. +_**Note:**_ Other examples of the pattern could have very different fields to identify the Subscriber, Filters and then whatever fields needed for content of the Message. Our Message Broker Codeunit will also serve as a central place to create Subscribers (Listen and StopListening functions) and a place to Poll for Messages. Note that the Poll function deletes the Messages as it reads them. ```al @@ -112,7 +112,7 @@ Our Message Broker Codeunit will also serve as a central place to create Subscri END; ``` -**__**The final part of this example is an object that calls the functions above. In this example we will use a Page with a PingPong Timer Control to do the polling in (almost) real time. These are the functions on the page: +**__** The final part of this example is an object that calls the functions above. In this example we will use a Page with a PingPong Timer Control to do the polling in (almost) real time. These are the functions on the page: ```al //OnQueryClosePage(CloseAction : Action None) : Boolean** diff --git a/content/NAVPatterns/1-patterns/currently-active-record/index.md b/content/NAVPatterns/1-patterns/currently-active-record/index.md index 456b20ed..c3913c8f 100644 --- a/content/NAVPatterns/1-patterns/currently-active-record/index.md +++ b/content/NAVPatterns/1-patterns/currently-active-record/index.md @@ -2,7 +2,7 @@ title = "Currently Active Record" weight = 450 +++ -Authors: Henrik Langbak and Kim Ginnerup, Bording Data +_Authors: Henrik Langbak and Kim Ginnerup, Bording Data_ ## Abstract @@ -65,7 +65,9 @@ Remember to set the link table property before you save it. ### 3. Implement the code -IF PriceView.FINDSET THEN // You have them +```al + IF PriceView.FINDSET THEN // You have them +``` ### 4. Create a deployment codeunit @@ -86,8 +88,8 @@ You need to deploy in three steps: If you later want to change the view, you need to follow these rules: -\* If you add columns, you need to add them to the view first and then add them to the Table Object. -\* If you want to remove columns from the view, you need to delete the Table Object, then change the view and last recreate the Table Object without the new columns. +* If you add columns, you need to add them to the view first and then add them to the Table Object. +* If you want to remove columns from the view, you need to delete the Table Object, then change the view and last recreate the Table Object without the new columns. ### Code example that accomplish the same but without using the pattern diff --git a/content/NAVPatterns/1-patterns/data-migration-facade/index.md b/content/NAVPatterns/1-patterns/data-migration-facade/index.md index 03a788f1..f92b60d7 100644 --- a/content/NAVPatterns/1-patterns/data-migration-facade/index.md +++ b/content/NAVPatterns/1-patterns/data-migration-facade/index.md @@ -1,9 +1,7 @@ +++ -title = "Data Migration Facade" +title = "Data Migration Façade" weight = 480 +++ -# **Data Migration Façade** - _By David Bastide and Soumya Dutta at Microsoft Development Center Copenhagen_ [![ ][image0]][anchor0] @@ -124,7 +122,7 @@ The following example shows how to migrate items without staging tables: end; ``` -_Figure 2: Example of Item and Item Unit of Measure migration without staging tables _ +_Figure 2: Example of Item and Item Unit of Measure migration without staging tables_ ### Usage with staging tables: @@ -139,10 +137,8 @@ The overall workflow is: * From the event subscribers, call the façade procedures to create entities and set their field values: * * **"Item Data Migration Façade".CreateItemIfNeeded('ITEM042','My Item Description';'My Item Description 2';ItemTypeToSet::Inventory)** - * -**"Item Data Migration Façade".SetBaseUnitOfMeasure('BOX')** - * -**"Item Data Migration Façade".ModifyItem(true)** + * **"Item Data Migration Façade".SetBaseUnitOfMeasure('BOX')** + * **"Item Data Migration Façade".ModifyItem(true)** [![ ][image2]][anchor2] @@ -267,7 +263,7 @@ The following Entity data migration façade codeunits are available: ## References: -Façade pattern on Wikipedia: https://en.wikipedia.org/wiki/Facade\_pattern +Façade pattern on Wikipedia: https://en.wikipedia.org/wiki/Facade_pattern diff --git a/content/NAVPatterns/1-patterns/discovery-event/index.md b/content/NAVPatterns/1-patterns/discovery-event/index.md index 91a9ff11..3c18b8f2 100644 --- a/content/NAVPatterns/1-patterns/discovery-event/index.md +++ b/content/NAVPatterns/1-patterns/discovery-event/index.md @@ -2,7 +2,7 @@ title = "Discovery Event" weight = 500 +++ -by waldo +_by waldo_ # Abstract @@ -51,7 +51,7 @@ When you publish an event, it should obviously be raised somewhere in the code a ## Step 3: Create one or more global functions, so that your subscriber can call into your functionality to configure, set up, or do whatever it needs to do to make itself discoverable -The generic functionality that I want to call, should be part of the main class - in this case the**Module Discovery** class, or better, the table (**Module Status**). In this table, I create this global function, because I want to make it available for the subscribers: +The generic functionality that I want to call, should be part of the main class - in this case the **Module Discovery** class, or better, the table (**Module Status**). In this table, I create this global function, because I want to make it available for the subscribers: [![ ][image3]][anchor3] The business logic doesn't really matter for this pattern. This is obviously dependent on the functionality where you would like to implement the pattern. diff --git a/content/NAVPatterns/1-patterns/document/index.md b/content/NAVPatterns/1-patterns/document/index.md index e37d9ae6..6c10f91c 100644 --- a/content/NAVPatterns/1-patterns/document/index.md +++ b/content/NAVPatterns/1-patterns/document/index.md @@ -25,7 +25,7 @@ To build this example from scratch, you will need: * Two tables, one for the header (called "Document Header"), and one for the document lines (called "Document Line"). Each document will be composed of "1 to N" line(s). * Three pages, one for the header, one for the subpage (lines), and the last for the document list obviously.Table "Document Header" -**Table "Document Header" **: Is the "header" table of your document (like Sales Header, Purchase Header, Transfer Header ...) +**Table "Document Header"**: Is the "header" table of your document (like Sales Header, Purchase Header, Transfer Header ...) * Add a field "No." (Code 20): Should be the first field and primary key of your documents, to be driven by Serial No. (See corresponding design pattern) @@ -63,7 +63,7 @@ Then simply add your subpage as new line in the designer, and adjust the propert **[![ ][image1]][anchor1]** -**Page "Document List": **Use the Page wizard to create a List page based on the Document table and add fields, FactBox (RecordLinks, Notes...), etc. +**Page "Document List":** Use the Page wizard to create a List page based on the Document table and add fields, FactBox (RecordLinks, Notes...), etc. Once created: @@ -74,7 +74,7 @@ Save our page and add it to the Role Page "Order Processor Role Center" for exam Now, observe how "Line No." is calculated on the first line, and when inserting a new line between the first and second one. -Code sample (copy link to your browser) : https://knk1fr-my.sharepoint.com/personal/xgaronnat\_knk\_fr/\_layouts/15/guestaccess.aspx?guestaccesstoken=hL0P%2fyQ1ZreY5KlSPc%2b8dHrO4zjUkqQbg8DnGSbgd1Y%3d&docid=02b3cb93e1ff1459380891795fb8441fc +Code sample (copy link to your browser) : https://knk1fr-my.sharepoint.com/personal/xgaronnat_knk_fr/_layouts/15/guestaccess.aspx?guestaccesstoken=hL0P%2fyQ1ZreY5KlSPc%2b8dHrO4zjUkqQbg8DnGSbgd1Y%3d&docid=02b3cb93e1ff1459380891795fb8441fc ## NAV Usages @@ -98,7 +98,7 @@ Use Series No. Pattern for your documents, and Copy Document to implement docume ## References Walkthrough: Creating a Document Page : [http://msdn.microsoft.com/en-us/library/dd338599(v=nav.71).aspx][anchor2] -[][anchor2][watch?v=S9cRD2D4c0&list=PLhZ3P LY7CqmVszuvtJLujFyHpsVN0Uw&index=27][anchor3] +{{< youtube S9cRD2D4c0>}} diff --git a/content/NAVPatterns/1-patterns/easy-update-of-setup-or-supplementary-information/index.md b/content/NAVPatterns/1-patterns/easy-update-of-setup-or-supplementary-information/index.md index 526c63b3..24eeb7c8 100644 --- a/content/NAVPatterns/1-patterns/easy-update-of-setup-or-supplementary-information/index.md +++ b/content/NAVPatterns/1-patterns/easy-update-of-setup-or-supplementary-information/index.md @@ -17,7 +17,7 @@ To guide users, we can prompt them with a dialog on which they can update the se Define two functions in the setup or supplementary table: One for verifying if the needed information is available, and another for exposing the page that contains the fields that the user must update. Call the code. For example: - +```AL Local IsXAvailable : Boolean If field X <\> '' then Exit(True) @@ -39,7 +39,7 @@ The calling code SetupTable.VerifyAndSetX .. - +``` ## NAV Specific Example **** @@ -53,10 +53,11 @@ Procedure VerifyAndSetOIOUBLPath(...) The code in the **Sales & Receivables Setup** table can now be called directly from the related processing codeunit, such as the **Sales-Post + Print** codeunit (82). Were the code is called: - +```AL IF ("EAN No." <\> '') THEN SalesSetup.VerifyAndSetOIOUBLPathSetup(SalesHeader."Document Type"); +``` If the setup is not updated properly, the user is prompted to update it as follows. @@ -82,7 +83,7 @@ The anti-pattern is to do a testfield on a field that is not in the table that y The test field message can often be confusing because the pages are often named differently than the tables, which can lead to misunderstanding and context-switching. -[watch?v=oeASJN zqTo&list=PLhZ3P LY7CqmVszuvtJLujFyHpsVN0Uw&index=18][anchor2] +{{< youtube oeASJN-zqTo>}} diff --git a/content/NAVPatterns/1-patterns/error-message-processing/index.md b/content/NAVPatterns/1-patterns/error-message-processing/index.md index 01cc942f..ea38af64 100644 --- a/content/NAVPatterns/1-patterns/error-message-processing/index.md +++ b/content/NAVPatterns/1-patterns/error-message-processing/index.md @@ -14,8 +14,8 @@ Missing, invalid or incomplete data is a common issue during data processing in This article describes how to use the Error Message component in NAV, which in short gives you the possibility to: -1\. Link an error message to the page which enables you to resolve the problem. -2\. Assemble all error messages in one central view instead of having to encounter them one by one. +1. Link an error message to the page which enables you to resolve the problem. +2. Assemble all error messages in one central view instead of having to encounter them one by one. Validating data is a common task during data processing in NAV. Unfortunately, validation is often done using NAV's integrated ERROR and TESTFIELD functions, which halt execution of the process. The user will then have to locate the invalid / missing data, correct it and reinitiate the process, possibly running into the next error, making the cycle repeat itself. This can be a very tedious, time-consuming and frustrating process. The error message component aims at improving this experience by providing a lightweight framework for error message logging and this article will explain how to leverage this functionality in your code. By doing so, all error messages are gathered during (pre-)processing and are finally presented to the user. The user then has the possibility to click on the error message, which will open the record where the invalid / missing data is located, thereby enabling the user to correct all mistakes efficiently, from one central place and in one go. @@ -31,13 +31,13 @@ By clicking on the error message, the user will be presented with the entity, wh In the processing function, define a temporary record of type "Error Message". Use the functions on that record to populate the record with error message, a few of them being: -* **LogIfEmpty****** -* **LogIfLengthExceeded****** -* **LogIfInvalidCharacters****** -* **LogIfOutsideRange****** -* **LogIfGreaterThan****** -* **LogIfEqualTo****** -* **LogMessage****** +* **LogIfEmpty** +* **LogIfLengthExceeded** +* **LogIfInvalidCharacters** +* **LogIfOutsideRange** +* **LogIfGreaterThan** +* **LogIfEqualTo** +* **LogMessage** The following parameters must be provided to these functions: @@ -52,38 +52,40 @@ When the processing is complete, you can check if any error messages of type "Er The code below is an example of how the error message component was used in one part of the before mentioned Mexican feature. This code iterates over all G/L Accounts and pipes information out into an XML file. While doing so, it is validated that all mandatory fields have values and meet certain conditions. And only if that is the case, is the XML document actually exported. Also notice, that an error message is logged, in case no G/L Accounts are found given the provided filters. That way, the user can be guided to setup the system correctly. +```AL PROCEDURE ExportChartOfAccounts@1(Year@1000 : Integer;Month@1001 : Integer); VAR - **TempErrorMessage@1003 : TEMPORARY Record 700; - **BEGIN - **TempErrorMessage.ClearLog;** // only necessary if variable is global + TempErrorMessage@1003 : TEMPORARY Record 700; + BEGIN + TempErrorMessage.ClearLog; // only necessary if variable is global ... CreateXMLHeader(Document,RootNode,CatalogoNodeTxt,Namespace,Year,Month,'1.1'); IF GLAccount.FINDSET THEN BEGIN - REPEAT - **TempErrorMessage.LogIfEmpty (GLAccount,GLAccount.FIELDNO(Name),TempErrorMessage."Message Type"::Error); - ** - XMLDOMManagement.AddElement(RootNode,'Ctas','',Namespace,Node); - XMLDOMManagement.AddAttribute(Node,'CodAgrup',GLAccount."SAT Account Code"); - ... - CASE GLAccount."Debit/Credit" OF - GLAccount."Debit/Credit"::Debit: - XMLDOMManagement.AddAttribute(Node,'Natur','D'); - GLAccount."Debit/Credit"::Credit: - XMLDOMManagement.AddAttribute(Node,'Natur','A'); - ELSE - **TempErrorMessage.LogMessage( - GLAccount,GLAccount.FIELDNO("Debit/Credit"),TempErrorMessage."Message Type"::Error, - STRSUBSTNO(GLAccountTypeErr,GLAccount."Debit/Credit",GLAccount.RECORDID)); - ** END; - UNTIL GLAccount.NEXT = 0; + REPEAT + TempErrorMessage.LogIfEmpty (GLAccount,GLAccount.FIELDNO(Name),TempErrorMessage."Message Type"::Error); + + XMLDOMManagement.AddElement(RootNode,'Ctas','',Namespace,Node); + XMLDOMManagement.AddAttribute(Node,'CodAgrup',GLAccount."SAT Account Code"); + ... + CASE GLAccount."Debit/Credit" OF + GLAccount."Debit/Credit"::Debit: + XMLDOMManagement.AddAttribute(Node,'Natur','D'); + GLAccount."Debit/Credit"::Credit: + XMLDOMManagement.AddAttribute(Node,'Natur','A'); + ELSE + TempErrorMessage.LogMessage( + GLAccount,GLAccount.FIELDNO("Debit/Credit"),TempErrorMessage."Message Type"::Error, + STRSUBSTNO(GLAccountTypeErr,GLAccount."Debit/Credit",GLAccount.RECORDID)); + END; + UNTIL GLAccount.NEXT = 0; END ELSE - **TempErrorMessage.LogSimpleMessage(TempErrorMessage."Message Type"::Error,NoSATAccountDefinedErr); - ** - **IF NOT TempErrorMessage.HasErrors(TRUE) THEN - ** SaveXMLToClient(Document,Year,Month,'CT'); - **TempErrorMessage.ShowErrorMessages(FALSE); - **END; + TempErrorMessage.LogSimpleMessage(TempErrorMessage."Message Type"::Error,NoSATAccountDefinedErr); + + IF NOT TempErrorMessage.HasErrors(TRUE) THEN + SaveXMLToClient(Document,Year,Month,'CT'); + TempErrorMessage.ShowErrorMessages(FALSE); + END; +``` One could also do pre-processing in a function of its own, and only if the pre-processing results in no error messages of type "Error" would the processing continue. diff --git a/content/NAVPatterns/1-patterns/extending-the-role-center-headlines/index.md b/content/NAVPatterns/1-patterns/extending-the-role-center-headlines/index.md index 4eb35d0b..ef4245f3 100644 --- a/content/NAVPatterns/1-patterns/extending-the-role-center-headlines/index.md +++ b/content/NAVPatterns/1-patterns/extending-the-role-center-headlines/index.md @@ -27,8 +27,7 @@ _ < --\[if gte mso 9\]\>< \[endif\]--\>< --\[if gte mso 9\]\>< \[endif\]--\>< --\[if gte mso 9\]\>< \[endif\]--\>< --\[if gte mso 10\]\> < \[endif\]--\> -_Figure 1: Qualifier, Payload and emphasized text. -_ +_Figure 1: Qualifier, Payload and emphasized text._ ## Usage @@ -149,11 +148,9 @@ To format headlines, you should use Codeunit 1439 Headline Management functions: _Figure 2: Sequence diagram of headline usage_ -## -Usages in NAV: +## Usages in NAV: -* Essential Business Headlines extension_ -_ +* Essential Business Headlines extension < --\[if gte mso 9\]\>< \[endif\]--\>< --\[if gte mso 9\]\>< \[endif\]--\>< --\[if gte mso 9\]\>< \[endif\]--\>< --\[if supportAnnotations\]--\>< --\[endif\]--\>< --\[if gte mso 10\]\> < \[endif\]--\> diff --git a/content/NAVPatterns/1-patterns/feature-localization-for-data-structures/index.md b/content/NAVPatterns/1-patterns/feature-localization-for-data-structures/index.md index 91b01f05..32cdadfa 100644 --- a/content/NAVPatterns/1-patterns/feature-localization-for-data-structures/index.md +++ b/content/NAVPatterns/1-patterns/feature-localization-for-data-structures/index.md @@ -63,6 +63,7 @@ The key question is: Where to tap into this flow when using a local data structu In W1, the codeunit simply outputs the same set of general journal lines that it receives as an input: +```AL OnRun(VAR Rec : Record "Gen. Journal Line") GenJnlLine.COPYFILTERS(Rec); @@ -92,6 +93,7 @@ LOCAL CreateTempJnlLines(VAR FromGenJnlLine : Record "Gen. Journal Line";VAR Tem // To fill TempGenJnlLine from the source identified by filters set on FromGenJnlLine TempGenJnlLine := FromGenJnlLine; +``` In a country, such as Italy, the codeunit will have the following functions: @@ -103,6 +105,7 @@ In a country, such as Italy, the codeunit will have the following functions: 1. Outputs the temporary general journal lines that will be further processed and exported, exactly as in W1\. +```AL OnRun(VAR Rec : Record "Gen. Journal Line") GenJnlLine.COPYFILTERS(Rec); @@ -222,6 +225,7 @@ Description := VendorBillLine.Description; INSERT; END; +``` The derived local feature flow is as follows: diff --git a/content/NAVPatterns/1-patterns/hooks/index.md b/content/NAVPatterns/1-patterns/hooks/index.md index fb22f7c1..45a11bb4 100644 --- a/content/NAVPatterns/1-patterns/hooks/index.md +++ b/content/NAVPatterns/1-patterns/hooks/index.md @@ -8,7 +8,7 @@ _By Eric Wauters ([waldo][anchor0]), Partner-Ready-Software_ As a partner, adding new code to NAV means interfering with code shipped by Microsoft. Minimize your footprint of changes in Microsoft code, so that, when a new NAV version is shipped, you avoid conflicts and upgrade impact. The core NAV code is the "danger zone" - the less you touch it, the happier your upgrade will be. -Description +## Description When doing development over years, by different developers with different mindsets, the standard codebase gets changed a lot, adding multiple lines of code, adding local and global variants, adding or changing keys, changing existing business logic, ... . In other terms, the standard text objects are being changed all over the place.. . @@ -28,42 +28,42 @@ I recommend to use this concept on: ## Usage -Step 1 - if it doesn't exist yet - you create your Hook Codeunit. As the name assumes .. this is always a codeunit. We apply the following rules to it: +**Step 1** - if it doesn't exist yet - you create your Hook Codeunit. As the name assumes .. this is always a codeunit. We apply the following rules to it: * One Hook always hooks into one object. Which basically means that I will only declare this new codeunit in one other object (which is its parent object) * The naming convention is: "The\_Original\_Object\_Name Hook". Naming conventions are important, just to find your mapped object, and also to be able to group the Hooks. -Step 2, you create the hook, which is basically a method (function) in your codeunit. The naming is important: +**Step 2**, you create the hook, which is basically a method (function) in your codeunit. The naming is important: * The naming of the hook should NOT describe what it is going to do (So, examples like "CheckMandatoryFields", "FillCustomFields" should not be used as a hook) * The naming of the hook should describe WHERE the hook is placed, not what the hook will be doing (as nobody is able to look into the future .. :-)) * To help with the naming, it is a good convention to use the "On"-prefix for these triggers. This way, it's very clear what are hooks, and what aren't.. -Step 3, it's time to hook it to its corresponding object and right place in the business logic of that object. You do this by declaring your codeunit as a global in your object, and using the created hook function on its place in the business logic. This way, these one-liners apply: +**Step 3**, it's time to hook it to its corresponding object and right place in the business logic of that object. You do this by declaring your codeunit as a global in your object, and using the created hook function on its place in the business logic. This way, these one-liners apply: * A Hook Codeunit is only used once in one object only (its corresponding object) * A Hook (function) is used only once in that object. As a consequence, changing the parameters has no consequence: you only need to change one function-call * The codeunit is declared as a global. That exact global is the only custom declaration in the existing object .. Everything else is pushed to the hook-codeunit. -Step 4, implement your business logic in the hook. Do this in the most atomic way, as there is a good chance that this same hook is going to be used for other business logic as well. Best is to use a one-line-function-call to business logic, so that the Hook Function itself stays readable. +**Step 4**, implement your business logic in the hook. Do this in the most atomic way, as there is a good chance that this same hook is going to be used for other business logic as well. Best is to use a one-line-function-call to business logic, so that the Hook Function itself stays readable. ## Example Suppose, we want to add business logic just before posting a sales document. In that case, we have to look for the most relevant place, which is somewhere in the "Sales-Post" codeunit. So: -Step 1: create codeunit "Sales-Post Hook" +**Step 1**: create codeunit "Sales-Post Hook" [![ ][image0]][anchor1] -Step 2: create the hook function "OnBeforePostDocument" +**Step 2**: create the hook function "OnBeforePostDocument" [![ ][image1]][anchor2] -Step 3: declare a global in the "Sales-Post"-codeunit, called "SalesPostHook". Then, call the Hook Function that you created in Step 2 in the right place. +**Step 3**: declare a global in the "Sales-Post"-codeunit, called "SalesPostHook". Then, call the Hook Function that you created in Step 2 in the right place. [![ ][image2]][anchor3] -Step 4: implement the business logic, by calling out to a new function. And implement the test-codeunit. +**Step 4**: implement the business logic, by calling out to a new function. And implement the test-codeunit. [![ ][image3]][anchor4] diff --git a/content/NAVPatterns/1-patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/index.md b/content/NAVPatterns/1-patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/index.md index dedca119..ee83d4f6 100644 --- a/content/NAVPatterns/1-patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/index.md +++ b/content/NAVPatterns/1-patterns/implementation-of-surrogate-keys-using-autoincrement-pattern/index.md @@ -2,7 +2,7 @@ title = "Surrogate keys using Autoincrement Pattern" weight = 630 +++ -_By [Soren Klemmensen][anchor0], [_Partner-Ready-Software_ ][anchor1]& [360 Visibility][anchor2]_ +_By [Soren Klemmensen][anchor0], [_Partner-Ready-Software_ ][anchor1] & [360 Visibility][anchor2]_ ## **Abstract** @@ -137,7 +137,7 @@ Other risks could be if Transfer Fields are used and data is being copied uninte This is a new pattern not currently used in Microsoft Dynamics NAV. -## **Ideas for improvement ****** +## **Ideas for improvement** The reason for doing it this way is that you now can reuse your code again and again with only creating the same link on other tables instead of building it from scratch each time reducing testing needed and improving the quality of the overall product. diff --git a/content/NAVPatterns/1-patterns/instructions-in-the-ui/index.md b/content/NAVPatterns/1-patterns/instructions-in-the-ui/index.md index 319ed005..5e768c32 100644 --- a/content/NAVPatterns/1-patterns/instructions-in-the-ui/index.md +++ b/content/NAVPatterns/1-patterns/instructions-in-the-ui/index.md @@ -42,7 +42,7 @@ Dismissible dialogs show the instructional message about the functionality, with On a recent usability study of the **Description** field on sales or purchase lines, most users ignored the **No.** field and started entering text in the description field before proceeded to enter a quantity. In the solution in question, text only is treated as a line comment if the **No.** field is blank. The fix was to update the field name to **Description/Comment** and to provide a message that typing in the field creates a comment only. Users that often use comments can then choose "Do not show again" to get rid of the instructional text. -**When to use: **Recommendation is to use only when many users are entering data in the wrong way and modifying the code is costly. This is an interrupting dialog, but the benefits are that it is very hard to overlook this dialog. +**When to use:** Recommendation is to use only when many users are entering data in the wrong way and modifying the code is costly. This is an interrupting dialog, but the benefits are that it is very hard to overlook this dialog. ## FastTabs with Instructional Text @@ -76,21 +76,21 @@ Example of the embed code: