Create Product Recipt and register inventory using X++(Sysoperation)

By using the below code we can create a product recipt for purchase order and register inventory aswell

points to remember:

in my requiremnet transaction base is the master table holds the data of transactions

inventory transactions will hold the data of  item number and quantity

Order entity will hold the data of PurchOrders.

Assume the data flowing from above tables and allow us to create product recipet and inventory registration.

 


class TestProductReceiptPostingService

{

    PurchFormLetterParmData          purchFormLetterParmData;

    PurchParmTable                   purchParmTable;

    PurchParmLine                    purchParmLine;

    purchParmUpdate                  purchParmUpdate;

    PurchTable                       purchTable;

    TransDate                        packingSlipDate;

    PackingSlipId                    packingSlipId;

    purchFormLetter                  purchFormLetter;

  testorderentity                   Orderentity,Orderentity1;

    

    


        /// <summary>

    /// Processer method to register the item

    /// </summary>

    /// <param name = "_Transbase">testtransactionbase</param>

    public void insertParmTableData(testInventoryTransactions _inventoryTrans, testtransactionbase _Transbase)

    {

        Orderentity     = testorderentity::findbyId(_Transbase.ID);

        if(!Orderentity)

        {

            throw Global::Error(strFmt('Manufacturing Order for inventroy transaction ID- %1 is not yet created',_Transbase.ID));

        }

        purchTable = PurchTable::find(Orderentity.OrderNumber,false);


        purchFormLetterParmData = PurchFormletterParmData::newData(DocumentStatus::PackingSlip,VersioningUpdateType::Initial);

        purchFormLetterParmData.parmOnlyCreateParmUpdate(true);

        purchFormLetterParmData.createData(false);

        purchParmUpdate = purchFormLetterParmData.parmParmUpdate();


        // Set PurchParmTable table

        purchParmTable.clear();

        purchParmTable.TransDate = DateTimeUtil::date(_Transbase.TransactionDate); // which can be changed

        purchParmTable.Ordering = DocumentStatus::PackingSlip;

        purchParmTable.ParmJobStatus = ParmJobStatus::Waiting;

        purchParmTable.Num = _Transbase.Reference; // product receipt no

        purchParmTable.PurchId = purchTable.PurchId;

        purchParmTable.PurchName = purchTable.PurchName;

        purchParmTable.DeliveryName = purchTable.DeliveryName;

        purchParmTable.DeliveryPostalAddress = purchTable.DeliveryPostalAddress;

        purchParmTable.OrderAccount = purchTable.OrderAccount;

        purchParmTable.CurrencyCode = purchTable.CurrencyCode;

        purchParmTable.InvoiceAccount = purchTable.InvoiceAccount;

        purchParmTable.ParmId = purchParmUpdate.ParmId;

        purchParmTable.insert();

    }


    public boolean insertParmLineData(testInventoryTransactions _inventoryTrans, testtransactionbase _Transbase)

    {

        InventDim inventDim;

        PurchLine purchLine;

        WMSLocation Location;

        int64       linenum;

        boolean ret = false;

        InventDimCombination    inventDimCombination;

        str itemid;


        select firstonly inventDimCombination where inventDimCombination.RetailVariantId == _inventoryTrans.ItemNumber;

        if (inventDimCombination.recid)

        {

            itemid  = inventDimCombination.ItemId;

        }

        else

        {

            itemid = _inventoryTrans.ItemNumber;

        }


        Orderentity1     = testorderentity::findbyId(_Transbase.ID);

        linenum          = str2Int64(Orderentity1.LineNumber);


        select firstonly Location where Location.RecId == str2Int64(_inventoryTrans.InventoryLocationKey);

        select firstonly purchLine 

            where purchLine.ItemId  == itemid

            && purchLine.PurchId    == purchTable.PurchId

            && purchLine.LineNumber == linenum

           ;

        purchParmLine.InitFromPurchLine(purchLine);

        inventDim = purchLine.inventDim(); 

        purchParmLine.ItemId = purchLine.ItemId;

        purchParmLine.ReceiveNow = decRound(_inventoryTrans.Quantity, 2);

        purchParmLine.InventDimId = inventDim.inventdimid;

        purchParmLine.ParmId = purchParmTable.ParmId;

        purchParmLine.TableRefId = purchParmTable.TableRefId;

        purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);

        purchParmLine.setLineAmount();

        purchParmLine.insert();               

       // inventDim.inventBatchId = _inventoryTrans.BatchLotNumber;

        inventDim.wMSLocationId = Location.wMSLocationId;

        inventDim = inventDim::findOrCreate(inventDim); //Creating new invent dim for registration

        this.registerInventory(purchParmLine, inventDim);

        ret = true;

        return ret;

    }


    public void registerInventory(PurchParmLine _purchParmline,InventDim _inventDim)

    {

        InventTransWMS_Register inventTransWMS_register;

        InventTrans inventTranslocal = InventTrans::findTransId(_purchParmline.InventTransId, true);

        TmpInventTransWMS tmpInventTransWMS;

        InventDim inventDimlocal = inventTranslocal.inventDim();

        InventDim InventBatchCheck;

 

        inventDimlocal.inventBatchId = _inventDim.inventBatchId;

        inventDimlocal.InventLocationId = _inventDim.InventLocationId;

        inventDimlocal.InventSiteId = _inventDim.inventSiteId;

        inventDimlocal = InventDim::findOrCreate(inventDimlocal);

        inventTransWMS_register = inventTransWMS_register::newStandard(tmpInventTransWMS);


        inventTranslocal.inventDimId = inventDimlocal.inventDimId;

    

        tmpInventTransWMS.clear();

        tmpInventTransWMS.initFromInventTrans(inventTranslocal);

        tmpInventTransWMS.ItemId = inventTranslocal.ItemId;

        tmpInventTransWMS.InventQty = _purchParmline.ReceiveNow;

        tmpInventTransWMS.insert();


        inventTransWMS_register.writeTmpInventTransWMS(tmpInventTransWMS,

                                                    inventTranslocal,

                                                     inventDimlocal);

       

        inventTransWMS_register.updateInvent(inventTranslocal);

    }


    public boolean processProductReceipt()

    {

        boolean ret  = false;

        purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);

        purchFormLetter.transDate(systemDateGet());

        purchFormLetter.proforma(false);

        purchFormLetter.specQty(PurchUpdate::ReceiveNow);

        purchFormLetter.purchTable(purchTable);

        purchFormLetter.parmParmTableNum(purchParmTable.Num);

        purchFormLetter.parmId(purchParmTable.ParmId);

        purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());

        purchFormLetter.run();

        ret = true;

        return ret;

    }


    public void updateTransactionBase( testtransactionbase _Transbase)

    {

        testTransactionBase  testtransactionbase;


        test   transactionbase                  = testtransactionbase::findbyId(_Transbase.ID,true);

        testtransactionbase.IsProcessed      = testIsprocessed::Processed;

        testtransactionbase.testJournalId     = purchTable.PurchId;

        testtransactionbase.ErrorDescription = ' ';

        testtransactionbase.update();

    }


}




Lets implement it in Sysoperation:

class TestProductReceiptPostingHelper extends SysOperationServiceBase

{

    public void processOperation()

    {

        Log                         errorMessage;

        SysInfologEnumerator        sysInfologEnumerator;

        TestTransactionBase          Transbase,transactionbase;

        TestInventoryTransactions    inventoryTrans;

        boolean                     firstrecord = false,ret = false,post = false;

        testProductReceiptPostingService PostingService = new testProductReceiptPostingService();


        #OCCRetryCount

        try

        {

            while select * from inventoryTrans

            join Transbase

                where Transbase.ID == inventoryTrans.ID

                   && Transbase.TransactionType == 'OReceiveItem'

                   && (Transbase.Task == 'ProcessOReceiveItemPurchaseReceiptToStock'

                   ||  Transbase.Task == 'ProcessOReceiveItemPurchaseReceiptToInspection'

                   ||  Transbase.Task == 'ProcessOReceiveItemPurchaseReceiptToDock')

                   &&  Transbase.IsProcessed == testIsprocessed::NotProcessed

            {

                ttsbegin;

                if (firstrecord == false)

                {

                    PostingService.insertParmTableData(inventoryTrans,Transbase);

                    firstrecord = true;

                }

                ret = PostingService.insertParmLineData(inventoryTrans,Transbase);

                if (ret == true)

                {

                    PostingService.updateTransactionBase(Transbase);

                }

                ttscommit;

            }

            if(ret == true)

            {

                post = PostingService.processProductReceipt();

            }

        }

        catch(Exception::Error)

        {

            error('Error: Posting failed!');

               

            errormessage = infolog.text(infologLine());


            ttsbegin;

            testtransactionbase                  = testtransactionbase::findbyId(Transbase.ID,true);

            testtransactionbase.IsProcessed      = testIsprocessed::NotProcessed;

            testtransactionbase.errordescription = errormessage;

            testtransactionbase.update();

            ttscommit;

        }

        catch (Exception::Deadlock)

        {

            retry; // *** here the program stucked and not continue.

        }

        catch (Exception::UpdateConflict)

        {

            retry;

        }

        catch(Exception::DuplicateKeyException)

        {

            // retry in case of an duplicate key conflict

            if (appl.ttsLevel() == 0)

            {

                if (xSession::currentRetryCount() >= #RetryNum)

                {

                    throw Exception::DuplicateKeyExceptionNotRecovered;

                }

                else

                {

                    retry;

                }

            }

            else

            {

                throw Exception::DuplicateKeyException;

            }

        }

    }

}



Controller class for run operation:



class testProductReceiptPostingController extends SysOperationServiceController

{

    protected void new()

    {

        super();

        this.parmClassName(classStr(TestProductReceiptPostingHelper));

        this.parmMethodName(methodStr(TestProductReceiptPostingHelper, processOperation));


        this.parmDialogCaption('TestProduct Receipt Posting Batch');

    }


    public ClassDescription caption()

    {

        return 'Test Product Receipt Posting Batch';

    }


    public static void main(Args args)

    {

        TestProductReceiptPostingController controller;

    

        controller = new TestProductReceiptPostingController();

        controller.parmShowDialog(true);

        controller.startOperation();

    }


}


If we implement it in Multithreading using Sysoperation. Well !! will see it  in my next blog !!!

Thank you !


BYOD connection using X++ code

 //using System.Data.SqlClient;

class BYODConnection

{

    //    private DMFDataSource dmfDataSource

//    /// <summary>

//    /// Runs the class with the specified arguments.

//    /// </summary>

//    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)

    {

        boolean issuccess;

        str connectionstr;

        DMFDataSource dmfdb = DMFDataSource::find("BYOD10");

        if(dmfdb)

        {

            issuccess = DMFDataSource::validateEntityConnectionString(dmfdb);

        }

        else

        {

            CryptoBlob encryptedCryptoBlob;

            str value = "Data Source=serverName,1433; Initial Catalog=DB; Integrated Security=False; User ID=USer; Password=Passwrd";

// encrpyt the connection string

            encryptedCryptoBlob = WinAPIServer::cryptProtectData(str2cryptoblob(value));

            dmfdb.SourceName = "BYOd10";

            dmfdb.Type = DMFSourceType::EntityDB;

            dmfdb.Description = 'D365 to AZure Sql';

            dmfdb.EnableTargetTriggers = NoYes::Yes;

            dmfdb.insert();

            if(dmfdb)

            {

                Common common = dmfdb;

                connectionstr = appl.EncryptToStringForPurpose(value, common.encryptionPurpose(fieldNum(DMFDataSource, EntityStoreConnectionString)));

                info(strFmt("%1",connectionstr));

                ttsbegin;

                dmfdb.selectForUpdate(true);

                dmfdb.EntityStoreConnectionString = connectionstr;

                dmfdb.update();

                ttscommit;

                issuccess = DMFDataSource::validateEntityConnectionString(dmfdb);

            }

        }

        if(issuccess)

        {

            Info("Done");

        }

        else

        {

            Error("Failed");

        

        }

    

    }


}

Publish Entity using X++ code in D365 Fo

Using the below class we can publish entities to BYOD


 class Entitypublish

{

    /// <summary>

    /// Runs the class with the specified arguments.

    /// </summary>

    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)

    {

        DmfPublishedEntity dmfPublishedEntity;

        MV2EntityList    EntityList;

        DMFDataSource dmfDataSource;

        container listOfUnPublishedEntites,listOfPublishedEnties;


        boolean alreadyPublished;

        Entitypublish class1 = new Entitypublish();

        while select * from EntityList

        {

            DMFEntity entityloc = DMFEntity::find(EntityList.EntityName);

            dmfDataSource = dmfDataSource::find("BYOD10");


            select firstonly EntityName from dmfPublishedEntity

                    where dmfPublishedEntity.EntityName == entityloc.EntityName

                       && dmfPublishedEntity.SourceFormat == dmfDataSource.SourceName;

            

            if (dmfPublishedEntity.RecId)

            {

                alreadyPublished = true;

                listOfPublishedEnties =conIns(listOfPublishedEnties,1, dmfPublishedEntity.EntityName);

            }

            else

            {

                listOfUnPublishedEntites =conIns(listOfUnPublishedEntites,1,entityloc.EntityName);

            }

            class1.changetracking(entityloc);

        }

    

        if (alreadyPublished)

        {

            str  publishedEnties = con2Str(listOfPublishedEnties,',');

            DialogButton dialogBox = Box::yesNo(strFmt('@DMF:DMFEntityRePublishConfirm',publishedEnties,dmfDataSource.SourceName),DialogButton::No);


            if (dialogBox == DialogButton::Yes)

            {

                DMFEntityDbPublish::publishSchemaAsync(str2con(dmfDataSource.SourceName),listOfPublishedEnties,NoYes::Yes, '');

            }

        }

            

        if (conLen(listOfUnPublishedEntites))

        {

            DMFEntityDbPublish::publishSchemaAsync(str2con(dmfDataSource.SourceName),listOfUnPublishedEntites,NoYes::No, '');

        }

    }


    //Change tracking

        

           

    public void changetracking(DMFEntity _entityloc)

    {

        DictDataEntity dictEntity = new DictDataEntity(tableName2Id(_entityloc.TargetEntity));

        Query query = DMFEntityBase::defaultCTQuery(dictEntity);

        if(query == null)

        {

            if (DMFEntityBase::enableChangeTracking(_entityloc, true, true, false))

            {

                this.listOfTablesCTEnabled(_entityloc, DMFChangeTrackingType::ALL);


            }

        }

        else

        {

            if(DMFEntityBase::enableChangeTracking(_entityloc, true, true,true))

            {

                this.listOfTablesCTEnabled(_entityloc, DMFChangeTrackingType::CustomQuery);

            }

        

        }

        

    }


    public void listOfTablesCTEnabled(DMFEntity _entity,DMFChangeTrackingType __changeTrackingType)

    {

           

        AifSqlChangeTrackingEnabledTables   CTEnabledTablesloc;

        container   listOfEnabledTables;

        while select TableName from CTEnabledTablesloc

            where CTEnabledTablesloc.EntityName == _entity.TargetEntity

        {

            listOfEnabledTables = conIns(listOfEnabledTables,1,CTEnabledTablesloc.TableName);

        }

        if (conLen(listOfEnabledTables))

        {

            info(strFmt("@DMF:DMFCTEnableSuccess", _entity.EntityName));

            info(strFmt("@DMF:DMFCTEnabledList",con2Str(listOfEnabledTables)));

            info("@DMF:DMFCTIncrementalPush");

        }

    

    }


}