Thursday 10 August 2023

Import General journal from excel in D365 F&O

 Hi Guys,

Import General journal from excel in D365 F&O


Code: 

using System.IO;

using OfficeOpenXml;

using OfficeOpenXml.ExcelPackage;

using OfficeOpenXml.ExcelRange;


public class SWC_GeneralJournalUpload

{

    str                  legalentityid,journalbatchnumber,journalname, voucher,accountType,accountdisplayvalue,defaultdimensionsdisplayvalue,text,currencycode,invoice,offsetAccountType, curJournal;

    TransDate            transDate,documentDate,dueDate,reverseDate;

    int                  rowCount, i, invoicingItemIterator = 0;

    str                  offsetLedgerDimension, offsetdefalutdimensiondisplayvalue,paymReference,postingProfile,postinglayer,reverseEntry;

    real                 lineNum,debitamount,creditamount ;

    container            journalContainer;

    boolean              colorDimval = false, sizeDimVal = false;

    int                  toDeleteIterator = 0;

    container            toDeleteCon;

    boolean              checkErrorJour = true;

    Notes                               errorNote = '';

    int                      errorCount;

    boolean                  receivedErrorInFile, createRecord = true;


  

    public static void main(Args _args)

    {

        System.IO.Stream                 stream;

        DialogGroup                      dlgUploadGroup;

        FileUploadBuild                  fileUploadBuild;

        FormBuildControl                 formBuildControl;

        SWC_GeneralJournalUpload    itemJournalImport;

        Name                             itemJournalForm;

        FormRun                          callerForm;


        Dialog  dialog          = new Dialog("Import the data from Excel");


        dlgUploadGroup          = dialog.addGroup("General Journal Import");

        formBuildControl        = dialog.formBuildDesign().control(dlgUploadGroup.name());

        fileUploadBuild         = formBuildControl.addControlEx(classstr(FileUpload), "Upload");


        fileUploadBuild.style(FileUploadStyle::MinimalWithFilename);

        fileUploadBuild.fileTypesAccepted(".xlsx");


        itemJournalImport = new SWC_GeneralJournalUpload();


        if (dialog.run() && dialog.closedOk())

        {

            infolog.clear();

            

            FileUpload fileUploadControl     = dialog.formRun().control(dialog.formRun().controlId("Upload"));

            FileUploadTemporaryStorageResult fileUploadResult = fileUploadControl.getFileUploadResult();


            if (fileUploadResult != null && fileUploadResult.getUploadStatus())

            {

                stream = fileUploadResult.openResult();


                callerForm = _args.caller();


                if(callerForm)

                {

                    itemJournalForm = callerForm.args().menuItemName();

                }

                

                ttsbegin;

                itemJournalImport.insertbudget(stream); //todo

                ttscommit;

            }

            else

            {

                error("Error here");

            }

        }

    }


    /// <summary>

    /// Static method to get default dimension

    /// </summary>

    /// <param name = "conAttr">Dimension attribute container</param>

    /// <param name = "conValue">Dimension value container</param>

    /// <returns>defualt dimension</returns>

    public static DimensionDefault getDefaultDim(container conAttr, container conValue)

    {

        DimensionAttributeValueSetStorage   valueSetStorage = new DimensionAttributeValueSetStorage();

        int                     i;

        DimensionAttribute      dimensionAttribute;

        DimensionAttributeValue dimensionAttributeValue;

        str                     dimValue;


        if((conLen(conAttr) <= 0) || (conLen(conValue) <= 0))

        {

            throw error("@SYS313886");

        }


        for (i = 1; i <= conLen(conAttr); i++)

        {

            dimensionAttribute = dimensionAttribute::findByName(conPeek(conAttr,i));

            if (dimensionAttribute.RecId == 0)

            {

                continue;

            }

            dimValue = conPeek(conValue,i);

            if (dimValue != "")

            {

                dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,dimValue,false,true);

                valueSetStorage.addItem(dimensionAttributeValue);

            }

        }


        return valueSetStorage.save();

    }


    // Started Here 10082023

    public void validateDimenison(container _conValue, container _conAttr)

    {

        DimensionAttributeValueSetStorage   valueSetStorage = new DimensionAttributeValueSetStorage();

        DimensionDefault                    result;

        int                     counti;

        DimensionAttribute      dimensionAttribute;

        DimensionAttributeValue dimensionAttributeValue;

        str                     dimValue;

       


        for (counti = 1; counti <= conLen(_conAttr); counti++)

        {

            dimensionAttribute = dimensionAttribute::findByName(conPeek(_conAttr,counti));

            if (dimensionAttribute.RecId == 0)

            {

                continue;

            }

            dimValue = conPeek(_conValue,counti);

            if (dimValue != "")

            {

                dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndValueNoError(dimensionAttribute,dimValue,false,true);

                if (!dimensionAttributeValue)

                {

                    errorNote += strFmt("%3: Value %1 does not existis for dimension %2 " , conPeek(_conValue, counti), conPeek(_conAttr, counti), errorCount);

                    receivedErrorInFile = true;

                    errorCount++;

                }

            }

        }

    }


    // Ended Here


    /// <summary>

    /// Account type Container Ledger dimesion is ledger combination of Main account And FD 10082023 Stated

    /// </summary>

    /// <param name = "_conData"></param>

    /// <param name = "mainAccountNumber"></param>

    /// <param name = "_conDimName"></param>

    /// <returns></returns>

    public DimensionDynamicAccount generateLedgerDimension_loc(container _conData,MainAccountNum mainAccountNumber, container _conDimName)

    {

        int hierarchyCount;

        int hierarchyIdx;

        LedgerRecId ledgerRecId;

        MainAccount mainAccount;

        RefRecId recordvalue;

        DimensionAttribute dimensionAttribute;

        DimensionAttributeValue dimensionAttributeValue;

        DimensionSetSegmentName dimensionSet;

        DimensionStorage dimStorage;

        LedgerAccountContract ledgerAccountContract = new LedgerAccountContract();

        DimensionAttributeValueContract valueContract;

        List valueContracts = new List(Types::Class);

        dimensionAttributeValueCombination dimensionAttributeValueCombination;


        mainAccount = MainAccount::findByMainAccountId(mainAccountNumber);

        recordvalue = DimensionHierarchy::getAccountStructure(mainAccount.RecId, Ledger::current());

        hierarchyCount = DimensionHierarchy::getLevelCount(recordvalue);

        dimensionSet = DimensionHierarchyLevel::getDimensionHierarchyLevelNames(recordvalue);

        for (hierarchyIdx = 1; hierarchyIdx <= conLen(_conDimName); hierarchyIdx++)

        {

            if (hierarchyIdx <= 1)

            {

                continue;

            }


            dimensionAttribute = DimensionAttribute::findByLocalizedName(conPeek(_conDimName, hierarchyIdx),false);

            if (dimensionAttribute)

            {

                dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,conPeek(_conData,hierarchyIdx));

                if (dimensionAttributeValue)

                {

                    valueContract = new DimensionAttributeValueContract();

                    valueContract.parmName(dimensionAttribute.Name) ;

                    valueContract.parmValue(dimensionAttributeValue.CachedDisplayValue);

                    valueContracts.addEnd(valueContract);

                }

                else if (!dimensionAttributeValue && conPeek(_conData,hierarchyIdx))

                {

                    throw Error(strFmt("The dimension value - %1 for dimension - %2 doesnot exists ", conPeek(_conData,hierarchyIdx), dimensionAttribute.DimensionKeyColumnName));

                }

            }

        }

        

        ledgerAccountContract.parmMainAccount(mainAccountNumber);

        ledgerAccountContract.parmValues(valueContracts);

        dimStorage = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(ledgerAccountContract);

        dimensionAttributeValueCombination = DimensionAttributeValueCombination::find(dimStorage.save());

        ledgerRecId = dimensionAttributeValueCombination.RecId;

        LedgerDimensionBudget accountDimension = LedgerDimensionFacade::serviceCreateLedgerDimensionForType(LedgerDimensionType::Account, ledgerRecId);


        return accountDimension;

    }


    //---------------EndHERE-------------------


    public static DimensionDynamicAccount createLedgerDimFromMainAccount(container conAttr, container conValue, Name mainAccount, LedgerJournalACType accountType)

    {

        DimensionDefault        dimensionDefault;

        DimensionDynamicAccount dimensionDynamicAccount;

        LedgerDimensionBase     ledgerDimBase;

        LedgerDimensionAccount  ledgerDim;


        dimensionDefault        = SWC_GeneralJournalUpload::getDefaultDim(conAttr, conValue);

        dimensionDynamicAccount = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(mainAccount, accountType);

        ledgerDim = LedgerDimensionFacade::serviceCreateLedgerDimension(dimensionDynamicAccount);


        ledgerDimBase   = LedgerDimensionFacade::serviceCreateLedgerDimForDefaultDim(dimensionDefault, ledgerDim);


        return ledgerDimBase;

    }


    public void insertbudget(System.IO.Stream  _stream)

    {

        

        CommaTextIO                 csvFile;

        container                   readCon;

        counter                     icount,inserted;

        Dialog                      dialog;

        DialogField                 dfFileName;

        FileName                    fileName;

        LedgerJournalTable          ledgerJournalTable;

        LedgerJournalTrans          ledgerJournalTrans;

        container                   offsetdimesionCon, offsetdimesionConValue;


        using (ExcelPackage Package = new ExcelPackage(_stream))

        {

            RecordInsertList                    recordinsertlist;

            int                                 insertedRecords =0, failedrecords=0;


            Package.Load(_stream);

            ExcelWorksheet  worksheet       = package.get_Workbook().get_Worksheets().get_Item(1);

            OfficeOpenXml.ExcelRange range  = worksheet.Cells;


            rowCount = worksheet.Dimension.End.Row - worksheet.Dimension.Start.Row + 1;

            

            //recordinsertlist = new recordinsertlist(tableNum(BudgetTransactionLine)); //todo

            for (i = 2; i<= rowCount; i++)

            {

                legalentityid                   = strLRTrim(range.get_Item(i, 1).value);

                journalbatchnumber              = strLRTrim(range.get_Item(i, 2).value);

                journalname                     = strLRTrim(range.get_Item(i, 3).value);

                transDate                       = any2Date(range.get_Item(i, 4).value);

                voucher                         = strLRTrim(range.get_Item(i, 5).value);

                lineNum                         = any2Real(range.get_Item(i, 6).value);

                accountType                     = strLRTrim(range.get_Item(i, 7).value);

                accountdisplayvalue             = strLRTrim(range.get_Item(i, 8).value);

                defaultdimensionsdisplayvalue   = strLRTrim(range.get_Item(i, 9).value);

                text                            = strLRTrim(range.get_Item(i, 10).value);

                currencycode                    = strLRTrim(range.get_Item(i, 11).value);

                debitamount                     = any2Real(range.get_Item(i, 12).value);

                creditamount                    = any2Real(range.get_Item(i, 13).value);

                invoice                         = strLRTrim(range.get_Item(i, 14).value);

                documentDate                    = any2Date(range.get_Item(i, 15).value);

                dueDate                         = any2Date(range.get_Item(i, 16).value);

                offsetLedgerDimension           = strLRTrim(range.get_Item(i, 17).value);

                offsetAccountType               = strLRTrim(range.get_Item(i, 18).value);

                offsetdefalutdimensiondisplayvalue = strLRTrim(range.get_Item(i, 19).value);

                paymReference                    = strLRTrim(range.get_Item(i, 20).value);

                postinglayer                    = strLRTrim(range.get_Item(i, 21).value);

                postingProfile                  = strLRTrim(range.get_Item(i, 22).value);

                reverseDate                     = any2Date(range.get_Item(i, 23).value);

                //reverseEntry         = strLRTrim(range.get_Item(i, 24).value);


                changecompany(legalentityid)

                {

                    if (!LedgerJournalTable::find(journalbatchnumber))

                    {

                        ledgerJournalTable.clear();

                        ledgerJournalTable.initValue();

                        //ledgerJournalTable.JournalName;

                        ledgerJournalTable.initFromLedgerJournalName();

                        ledgerJournalTable.JournalNum   = journalbatchnumber;//JournalTableData::newTable(ledgerJournalTable).nextJournalId();

                        ledgerJournalTable.JournalName  = journalname;   

                        ledgerJournalTable.insert();


                        info(strFmt("Journal %1 created", ledgerJournalTable.JournalNum));

                    }

                    LedgerJournalACType ledgerJournalACType;

                    

                    offsetdimesionCon = ["","A_Budget_L3","B_Vehicle","C_Electricity_Meter","D_FDR","E_Mutual_Fund","F_Employee","G_Vendor","H_Budget_L2","I_Budget_L1","J_Vehicle_Ownership","K_Electricity_Meter_Subhead"];

                    offsetdimesionConValue = conNull();//["","","","","","",""];


                    //coded by validation start 10082023

                    offsetdimesionConValue = str2con_RU(accountdisplayvalue, "|");

                    MainAccount mainAccount = MainAccount::findByMainAccountId(conPeek (offsetdimesionConValue, 1));


                    if (!mainAccount)

                    {

                        errorNote += strFmt("%2. Main account %1 does not exsits " , conPeek (offsetdimesionConValue, 1), errorCount);

                        receivedErrorInFile = true;

                        errorCount++;

                    }

                    offsetdimesionConValue = conPoke(offsetdimesionConValue, 1, "");

                    this.validateDimenison(offsetdimesionConValue, offsetdimesionCon);

                    //this.generateLedgerDimension_loc(offsetdimesionConValue, conPeek(offsetdimesionConValue, 1), offsetdimesionCon);

                    //coded by validation End Here 10082023


                    ledgerJournalTrans.clear();

                    ledgerJournalTrans.initValue();

                    ledgerJournalTrans.JournalNum           = ledgerJournalTable.JournalNum;

                    ledgerJournalTrans.TransDate            = transDate;

                    //LedgerJournalName           ledgerJournalName;

                    //NumberSeq                   numberseq;

                    //NumberSequenceTable         numberSequenceTable;

                    //Voucher                     voucherNum;

                    //LedgerParameters       LedgerParameters;

                    //ledgerParameters    = LedgerParameters::find();

                    //ledgerJournalName   = LedgerJournalName::find(JournalName);

                    //numberseq   = NumberSeq::newGetVoucherFromCode(NumberSequenceTable::find(ledgerJournalName.NumberSequenceTable).NumberSequence);

                    //numberseq.voucher();


                    ledgerJournalTrans.Voucher              = voucher;

                    ledgerJournalTrans.LineNum              = lineNum;

                    ledgerJournalTrans.AccountType          = str2Enum(ledgerJournalACType, accountType );

                    if(accountType =="Bank")

                    {

                        ledgerJournalTrans.LedgerDimension      = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(accountdisplayvalue,LedgerJournalACType::Bank);//str2Int64(accountdisplayvalue);

                    }

                    if(accountType =="Vend")

                    {

                        ledgerJournalTrans.LedgerDimension      = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(accountdisplayvalue,LedgerJournalACType::Vend);//str2Int64(accountdisplayvalue);

                    }

                    if(accountType =="Cust")

                    {

                        ledgerJournalTrans.LedgerDimension      = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(accountdisplayvalue,LedgerJournalACType::Cust);//str2Int64(accountdisplayvalue);

                    }

                    if(accountType =="Ledger")

                    {

                        offsetdimesionCon = ["","A_Budget_L3","B_Vehicle","C_Electricity_Meter","D_FDR","E_Mutual_Fund","F_Employee","G_Vendor","H_Budget_L2","I_Budget_L1","J_Vehicle_Ownership","K_Electricity_Meter_Subhead"];

                        offsetdimesionConValue = conNull();

                        offsetdimesionConValue = str2con_RU(accountdisplayvalue, "|");

                        //ledgerJournalTrans.LedgerDimension      = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(accountdisplayvalue,LedgerJournalACType::Ledger);

                        ledgerJournalTrans.LedgerDimension =  this.generateLedgerDimension_loc(offsetdimesionConValue, conPeek(offsetdimesionConValue, 1), offsetdimesionCon);

                        //SWC_GeneralJournalUpload::createLedgerDimFromMainAccount(offsetdimesionCon,offsetdimesionConValue,accountdisplayvalue,LedgerJournalACType::Ledger);

           

                    }

                    ledgerJournalTrans.CurrencyCode             = currencycode;

                    ledgerJournalTrans.AmountCurDebit           = debitamount;

                    ledgerJournalTrans.AmountCurCredit          = creditamount;

                    ledgerJournalTrans.Invoice                  = invoice;

                    ledgerJournalTrans.DocumentDate             = documentDate;

                    ledgerJournalTrans.Due                      = dueDate;

                    ledgerJournalTrans.Txt                      = text;

                    ledgerJournalTrans.OffsetAccountType        = str2Enum(LedgerJournalACType, offsetAccountType );

                    //ledgerJournalTrans.OffsetDefaultDimension

                    ledgerJournalTrans.OffsetLedgerDimension    = SWC_GeneralJournalUpload::createLedgerDimFromMainAccount(offsetdimesionCon,offsetdimesionConValue,offsetLedgerDimension,ledgerJournalTrans.OffsetAccountType);

                    ledgerJournalTrans.DefaultDimension         = ledgerJournalTrans.OffsetLedgerDimension;


                    ledgerJournalTrans.PaymReference            = paymReference;


                    ledgerJournalTrans.PostingProfile           = postingProfile;

                    ledgerJournalTrans.ReverseDate              = reverseDate;

                    //ledgerJournalTrans.ReverseEntry   = reverseEntry;

                    ledgerJournalTrans.insert();

                    insertedRecords++;


                }

            }

   

            if(failedrecords == 0 && insertedRecords > 0)

            {

                //recordinsertlist.insertDatabase(); //todo

                for(i = 1; i <= conLen(journalContainer); i++)

                {

                    info(strFmt("Journal Id - '%1' created", conPeek(journalContainer, i)));

                }

                info("Upload successful");

            }

                

        }

    }


}



Excel Template :
















Saturday 24 December 2022

Get Pegging reference number (ReqTransSettled.RefId) in Planned Production order in D365 F&O

Hi All,

I was facing a lot of problem to find pegging records in planned production order in D365 F&O, after struggling a lot I found a solution so here I am with you..👇

public display InventTransRefId cplRefID()

{

    ReqTrans reqTrans,reqTransSettled;

    ReqTransCov reqTransCov;

   

    select reqTrans

    where reqTrans.RefId == this.RefId

    && ReqTrans.RefType == this.RefType

    && reqTrans.PlanVersion == this.PlanVersion

    join reqTransCov

    where reqTransCov.ReceiptRecId == reqTrans.RecId

    join reqTransSettled

    where reqTransSettled.RecId == reqTransCov.IssueRecId;

    

    if (reqTrans.RefId != '')

    {

        return reqTransSettled.RefId;

    }

}


Many Thanks, Atul Kumar  

Friday 13 May 2022

Run multiple Desktop client of Teams at the same time

 Hi All,

Today we found a new way to run multiple instances of Teams, and desktop clients simultaneously.

Copy and paste the following into a text editor (Save with any name and give extension as .CMD)


@ECHO OFF

REM Uses the file name as the profile name

SET MSTEAMS_PROFILE=%~n0

ECHO - Using profile "%MSTEAMS_PROFILE%"

SET "OLD_USERPROFILE=%USERPROFILE%"

SET "USERPROFILE=%LOCALAPPDATA%\Microsoft\Teams\CustomProfiles\%MSTEAMS_PROFILE%"

ECHO - Launching MS Teams with profile %MSTEAMS_PROFILE%

cd "%OLD_USERPROFILE%\AppData\Local\Microsoft\Teams"

"%OLD_USERPROFILE%\AppData\Local\Microsoft\Teams\Update.exe" --processStart "Teams.exe"


Now, double click on the saved file like Team_1.cmd 




It'll launch the desktop team client, then log in with customer or work accounts. :-) 



Cheers! 







 

Sunday 3 April 2022

OData Action method in D365FO(FSCM) and test it using Postman tool

Using Data entity OData action method, we can now expose any custom business logic from D365, without having to create any custom service. And we can create and expose the methods for integrations processes. 

Here we are creating OData Action to validate the sales line price and putting sales orders on hold based on the validation logic from EDI(3rd party).

Step 1:  Create a custom Data entity in D365 Fno and create the OData Action method on the method node of Data entity



Here we have created a static method and decorated it with an attribute [SysOdataActionAttribute].
SysOdataActionAttribute class is used to expose the method as Action.
First, the argument is the Action name and 2nd is Boolean. If Boolean parm is true it means Action is available to use. 
Now we have created the Odata Action method and 3rd party will execute Action “priceValidateEDI” from  API. 



Step 2: Now we can call this Odata action by the below URL from the postman tool.

[D365FO url]/data/DataEntity name /Microsoft.Dynamics.DataEntities.ActionName

Step 3: How to set up postman tool : >

First, go to https://portal.azure.com and click on the "Azure Active Directory"



 Then click on "App registrations" and +New registration
1: Give App registration name 
2: select Any Azure AD Directory-Multitenant
3: select URI as Web and set D365 Fno URL and click Register.

Application created successfully. Now click on App permissions 


Click Add permission and select Microsoft Dynamics ERP


Then select "Delegated permissions" and "Application permissions" and give full permissions and then click Add permissions 






Then you can see the below screen and then "Grant Admin consent for ABC" and then you will see the green status, which means permissions Granted.  


Step 4: After that Create "Client Secret": Click new client secret then give Description and Expires, click Add.







Now click on Overview and copy the client and Tenant

 


Step 5: All the keys will be used in postman setups so copy from the above step4 and keep it like Client, Tenant, and Secret value.

Four Keys
grant_type   = client_credentials
client_id = {clientId}
client_secret = {client Secret}
resource = {d365 instance url}


Client : 
Tenant : 
Secret Value : 


Then Go to the D365 FO > System Administration > Azure Active Directory applications
Create a new record and give clientId and userid. 




Now we are all set to ready to test API in postman, 

Step 6: First, we need to create a request to generate the Access Token, then we will be able to access the D365FO API.

Decorate the URL(1) above to get the access Token, set the Tenant which already we have copied in steps 4 & 5, https://login.microsoftonline.com/Tenant/oauth2/token
and then click Body (2) and select Form-Data then you need to add Four Keys to generate the Token (3).



Step 7: Click send So here we can see the Access Token, copy the access token this will be used for Authorization.


Step 8: Now click new request and use the below URL for OData action method API 

[D365FO URL]/data/[Your data entity]/Microsoft.Dynamics.DataEntities.['Method name']

Sample URL: https://usnconeboxax1aos.cloud.onebox.dynamics.com/data/PriceValidationSOes/Microsoft.Dynamics.DataEntities.priceValidateEDI

Click the Authorization tab, then select Bearer Token and give access token which is copied from the above step 7.



Step 9: Click Body and we have 2 parameters in the OData action method so we are giving parameters as salesId and companyId as a parameter in JSON.
On clicking the 'send button for POST request, the called method will be executed.




Step 10: We can go back to D365FO to check if this succeed. Below is the screenshot, where the mentioned sales order has been on-hold.




Many Thanks:-) 























 










































































Wednesday 27 October 2021

Merge main account with default dimension in D365 fno

Hi Guys,

Merge main account with the default dimension in D365 FnO. we can use the below code to implement it.


transJournal.OffsetLedgerDimension    = LedgerDimensionFacade::ServiceCreateLedgerDimension(CustWriteOffFinancialReasonsSetup.WriteOffLedgerDimension, salesLine.DefaultDimension);


After the merge is completed, a new ledger account combination will be created, This behavior resembles the behavior when default dimensions are merged with each other.


Thanks,


Create customer payment journal from code in D365 Fno

Hi Guys,

This is a very common requirement to create Journal from code(X++) but in D365fno some dimension classes are eliminated so here is the code to create and post a customer payment journal in D365 FnO.


1. Create journal header from click method then call below method to create journal lines.

        public void clicked()

        {

            LedgerJournalTable      ledgerJournalTable;

            CustomerCreditTable  customerCreditTable;

            CreateJournal        createJournal;

            LedgerjournalCheckPost  LedgerjournalCheckPost;

            super();

            try

            {

                ttsbegin;

                ledgerJournalTable.initValue();

                ledgerJournalTable.initFromLedgerJournalName("@Ext:CustPay");

                ledgerJournalTable.JournalNum =  JournalTableData::newTable(ledgerJournalTable).nextJournalId();

                ledgerJournalTable.Name = strFmt("@Ext:WriteOff",DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone()));

                createJournal =  new CreateJournal();


                int numlines = createJournal.createJournalLines(ledgerJournalTable.JournalNum,customerCreditTable.JournalNum);


                if(numlines > 0)

                {

                    ledgerJournalTable.insert();

                    if (ledgerJournalTable)

                    {

                        LedgerjournalCheckPost      =   LedgerjournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::Yes);

                        LedgerjournalCheckPost.runOperation(); 

                    }

                    ttsbegin;

                    select firstonly forupdate customerCreditTable

                        where customerCreditTable.JournalNum == customerCreditTable.JournalNum &&

                        customerCreditTable.IsProcessed == NoYes::No;

                    if (customerCreditTable)

                    {    

                        customerCreditTable.IsProcessed = NoYes::Yes;

                        customerCreditTable.JournalNumRef = ledgerJournalTable.JournalNum;

                        customerCreditTable.doUpdate();

                    }

                    customerCreditTable_ds.research();

                    customerCreditTable_ds.refresh();

                    ttscommit;

                    info(strFmt("@Ext:JVCreated",ledgerJournalTable.JournalNum, numlines));

                }

                ttscommit;

            }

            catch (Exception::Error)

            {

                throw Exception::Error;

            }

        }

2. Call this method in the clicked method to create journal lines as per requirement.

    public int createJournalLines(LedgerJournalId   journalId,LedgerJournalId journalIdOrig)

    {

        LedgerJournalTrans              transJournal;

        RecordInsertList                ledgerJournalTransList;

        NumberSeq                       numberseq;

        Voucher                         voucherNum;

        int                             counter;

        CustomerCreditTable          customerCreditTable;

        //CustInvoiceJour                 custInvoiceJour;

        //SalesLine                       salesLine;

        //LedgerDimensionDefaultAccount   getReasonDim;


        LedgerJournalName ledgerJournalName = ledgerJournalName::find("@Ext:CustPay");

        ledgerJournalTransList = new RecordInsertList(transJournal.TableId);

        numberseq = NumberSeq::newGetVoucherFromCode(NumberSequenceTable::find(ledgerJournalName.NumberSequenceTable).NumberSequence);

        voucherNum = numberseq.voucher();


        while select customerCreditTable where customerCreditTable.IsProcessed == NoYes::No && customerCreditTable.JournalNum == journalIdOrig

        {

            transJournal.clear();

            transJournal.initValue();

            transJournal.JournalNum               =  journalId;

            transJournal.TransDate                =                         DateTimeUtil::getToday(DateTimeUtil::getUserPreferredTimeZone());

            transJournal.AccountType              =  LedgerJournalACType::Cust;

            transJournal.LedgerDimension          = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(customerCreditTable.Customer,LedgerJournalACType::Cust);//Journal_Tmp.LedgerDimension;

            transJournal.DefaultDimension         = LedgerDimensionFacade::getDefaultDimensionFromLedgerDimension(transJournal.LedgerDimension);

            transJournal.OffsetAccountType        = customerCreditTable.AccountType;//LedgerJournalACType::Ledger;


            //select firstonly InvoiceId,SalesId from custInvoiceJour

            //    where custInvoiceJour.InvoiceId == customerCreditTable.InvoiceId

            //        join firstonly DefaultDimension from salesLine

            //            where salesLine.SalesId == custInvoiceJour.SalesId;


            //getReasonDim = CustWriteOffFinancialReasonsSetup::findByReasonCode(customerCreditTable.Reason).WriteOffLedgerDimension;

            //transJournal.OffsetLedgerDimension    = LedgerDimensionFacade::ServiceCreateLedgerDimension(getReasonDim, salesLine.DefaultDimension);//22565422738);

            transJournal.OffsetLedgerDimension    = customerCreditTable.LedgerDimension;

            transJournal.CurrencyCode             = customerCreditTable.Currency;

            transJournal.AmountCurCredit          = customerCreditTable.Credit;

            transJournal.MarkedInvoice            = customerCreditTable.InvoiceId;

            transJournal.Txt                      = customerCreditTable.TransactonTxt;

            transJournal.Approved                 = NoYes::Yes;

            transJournal.Approver                 = HcmWorker::userId2Worker(curUserId());

            transJournal.SkipBlockedForManualEntryCheck  = true;

            transJournal.defaultRow();

            if(!transJournal.Voucher)

            {

                transJournal.Voucher                  = voucherNum;

            }

            ledgerJournalTransList.add(transJournal);

            counter++;

        }

        ledgerJournalTransList.insertDatabase();

        numberseq.used();


        return counter;

    }


Thanks,

Import General journal from excel in D365 F&O

 Hi Guys, Import General journal from excel in D365 F&O Code:  using System.IO; using OfficeOpenXml; using OfficeOpenXml.ExcelPackage; u...