Wednesday, July 29, 2020

Create Movement Journal using X++


    InventJournalId                journalNum;
    JournalCheckPost           journalCheckPost;
    InventDim                      inventDim;
    InventJournalTrans          journalTrans;
    InventJournalTable          inventJournal;
    JournalTableData            journalTableData;
    Counter                          lineNum;
    InventLocation               inventLocation;

public void createJournal()
{
    this.createHeader();
    this.createLine();
    this.postJournal()
}

public void createHeader()
{
        InventJournalName   inventJournalName;
        NumberSeq num;
        num = NumberSeq::newGetNum(InventParameters::numRefInventJournalId());
        journalNum = num.num();
        inventJournalName = InventJournalName::find("JournalName");
        inventJournal.initFromInventJournalName(inventJournalName);
        inventJournal.JournalId     = journalNum;
        inventJournal.JournalType   = InventJournalType::Movement;
        inventJournal.Description = "Description";
        inventJournal.insert();            
        journalTableData = JournalTableData::newTable(inventJournal);
        lineNum++;
}

public void createLine()
{
            inventDim.clear();
            inventDim.initValue();        
            inventDim.InventSiteId  = inventLocation.InventSiteId;
            inventDim.InventLocationId = inventLocation.InventLocationId;
            inventDim.wMSLocationId = inventLocation.WMSlocationIdDefaultIssue;
            inventDim = InventDim::findOrCreate(inventDim);
            journalTrans.clear();
            journalTrans.initValue();
            journalTrans.initFromInventJournalTable(inventJournal);
            journalTrans.JournalType = inventJournal.JournalType;
            journalTrans.TransDate      = "Trans_Date";
            journalTrans.ItemId         = "ItemId";
            journalTrans.InventDimId    = inventDim.InventDimId;
            journalTrans.initFromInventTable(InventTable::find("ItemId")); 
            journalTrans.LineNum        = lineNum;
            journalTrans.Qty            = "Quantity";
            journalTrans.CostAmount     = journalTrans.Qty * journalTrans.CostPrice;
            journalTrans.insert(false);
            lineNum++;
}

public void postJournal()
{
            inventJournal.selectForUpdate(true);
            inventJournal.SystemBlocked = true;
            inventJournal.update();
            journalCheckPost =                     InventJournalCheckPost::newJournalCheckPost(JournalCheckPostType::Post, inventJournal);
            journalCheckPost.run();

}

Monday, July 27, 2020

How to read csv data from SFTP location through Microsoft Flow and Import into Dynamics 365 Finance and Operations

File based integration with Dynamics 365 Finance and Operation using Power Automate

Step 1: Login to Power Automate
Step 2: Create New Flow Connector


Step 3: Add Trigger Point SFTP Folder 'When a file is added or modified'

(This operation triggers a flow when a file is added or modified in a folder. The trigger will fetch both the file metadata as well as the content of the file. The trigger relies on the last modified time of a file. If a file is being created by a third-party client, the preservation of the last modified time should be disabled in the client. Files larger than 50 megabytes are skipped by the trigger)

Step 4: Create SFTP connection and select the folder.
Step 5: Add new Action step 'Get file content'
Step 6: Add new Action step 'Dynamics 365 FO' with in 'Apply to each' action.

Create Purchase Order using X++

PurchTable                        purchTable;
PurchLine                         purchLine;
PurchId                             purchId;
LogisticsPostalAddress    logisticsPostalAddress;

//Create purchase order
public void createPO()
{
    ttsbegin;
    
    this.createHeader();
    this.createLine();
    if(purchId)
    {
            this.postConfirmation();
     }
    ttscommit;
}

//Create purchase order header
public void createHeader()
{
        purchId = NumberSeq::newGetNum(PurchParameters::numRefPurchId()).num();
        purchTable.clear();
        purchTable.PurchId = purchId;
        purchTable.initValue();
        purchTable.initFromVendTable(VendTable::find("VendAccount"));
        purchTable.PurchStatus = PurchStatus::Backorder;
        purchTable.DocumentState = VersioningDocumentState::Approved;
        purchTable.InventSiteId = InventLocation::find("ToWarehouse").InventSiteId;
        purchTable.InventLocationId = "ToWarehouse";
        purchTable.ChangeRequestRequired = NoYes::no;
        purchTable.MCRDropShipment = NoYes::Yes;
        logisticsPostalAddress = InventLocation::find("ToWarehouse").logisticsPostalAddress();
        purchTable.DeliveryName = Logisticslocation::find(logisticsPostalAddress.location).description;
        purchTable.DeliveryPostalAddress = logisticsPostalAddress.RecId;
        purchTable.VendorRef  = "Vendor reference"; //Optional
        purchTable.Requester = "HCMWorkerRecId";
        purchTable.WorkerPurchPlacer = this.getWorkerPurchPlacer();
        purchTable.insert();
}

//Create purchase order line
public void createLine()
{
        purchLine.clear();
        purchLine.PurchId = purchId;
        purchLine.ItemId = "ItemId";
        purchLine.itemIdChanged();
        purchLine.PurchQty = "Quantity";
        purchLine.DeliveryType = TradeLineDlvType::DropShip;
        inventDimfind.InventSiteId = purchTable.InventSiteId;
        inventDimfind.InventLocationId = purchTable.InventLocationId;
        inventDimfind.wMSLocationId = InventLocation::find(purchTable.InventLocationId).WMSLocationIdDefaultReceipt;
        inventDimLines = InventDim::findOrCreate(inventDimfind);
        purchLine.createLine(true, true, true, false, true, true);
        purchLine.selectForUpdate(true);
        purchLine.InventDimId = inventDimLines.inventDimId;
        purchLine.doUpdate();
}

//Post purchase order confirmation
public void postConfirmation()
{
        PurchFormLetter     purchFormLetter;
        purchformletter = PurchFormLetter::construct(documentstatus::PurchaseOrder);
        purchformletter.update(purchtable,
                                strfmt("inv_%1", purchId), systemDateGet(), PurchUpdate::All, 
                                AccountOrder::None,
                                NoYes::No,
                                true,
                                true);
}

public RefRecId getWorkerPurchPlacer ()
{
        UserInfo userInfo;
        RefRecId refRecId;
        select name from userInfo where userInfo.id == curUserId();

        if(userInfo.id != '')
        {        
            refRecId = HcmWorker::findByPerson(DirPerson::find(DirPartyTable::findByName(                                                userInfo.name).RecId).RecId).RecId;
        }
        return refRecId;
}

Sunday, July 26, 2020

Create Transfer Order using X++.


InventTransferTable                 inventTransferTable;

InventTransferLine                  inventTransferLine;

InventTransferId                      inventTransferId;


public void createTransferOrder()

{

     ttsBegin;

     createHeader();

        createLine()

    ttsCommit;

}

Sample code to create header of the Transfer Order

public void createHeader()

{        

        //create the transfer order id.

        inventTransferId = InventTransferTable::numberSeq().num(); 

        inventTransferTable.clear();

        inventTransferTable.initValue();

        inventTransferTable.TransferId = inventTransferId; // assign the transfer order id

        inventTransferTable.InventLocationIdFrom = “FromWarehouse”;  // assign the from warehouse

        inventTransferTable.InventLocationIdTo = “ToWarehouse”; // assign the to warehouse

        inventTransferTable.TransferStatus = InventTransferStatus::Created; // assign the transfer status

        inventTransferTable.DlvModeId = “ShipMethod”; 

        inventTransferTable.ShipDate = “ShipDate”; // assign the ship date

        inventTransferTable.ReceiveDate = “ReceiveDate”; // assign the receive date

        inventTransferTable.AutoReservation = NoYes::No;

        inventTransferTable.initToAddress();

        inventTransferTable.initFromAddress();

        inventTransferTable.InventLocationIdTransit = InventLocation::find(“FromWarehouse”).InventLocationIdTransit;

        inventTransferTable.validateWrite();

        inventTransferTable.insert();

   

Sample code to create line of the Transfer Order

    public void createLine()

    {

        InventDim                   inventDim;

        inventDim.clear();

        inventTransferLine.clear();

        inventDim = inventTransferLine.inventDim();

        inventDim.InventSiteId = InventLocation::find(inventTransferTable.InventLocationIdFrom).InventSiteId;

        inventDim.InventLocationId = inventTransferTable.InventLocationIdFrom;             

        inventTransferLine.initFromInventTransferTable(inventTransferTable,NoYes::Yes);

        inventTransferLine.ItemId = “ItemId”;

        inventTransferLine.LineNum = inventTransferLine::lastLineNum(inventTransferTable.TransferId) + 1;

        inventTransferLine.initFromInventTable(InventTable::find(“ItemId”));

        inventTransferLine.QtyTransfer = “Quantity”;

        inventTransferLine.QtyRemainReceive = “Quantity”;

        inventTransferLine.QtyRemainShip = “Quantity”;

        inventTransferLine.QtyShipNow = 0;

        inventTransferLine.QtyReceiveNow = 0;

        inventTransferLine.RemainStatus = InventTransferRemainStatus::Shipping;

        inventTransferLine.AutoReservation  = NoYes::No;

        inventTransferLine.InventDimId = InventDim::findOrCreate(inventDim).inventDimId;;

        inventTransferLine.insert();      

    }


Wednesday, July 31, 2019

Write csv file on Azure Blob

##How to write csv file on Azure Blob from Dynamics 365 FO using X++?

This blog will explain how and why export data from dynamics 365 using X++ without data entity. There are some scenarios where we can not use directly the data entity to export data from dynamics 365 FO like incremental export. In this situation, we can use following way to export data in CSV/Excel format.
 
 public void WriteCSVFileOnBlob()
 {     
        System.Byte[]                       byteArray;
        System.Text.Encoding                encodingUTF8;
        str                                 accountName ="<<AccountNameOfBlob>>";
        str                                 accountKey ="<<AccountKeyofBlob>>";
str     blobName ="<<BlobName>>";
        str                                 fileName;
        str                                 strRowData;
        boolean                             isColumnsAdded=false;
        LogTable     logTable;
               
     

            if(logTable)
            {
                fileName="inputfilename.csv";

                Microsoft.WindowsAzure.Storage.Auth.StorageCredentials storageCredentials = new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(accountName, accountKey);

                Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = new Microsoft.WindowsAzure.Storage.CloudStorageAccount(storageCredentials, true);

                var blobcli = storageAccount.CreateCloudBlobClient();

                Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer cont = blobcli.GetContainerReference(blobName);

                CloudBlockBlob cloudBlockBlob = cont.GetBlockBlobReference(fileName);

                using (Microsoft.WindowsAzure.Storage.Blob.CloudBlobStream x = cloudBlockBlob.OpenWriteAsync().Result)
                {
                    while select logTable where logTable.InputfileName==fileName
                    {
                        if(logTable.RecId>0)
                        {
                            if(!isColumnsAdded)
                            {
                                isColumnsAdded=true;

                                strRowData= strFmt("%1,%2,%3,%4,%5,%6,%7,%8,%9","ItemCode","DocumentNumber","DocumentReference","WarehouseCode","ProcessName","DateTime","InputFileName","ErrorMessage","\r\n");

                                encodingUTF8 = System.Text.Encoding::get_UTF8();
                                byteArray = encodingUTF8.GetBytes(strRowData);
                                x.Write(byteArray,0,byteArray.Length);
                            }


                            strRowData=strFmt("%1,%2,%3,%4,%5,%6,%7,%8,%9",logTable.ItemCode,logTable.DocumentNumber,logTable.DocumentReference,logTable.WarehouseCode,enum2Str(ProcessType),logTable.Datetime,inputfilename,strReplace(logTable.Errormessage,",",";"),"\r\n");

                            encodingUTF8 = System.Text.Encoding::get_UTF8();
                            byteArray = encodingUTF8.GetBytes(strRowData);
                            x.Write(byteArray,0,byteArray.Length);

                        }

                    }

                    if(isColumnsAdded)
                    {
                        x.Flush();
                        x.Close();
                    }

                }
            }

    }