Monday, August 8, 2022

How to consume web service on Navision 5.0

 Based on walkthrough from Microsoft (https://docs.microsoft.com/en-us/dynamics-nav/walkthrough--creating-and-using-a-codeunit-web-service--soap-), it will consume the web service by creating .NET application. I would like to consume it from Navision 5.0 and the pseudocode as follows:

WinHttp

DataType = Automation

Subtype = 'Microsoft WinHTTP Services, version 5.1'.WinHttpRequest


IF ISCLEAR(WinHttp) THEN

   CREATE(WinHttp);

XMLHttp.open('POST','http://<localhostname>/DynamicsNAV110/WS/CRONUS%20International%20Ltd./Codeunit/Letters');

XMLHttp.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');

XMLHttp.setRequestHeader('SOAPAction','Capitalize');


XMLHttp.send(

  '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' +

  '<soap:Body><' + 'Capitalize' + ' xmlns="urn:microsoft-dynamics-schemas' + '/codeunit/Letters' + '">' +

  '<inputstring>'+'testmessage'+'</inputstring>' +  // Parameter 1

  '</' + 'Capitalize' + '></soap:Body></soap:Envelope>');


// If status is OK - Get Result XML

IF XMLHttp.status=200 THEN

BEGIN

XMLDoc.load(XMLHttp.responseXML);

XMLDoc.save('D:\XMLResponse1.xml');

END;

CLEAR(XMLHttp);


Note. Dynamic way to construct XML request message is using the following method (https://freddysblog.com/2010/01/21/connecting-to-nav-web-services-from-microsoft-dynamics-nav-2009-sp1/)


Important!!!

'Microsoft XML, v6.0'.DOMDocument60 >> issue on blank "xmlns" so that need to use 'Microsoft XML, v3.0'.DOMDocument30 instead. 

<Soap:Envelope xmlns:Soap="http://schemas.xmlsoap.org/soap/envelope/">

<Soap:Body>

<Capitalize xmlns="urn:microsoft-dynamics-schemas/codeunit/Letters">

<inputstring xmlns="">Hello test capital</inputstring>

</Capitalize>

</Soap:Body>

</Soap:Envelope>


Sample codes for dynamic way:

Var Name                     DataType Subtype Length

No URL                     Text                 250

No method                     Text                 20

No nameSpace             Text                 80

No returnTag                     Text                 20

No parameters             Text                 1024

No nodeList                     Automation 'Microsoft XML, v3.0'.IXMLDOMNodeList


Return Value

Name = result

Return Type = Boolean


 Name                           DataType    Subtype 

 xmlhttp                        Automation 'Microsoft XML, v6.0'.XMLHTTP60

 xmldoc                        Automation 'Microsoft XML, v3.0'.DOMDocument30

 soapEnvelope             Automation 'Microsoft XML, v3.0'.IXMLDOMElement

 soapBody                    Automation 'Microsoft XML, v3.0'.IXMLDOMElement

 soapMethod                Automation 'Microsoft XML, v3.0'.IXMLDOMElement

 node                            Automation 'Microsoft XML, v3.0'.IXMLDOMNode

 parametersXmlDoc    Automation 'Microsoft XML, v3.0'.DOMDocument30


Res    := InvokeNavWS(

          'http://<localhostname>/DynamicsNAV110/WS/CRONUS%20International%20Ltd./Codeunit/Letters',

          'Capitalize', 

          'urn:microsoft-dynamics-schemas/codeunit/Letters',

           'return_value',

           '<inputstring>Hello test capital</inputstring>', nodeList);

           //'', nodeList);


InvokeNavWS Function:


result := FALSE;


// Create XML Document

CREATE(xmldoc,TRUE);


// Create SOAP Envelope

soapEnvelope := xmldoc.createElement('Soap:Envelope');

soapEnvelope.setAttribute('xmlns:Soap', 'http://schemas.xmlsoap.org/soap/envelope/');

xmldoc.appendChild(soapEnvelope);


// Create SOAP Body

soapBody := xmldoc.createElement('Soap:Body');

soapEnvelope.appendChild(soapBody);


// Create Method Element

soapMethod := xmldoc.createElement(method);

soapMethod.setAttribute('xmlns', nameSpace);

soapBody.appendChild(soapMethod);


// Transfer parameters by loading them into a XML Document and move them

CREATE(parametersXmlDoc,TRUE);

parametersXmlDoc.loadXML('<parameters>'+parameters+'</parameters>');

IF parametersXmlDoc.firstChild.hasChildNodes THEN

BEGIN

  WHILE parametersXmlDoc.firstChild.childNodes.length>0 DO

  BEGIN

    node := parametersXmlDoc.firstChild.firstChild;

    node := parametersXmlDoc.firstChild.removeChild(node);

    soapMethod.appendChild(node);

  END;

END;


xmldoc.save('D:\XMLRequest.txt');


// Create XMLHTTP and SEND

CREATE(xmlhttp, TRUE);

xmlhttp.open('POST',URL,FALSE);

xmlhttp.setRequestHeader('Content-type', 'text/xml; charset=utf-8');

xmlhttp.setRequestHeader('SOAPAction',method);


xmlhttp.send(xmldoc);


MESSAGE(FORMAT(xmlhttp.status) + ' ' + xmlhttp.statusText);


// If status is OK - Get Result XML

IF xmlhttp.status=200 THEN

BEGIN

  //xmldoc := xmlhttp.responseXML;


  //get the response

  xmldoc.load(xmlhttp.responseXML);

  xmldoc.setProperty('SelectionLanguage','XPath');

  xmldoc.setProperty('SelectionNamespaces','xmlns:tns="'+nameSpace+'"');

  nodeList := xmldoc.selectNodes('//tns:'+returnTag);


  nodeList := xmldoc.getElementsByTagName('return_value');

  FOR i:=0 TO nodeList.length()-1 DO BEGIN

    MESSAGE(nodeList.item(i).text);

  END;


  //this is for diagnostics only, so you can see what you got back

  xmldoc.save('D:\XMLResponse1.xml');


  result := TRUE;

END;

Thursday, April 7, 2022

Irritating error after posting transaction

 

Today I encounter irritating error after posting document. it happens when there is only 1 order document (due to some filters based on company's requirement). 

The Sales Header does not exist ...



The proposed solution:
Use CurrForm.CLOSE once posting is done so that the error will not prompt anymore.
However, if the order document is more than 1 order, just bypass CurrForm.CLOSE




Sunday, March 13, 2022

NAS Error: MMC could not create the Snap-In

 Copied from: Microsoft Dynamics Corner blogger

After Successful installation of NAS, the following error message appears when we try to open the NAS Snap-In.

MMC cannot initialize the snap-in.

Name: Application Server for Microsoft Dynamics NAV Manager


CLSID: {50000003-0000-1000-0001-0000836BD2D2}


We tried the following Solution and it works fine for us.

Solution:
  1. Install NAS
  2. Go to the NAS Installed folder in the Local Drive (By Default: C:\Program Files\Microsoft Dynamics NAV\60\Application Server).
  3. Check whether NAS.exe and NASSQL.exe is available in the folder and then look for the NASM.dll
  4. Register the NASM.dll.
  5. Go to Command Prompt. Run the Command Prompt as administrator
  6. Go to the folder C:\Program Files\Microsoft Dynamics NAV\60\Application Server
  7. Now Type regsvr32 NASM.dll to successfully register
  8. Now open the NAS Snap-In without any error.

Monday, April 10, 2017

Home Delivery Management System - Navision - LS Retail

In last December 2016, I was assigned Home Delivery Management System project. I wrote this blog to memorize what I've done and to appreciate myself that I can do something even though I'm not a smart person. As Albert Einstein said "I have no special TALENTS. I am only passionately CURIOUS". I'm not an expert in Navision but when I'm focused doing something, I can make it right. Home Delivery project is created from the scratch and I'm totally focused to finish it from Zero. 

Basically, the workflow is quite simple. There are Self Registration Kiosk Counter and Customer Service Counter. When customer would like to do a delivery, customer will go to Self Registration Kiosk Counter to scan the receipt bar-code, register their particulars (name, address, phone number, etc), and system will estimate the charge based on their location and calculate the delivery date. After customer confirm the registration, system will print a slip with queue number. 

Customer Service Counter will call the customer based on the queue number and do confirmation with customer about the particulars and will start packing the item and put it all into the box. After Customer Service person know how many box is needed, he/she will input into the system and ask the system to print the label for the box. This application will improve the efficiency, productivity, and accuracy. Previously, Customer Service need to write customer address on the box manually. It's tedious job, time consuming, and many mistakes occurred. Finally, of course, an acknowledgement document is printed and signed by customer.

Both Self Registration Kiosk Counter  and Customer Service Counter interface was built by using Microsoft Dynamics Navision - LS Retail. User friendly is important part  on Self Registration Kiost Counter so that customers are able to use it easily. 


On the picture above, there are 2 Self Registration Kiosk Counters and 2 Customer Service Counters.

Wednesday, August 10, 2016

Error on Data Director: ConnectServerAndOpenDatabase Can not initialize automation server

I would like to record this error and the solution for my reference in future. We encounter this error when run the scheduler job by schedule, however if we run the scheduler job manually, it works perfectly.

This is the complete error on Data Director:
"PlusCFrontClient: ConnectServerAndOpenDatabase Can not initialize automation server\Program returned error"

Solution:
Choose the lowest notification level on User Account Control Setting (Windows)

SSIS - Use Script Task to send Email (HTML Message Body format)

On this session, I would like to write a simple document about how to send email by using SSIS - Script Task. Initially, I want to use "Send Mail Task" in SSIS, however, the message body is a plain text so that I can't do message body formatting (e.g. give a link on email body, bold text, italic text, etc). I hope in future SSIS version give us an option to use plain text or HTML format.

These are the steps:

1. On SSDT, drag Script Task from toolbox and set the name "Script Task - Send Email"
2. Create new SMTP Connection Manager and set the name "My SMTP Server"

















3. Create 4 new variables
EmailBody value :
Hi All,<br><br><b>This</b> message body is using HTML format.<br><br>Regards,<br>abc<br><i>Generated by using SSIS</i>




















4. Double click Script Task to open Script Task Editor. On "ReadOnlyVariables", input 4 new created variables




















5. Click "Edit Script" on Script Task Editor to bring you to go to Visual Studio




















6. Add the script as following: (I'm using C#)

#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Net.Mail;  //Add Mail Reference
#endregion

...

public void Main()
{                             
//Get information from variables
String EmailFrom = Dts.Variables["EmailFrom"].Value.ToString();
String EmailTo = Dts.Variables["EmailTo"].Value.ToString();
String EmailSubject = Dts.Variables["EmailSubject"].Value.ToString();
String EmailBody = Dts.Variables["EmailBody"].Value.ToString();
String mySmtpServer = Dts.Connections["My SMTP Server"].Properties["SmtpServer"].GetValue(Dts.Connections["My SMTP Server"]).ToString();

//Create an email and change the format to HTML
MailMessage myHtmlEmail = new MailMessage(EmailFrom, EmailTo, EmailSubject, EmailBody);
myHtmlEmail.IsBodyHtml = true;

//Create a SMTP client to send the email
SmtpClient mySmtpClient = new SmtpClient(mySmtpServer);
//mySmtpClient.Port = 25; //Default Port
mySmtpClient.Send(myHtmlEmail);

Dts.TaskResult = (int)ScriptResults.Success;
}



7. Close Visual Studio and go back to Script Task Editor. Dont forget to click "OK"
8. It's ready to run the script


















9. The result on Email: