Create a batch job to export the file in azure blob container through batch job

 Today we have requirement to create batch job that export the data and put in the azure container for that we need a config and string that needs to be validate in the custom form.


=====================================================================


//Batch job to export transfer order 

class AVABLMExportBatch extends RunBaseBatch

{  

    QueryRun    queryRun;

    str         itemData2;


    #DEFINE.CurrentVersion(1)

 

    public container pack()

    {

        container pack = conNull();


        if (queryRun)

        {

            pack = queryRun.pack();

        }

        return [#CurrentVersion] + [pack];

    }


    public Object dialog()

    {

        DialogRunbase dialog = super();

 

                

        return dialog;

    }


    public boolean getFromDialog()

    {

        boolean         ret;

 

        ret = super();

        

 

        return ret;

    }


    /// <summary>

    /// Contains the code that does the actual job of the class.

    /// </summary>

    public void run()

    {

        TextStreamIo                                    textStreamIo;

        AVAInventTransferOrderHeaderLineExportEntityV2  transferOrderExport;

        System.IO.Stream                                fileStream;

        InventTransferTable                             transferTable;

        str                                             fileName;

        SystemParameters                                systemParameters = SystemParameters::find();

        int                                             check = 0;

        ProdTable                                       prodTable,parentProdTable;

        InventDim                                       inventDim,parentInventDim,prodBomInventdim;

        Route                                           route, routeKitItem;

        ProdPool                                        prodPool,bomProdPool;

        ProdBOM                                         prodBom;

        BOMTable                                        bomTable;

        BOM                                             bom;

        InventTable                                     inventTableProdBom;

        RouteVersionV2Entity                            routeVersionEntity;

        boolean                                         foundKitItem;

        real                                            totalQty;

        

        #File

        ;

       

        //If condn Validates azure blob connection

        if(AVAAzureStorageHelper::azureBlobConnectionChk(systemParameters.AVAAzureConnectionString,systemParameters.AVABLMContainer) == NoYes::Yes)

        {

            textStreamIo = TextStreamIo::constructForWrite();

            textStreamIo.outRecordDelimiter(#delimiterCRLF);

            textStreamIo.outFieldDelimiter(";");

            fileName     = "BLM export";


            //Header

            textStreamIo.writeExp(['FIELD5','FIELD3','Field1','Field10Str','Field11','Field12','Field13','Field14','FIELD15','Field16','Field17','Field18','Field19','Field2','Field20','Field21','Field22','Field23','Field24','Field25','Field26','Field27','Field28','Field29','Field30','Field31','Field32','Field33','Field34','Field35','Field36','Field4','Field6','Field7','Field8','Field9','INVENTCOLORID','INVENTREVISION','INVENTSIZEID','INVENTSTYLEID','ParentDeliveryDate','ParentItemId','ParentItemInventColorId','ParentItemInventRevision','ParentItemInventSizeId','ParentItemInventStyleId','ParentProdId','ParentProdPoolId','PRODPOOLID']);


            try

            {

                queryRun = this.queryRun();

                while (queryRun.next())

                {                     

                    prodTable = queryRun.get(tableNum(ProdTable));

                    inventDim = queryRun.get(tableNum(InventDim));

                    //If condn to check if nesting flag is set for the prod orders

                    if(AVACheckNestingResourceGroup_EventHandler::checkBLMResGroup(prodTable.ProdId))

                    {

                        check = 1;


                        foundKitItem = AVACheckRouteVersionDetailHelper::checkKitItem(prodTable.ProdPoolId);


                        if(foundKitItem)

                        {

                            while select bomtable

                                where bomTable.BOMId == prodTable.BOMId

                            join bom

                                where bom.BOMId == bomTable.BOMId

                            join inventTableProdBom

                               where inventTableProdBom.ItemId == bom.ItemId

                            join bomProdPool

                                where bomProdPool.ProdPoolId == inventTableProdBom.ProdPoolId

                                   && bomProdPool.AVACutList  == NoYes::Yes

                            {

                                prodBomInventdim = inventDim::find(bom.InventDimId);


                                EcoResProduct            product            = EcoResProduct::findByProductNumber(bom.ItemId);

                                EcoResProductTranslation productTranslation = EcoResProductTranslation::findByProductLanguage(product.Recid, 'EN-US');

                                

                                routeVersionEntity = AVACheckRouteVersionDetailHelper::avaGetRouteVersionDetail(bom.ItemId,prodBomInventdim.InventStyleId,prodBomInventdim.configId,prodBomInventdim.InventColorId,prodBomInventdim.InventSizeId,prodBomInventdim.InventDimension1);


                                routeKitItem = route::findFirst(routeVersionEntity.RouteId);

                                totalQty     = (bom.BOMQty * prodTable.QtySched);


                                textStreamIo.writeExp([prodTable.ProdId,bom.ItemId,'',date2Str(prodTable.SchedStart,123,DateDay::Digits2,DateSeparator::Slash,                      DateMonth::Digits2,DateSeparator::Slash,DateYear::Digits4),'','','','',totalQty,'','','','',productTranslation.Description,'','','',routeKitItem.AVALength,'','',enum2Str(routeKitItem.AVATubeType),'','','','',routeKitItem.AVAUnloadPosition,'',routeKitItem.avanotes,'','','','','','','','',prodBomInventdim.InventColorId,prodBomInventdim.InventDimension1,prodBomInventdim.InventSizeId,prodBomInventdim.InventStyleId,date2Str(parentProdTable.DlvDate,123,DateDay::Digits2,DateSeparator::Slash,DateMonth::Digits2,DateSeparator::Slash,DateYear::Digits4),prodTable.ItemId,inventDim.InventColorId,inventDim.InventDimension1,inventDim.InventSizeId,inventDim.InventStyleId,prodTable.ProdId,prodTable.ProdPoolId,bomProdPool.ProdPoolId]);

                               

                            }

                            //Set the blm check export, to eliminate the export of both new and changed records

                            ttsbegin;

                            prodTable.selectForUpdate(true);

                            prodTable.skipAosValidation(true);

                            prodTable.AVABLMExportCheck = NoYes::Yes;

                            prodTable.doUpdate();

                            ttscommit;

                        }

                        

                        else

                        {

                            EcoResProduct            product            = EcoResProduct::findByProductNumber(prodTable.ItemId);

                            EcoResProductTranslation productTranslation = EcoResProductTranslation::findByProductLanguage(product.Recid, 'EN-US');


                            select firstonly AVANotes, AVATubeType, AVAUnloadPosition, AVALength from route

                                where route.RouteId == prodTable.RouteId;


                            //parent production order details

                            parentProdTable        = AVABLMNestEntity::parentProdDeatils(prodTable);


                            if(parentProdTable)

                            {

                                select firstonly InventColorId,InventSizeId,InventStyleId,InventDimension1 from parentInventDim

                                    where parentInventDim.inventDimId == parentProdTable.InventDimId;

                            }


                            textStreamIo.writeExp([prodTable.ProdId,prodTable.ItemId,'',date2Str(prodTable.SchedStart,123,DateDay::Digits2,DateSeparator::Slash,                      DateMonth::Digits2,DateSeparator::Slash,DateYear::Digits4),'','','','',prodTable.QtySched,'','','','',productTranslation.Description,'','','',route.AVALength,'','',enum2Str(route.AVATubeType),'','','','',route.AVAUnloadPosition,'',route.avanotes,'','','','','','','','',inventDim.InventColorId,inventDim.InventDimension1,inventDim.InventSizeId,inventDim.InventStyleId,date2Str(parentProdTable.DlvDate,123,DateDay::Digits2,DateSeparator::Slash,

                                  DateMonth::Digits2,DateSeparator::Slash,DateYear::Digits4),parentProdTable.ItemId,parentInventDim.InventColorId,parentInventDim.InventDimension1,parentInventDim.InventSizeId,parentInventDim.InventStyleId,parentProdTable.ProdId,parentProdTable.ProdPoolId,prodTable.ProdPoolId]);


                            //Set the blm check export, to eliminate the export of both new and changed records

                            ttsbegin;

                            prodTable.selectForUpdate(true);

                            prodTable.skipAosValidation(true);

                            prodTable.AVABLMExportCheck = NoYes::Yes;

                            prodTable.doUpdate();

                            ttscommit;

                        }

                    }

                }


                if(check == 1)

                {

                    AVAAzureStorageHelper::uploadFileToAzureBlob(textStreamIo,fileName);

                }

            }

            catch(Exception::Error)

            {

                error("ERROR");

            }

            CodeAccessPermission::revertAssert();

           

        }

    }


    /// <summary>

    /// Determines whether the batch task is run on the server or on a client.

    /// </summary>

    /// <returns>

    /// true if the task is run on the server; otherwise, false.

    /// </returns>

    /// <remarks>

    /// Your classes that extend <c>RunBaseBatch</c> must override the <c>runsImpersonated</c> method and

    /// return false, if you want those tasks to run on a client.

    /// </remarks>

    public boolean runsImpersonated()

    {

        return true;

    }


    /// <summary>

    /// Determines whether to add a Select button to the dialog box.

    /// </summary>

    /// <returns>

    /// Always returns true.

    /// </returns>

    /// <remarks>

    /// If you click this button, it will show the query form. Therefore, the <c>queryRun</c> method has to

    /// return a valid <c>queryRun</c> value.

    /// </remarks>

    public boolean showQueryValues()

    {

        return true;

    }


   /// <summary>

    /// </summary>

    public void initQueryRun()

    {

        Query                               query = new Query();

        QueryBuildDataSource                prodTableDS,inventDimDS;

        QueryBuildRange                     prodStatusRange,prodExpChkRange;

           

        prodTableDS     = query.addDataSource(tableNum(ProdTable));

        prodStatusRange = prodTableDS.addRange(fieldNum(ProdTable, ProdStatus));

        prodStatusRange.value(SysQuery::value(ProdStatus::Released));

        prodExpChkRange = ProdTableDS.addRange(fieldNum(ProdTable,AVABLMEXPORTCHECK));

        prodExpChkRange.value(SysQuery::value(NoYes::No));


        inventDimDS     = prodTableDS.addDataSource(tableNum(InventDim));

        inventDimDS.relations(true);

            

        queryRun = new QueryRun(query);

        queryRun.saveUserSetup(true);

    }


    /// <summary>

    ///

    /// </summary>

    /// <returns></returns>

    public QueryRun queryRun()

    {

        return queryRun;

    }


    public boolean unpack(container _packedClass)

    {

        boolean     ret         = false;

        int         version     = RunBase::getVersion(_packedClass);

        container   packedQuery = conNull();


        switch (version)

        {

            case #CurrentVersion:

                [version, packedQuery] = _packedClass;


                if (SysQuery::isPackedOk(packedQuery))

                {

                    queryRun   = new QueryRun(packedQuery);

                    ret         = true;

                }

                break;


            default:

                ret = false;

        }

        return ret;

    }


    public static AVABLMExportBatch  construct()

    {

        return new AVABLMExportBatch();

    }


    Static public ClassDescription description()

    {

        return "BLM export";

    }


    client static void main(Args  args)

    {

        AVABLMExportBatch     obj = AVABLMExportBatch::construct();

        obj.parmInBatch(true);

        obj.getLast();

        obj.caption();

        obj.initQueryRun();


        if (obj.prompt())

        {

            obj.runOperation();

        }

    }


    protected boolean canRunInNewSession()

    {

        return false;

    }


    /// <summary>

    /// Sigma nest check box

    /// </summary>

    public boolean checkNestedResGroup(ProdId _prodId)

    {

        ProdTable                                          prodTable;

        Route                                              routeTable;

        RouteOpr                                           routeOpr;

        WrkCtrResourceGroup                                resourceGroup;

        RouteOperationPropertiesResourceRequirementEntity  routeOperationPropertiesResourceRequirementEntity;

        wrkCtrActivityResourceGroupRequirement             wrkCtrActivityResourceGroupRequirement;

        WrkCtrResourceGroupResource                        wrkCtrResourceGroupResource;

        WrkCtrCapRes                                       wrkCtrCapRes;

        Route                                              route;

        NoYesId                                            checkNestedResGroup = NoYes::No;

        InventDim                                          inventDim;

            

        select firstonly * from routeOperationPropertiesResourceRequirementEntity

            join prodTable

               where prodTable.RouteId == routeOperationPropertiesResourceRequirementEntity.RouteId

                  && prodTable.ProdId == _prodId

            join resourceGroup

               where resourceGroup.WrkCtrId == routeOperationPropertiesResourceRequirementEntity.RequiredOperationsResourceGroupId

                  && resourceGroup.AVANestingFlag == NoYes::Yes;


        if (routeOperationPropertiesResourceRequirementEntity)

        {

            checkNestedResGroup = NoYes::Yes;

            //Next operation of the resource where the nesting flag is set <Start>

            inventDim    = InventDim::find(prodTable.inventDimID);

                      

            select firstonly WrkCtrId from wrkCtrCapRes

                join route

            where route.OprId              == routeOperationPropertiesResourceRequirementEntity.RouteOperationId

               && route.RouteId            == prodTable.RouteId

               && wrkCtrCapRes.OprNum      == route.OprNumNext

               && wrkCtrCapRes.OprPriority == route.OprPriority

               && wrkCtrCapRes.RefId       == prodTable.ProdId

               && wrkCtrCapRes.RefType     == WrkCtrCapRefType::Production;


            this.ItemData2 = wrkCtrCapRes.WrkCtrId;

           

            //Next operation of the resource where the nesting flag is set <End>

        }

        else

        {

            select firstonly * from routeOperationPropertiesResourceRequirementEntity

            join prodTable

               where prodTable.RouteId == routeOperationPropertiesResourceRequirementEntity.RouteId

                  && prodTable.ProdId == _prodId

            join wrkCtrResourceGroupResource

               where wrkCtrResourceGroupResource.WrkCtrId == routeOperationPropertiesResourceRequirementEntity.RequiredOperationsResourceId

            join resourceGroup

               where resourceGroup.RecId == wrkCtrResourceGroupResource.ResourceGroup

                  && resourceGroup.AVANestingFlag == NoYes::Yes;

            if (routeOperationPropertiesResourceRequirementEntity)

            {

                checkNestedResGroup = NoYes::Yes;

                //Next operation of the resource where the nesting flag is set <Start>

                inventDim    = InventDim::find(prodTable.inventDimID);

               

                select firstonly WrkCtrId from wrkCtrCapRes

                        join route

                    where route.OprId              == routeOperationPropertiesResourceRequirementEntity.RouteOperationId

                        && route.RouteId            == prodTable.RouteId

                        && wrkCtrCapRes.OprNum      == route.OprNumNext

                        && wrkCtrCapRes.OprPriority == route.OprPriority

                        && wrkCtrCapRes.RefId       == prodTable.ProdId

                        && wrkCtrCapRes.RefType     == WrkCtrCapRefType::Production;


                this.ItemData2 = wrkCtrCapRes.WrkCtrId;

                        

                //Next operation of the resource where the nesting flag is set <End>

            }

        }

       

        return checkNestedResGroup;

              

    }


}

======================================================================

Step 2 :- Create a Azure helper class 


//File upload to azure storage

using Microsoft.Azure;

using Microsoft.WindowsAzure.Storage;

using Microsoft.WindowsAzure.Storage.Blob;

using Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer;

using Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob;

class AVAAzureStorageHelper

{   

    static CloudStorageAccount storageAccount;

    static CloudBlobClient     storageBlobClient ;

    static CloudBlobContainer  storageBlobContainer ;

    static CloudBlockBlob     storageBlockBlob;

    public static void uploadFileToAzureBlob(StreamIo fileAzure, str fileName)

    {

        var         fileContent         = fileAzure.getStream();

        str         fileCreationDate    = date2Str(today(),213,2,0,2,0,4);

        utcdatetime currentDateTime     = HcmDateTimeUtil::dateTimeUser(DateTimeUtil::utcNow());

        str         time                = time2Str(DateTimeUtil::time(currentDateTime),1,2);

        str         timestamp           = '_'+fileCreationDate+'_'+time;

            

        if(fileContent.CanSeek)

        {

            fileContent.Seek(0,System.IO.SeekOrigin::Begin);

        }


        storageBlockBlob        = storageBlobContainer.GetBlockBlobReference(fileName+timestamp+'.txt');

        storageBlockBlob.UploadFromStreamAsync(fileContent).Wait();

    }


    // check Azure blob connection

    public static boolean azureBlobConnectionChk(str azureConnectionString,str blobContainer)

    {

        boolean ret;

        try

        {

            storageAccount          = CloudStorageAccount::Parse(azureConnectionString);

            storageBlobClient       = storageAccount.CreateCloudBlobClient();

            storageBlobContainer    = storageBlobClient.GetContainerReference(blobContainer);

            ret = true;

        }

        catch

        {

            ret = false;

        }

        return ret;

    }


}

=============================================================

Comments

Popular posts from this blog

Customization on Sales invoice Report in D365 F&O

75) COC - Create a coc of the table modified method

46) D365 FO: SHAREPOINT FILE UPLOAD USING X++