A DotNet Interop Soap Web Request

I am currently working on a solution that requires a Dynamics NAV client to communicate with Dynamics NAV web service.  This I have done before with the classic client and have used automation objects for the job.  Now I wanted to do this with dotnet only objects in the Role Tailored Client.  Took some time to put all things together but here it is.  This version is running the request from the client.

OBJECT Codeunit 50027 IC Addon Inbox WebService
{
  OBJECT-PROPERTIES
  {
    Date=09.04.14;
    Time=17:28:02;
    Modified=Yes;
    Version List=IC7.10;
  }
  PROPERTIES
  {
    OnRun=BEGIN
          END;

  }
  CODE
  {

    PROCEDURE LoadTransaction@1100408001(FromPartnerCode@1100408004 : Code[20];FromRespCenterCode@1100408005 : Code[10];ToPartnerCode@1100408006 : Code[20];ToRespCenterCode@1100408007 : Code[10];Transaction@1100408000 : BigText;PDFInvoice@1100408001 : BigText;PDFDetails@1100408002 : BigText;XMLInvoice@1100408003 : BigText;VAR ResponseMessage@1100408009 : Text) Success : Boolean;
    VAR
      Loader@1000000000 : Codeunit 50019;
      TransactionStream@1000000014 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.MemoryStream";
      PDFInvoiceStream@1000000016 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.MemoryStream";
      PDFDetailsStream@1000000015 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.MemoryStream";
      XMLInvoiceStream@1000000013 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.MemoryStream";
    BEGIN
      TransactionStream := TransactionStream.MemoryStream;
      PDFInvoiceStream := PDFInvoiceStream.MemoryStream;
      PDFDetailsStream := PDFDetailsStream.MemoryStream;
      XMLInvoiceStream := XMLInvoiceStream.MemoryStream;
      IF Transaction.LENGTH > 0 THEN
        Transaction.WRITE(TransactionStream);
      IF PDFInvoice.LENGTH > 0 THEN
        PDFInvoice.WRITE(PDFInvoiceStream);
      IF PDFDetails.LENGTH > 0 THEN
        PDFDetails.WRITE(PDFDetailsStream);
      IF XMLInvoice.LENGTH > 0 THEN
        XMLInvoice.WRITE(XMLInvoiceStream);

      Loader.SetProperties(
        FromPartnerCode,
        FromRespCenterCode,
        ToPartnerCode,
        ToRespCenterCode,
        TransactionStream,
        PDFInvoiceStream,
        PDFDetailsStream,
        XMLInvoiceStream,
        Transaction.LENGTH > 0,
        PDFInvoice.LENGTH > 0,
        PDFDetails.LENGTH > 0,
        XMLInvoice.LENGTH > 0);

      IF Loader.RUN THEN
        EXIT(TRUE)
      ELSE BEGIN
        ResponseMessage := GETLASTERRORTEXT;
        EXIT(FALSE);
      END;
    END;

    BEGIN
    END.
  }
}
OBJECT Codeunit 50028 IC Addon Web Service Client
{
  OBJECT-PROPERTIES
  {
    Date=08.03.15;
    Time=16:01:05;
    Modified=Yes;
    Version List=IC7.10.0432;
  }
  PROPERTIES
  {
    OnRun=BEGIN
          END;

  }
  CODE
  {
    VAR
      Text001@1000000019 : TextConst 'ENU=Succesfully delivered;ISL=Sending hepnaÐist';
      Text003@1100408001 : TextConst 'ENU=Error: %1\%2;ISL=St”Ðuvilla: %1\%2';
      Credential@1000000015 : DotNet "'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Net.NetworkCredential";
      HttpWebRequest@1000000014 : DotNet "'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Net.HttpWebRequest";
      HttpWebResponse@1000000013 : DotNet "'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Net.WebResponse";
      HttpWebException@1000000017 : DotNet "'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Net.WebException";
      MemoryStream@1000000012 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.MemoryStream";
      XMLRequestDoc@1000000011 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlDocument";
      XMLResponseDoc@1000000010 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlDocument";
      XMLProsInstr@1000000009 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlProcessingInstruction";
      XMLElement1@1000000008 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlElement";
      XMLElement2@1000000007 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlElement";
      XMLElement3@1000000006 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlElement";
      XMLNode4@1000000005 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNode";
      XMLNsMgr@1000000004 : DotNet "'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNamespaceManager";
      Bytes@1000000003 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Array";
      String@1000000002 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.String";
      Convert@1000000001 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Convert";
      ServerFile@1000000000 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.File";
      NAVWebRequest@1000000018 : DotNet "'NAVWebRequest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f53f0925d26e1382'.NAVWebRequest.NAVWebRequest";
      RespCenter@1100408000 : Record 5714;
      CompanyInfo@1100408002 : Record 79;
      Log@1000000016 : Record 50009;
      FileMgt@1100408003 : Codeunit 419;
      WebServiceName@1100408008 : Text[1024];
      InStr@1100408005 : InStream;
      Text006@1100408007 : TextConst 'ENU=Export;ISL=Flytja £t';
      Text009@1100408006 : TextConst 'ENU=All Files (*.*)|*.*;ISL=Allar skr r (*.*)|*.*';

    PROCEDURE SendToPartner@1100408000(ICOutboxTrans@1100408000 : Record 414;ICPartner@1100408001 : Record 413;FileName@1100408002 : Text[250]);
    BEGIN
      ICPartner.TESTFIELD("Inbox Details");
      WebServiceName := FindWebServiceName(ICPartner."Inbox Details");

      WITH ICOutboxTrans DO BEGIN
        CALCFIELDS("PDF Document","XML Document","Details Document");

        IF "Responsibility Center" <> '' THEN BEGIN
          RespCenter.GET("Responsibility Center");
          RespCenter.TESTFIELD("IC Partner Code");
          CompanyInfo."IC Partner Code" := RespCenter."IC Partner Code";
        END ELSE BEGIN
          CompanyInfo.GET;
          CompanyInfo.TESTFIELD("IC Partner Code");
        END;

      END;

      SendTransactionToPartnerDotNet(ICOutboxTrans,ICPartner,FileName)
    END;

    LOCAL PROCEDURE FindWebServiceName@1100408002(URL@1100408000 : Text[1024]) WebServiceName : Text[1024];
    VAR
      i@1100408001 : Integer;
    BEGIN
      FOR i := 1 TO STRLEN(URL) DO
        IF COPYSTR(URL,i,1) = '/' THEN
          WebServiceName := COPYSTR(URL,i + 1);
    END;

    LOCAL PROCEDURE SendTransactionToPartnerDotNet@1100408003(ICOutboxTrans@1100408000 : Record 414;ICPartner@1100408001 : Record 413;FileName@1100408002 : Text[250]);
    VAR
      TempFile@1000000001 : File;
      TempFileName@1000000000 : Text[250];
      WebServiceUserID@1000000003 : Text[1024];
      OutStr@1000000002 : OutStream;
    BEGIN
      WITH ICOutboxTrans DO BEGIN

        Log.GET("Transaction No.");
        Log."Delivered Date and Time" := CURRENTDATETIME;
        Log."Delivered by User ID" := USERID;

        XMLRequestDoc := XMLResponseDoc.XmlDocument;
        XMLProsInstr := XMLRequestDoc.CreateProcessingInstruction('xml','version="1.0" encoding="utf-8"');
        XMLRequestDoc.AppendChild(XMLProsInstr);

        XMLElement1 := XMLRequestDoc.CreateElement('soap','Envelope','http://schemas.xmlsoap.org/soap/envelope/');
        XMLElement1.SetAttribute('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance');
        XMLElement1.SetAttribute('xmlns:xsd','http://www.w3.org/2001/XMLSchema');

        XMLElement2 := XMLRequestDoc.CreateElement('soap','Body', 'http://schemas.xmlsoap.org/soap/envelope/');
        XMLElement3 := XMLRequestDoc.CreateElement('LoadTransaction');
        XMLElement3.SetAttribute('xmlns',STRSUBSTNO('urn:microsoft-dynamics-schemas/codeunit/%1',WebServiceName));

        XMLNode4 := XMLRequestDoc.CreateElement('fromPartnerCode');
        XMLNode4.InnerText := CompanyInfo."IC Partner Code";
        XMLElement3.AppendChild(XMLNode4);

        XMLNode4 := XMLRequestDoc.CreateElement('fromRespCenterCode');
        IF ICPartner."Send Resp. Center Code" THEN
          XMLNode4.InnerText := "Responsibility Center";
        XMLElement3.AppendChild(XMLNode4);

        XMLNode4 := XMLRequestDoc.CreateElement('toPartnerCode');
        XMLNode4.InnerText := "IC Partner Code";
        XMLElement3.AppendChild(XMLNode4);

        XMLNode4 := XMLRequestDoc.CreateElement('toRespCenterCode');
        XMLNode4.InnerText := "IC Partner Resp. Center";

        XMLElement3.AppendChild(XMLNode4);

        XMLNode4 := XMLRequestDoc.CreateElement('transaction');
        XMLNode4.InnerText := Convert.ToBase64String(ServerFile.ReadAllBytes(FileName));
        XMLElement3.AppendChild(XMLNode4);
        TempFile.OPEN(FileName);
        TempFile.CREATEINSTREAM(InStr);
        Log.Transaction.CREATEOUTSTREAM(OutStr);
        COPYSTREAM(OutStr,InStr);
        TempFile.CLOSE;
        ServerFile.Delete(FileName);

        XMLNode4 := XMLRequestDoc.CreateElement('pDFInvoice');
        IF "PDF Document".HASVALUE THEN BEGIN
          "PDF Document".CREATEINSTREAM(InStr);
          TempFileName := FileMgt.ServerTempFileName('pdf');
          TempFile.CREATE(TempFileName);
          TempFile.CREATEOUTSTREAM(OutStr);
          COPYSTREAM(OutStr,InStr);
          TempFile.CLOSE;
          XMLNode4.InnerText := Convert.ToBase64String(ServerFile.ReadAllBytes(TempFileName));
          ServerFile.Delete(TempFileName);
        END;
        XMLElement3.AppendChild(XMLNode4);

        XMLNode4 := XMLRequestDoc.CreateElement('pDFDetails');
        IF "Details Document".HASVALUE THEN BEGIN
          "Details Document".CREATEINSTREAM(InStr);
          TempFileName := FileMgt.ServerTempFileName('pdf');
          TempFile.CREATE(TempFileName);
          TempFile.CREATEOUTSTREAM(OutStr);
          COPYSTREAM(OutStr,InStr);
          TempFile.CLOSE;
          XMLNode4.InnerText := Convert.ToBase64String(ServerFile.ReadAllBytes(TempFileName));
          ServerFile.Delete(TempFileName);
        END;
        XMLElement3.AppendChild(XMLNode4);

        XMLNode4 := XMLRequestDoc.CreateElement('xMLInvoice');
        IF "XML Document".HASVALUE THEN BEGIN
          "XML Document".CREATEINSTREAM(InStr);
          TempFileName := FileMgt.ServerTempFileName('xml');
          TempFile.CREATE(TempFileName);
          TempFile.CREATEOUTSTREAM(OutStr);
          COPYSTREAM(OutStr,InStr);
          TempFile.CLOSE;
          XMLNode4.InnerText := Convert.ToBase64String(ServerFile.ReadAllBytes(TempFileName));
          ServerFile.Delete(TempFileName);
        END;
        XMLElement3.AppendChild(XMLNode4);

        XMLNode4 := XMLRequestDoc.CreateElement('responseMessage');
        XMLElement3.AppendChild(XMLNode4);
        XMLElement2.AppendChild(XMLElement3);
        XMLElement1.AppendChild(XMLElement2);
        XMLRequestDoc.AppendChild(XMLElement1);

        HttpWebRequest := HttpWebRequest.Create(ICPartner."Inbox Details");
        HttpWebRequest.Timeout := 30000;
        WebServiceUserID := ICPartner.GetUserID;
        IF WebServiceUserID = '' THEN
          HttpWebRequest.UseDefaultCredentials(TRUE)
        ELSE BEGIN
          HttpWebRequest.UseDefaultCredentials(FALSE);
          Credential := Credential.NetworkCredential;
          Credential.UserName := WebServiceUserID;
          Credential.Password := ICPartner.GetPassword;
          Credential.Domain := ICPartner.GetDomain;
          HttpWebRequest.Credentials := Credential;
        END;
        HttpWebRequest.Method := 'POST';
        HttpWebRequest.ContentType := 'text/xml; charset=utf-8';
        HttpWebRequest.Accept := 'text/xml';
        HttpWebRequest.Headers.Add('SOAPAction','LoadTransaction');
        MemoryStream := HttpWebRequest.GetRequestStream;
        XMLRequestDoc.Save(MemoryStream);
        MemoryStream.Flush;
        MemoryStream.Close;

        NAVWebRequest := NAVWebRequest.NAVWebRequest;
        IF NOT NAVWebRequest.doRequest(HttpWebRequest,HttpWebException,HttpWebResponse) THEN BEGIN
          Log.Delivered := FALSE;
          Log.SetMessage(HttpWebException.Message);
          Log.MODIFY;
          COMMIT;
          ERROR(Text003,HttpWebException.Status.ToString,HttpWebException.Message);
        END;

        MemoryStream := HttpWebResponse.GetResponseStream;
        XMLResponseDoc := XMLResponseDoc.XmlDocument;
        XMLResponseDoc.Load(MemoryStream);
        MemoryStream.Flush;
        MemoryStream.Close;

        XMLNsMgr := XMLNsMgr.XmlNamespaceManager(XMLResponseDoc.NameTable);
        XMLNsMgr.AddNamespace('urn',STRSUBSTNO('urn:microsoft-dynamics-schemas/codeunit/%1',WebServiceName));
        XMLNode4 := XMLResponseDoc.SelectSingleNode('//urn:return_value',XMLNsMgr);

        IF UPPERCASE(XMLNode4.InnerText) = 'FALSE' THEN BEGIN
          XMLNode4 :=  XMLResponseDoc.SelectSingleNode('//urn:responseMessage',XMLNsMgr);
          Log.Delivered := FALSE;
          Log.SetMessage(XMLNode4.InnerText);
          Log.MODIFY;
          COMMIT;
          ERROR(XMLNode4.InnerText);
        END;

        Log.Delivered := TRUE;
        Log.SetMessage(Text001);
        Log.MODIFY;
        COMMIT;

      END;
    END;

    EVENT XMLResponseDoc@1000000010::NodeInserting@93(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLResponseDoc@1000000010::NodeInserted@94(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLResponseDoc@1000000010::NodeRemoving@95(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLResponseDoc@1000000010::NodeRemoved@96(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLResponseDoc@1000000010::NodeChanging@97(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLResponseDoc@1000000010::NodeChanged@98(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLRequestDoc@1000000011::NodeInserting@93(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLRequestDoc@1000000011::NodeInserted@94(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLRequestDoc@1000000011::NodeRemoving@95(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLRequestDoc@1000000011::NodeRemoved@96(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLRequestDoc@1000000011::NodeChanging@97(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    EVENT XMLRequestDoc@1000000011::NodeChanged@98(sender@1000000001 : Variant;e@1000000000 : DotNet "'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlNodeChangedEventArgs");
    BEGIN
    END;

    BEGIN
    END.
  }
}

OBJECT Codeunit 50019 IC Addon Load Transaction
{
  OBJECT-PROPERTIES
  {
    Date=02.05.14;
    Time=10:12:10;
    Modified=Yes;
    Version List=IC7.10;
  }
  PROPERTIES
  {
    OnRun=BEGIN
            LoadTransaction;
          END;

  }
  CODE
  {
    VAR
      Text001@1100408000 : TextConst 'ENU=IC Partner Code %1 not found;ISL=Mf. f‚lagak¢ti %1 finnst ekki';
      Text002@1100408001 : TextConst 'ENU=Responsibility Center Code mismatch, %1 <> %2;ISL=µbyrgÐast”Ðvark¢ti stemmir ekki, %1 <> %2';
      Convert@1100408004 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Convert";
      DocumentFile@1100408003 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.File";
      Bytes@1100408010 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Array";
      MemoryStream@1100408008 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.MemoryStream";
      FileMgt@1100408009 : Codeunit 419;
      TempFile@1100408007 : File;
      InStr@1000000011 : InStream;
      OutStr@1000000010 : OutStream;
      TempFileName@1100408006 : Text[1024];
      Text003@1100408011 : TextConst 'ENU=No data received;ISL=Engin g”gn m¢ttekin';
      Text004@1100408012 : TextConst 'ENU=Transaction no. %1 is already imported;ISL=F‘rsla nr. %1 er çegar innflutt';
      Text005@1000000000 : TextConst 'ENU=From Partner Code Error in Transaction, %1 <> %2;ISL=Fr  mf. f‚lagak¢ta villa ¡ f‘rslu, %1 <> %2';
      Text006@1000000001 : TextConst 'ENU=To Partner Code Error in Transaction, %1 <> %2;ISL=Til mf. f‚lagak¢ta villa ¡ f‘rslu, %1 <> %2';
      FromPartnerCode@1000000009 : Code[20];
      FromRespCenterCode@1000000008 : Code[10];
      ToPartnerCode@1000000007 : Code[20];
      ToRespCenterCode@1000000006 : Code[10];
      Transaction@1000000005 : BigText;
      PDFInvoice@1000000004 : BigText;
      PDFDetails@1000000003 : BigText;
      XMLInvoice@1000000002 : BigText;

    LOCAL PROCEDURE LoadTransaction@1100408001();
    VAR
      ICPartner@1100408010 : Record 413;
      TempBlob@1100408024 : TEMPORARY Record 99008535;
      TempICOutboxTrans@1100408020 : TEMPORARY Record 414;
      TempICOutBoxJnlLine@1100408019 : TEMPORARY Record 415;
      TempICIOBoxJnlDim@1100408018 : TEMPORARY Record 423;
      TempICOutBoxSalesHdr@1100408017 : TEMPORARY Record 426;
      TempICOutBoxSalesLine@1100408016 : TEMPORARY Record 427;
      TempICOutBoxPurchHdr@1100408015 : TEMPORARY Record 428;
      TempICOutBoxPurchLine@1100408014 : TEMPORARY Record 429;
      TempICDocDim@1100408013 : TEMPORARY Record 442;
      ICInboxTransaction@1100408022 : Record 418;
      ICInboxTransaction2@1100408032 : Record 418;
      ICInboxJnlLine@1100408030 : Record 419;
      ICInboxSalesHdr@1100408029 : Record 434;
      ICInboxSalesLine@1100408028 : Record 435;
      ICInboxPurchHdr@1100408027 : Record 436;
      ICInboxPurchLine@1100408026 : Record 437;
      ICInboxJnlLineDim@1100408025 : Record 423;
      ICInboxDocDim@1100408023 : Record 442;
      HandledICInboxTransaction@1000000000 : Record 420;
      ICInboxOutboxMgt@1100408021 : Codeunit 427;
      FromICPartnerCode@1100408012 : Code[20];
      ToICPartnerCode@1100408011 : Code[20];
      ICOutboxExportXML@1100408008 : XMLport 12;
      NewTableID@1100408031 : Integer;
    BEGIN
      IF NOT ICPartner.GET(FromPartnerCode) THEN
        ERROR(Text001,FromPartnerCode);

      IF ICPartner."Responsibility Center" <> FromRespCenterCode THEN
        ERROR(Text002,ICPartner."Responsibility Center",FromRespCenterCode);

      IF NOT ICPartner.GET(ToPartnerCode) THEN
        ERROR(Text001,ToPartnerCode);

      IF ICPartner."Responsibility Center" <> ToRespCenterCode THEN
        ERROR(Text002,ICPartner."Responsibility Center",ToRespCenterCode);

      IF Transaction.LENGTH > 0 THEN BEGIN
        Bytes := Convert.FromBase64String(Transaction);
        MemoryStream := MemoryStream.MemoryStream(Bytes);
        TempBlob.Blob.CREATEOUTSTREAM(OutStr);
        MemoryStream.WriteTo(OutStr);
        TempBlob.Blob.CREATEINSTREAM(InStr);

        ICOutboxExportXML.SETSOURCE(InStr);
        ICOutboxExportXML.IMPORT;
        ICOutboxExportXML.GetICOutboxTrans(TempICOutboxTrans);
        ICOutboxExportXML.GetICOutBoxJnlLine(TempICOutBoxJnlLine);
        ICOutboxExportXML.GetICIOBoxJnlDim(TempICIOBoxJnlDim);
        ICOutboxExportXML.GetICOutBoxSalesHdr(TempICOutBoxSalesHdr);
        ICOutboxExportXML.GetICOutBoxSalesLine(TempICOutBoxSalesLine);
        ICOutboxExportXML.GetICOutBoxPurchHdr(TempICOutBoxPurchHdr);
        ICOutboxExportXML.GetICOutBoxPurchLine(TempICOutBoxPurchLine);
        ICOutboxExportXML.GetICSalesDocDim(TempICDocDim);
        ICOutboxExportXML.GetICSalesDocLineDim(TempICDocDim);
        ICOutboxExportXML.GetICPurchDocDim(TempICDocDim);
        ICOutboxExportXML.GetICPurchDocLineDim(TempICDocDim);
        FromICPartnerCode := ICOutboxExportXML.GetFromICPartnerCode;
        ToICPartnerCode := ICOutboxExportXML.GetToICPartnerCode;

        TempICOutBoxSalesHdr.MODIFYALL("Responsibility Center",FromRespCenterCode);
        TempICOutBoxSalesHdr.MODIFYALL("IC Partner Resp. Center",ToRespCenterCode);
        TempICOutBoxPurchHdr.MODIFYALL("Responsibility Center",FromRespCenterCode);
        TempICOutBoxPurchHdr.MODIFYALL("IC Partner Resp. Center",ToRespCenterCode);

        IF FromICPartnerCode <> FromPartnerCode THEN
          ERROR(Text005,FromICPartnerCode,FromPartnerCode);

        IF ToICPartnerCode <> ToPartnerCode THEN
          ERROR(Text006,ToICPartnerCode,ToPartnerCode);

        ICInboxTransaction2.SETRANGE("Transaction No.",TempICOutboxTrans."Transaction No.");
        ICInboxTransaction2.SETRANGE("IC Partner Code",FromICPartnerCode);
        ICInboxTransaction2.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
        IF ICInboxTransaction2.FINDFIRST THEN
          ERROR(Text004,TempICOutboxTrans."Transaction No.");

        HandledICInboxTransaction.SETRANGE("Transaction No.",TempICOutboxTrans."Transaction No.");
        HandledICInboxTransaction.SETRANGE("IC Partner Code",FromICPartnerCode);
        HandledICInboxTransaction.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
        IF HandledICInboxTransaction.FINDFIRST THEN
          ERROR(Text004,TempICOutboxTrans."Transaction No.");

        IF TempICOutboxTrans.FIND('-') THEN BEGIN
          ICInboxOutboxMgt.OutboxTransToInbox(TempICOutboxTrans,ICInboxTransaction,FromICPartnerCode);

          TempICOutBoxJnlLine.SETRANGE("Transaction No.",TempICOutboxTrans."Transaction No.");
          TempICOutBoxJnlLine.SETRANGE("IC Partner Code",TempICOutboxTrans."IC Partner Code");
          TempICOutBoxJnlLine.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
          IF TempICOutBoxJnlLine.FIND('-') THEN
            REPEAT
              ICInboxOutboxMgt.OutboxJnlLineToInbox(ICInboxTransaction,TempICOutBoxJnlLine,ICInboxJnlLine);
              TempICIOBoxJnlDim.SETRANGE("Transaction No.",TempICOutboxTrans."Transaction No.");
              TempICIOBoxJnlDim.SETRANGE("IC Partner Code",TempICOutboxTrans."IC Partner Code");
              TempICIOBoxJnlDim.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
              TempICIOBoxJnlDim.SETRANGE("Line No.",ICInboxJnlLine."Line No.");
              IF TempICIOBoxJnlDim.FIND('-') THEN
                REPEAT
                  ICInboxOutboxMgt.OutboxJnlLineDimToInbox(
                    ICInboxJnlLine,TempICIOBoxJnlDim,ICInboxJnlLineDim,DATABASE::"IC Inbox Jnl. Line");
                UNTIL TempICIOBoxJnlDim.NEXT = 0;
            UNTIL TempICOutBoxJnlLine.NEXT = 0;

          TempICOutBoxSalesHdr.SETRANGE("IC Transaction No.",TempICOutboxTrans."Transaction No.");
          TempICOutBoxSalesHdr.SETRANGE("IC Partner Code",TempICOutboxTrans."IC Partner Code");
          TempICOutBoxSalesHdr.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
          IF TempICOutBoxSalesHdr.FIND('-') THEN
            REPEAT
              ICInboxOutboxMgt.OutboxSalesHdrToInbox(ICInboxTransaction,TempICOutBoxSalesHdr,ICInboxPurchHdr);
            UNTIL TempICOutBoxSalesHdr.NEXT = 0;

          TempICOutBoxSalesLine.SETRANGE("IC Transaction No.",TempICOutboxTrans."Transaction No.");
          TempICOutBoxSalesLine.SETRANGE("IC Partner Code",TempICOutboxTrans."IC Partner Code");
          TempICOutBoxSalesLine.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
          IF TempICOutBoxSalesLine.FIND('-') THEN BEGIN
            REPEAT
              ICInboxOutboxMgt.OutboxSalesLineToInbox(ICInboxTransaction,TempICOutBoxSalesLine,ICInboxPurchLine);
            UNTIL TempICOutBoxSalesLine.NEXT = 0;
            ICInboxPurchLine.SETRANGE("IC Transaction No.",ICInboxPurchHdr."IC Transaction No.");
            ICInboxPurchLine.SETRANGE("IC Partner Code",ICInboxPurchHdr."IC Partner Code");
            ICInboxPurchLine.SETRANGE("Transaction Source",ICInboxPurchHdr."Transaction Source");
            ICInboxPurchLine.SETRANGE("VAT Base Amount",-0.5,0.5);
            ICInboxPurchLine.CALCSUMS("Amount Including VAT");
            ICInboxPurchHdr."Payable Rounding Amount" := ICInboxPurchLine."Amount Including VAT";
            ICInboxPurchLine.SETRANGE("VAT Base Amount");
            ICInboxPurchLine.CALCSUMS("Amount Including VAT","VAT Base Amount");
            ICInboxPurchHdr."Payable Amount" := ICInboxPurchLine."Amount Including VAT";
            ICInboxPurchHdr."Line Extension Amount" := ICInboxPurchLine."VAT Base Amount" - ICInboxPurchHdr."Payable Rounding Amount";
            ICInboxPurchHdr."Tax Exclusive Amount" := ICInboxPurchHdr."Line Extension Amount";
            ICInboxPurchHdr."Tax Inclusive Amount" := ICInboxPurchLine."Amount Including VAT" - ICInboxPurchHdr."Payable Rounding Amount";
            ICInboxPurchHdr."Tax Amount" :=  ICInboxPurchHdr."Tax Inclusive Amount" - ICInboxPurchHdr."Tax Exclusive Amount";
            ICInboxPurchHdr.MODIFY;
          END;

          TempICOutBoxPurchHdr.SETRANGE("IC Transaction No.",TempICOutboxTrans."Transaction No.");
          TempICOutBoxPurchHdr.SETRANGE("IC Partner Code",TempICOutboxTrans."IC Partner Code");
          TempICOutBoxPurchHdr.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
          IF TempICOutBoxPurchHdr.FIND('-') THEN
            REPEAT
              ICInboxOutboxMgt.OutboxPurchHdrToInbox(ICInboxTransaction,TempICOutBoxPurchHdr,ICInboxSalesHdr);
            UNTIL TempICOutBoxPurchHdr.NEXT = 0;

          TempICOutBoxPurchLine.SETRANGE("IC Transaction No.",TempICOutboxTrans."Transaction No.");
          TempICOutBoxPurchLine.SETRANGE("IC Partner Code",TempICOutboxTrans."IC Partner Code");
          TempICOutBoxPurchLine.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
          IF TempICOutBoxPurchLine.FIND('-') THEN
            REPEAT
              ICInboxOutboxMgt.OutboxPurchLineToInbox(ICInboxTransaction,TempICOutBoxPurchLine,ICInboxSalesLine);
            UNTIL TempICOutBoxPurchLine.NEXT = 0;

          TempICDocDim.SETRANGE("Transaction No.",TempICOutboxTrans."Transaction No.");
          TempICDocDim.SETRANGE("IC Partner Code",TempICOutboxTrans."IC Partner Code");
          TempICDocDim.SETRANGE("Transaction Source",TempICOutboxTrans."Transaction Source");
          IF TempICDocDim.FIND('-') THEN
            REPEAT
              CASE TempICDocDim."Table ID" OF
                DATABASE::"IC Outbox Sales Header": NewTableID := DATABASE::"IC Inbox Purchase Header";
                DATABASE::"IC Outbox Sales Line": NewTableID := DATABASE::"IC Inbox Purchase Line";
                DATABASE::"IC Outbox Purchase Header": NewTableID := DATABASE::"IC Inbox Sales Header";
                DATABASE::"IC Outbox Purchase Line": NewTableID := DATABASE::"IC Inbox Sales Line";
              END;
              ICInboxOutboxMgt.OutboxDocDimToInbox(
                TempICDocDim,ICInboxDocDim,NewTableID,FromICPartnerCode,ICInboxTransaction."Transaction Source");
            UNTIL TempICDocDim.NEXT = 0;
        END;

        ICInboxTransaction."Responsibility Center" := ToRespCenterCode;
        ICInboxTransaction."IC Partner Resp. Center" := FromRespCenterCode;

        IF XMLInvoice.LENGTH > 0 THEN BEGIN
          Bytes := Convert.FromBase64String(XMLInvoice);
          MemoryStream := MemoryStream.MemoryStream(Bytes);
          ICInboxTransaction."XML Document".CREATEOUTSTREAM(OutStr);
          MemoryStream.WriteTo(OutStr);
        END;

        IF PDFInvoice.LENGTH > 0 THEN BEGIN
          Bytes := Convert.FromBase64String(PDFInvoice);
          MemoryStream := MemoryStream.MemoryStream(Bytes);
          ICInboxTransaction."PDF Document".CREATEOUTSTREAM(OutStr);
          MemoryStream.WriteTo(OutStr);
        END;

        IF PDFDetails.LENGTH > 0 THEN BEGIN
          Bytes := Convert.FromBase64String(PDFDetails);
          MemoryStream := MemoryStream.MemoryStream(Bytes);
          ICInboxTransaction."Details Document".CREATEOUTSTREAM(OutStr);
          MemoryStream.WriteTo(OutStr);
        END;

        ICInboxTransaction.MODIFY;
      END ELSE
        ERROR(Text003);
    END;

    PROCEDURE SetProperties@1000000000(VAR SetFromPartnerCode@1000000007 : Code[20];VAR SetFromRespCenterCode@1000000006 : Code[10];VAR SetToPartnerCode@1000000005 : Code[20];VAR SetToRespCenterCode@1000000004 : Code[10];VAR SetTransaction@1000000003 : InStream;VAR SetPDFInvoice@1000000002 : InStream;VAR SetPDFDetails@1000000001 : InStream;VAR SetXMLInvoice@1000000000 : InStream;TransactionHasValue@1000000011 : Boolean;PDFInvoiceHasValue@1000000010 : Boolean;PDFDetailsHasValue@1000000009 : Boolean;XMLInvoiceHasValue@1000000008 : Boolean);
    BEGIN
      FromPartnerCode := SetFromPartnerCode;
      FromRespCenterCode := SetFromRespCenterCode;
      ToPartnerCode := SetToPartnerCode;
      ToRespCenterCode := SetToRespCenterCode;
      IF TransactionHasValue THEN
        Transaction.READ(SetTransaction);
      IF PDFInvoiceHasValue THEN
        PDFInvoice.READ(SetPDFInvoice);
      IF PDFDetailsHasValue THEN
        PDFDetails.READ(SetPDFDetails);
      IF XMLInvoiceHasValue THEN
        XMLInvoice.READ(SetXMLInvoice);
    END;

    BEGIN
    END.
  }
}

 

WinHTTP and RTC Client

I have been using the automation ‘Microsoft XML, v6.0’.XMLHTTP to communicate with web services and web sites.  I have been experiencing a problem with this automation when running in Role Tailored Client.  The solution has been to use the automation ‘Microsoft XML, v6.0’.ServerXMLHTTP when running in the service tier.
[code htmlscript=”false”]IF ISSERVICETIER THEN BEGIN
IF ISCLEAR(WinHTTPServer) THEN
CREATE(WinHTTPServer,TRUE,FALSE);
WinHTTPServer.open(‘GET’,URL,FALSE);
WinHTTPServer.send(”);

IF WinHTTPServer.status <> 200 THEN
ERROR(Text007,WinHTTPServer.status,WinHTTPServer.statusText);

DOMDocument.load(WinHTTPServer.responseXML);
CLEAR(WinHTTPServer);
END ELSE BEGIN
IF ISCLEAR(WinHTTP) THEN
CREATE(WinHTTP,TRUE,FALSE);
WinHTTP.open(‘GET’,URL,FALSE);
WinHTTP.send(”);

IF WinHTTP.status <> 200 THEN
ERROR(Text007,WinHTTP.status,WinHTTP.statusText);

DOMDocument.load(WinHTTP.responseXML);
CLEAR(WinHTTP);
END;[/code]
Where Error string Text007 is “Status error %1 %2”.

WSDL Code Generator

On several occasions I have needed to create a code to communicate with Soap Web Services. The manual labor in creating the functions and XML Ports is something that I would like to be rid of. On that node I created a Batch that does most of the job for me.

Execute this and you will be asked to save the “Web Service Objects.txt” file to your computer and from there you will be able to import the file and continue the work.

You will get XMP Ports for every method, both the request and response.  You will also get a Codeunit with a function for every method and the necessary functions to handle the web service communication.

What is left is for you to connect your data to the functions and the XML Ports.

This is not fully tested, so any updates would be appreciated.

Import WSDL (Updated 2012-12-08)

Creating Web Services in NAV 2009

I have been working on NAV Time Registration and the solution is almost ready.  The last step was to create a web service that supports stand-alone punching clocks, both in .net c# and also as a NAV client.

The web service is a standard codeunit with functions.  I make sure the functions that are not to be published have the Local property set to Yes.

Using XMLport in web services requires a few parameter changes.  First I include them in the function parameters.  I use a boolean parameter in Return Value as a success flag.

Then in XMLport properties I change direction to export, change format to XML and select to use default namespace.

The C/Side code to answer this web service is.
[code htmlscript=”false”]IF NOT ValidateClockID(ClockID,ResponseMessage) THEN BEGIN
InsertLog(ClockID,Log.GetEmployeeList,FALSE,ResponseMessage,”);
EXIT(FALSE);
END;

IF NOT CreateEmployeeBuffer(EmployeeBuffer,ResponseMessage) THEN BEGIN
InsertLog(ClockID,Log.GetEmployeeList,FALSE,ResponseMessage,”);
EXIT(FALSE);
END;

EmployeeList.SetEmployeeList(PunchClock.Code,EmployeeBuffer);
ResponseMessage := Text033;
InsertLog(ClockID,Log.GetEmployeeList,TRUE,”,”);
EXIT(TRUE);[/code]
Then finally I run form 860, Web Services and add a line for this web service to be published.

Next post is a demonstration on how to use this web service.  I used Freddys multiple service tier post in my developement enviroment to setup NAV services.

 

Add Namespaces to outgoing XML

The tax authority in Iceland are using Soap web services.  I have built XML Ports in NAV to create the request XML and another one to read the response XML.

I already wrote about using stylesheet to strip namespaces from the incoming XML before passing it to the XML Port.  I previously just added namespaces to the outgoing XML with attributes in the request XML Port.  This does not work in Role Tailored Client.

The solution was to remove all the namespaces attributes from the request XML Ports and create a function to add namespaces to the XML before passing it to the web server.  This work both in Classic Client and in Role Tailored Client.

AddNameSpaces source code

Data Transfer with XML Port

In my Payroll development I created a solution to import and export setup data from one company to another.  This is done via XMLPort.  I created the XMLPort code with a Report that is attached at the bottom of the post.

First I need a function to create the table list for the setup data
[code]SetupObjectNoList(VAR TempObject : Record Object)
TableIDArray[1] := DATABASE::"Payroll Setup";
TableIDArray[2] := DATABASE::"Payroll Tax Setup";

TableIDArray[57] := DATABASE::"Payroll Column Layout";

Object.SETRANGE(Type,Object.Type::Table);

FOR Index := 1 TO ARRAYLEN(TableIDArray) DO BEGIN
Object.SETRANGE(Object.ID,TableIDArray[Index]);
IF Object.FINDFIRST THEN BEGIN
TempObject := Object;
TempObject.INSERT;
END;
END;[/code]
And to be able to import new setup data I must clear all data from the setup tables
[code]DeleteSetupData()
IF NOT CONFIRM(Text005,FALSE) THEN EXIT;

SetupObjectNoList(TempObject);
DialogMgt.WindowOpen(‘@1@@@@@@@@@@@@@@@@@@@@@@’);
DialogMgt.WindowSetTotal(1,TempObject.COUNT);
TempObject.FINDSET;
REPEAT
RecRef.OPEN(TempObject.ID);
IF NOT RecRef.ISEMPTY THEN
RecRef.DELETEALL;
RecRef.CLOSE;
DefaultDim.SETRANGE("Table ID",TempObject.ID);
IF NOT DefaultDim.ISEMPTY THEN
DefaultDim.DELETEALL;
LineDim.SETRANGE("Table ID",TempObject.ID);
IF NOT LineDim.ISEMPTY THEN
LineDim.DELETEALL;
Translation.SETRANGE("Table ID",TempObject.ID);
IF NOT Translation.ISEMPTY THEN
Translation.DELETEALL;
DialogMgt.WindowProcess(1);
UNTIL TempObject.NEXT = 0;
DialogMgt.WindowClose;
COMMIT;[/code]
Then I have the Import and Export functions. In this code I am using a Log table BLOB field but could as well use the TempBlob table.
[code]ImportFile(FileName : Text[1024])
DialogMgt.WindowOpen(Text003);
Log.INIT;
Log."Entry No." := 0;
Log."Service Description" := Text001;
Log."Created by User ID" := USERID;
Log."Creation Date and Time" := CURRENTDATETIME;
IF Log.ImportIncomingXML(FileName,FALSE) &lt;&gt; ” THEN BEGIN
Log."Incoming Message".CREATEINSTREAM(InStr);
XML.SETSOURCE(InStr);
XML.IMPORT;
CLEAR(XML);
END;
Log.INSERT;
DialogMgt.WindowClose;

ExportFile(FileName : Text[1024])
DialogMgt.WindowOpen(Text004);
Log.INIT;
Log."Entry No." := 0;
Log."Service Description" := Text002;
Log."Created by User ID" := USERID;
Log."Creation Date and Time" := CURRENTDATETIME;
Log."Outgoing Message".CREATEOUTSTREAM(OutStr);
XML.SETDESTINATION(OutStr);
XML.EXPORT;
CLEAR(XML);
Log.INSERT;
Log.ExportOutgoingXML(FileName,FALSE);
DialogMgt.WindowClose;[/code]
Report to create XMLPort

Transferring small amount of data between databases

Most of us have needed to copy data from one Dynamics NAV database to another.  For example the posting setup tables, payment terms, currency, etc.

If the databases are not identical you will not be able to copy and paste the data and you have to solve this problem with dataports or XMLPorts.

I offer a solution to this problem.  I have created a form that is able to export and import data based on table and field numbers.  It will import data to a table even if some fields are missing in the destination database.

Here is the source code