Friday, December 9, 2016

Vendor Approval Workflows added in NAV 2017

New Workflows added in NAV 2017


Hi All,
    Today i came with amazing article in NAV 2017.

First of all, I would like to say thanks to NAV developers to add the amazing workflow templates.
Guys, I don’t know about you but earlier I developed one Item Approval workflow in NAV 2016 for production, and I know the cost, but now it’s a standard functionality added by NAV itself, and that's why i would like to share with you all.
The new templates are:
Ø Vendor Approval Workflow.
Ø Item Approval Workflow.
Ø Item Unit Price Change Approval Workflow.
See the bellow screenshot for better understanding.




Walkthrough: Implementing Workflow Events and Responses

Introduction

Microsoft Dynamics NAV Workflows enable you to model real-life business processes like best practices or industry-standard practices. Ensuring a customer’s credit limit has been independently verified or requiring a two-person approval for a significant vendor payment are both examples of these.  Workflow can be thought of as the movement of documents or tasks through a work process. Workflows in Dynamics NAV focus on three main building blocks and almost any workflow process, short or long, is likely to be comprised of steps related to these three blocks.  They are:
·         Approval, approval leaves a work task, item or document in an blocked or unapproved state until approved by a suitable person in your organization
·         Notification, notifications tell users that something has happened and/or that they need to take some kind of action
·         Process automation, process automation means executing a process routine and have the Dynamics NAV system calculate something or perform an action

The workflows in Dynamics NAV are represented by Workflow Events and Responses.  The smallest workflow is the pairing of a single Event and a Response.  Simple workflows could be
·         When a new customer is created, email the sales person responsible for that region to alert them to the new customer.
·         When a new vendor is created, email the purchaser person responsible for that region to alert them to the new vendor.
·         When a purchase invoice exceeds $250, email the financial controller to alert them

More complex workflows are built of chains of events and responses.  Examples could be
·         When a Purchase Invoice exceeds $250, put the purchase invoice on hold until it is approved by a manager.
·         When new customers are created, block them until they have had a credit check performed.
·         Once a purchase document has been approved by the accounting manager, automatically post it to the Dynamics NAV system.

Note: in all the examples above, you can see a “when something happens, do something” pattern.  This is the “Event and Response” model and is the simple but effective design behind Dynamics NAV workflows.

Events and Workflow Events

Perhaps confusingly, Dynamics NAV 2016 introduces two new event concepts.  Events and Workflow events.  The two are distinct but often coupled together to build solutions.  Dynamics NAV Events allow you to write code which will be called when an event occurs – this is called subscribing to an event.  An example could be to subscribe to the OnCreate trigger for a table and writing code which will be called whenever a new record is created.
Workflow Events typically use Platform Events as their trigger, but are richer.  Workflow events are registered in the workflow engine and show up in the workflow designer.  Microsoft recommends that Workflow events be written at a higher level of abstraction than Platform Events, for example while OnCreateNewCustomerRecord makes a suitable platform event, a good workflow event could be AfterOverduePaymentIsPosted.

Scenarios

Demo 1 - Enable the workflow & response in the NAV system

The scenario of this part of the demo script is to show managing workflow events & responses from a Dynamics NAV system to build a workflow.  This task is typically performed by super users.
AIM:    Create a workflow from Workflow template for Vendor creation.
Demo 1 — Enable the workflow event in the NAV system
Managing workflow events from a Dynamics NAV system.  An entire workflow is comprised of binding a Workflow Event and a Response together and then enabling it.
This Setup can be done from Workflows, or Workflows Templates.
In My demo, I used workflows.
Follow the bellow steps to achieve earlier aim.
Ø  Create users, [See the bellow screenshot for better understanding].







Ø  Create Approval User Setup and Notification Setup, [See the bellow screenshot for better understanding].




Note:            You have to also setup SMTP mail setup for sending Mail.
                     In NAV 2017 NAS/Job queue must be start from services, unlike NAV 2016.



Ø Type workflows in search box and select the relevant link, Click the “New Workflow from Template” action from Home Tab under New Group.
Ø  A Workflow Template Dialog Box will appear, now expand the “Purchase and Payables” Category and select the “Vendor Approval Workflow”, [See the bellow screenshot for better understanding].





Ø  Now MS-VENDAPW-01 Vendor Approval Workflow window will display, now you can give your condition but in my case I didn’t give because I need whenever a vendor will be created by SATYANARAYNA user that time I need a notification to BINESH.SINGH for Approval the Vendor.
Ø  Make enabled true to run the workflow, See the bellow screenshot for better understanding.




Ø  Once the workflow created and enabled it looks like





Ø  Testing the workflow: Login with SATYANARAYANA.V user and create a new vendor, send the Approval request.







Now See the bellow screenshot for Approval request got the BINESH.SINGH User.



Now he can able to Approve, Reject, Delegate also he can see the Record by clicking the Open Record.
Ø  I already setup for emailing also for user BINESH.SINGH, So he got mail, See the bellow screenshot for better understanding.









Friday, October 21, 2016

DATA MIGRATION IN NAV 2016 FROM NAV 2009

DATA MIGRATION IN NAV 2016 FROM NAV 2009
Hi all,
Today i came across with different type of requirement, Sometimes we need to move/Copy our NAV data from one Database to others, OR One server to other server.
we can do this task using "Departments -> Administration -> Application Setup -> RapidStart Services for Microsoft Dynamics NAV -> Config. Package Card.
Note: In this scenario, BLOB fields are not copied, Due to overcome this we have to do using SQL Server.
But Now today i am going to talk about Data migration using Rapid Start Services.
Look guys, Earlier we are simply Export the Excel format and Import it, but in NAV 2016 if we go for import we will get exception, see the bellow screenshot.



To Overcome this we need to customize our NAV 2009 Objects, But before going i just want to tell you why this issue came.
See the bellow screenshot of NAV 2016 Excel file, there i marked PackageCode that are added.



You can also check NAV 2009 Excel, In that you can’t find PackageCode.
So now our job to add this PackageCode in NAV 2009 Excel file, To do this we have to customize several objects, these are as:
                Table ID                :               8613, 8614, 8615, 8616
                Form ID                                :               8614
                XmlPort ID          :               8610
                Codeunit ID        :               8611
                                In this Codeunit we have to upgrade 2 functions, these are as:
ExportSetupDataToExcel
CreateRecordNodes
Step 1:  Add the PackageCode field of type Code in Tables 8613, 8614, 8615, 8616.
In Table 8614 and 8615 give the Table relation to 8613 i.e. ”Migration Table”.
After adding the field write code for initializing the PackageCode, See the bellow screenshot.

               



Step 2:  Add codes in Codeunit 8611 ”Migration Management”, in this codeunit we have to upgrade two function as earlier i discussed. These are
                                ExportSetupDataToExcel
CreateRecordNodes
See the bellow screenshot for added code.



Find the ExportSetupDataToExcel function and update as like in screenshot.



Now update the second function i.e. ”CreateRecordNodes”, See the bellow screenshot
Note:    In Both images only the customize code, remaing Upper and lower code as in standard.
                Just match the code something like:
For ExportDataSetupToExcel find the CreateBook and start writting from screenshot, because some code are removed.
Also go thru something like other function called ”CreateRecordNodes”.





Now Compile, Save, Exit from this codeunit.

Step 3:  In this step we are going to upgrade XmlPort 8610 "Setup Data Schema" something like NAV 2016.
Design  XmlPort 8610 "Setup Data Schema" and upgrade as it is in bellow screenshot.



After designing the Xmlport Open the CAL Editor in this Xmlport only. And make changes



Now Compile, Save, and exit from this Xmlport.
Step 4:  Upgrade the Form 8614 ”Migration Overview” , Add the PackageCode field, so we can export.
See the bellow screenshot for Form, and update as it is.




Compile, Save & Exit from this form.

Step 5:  Now export the Data from Data migration, see the bellow screenshot.



Note: Whatever you given here PackageCode value that you need to give in NAV 2009.
Also remeber onething still it create a .xls file, So you have to just open and save as .xlsx format.
Also remeber one thing, if you are going to export multiple tables then you have to delete manually Sheet1 from exported file, it creates by default sheet1 extra. So to avoid exception delete manually sheet1.
See the bellow screenshot for exported excel file from NAV 2009 after upgraded.
Once the file is exported and save as with .xlsx, then you can import in NAV 2016 directly.


                                                       

Step 6 :                                         Now i am going to import this file. See the bellow screenshot.











Wednesday, October 5, 2016

Creating/Populating the Sales & Purchase Journal from Ledger/Buffer Table in NAV

Hi all,
Today i came across with different type of requirement, Sometimes we need to populate/Create Journals thru codding.


Bellow are the whole codeunit with business logic.

OBJECT Codeunit 50081 Populate Journals
{
  OBJECT-PROPERTIES
  {
    Date=10/05/16;
    Time=[ 6:33:05 AM];
    Modified=Yes;
    Version List=Sbinesh;
  }
  PROPERTIES
  {
    OnRun=BEGIN
            CLEARLASTERROR;
            IF NOT PopulateSalesJournal THEN
              ERROR('Not populated, for more info read bellow lines\\%1',GETLASTERRORTEXT);
            IF NOT PopulatePurchaseJournal THEN
              ERROR('Not populated, for more info read bellow lines\\%1',GETLASTERRORTEXT);
          END;

  }
  CODE
  {

    [TryFunction]
    PROCEDURE PopulateSalesJournal@1000000000();
    VAR
      GenJournalTemplate@1000000006 : Record 80;
      GenJournalLine@1000000005 : Record 81;
      GenJournalBatch@1000000004 : Record 232;
      CustLedgerEntry@1000000003 : Record 21;
      CustLedgerEntryBuffer@1000000002 : Record 80021;
      GenJournalTemplateName@1000000001 : Text;
      GenJournalBatchName@1000000000 : Text;
      LineNo@1000000007 : Integer;
      MyDialog@1000000008 : Dialog;
      CountL@1000000009 : Integer;
    BEGIN
      IF GenJournalTemplate.GET('SALES') THEN
        GenJournalTemplateName := GenJournalTemplate.Name;

      IF GenJournalBatch.GET(GenJournalTemplateName,'DEFAULT') THEN
        GenJournalBatchName := GenJournalBatch.Name;

      CustLedgerEntryBuffer.RESET;
      IF CustLedgerEntryBuffer.FINDSET THEN BEGIN
        GenJournalLine.RESET;
        GenJournalLine.SETRANGE(GenJournalLine."Journal Template Name",GenJournalTemplateName);
        GenJournalLine.SETRANGE(GenJournalLine."Journal Batch Name",GenJournalBatchName);
        IF GenJournalLine.FINDLAST THEN
          LineNo := GenJournalLine."Line No."
        ELSE
          CLEAR(LineNo);
        MyDialog.OPEN('Record populating... #1###############');
        REPEAT
          LineNo += 10000;
          GenJournalLine.INIT;
          GenJournalLine.VALIDATE(GenJournalLine."Journal Template Name",GenJournalTemplateName);
          GenJournalLine.VALIDATE(GenJournalLine."Journal Batch Name",GenJournalBatchName);
          GenJournalLine.VALIDATE("Line No.",LineNo);
          GenJournalLine.VALIDATE(GenJournalLine."Posting Date",CustLedgerEntryBuffer."Posting Date");
          GenJournalLine.VALIDATE(GenJournalLine."Document Type",CustLedgerEntryBuffer."Document Type");
          GenJournalLine.VALIDATE(GenJournalLine."Document No.",CustLedgerEntryBuffer."Document No.");
          GenJournalLine.VALIDATE(GenJournalLine."Account Type",GenJournalLine."Account Type"::Customer);//Bcoz in Buffer table 1 option is there.
          GenJournalLine.VALIDATE(GenJournalLine."Account No.",CustLedgerEntryBuffer."Account No.");
          GenJournalLine.VALIDATE(GenJournalLine.Description,CustLedgerEntryBuffer.Description);
          GenJournalLine.VALIDATE(GenJournalLine.Amount,CustLedgerEntryBuffer."Remaining Amount");
          GenJournalLine.VALIDATE(GenJournalLine."Bal. Account Type",GenJournalLine."Bal. Account Type"::"G/L Account");
          GenJournalLine.VALIDATE(GenJournalLine."Bal. Account No.",'31040');
          GenJournalLine.VALIDATE(GenJournalLine."External Document No.",CustLedgerEntryBuffer."External Document No.");
          GenJournalLine.VALIDATE(GenJournalLine."Due Date",CustLedgerEntryBuffer."Due Date");
          GenJournalLine.VALIDATE(GenJournalLine."Document Date",CustLedgerEntryBuffer."Document Date");
          GenJournalLine.VALIDATE(GenJournalLine."Territory Code",CustLedgerEntryBuffer."Territory Code");
          GenJournalLine.VALIDATE(GenJournalLine."Ship-to Territory Code",CustLedgerEntryBuffer."Ship-to Territory Code");
          GenJournalLine.VALIDATE(GenJournalLine."Salespers./Purch. Code",CustLedgerEntryBuffer."Salesperson Code");
          GenJournalLine.VALIDATE(GenJournalLine."Ship-to Salesperson Code",CustLedgerEntryBuffer."Ship-to Salesperson Code");
          GenJournalLine.VALIDATE(GenJournalLine."Mark Text",CustLedgerEntryBuffer."Mark Text");
          GenJournalLine.VALIDATE(GenJournalLine."Payment Terms Code",CustLedgerEntryBuffer."Payment Terms Code");
          GenJournalLine.INSERT(TRUE);
          CountL += 1;
          MyDialog.UPDATE(1,CountL);
        UNTIL CustLedgerEntryBuffer.NEXT = 0;
      END;
      MyDialog.CLOSE();
      MESSAGE('[%1] record(s) populated!',CountL);
    END;

    [TryFunction]
    PROCEDURE PopulatePurchaseJournal@1000000002();
    VAR
      GenJournalTemplate@1000000006 : Record 80;
      GenJournalLine@1000000005 : Record 81;
      GenJournalBatch@1000000004 : Record 232;
      VendorLedgerEntry@1000000003 : Record 25;
      VendorLedgerEntryBuffer@1000000002 : Record 80025;
      GenJournalTemplateName@1000000001 : Text;
      GenJournalBatchName@1000000000 : Text;
      LineNo@1000000007 : Integer;
      MyDialog@1000000008 : Dialog;
      CountL@1000000009 : Integer;
    BEGIN
      IF GenJournalTemplate.GET('PURCHASES') THEN
        GenJournalTemplateName := GenJournalTemplate.Name;

      IF GenJournalBatch.GET(GenJournalTemplateName,'DEFAULT') THEN
        GenJournalBatchName := GenJournalBatch.Name;

      VendorLedgerEntryBuffer.RESET;
      IF VendorLedgerEntryBuffer.FINDSET THEN BEGIN
        GenJournalLine.RESET;
        GenJournalLine.SETRANGE(GenJournalLine."Journal Template Name",GenJournalTemplateName);
        GenJournalLine.SETRANGE(GenJournalLine."Journal Batch Name",GenJournalBatchName);
        IF GenJournalLine.FINDLAST THEN
          LineNo := GenJournalLine."Line No."
        ELSE
          CLEAR(LineNo);
        MyDialog.OPEN('Record populating... #1###############');
        REPEAT
          LineNo += 10000;
          GenJournalLine.INIT;
          GenJournalLine.VALIDATE(GenJournalLine."Journal Template Name",GenJournalTemplateName);
          GenJournalLine.VALIDATE(GenJournalLine."Journal Batch Name",GenJournalBatchName);
          GenJournalLine.VALIDATE("Line No.",LineNo);
          GenJournalLine.VALIDATE(GenJournalLine."Posting Date",VendorLedgerEntryBuffer."Posting Date");
          GenJournalLine.VALIDATE(GenJournalLine."Document Type",VendorLedgerEntryBuffer."Document Type");
          GenJournalLine.VALIDATE(GenJournalLine."Document No.",VendorLedgerEntryBuffer."Document No.");
          GenJournalLine.VALIDATE(GenJournalLine."Account Type",GenJournalLine."Account Type"::Vendor);
          GenJournalLine.VALIDATE(GenJournalLine."Account No.",VendorLedgerEntryBuffer."Account No.");
          GenJournalLine.VALIDATE(GenJournalLine.Description,VendorLedgerEntryBuffer.Description);
          GenJournalLine.VALIDATE(GenJournalLine.Amount,VendorLedgerEntryBuffer."Remaining Amount");
          GenJournalLine.VALIDATE(GenJournalLine."Bal. Account Type",GenJournalLine."Bal. Account Type"::"G/L Account");
          GenJournalLine.VALIDATE(GenJournalLine."Bal. Account No.",'31040');
          GenJournalLine.VALIDATE(GenJournalLine."External Document No.",VendorLedgerEntryBuffer."External Document No.");
          GenJournalLine.VALIDATE(GenJournalLine."Due Date",VendorLedgerEntryBuffer."Due Date");
          GenJournalLine.VALIDATE(GenJournalLine."Document Date",VendorLedgerEntryBuffer."Document Date");
          GenJournalLine.VALIDATE(GenJournalLine."Payment Terms Code",VendorLedgerEntryBuffer."Payment Terms Code");
          GenJournalLine.VALIDATE(GenJournalLine."Salespers./Purch. Code",VendorLedgerEntryBuffer."Purchaser Code");
          GenJournalLine.INSERT(TRUE);
          CountL += 1;
          MyDialog.UPDATE(1,CountL);
        UNTIL VendorLedgerEntryBuffer.NEXT = 0;
      END;
      MyDialog.CLOSE();
      MESSAGE('[%1] record(s) populated!',CountL);
    END;

    BEGIN
    {
      October, 05 2016 :  This codeunit is developed for creating the Sales & Purchase Journal from buffer table.
                          Cust. Ledger Entry Buffer table contains the mandatory fields from Cust. Ledger Entry.
                          Vendor Ledger Entry Buffer table contains the mandatory fields from Vendor Ledger Entry.
      Solution Developed by Binesh Singh Rajput
    }
    END.
  }
}


You can download this solution from here.
 

Popular Posts