Create and Post Hour journals using X++

In this blog, we will explore how to create and post an hour journal using X++ code. I have taken examples from a staging table, where we can utilize the data to create hour journals using the following method.

  public boolean createHourJournal(DaxHourStaging stagingData)
  {
      ProjJournalTableData            JournalTableData;
      ProjJournalTransData            journalTransData;
      ProjJournalTable                journalTable, journalTableUpdate;
      ProjJournalTrans                journalTrans;
      ProjTable                       projTable;
      ProjInvoiceTable                projInvoiceTable;
      NumberSeq                       numberSeq;
      ProjJournalCheckPost            jourPost;
      ProjQtyEmpl                     qty;
      JournalNumOfLines               numOfLines;
      DataAreaId                      company = '';
      journalNum = '';
      DaxHourStaging  stagingDataHour;
      boolean ret = false;

      while select stagingDataHour
          where stagingDataHour.InvoiceNumber == stagingData.InvoiceNumber
              && stagingDataHour.TransID == stagingData.TransID
              && stagingDataHour.TransactionType == DAXTransactionType::Hour
              && stagingDataHour.DAXProcessedUnprocessed == DAXProcessedUnprocessed::UnProcessed
              && stagingDataHour.Type == DAXType::Invoice
      {
          select crosscompany projTable
              where projTable.DAXTransID == stagingDataHour.TransID;

          changecompany(projTable.DataAreaId)
          {
              company = projTable.DataAreaId;
              if (!journalNum)
              {
                  journalTableData = JournalTableData::newTable(journalTable);
                  journalTransData = journalTableData.journalStatic().newJournalTransData(journalTrans, journalTableData);
                  journalTable.clear();
                  journalTable.JournalId      = journalTableData.nextJournalId();
                  journalTable.JournalType    = ProjJournalType::Hour;
                  journalTable.JournalNameId  = ProjParameters::find().EmplJournalNameId;
                  journalTable.initFromProjJournalName(ProjJournalName::find(journalTable.JournalNameId));
                  journalTable.insert();
                  journalNum = journalTable.JournalId;
              }
              ResourceView            ResResourcesListView;
              ResResourceIdentifier   ResResourceIdentifier;
              ResourceCategoryView    ResourceCategoryView;
              WrkCtrTable             wrkctrTable;
              str                     resourceId = '';
              str                     resourceCompany = '';
              HcmWorker               hcmWorker;
              HcmEmployment           hcmEmployment;
              utcdatetime             now = DateTimeUtil::utcNow();
              CompanyInfo             companyInfo;

              select firstonly ResResourcesListView
                  where ResResourcesListView.ResourceId == stagingDataHour.DAXologyResourceId
                      && ResResourcesListView.ResourceCompanyId == projTable.DataAreaId;

              if (!ResResourcesListView.RecId)
              {
                  select ValidTimeState(now) hcmEmployment
                      join hcmWorker
                      where hcmWorker.RecId == hcmEmployment.Worker
                          && hcmWorker.PersonnelNumber == stagingDataHour.DAXologyResourceId
                      join companyInfo where companyInfo.RecId == hcmEmployment.LegalEntity;

                  if (hcmWorker.RecId)
                  {
                      resourceId      = hcmWorker.PersonnelNumber;
                      resourceCompany = companyInfo.DataArea;
                  }
              }
              select firstonly ResResourceIdentifier
                  where ResResourceIdentifier.RecId == ResResourcesListView.RecId;

              journalTableData.initFromJournalName(journalTableData.journalStatic().findJournalName(ProjJournalTable::find(journalNum).JournalNameId));
              journalTrans.clear();
              journalTransData.initFromJournalTable();

              projInvoiceTable    = projTable.projInvoice();
              journalTrans.setTransDate();
              journalTrans.TransDate          = stagingDataHour.TransDate;
              journalTrans.ProjTransDate      = stagingDataHour.TransDate;
              journalTrans.ProjId             = projTable.ProjId;
              journalTrans.Qty                = stagingDataHour.Quantity;
              journalTrans.DAXInvoiceId      = stagingDataHour.InvoiceNumber;
              journalTrans.DAXInvoiceDate    = stagingDataHour.InvoiceDate;
              journalTrans.DAXTransactionId  = stagingDataHour.TransactionId;
              journalTrans.CategoryId         = ProjParameters::find().EmplCategory;
              // journalTrans.Resource           = ResResourceIdentifier.RefRecId;
              journalTrans.Worker             = ResResourcesListView.Worker;
              journalTrans.LinePropertyId     = 'Chargeable';
              //journalTrans.DAXResourceCompany = resourceCompany;
              journalTrans.DAXWrkCtrId       = stagingDataHour.DAXologyResourceId;
              journalTrans.DAXResourceName   = stagingDataHour.DAXologyResourceName;
              journalTrans.DAXologyRoleName  = stagingDataHour.DAXologyRoleName;
              journalTrans.Txt                = stagingDataHour.Description;
              journalTrans.CurrencyId         = projInvoiceTable.CurrencyId;
              journalTrans.DefaultDimension   = projTable.DefaultDimension;
              journalTrans.TaxGroupId         = ProjParameters::taxGroupInvoice(projTable.ProjId);
              journalTrans.SalesPrice         = stagingDataHour.SalesPrice;
              InventTableModule   inventTableModule;

              select inventTableModule
                  where inventTableModule.ItemId == InventTable::find(DAX_ProjectHourJournalCreateService::getDimensionValueFromDefaultDimension(projTable.DefaultDimension)).ItemId
                      && inventTableModule.ModuleType == ModuleInventPurchSales::Sales;

              journalTrans.TaxItemGroupId     = inventTableModule.TaxItemGroupId;
              numberSeq = NumberSeq::newGetVoucherFromId(journalTable.VoucherNumberSequenceTable, false);

              journalTrans.Voucher            = numberSeq.voucher();
              journalTransData.create();
              if (TaxParameters::checkTaxParameters_IN())
              {
                  ProjJournalTransTaxExtensionIN     projJournalTransHourTaxExtensionIN = null;
                  projJournalTransHourTaxExtensionIN  = ProjJournalTransTaxExtensionIN::findByProjJournalTrans(journalTrans.RecId);
                  if (!projJournalTransHourTaxExtensionIN.RecId)
                  {
                      projJournalTransHourTaxExtensionIN.initValue();
                      projJournalTransHourTaxExtensionIN.ProjJournalTrans = journalTrans.RecId;
                      projJournalTransHourTaxExtensionIN.AssessableValueTransactionCurrency = journalTrans.Qty * journalTrans.SalesPrice;
                      projJournalTransHourTaxExtensionIN.insert();
                  }
              }
          }

      }
      try
      {
          changecompany(projTable.DataAreaId)
          {
              if (journalNum)
              {
                  jourPost = ProjJournalCheckPost::newJournalCheckPost(true,true,JournalCheckPostType::Post,tableNum(ProjJournalTable), journalNum);
                  jourPost.run();
                  ret = true;
                  ProjJournalTrans                projJournalTrans;
                  ProjJournalTable                projJournalTabeUpd;

                  projJournalTabeUpd = ProjJournalTable::find(journalNum,true);

                  select count(RecId), sum(Qty) from projJournalTrans
                              where projJournalTrans.JournalId == journalNum;

                  projJournalTabeUpd.NumOfLines = int642int(projJournalTrans.RecId);
                  projJournalTabeUpd.ProjQty = projJournalTrans.Qty;
                  projJournalTabeUpd.update();

                  DaxHourStaging  stagingGlobalUpd;
                  update_recordset stagingGlobalUpd setting DAXProcessedUnprocessed = DAXProcessedUnprocessed::Processed
                          where stagingGlobalUpd.InvoiceNumber == stagingData.InvoiceNumber
                              && stagingGlobalUpd.OrderItemId  == stagingData.OrderItemId
                              && stagingGlobalUpd.TransactionType == DAXTransactionType::Hour;

              }
          }
      }
      catch
      {
          //Posting exception
      }
      finally
      {
          // Can go with an final update here
      }
      return ret;
  }
Thanks !!

Create and Post Pending vendor invoice using X++

 

The class below will be used to create and post pending vendor invoices along with the project information. In my case, I retrieved the data from a staging table and created the pending vendor invoices.

public class CreatePendingVendorInvoice
{
    VendInvoiceInfoTable    vendInvoiceInfoTable;
    ProjParameters          projParameters;
    str                     ItemCompany;
    str                     ItemProjId;
    RecId                   ItemProjDimension;

    /// <summary>
    /// This method will be used to create the Pending vendor invoice header
    /// </summary>
    /// <param name = "_stagingTrans"></param>
    public void createPendingVendorInvoiceHeader(DaxStagingTrans    _stagingTrans)
    {
        projParameters = ProjParameters::find();

        NumberSeq   numberSeq = NumberSeq::newGetNum(ProjParameters::invoiceId());

        vendInvoiceInfoTable.clear();
        vendInvoiceInfoTable.initValue();

        vendInvoiceInfoTable.DocumentOrigin          = DocumentOrigin::Manual;
        vendInvoiceInfoTable.InvoiceAccount          = this.getVendorAccount();
        vendInvoiceInfoTable.defaultRow(null, null, true);

        vendInvoiceInfoTable.Num                     = numberSeq.num();
        vendInvoiceInfoTable.VendInvoiceSaveStatus   = VendInvoiceSaveStatus::Pending;
        vendInvoiceInfoTable.DocumentDate            = _stagingTrans.JournalDate;
        vendInvoiceInfoTable.ReceivedDate            = _stagingTrans.JournalDate;
        vendInvoiceInfoTable.TransDate               = _stagingTrans.JournalDate;
        vendInvoiceInfoTable.LastMatchVariance       = LastMatchVarianceOptions::OK;
        vendInvoiceInfoTable.RequestStatus           = VendInvoiceRequestStatus::Approved;
        vendInvoiceInfoTable.insert();

        this.createPendingVendorInvoiceLine(_stagingTrans);
    }

    /// <summary>
    /// This method used to create the Pending Vendor incvoice lines
    /// </summary>
    /// <param name = "_stagingTrans">DaxStagingTrans</param>
    public void createPendingVendorInvoiceLine(DaxStagingTrans    _stagingTrans)
    {
        VendInvoiceInfoLine     vendInvoiceInfoLine;

        vendInvoiceInfoLine.clear();
        vendInvoiceInfoLine.initValue();
        vendInvoiceInfoLine.DeliveryName        = vendInvoiceInfoTable.DeliveryName;
        vendInvoiceInfoLine.TableRefId          = vendInvoiceInfoTable.TableRefId;
        vendInvoiceInfoLine.currencyCode        = vendInvoiceInfoTable.CurrencyCode;
        vendInvoiceInfoLine.LineNum             = 1;
        vendInvoiceInfoLine.InvoiceAccount      = vendInvoiceInfoTable.InvoiceAccount;
        vendInvoiceInfoLine.OrderAccount        = vendInvoiceInfoTable.OrderAccount;
        vendInvoiceInfoLine.ProcurementCategory = projParameters.ANTHProcurCategory;
        vendInvoiceInfoLine.modifiedField(fieldNum(VendInvoiceInfoLine, ProcurementCategory));
        vendInvoiceInfoLine.ReceiveNow          = 1;
        vendInvoiceInfoLine.PurchUnit           = projParameters.ANTHPurchUnit;
        vendInvoiceInfoLine.DocumentOrigin      = DocumentOrigin::Manual;

        container           conAttribute            = ANTHConcurCreateGeneralJournalService::getFDFromParameters();
        container           convalue                = this.getProjectDimensions(conAttribute, _stagingTrans);

        vendInvoiceInfoLine.DefaultDimension    = ANTHConcurCreateGeneralJournalService::createDefaultDimension(conAttribute, convalue);
        vendInvoiceInfoLine.insert();

        if (vendInvoiceInfoLine)
        {
            VendInvoiceInfoLine_Project   vendInvoiceInfoLine_Project;

            vendInvoiceInfoLine_Project.VendInvoiceInfoLineRefRecId = vendInvoiceInfoLine.RecId;
            vendInvoiceInfoLine_Project.ProjDataAreaId              = ItemCompany;
            vendInvoiceInfoLine_Project.ProjId                      = ItemProjId;
            vendInvoiceInfoLine_Project.ProjCategoryId              = _stagingTrans.Expensecategory;
            vendInvoiceInfoLine_Project.ProjLinePropertyId          = CreatePendingVendorInvoice::findLineProperty();
            vendInvoiceInfoLine_Project.TransDate                   = _stagingTrans.JournalDate;
            vendInvoiceInfoLine_Project.ProjSalesUnitId             = UnitOfMeasure::findBySymbol(projParameters.ANTHPurchUnit).RecId;
            vendInvoiceInfoLine_Project.ProjSalesCurrencyId         = _stagingTrans.Currency;
            vendInvoiceInfoLine_Project.TransferCurrency            = _stagingTrans.Currency;
            vendInvoiceInfoLine_Project.TransferPrice               = _stagingTrans.Costamount;
            vendInvoiceInfoLine_Project.ANTHConcurTransactionID     = _stagingTrans.ConcurTransactionID;
            vendInvoiceInfoLine_Project.ProjTaxGroupId              = '';
            vendInvoiceInfoLine_Project.ProjTaxItemGroupId          = '';
            vendInvoiceInfoLine_Project.insert();
        }
    }

    /// <summary>
    /// This method used to Post the Vendor invoice
    /// </summary>
    public void postInvoice()
    {
        PurchFormLetter         purchFormLetter;

        purchFormLetter = PurchFormLetter_Invoice::newFromSavedInvoice(vendInvoiceInfoTable);
        purchFormLetter.purchParmUpdate(null);
        purchFormLetter.parmId('');
        purchFormLetter.initNewPurchParmUpdate();
        purchFormLetter.proforma(false);
        purchFormLetter.reArrangeNow(false);

        purchFormLetter.update(vendInvoiceInfoTable,
                                vendInvoiceInfoTable.Num,
                                purchFormLetter.transDate(),
                                PurchUpdate::All,
                                AccountOrder::None,
                                purchFormLetter.proforma(),
                                purchFormLetter.printFormLetter(),
                                false,
                                purchFormLetter.creditRemaining(),
                                conNull(),
                                true);

    }

    /// <summary>
    /// This method used to retrieve the Default Dimensions
    /// </summary>
    /// <param name = "_attribute">Container</param>
    /// <param name = "_stagingTrans">DaxStagingTrans</param>
    /// <returns>Container</returns>
    private container getProjectDimensions(container    _attribute, DaxStagingTrans _stagingTrans)
    {
        // DeptCC-ProfitCenter-PRODGRP-UnifiedProductID-Customer-Vendor
        return [_stagingTrans.Costcenter, projParameters.DAXProfitCenter,
                CreatePendingVendorInvoice::getDimensionValue(orderItemProjDimension, conPeek(_attribute, 3)),
                CreatePendingVendorInvoice::getDimensionValue(orderItemProjDimension, conPeek(_attribute, 4)),
                CreatePendingVendorInvoice::getDimensionValue(orderItemProjDimension, conPeek(_attribute, 5))];
    }

    /// <summary>
    /// Gets the display value from the Dimension Recid
    /// </summary>
    /// <param name = "_dimension">RecId</param>
    /// <param name = "_dimensionName">Str</param>
    /// <returns>DimensionValue</returns>
    public static DimensionValue getDimensionValue(RecId  _dimension, str _dimensionName)
    {
        DimensionAttributeValueSetStorage   dimensionAttributeValueSetStorage ;
        DimensionAttribute                  dimensionAttribute;
        DimensionValue                      dimensionValue;

        dimensionAttributeValueSetStorage = dimensionAttributeValueSetStorage::find(_dimension);

        dimensionAttribute  = dimensionAttribute::findbyname(_dimensionName);
        dimensionValue      = dimensionAttributeValueSetStorage.getDisplayValueByDimensionAttribute(dimensionAttribute.recId);

        return dimensionValue;
    }

    public void OrderDetails(container  _OrderCon)
    {
        [orderItemCompany, orderItemProjId, orderItemProjDimension] = _OrderCon;
    }

    public str getVendorAccount()
    {
        DirPartyView    partyView;
        DirPartyRecId   partyId = CompanyInfo::findDataArea(orderItemCompany).RecId;

        select firstonly AccountNum from partyView
            where partyView.Party == partyId && partyView.RoleType == DirPartyRoleType::Vendor && partyView.DataArea == curExt();

        return partyView.AccountNum;
    }

    public static CreatePendingVendorInvoice construct(container  _OrderCon)
    {
        CreatePendingVendorInvoice    concurCreatePendingVendorInvoice = new CreatePendingVendorInvoice();

        concurCreatePendingVendorInvoice.OrderDetails(_OrderCon);

        return concurCreatePendingVendorInvoice;
    }

    public static str findLineProperty()
    {
        ProjLineProperty    projLineProperty;

        select firstonly LinePropertyId from projLineProperty
            where projLineProperty.ToBeInvoiced == false;

        return projLineProperty.LinePropertyId;
    }

    public static ResourceView findResource(str _resourceId)
    {
        ResourceView resource;

        select firstonly resource
            where resource.ResourceId == _resourceId;

        return resource;
    }

}

Thanks !!

Create General Journals in D365 fo using X++


Below is the code to create general journals in D365 using X++. In this implementation, we utilize the LedgerJournalEngine, which can handle both single- and multi-voucher journal creation scenarios. This approach increases the likelihood that the resulting lines will match those created manually.

public class CreateGeneralJournalService
{
    ledgerJournalTable      ledgerJournalTable;
    ProjParameters          projParameters;
    LedgerJournalEngine     ledgerJournalEngine;

    /// <summary>
    /// Method Used to create the Journal Header
    /// </summary>
    /// <returns>ledgerJournalTable</returns>
    public ledgerJournalTable createGeneralJournalHeader()
    {
        projParameters = ProjParameters::find();

        ledgerJournalTable.clear();
        ledgerJournalTable.initValue();
        ledgerJournalTable.initFromLedgerJournalName(projParameters.DaxJournalNameId);
        ledgerJournalTable.JournalNum = JournalTableData::newTable(ledgerJournalTable).nextJournalId();
        ledgerJournalTable.insert();

        ledgerJournalEngine = LedgerJournalEngine::construct(ledgerJournalTable.JournalType);
        ledgerJournalEngine.newJournalActive(ledgerJournalTable);

        return ledgerJournalTable;
    }

    /// <summary>
    ///Method Used to create the journal Lines
    /// </summary>
    /// <param name = "_StagingTrans"></param>
    public void createGeneralJournalLine(DaxStagingTrans    _StagingTrans)
    {
        ledgerJournalTrans  ledgerJournalTrans;

        // DeptCC-ProfitCenter-PRODGRP-UnifiedProductID-Customer-Vendor
        container           conAttribute            = CreateGeneralJournalService::getFDFromParameters();
        container           convalue                = [_StagingTrans.Costcenter, projParameters.DaxProfitCenter];
        RecId               defaultDimensionRecId   = CreateGeneralJournalService::createDefaultDimension(conAttribute, convalue);

        ledgerJournalTrans.clear();
        ledgerJournalTrans.initValue();
        ledgerJournalEngine.initValue(ledgerJournalTrans);

        ledgerJournalTrans.JournalNum             = ledgerJournalTable.JournalNum;
        ledgerJournalTrans.TransDate              = _StagingTrans.JournalDate;
        ledgerJournalTrans.AccountType            = LedgerJournalACType::Ledger;
        ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, AccountType));
        ledgerJournalTrans.LedgerDimension        = LedgerDimensionFacade::serviceCreateLedgerDimension(this.getDefaultAccount(_StagingTrans.Expensecategory), defaultDimensionRecId);;
        ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, LedgerDimension));
        ledgerJournalEngine.accountModified(LedgerJournalTrans);

        ledgerJournalTrans.OffsetAccountType        = LedgerJournalACType::Ledger;
        ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, OffsetAccountType));
        ledgerJournalTrans.OffsetLedgerDimension    = LedgerDimensionFacade::serviceCreateLedgerDimension(projParameters.DaxReimbursableEmpExpensePayAccount, defaultDimensionRecId);
        ledgerJournalTrans.modifiedField(fieldNum(LedgerJournalTrans, OffsetLedgerDimension));
        ledgerJournalEngine.offsetAccountModified(ledgerJournalTrans);

        ledgerJournalTrans.CurrencyCode             = _StagingTrans.Currency;
        ledgerJournalEngine.currencyModified(LedgerJournalTrans);
        ledgerJournalTrans.AmountCurDebit           = _StagingTrans.Costamount;
        ledgerJournalTrans.DaxTransID               = _StagingTrans.TransID;
        ledgerJournalTrans.DaxOrderItemID           = _StagingTrans.OrderItemId;
        ledgerJournalTrans.DaxExpenseCategory       = _StagingTrans.Expensecategory;
        ledgerJournalTrans.Approved = NoYes::Yes;
        ledgerJournalTrans.SkipBlockedForManualEntryCheck = true;

        ledgerJournalTrans.defaultRow();
        ledgerJournalTrans.TaxItemGroup = nullValueFromType(Types::String);
        ledgerJournalTrans.TaxGroup     = nullValueFromType(Types::String);

        if (ledgerJournalTrans.validateWrite())
        {
            ledgerJournalTrans.insert();

            ledgerJournalEngine.write(ledgerJournalTrans);
        }
    }

    /// <summary>
    /// A construct method to Create an object
    /// </summary>
    /// <returns></returns>
    public static CreateGeneralJournalService construct()
    {
        return new CreateGeneralJournalService();
    }

    /// <summary>
    /// Gets the default dimension from Proj posting setup
    /// </summary>
    /// <param name = "_categoryRelation">Str</param>
    /// <returns>LedgerDimensionDefaultAccount</returns>
    public LedgerDimensionDefaultAccount getDefaultAccount(str _categoryRelation)
    {
        ProjPosting   projPosting;

        select firstonly projPosting
            where projPosting.ProjAccountType       == ProjAccountType::CostAccount
               && projPosting.ProjCategoryRelation  == _categoryRelation;

        return projPosting.LedgerDimension;
    }

    /// <summary>
    /// It will returns the format of finanicaial dimensions
    /// </summary>
    /// <returns>container</returns>
    public static container getFDFromParameters()
    {
        DimensionHierarchy              dimensionHierarchy;
        DimensionHierarchyIntegration   dimensionHierarchyIntegration;

        select firstonly DisplayString from dimensionHierarchyIntegration
            exists join dimensionHierarchy
                where dimensionHierarchy.RecId == dimensionHierarchyIntegration.DimensionHierarchy
                    && dimensionHierarchy.StructureType == DimensionHierarchyType::DataEntityDefaultDimensionFormat
                    && dimensionHierarchyIntegration.IsDefault == true;

        return str2con(dimensionHierarchyIntegration.DisplayString, DimensionParameters::getDimensionSegmentDelimiter());
    }

    /// <summary>
    /// Method Used to create the default Dimension
    /// </summary>
    /// <param name = "conAttribute"></param>
    /// <param name = "convalue"></param>
    /// <returns></returns>
    public static  DimensionDefault createDefaultDimension(container conAttribute , container convalue)
    {
        DimensionAttributeValueSetStorage   valueSetStorage = new DimensionAttributeValueSetStorage();
        DimensionAttribute                  dimensionAttribute;
        DimensionAttributeValue             dimensionAttributeValue;
        str                                 dimValue;

        for (int i = 1; i <= conLen(conAttribute); i++)
        {
            dimensionAttribute = dimensionAttribute::findByName(conPeek(conAttribute,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();
    }

}


Additionally, to post the above created Journals we can use LedgerJournalcheckpost class as below

LedgerJournalCheckPost ledgerjournalcheckpost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::Yes);
    if (ledgerjournalcheckpost.validate())
    {
        ledgerjournalcheckpost.run();
    }

Thanks !!

Create Expense Journals in D365 FO Using X++


Here is the sample code to create project expense journals in D365 FO using X++. In my case, I will retrieve data from a staging table sourced from a third-party system. The job outlined below will use values from the staging table to create the expense journals.

Public  final class CreateExpenseJournalService
{
    DaxExpenseStaging         StagingTrans;
    str                            empId;
    JournalId                      journalId;

    /// <summary>
    /// This method will create the ledger dimension for expense journals
    /// </summary>
    /// <param name = "_conData">DmensionData</param>
    /// <param name = "_mainAccount">MainAccountNum</param>
    /// <returns>DimensionDynamicAccount</returns>
    public DimensionDynamicAccount  generateLedgerDimension(container    _conData, MainAccountNum _mainAccount)
    {
        int                                 hierarchyCount;
        int                                 hierarchyIdx;
        RecId                               dimAttId_MainAccount;
        LedgerRecId                         ledgerRecId;
        MainAccount                         mainAccount;
        RefRecId                            recordvalue;
        DimensionAttribute                  dimensionAttribute;
        DimensionAttributeValue             dimensionAttributeValue;
        DimensionSetSegmentName             DimensionSet;
        DimensionStorage                    dimStorage;
        DimensionAttributeValueContract     ValueContract;
        DimensionAttributeValueCombination  dimensionAttributeValueCombination;
        LedgerAccountContract               LedgerAccountContract = new LedgerAccountContract();

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

        try
        {
            mainAccount         = MainAccount::findByMainAccountId(_mainAccount);
            recordvalue         = DimensionHierarchy::getAccountStructure(mainAccount.RecId,Ledger::current());
            hierarchyCount      = DimensionHierarchy::getLevelCount(recordvalue);
            DimensionSet        = DimensionHierarchyLevel::getDimensionHierarchyLevelNames(recordvalue);
            for(hierarchyIdx = 1;hierarchyIdx<=hierarchyCount;hierarchyIdx++)
            {
                if(hierarchyIdx == 1)
                    continue;
                dimensionAttribute = DimensionAttribute::findByLocalizedName(DimensionSet[hierarchyIdx],false,"en-us");
                if(dimensionAttribute)
                {
                    dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,conPeek(_conData,hierarchyIdx) ,false ,false);
                    if(dimensionAttributeValue)
                    {
                        ValueContract = new DimensionAttributeValueContract();
                        ValueContract.parmName(dimensionAttribute.Name) ;
                        ValueContract.parmValue(dimensionAttributeValue.CachedDisplayValue);
                        valueContracts.addEnd(ValueContract);
                    }
                }
            }
            LedgerAccountContract.parmMainAccount(_mainAccount);
            LedgerAccountContract.parmValues(valueContracts);
            dimStorage                         = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(LedgerAccountContract);
            dimensionAttributeValueCombination = DimensionAttributeValueCombination::find(dimStorage.save());
            ledgerRecId                        = dimensionAttributeValueCombination.RecId;
        }
        catch
        {
            throw Exception::error;
        }
        return ledgerRecId;
    }

    /// <summary>
    /// A construct method to create object of this class
    /// </summary>
    /// <param name = "_stagingTrans">DaxExpenseStaging</param>
    /// <returns>CreateExpenseJournalService</returns>
    public static CreateExpenseJournalService construct(DaxExpenseStaging _stagingTrans)
    {
        CreateExpenseJournalService createExpenseExpense =  new CreateExpenseJournalService();
        createExpenseExpense.parmstagingTrans(_stagingTrans);
        return createExpenseExpense;
    }

    /// <summary>
    /// A parm method to return the current staging
    /// </summary>
    /// <param name = "_stagingTrans">DaxExpenseStaging</param>
    /// <returns>DaxExpenseStaging</returns>
    public DaxExpenseStaging parmstagingTrans(DaxExpenseStaging _stagingTrans)
    {
        StagingTrans = _stagingTrans;

        return StagingTrans;

    }

    /// <summary>
    /// Method to create the Journal Header
    /// </summary>
    /// <returns></returns>
    public LedgerJournalTable createJournalHeader()
    {
        LedgerJournalTable                                         ledgerJournalTable,jourTable1;
        ProjParameters                                             projParmeters = ProjParameters::find();

        ledgerJournalTable.initValue();
        ledgerJournalTable.JournalName                               = LedgerJournalName::find(projParmeters.DAXProjExpenseJournal).JournalName;
        ledgerJournalTable.initFromLedgerJournalName();
        ledgerJournalTable.Name                                      = ledgerJournalTable.ledgerJournalName().Name;
        ledgerJournalTable.JournalType                               = ledgerJournalType::Cost;
        ledgerJournalTable.LedgerJournalInclTax                      = NoYes::No;
        ledgerJournalTable.insert();

        return ledgerJournalTable;

    }

    /// <summary>
    /// Method used to create the Journal Lines
    /// </summary>
    /// <param name = "_ledgerJournalTable">LedgerJournalTable</param>
    public void createJournalTrans(LedgerJournalTable       _ledgerJournalTable)
    {
        LedgerJournalTrans                                         ledgerJournalTrans;
        LedgerJournalTrans_Project                                 ledgerJournalTrans_Project;
        ProjJournalCheckPost                                       jourPost;
        ledgerJournalCheckPost                                     ledgerJournalCheckPost;
        ProjTable                                                  projTable;
        NumberSequenceTable                                        numberSequenceTable;
        Voucher                                                    voucher;
        ResourceView                                               resourceView;
        MainAccount                                                mainaccount;
        ProjParameters                                             projParmeters = ProjParameters::find();



        if (_ledgerJournalTable)
        {
            select firstonly projTable
                    where projTable.DaxTransID == StagingTrans.TransID;

            ledgerJournalTrans.clear();
            ledgerJournalTrans.JournalNum            = _ledgerJournalTable.JournalNum;
            ledgerJournalTrans.DefaultDimension      = projTable.DefaultDimension;
            ledgerJournalTrans.AccountType           = LedgerJournalACType::Project;
            numberSequenceTable                      = NumberSequenceTable::find(LedgerJournalName::find(LedgerJournalName::find(projParmeters.DAXProjExpenseJournal).JournalName).NumberSequenceTable);
            voucher                                  = NumberSeq::newGetVoucherFromCode(numberSequenceTable.NumberSequence).voucher();
            ledgerJournalTrans.Voucher               = voucher;
            ledgerJournalTrans.CurrencyCode          = StagingTrans.Currency;
            ledgerJournalTrans.Qty                   = 1;
            ledgerJournalTrans.TransDate             = StagingTrans.JournalDate;
            ledgerJournalTrans.LedgerDimension       = LedgerDynamicAccountHelper::getDynamicAccountFromAccountNumber(projTable.ProjId,LedgerJournalACType::Project);
            ledgerJournalTrans.modifiedField(fieldNum(ledgerJournalTrans ,LedgerDimension ));

            ledgerJournalTrans.OffsetAccountType    = LedgerJournalACType::Ledger;
            ledgerJournalTrans.ExchRate = 100;
            Amount amount = StagingTrans.Costamount;
            if(amount> 0)
            {
                ledgerJournalTrans.AmountCurDebit = amount;
            }
            else
            {
                ledgerJournalTrans.AmountCurCredit = abs(amount);
            }
            ledgerJournalTrans.Company                  = strUpr(curExt());
            ledgerJournalTrans.OffsetCompany            = strUpr(curExt());
            ledgerJournalTrans.DAXstagingTransactionID  = StagingTrans.TransID;

           // mainaccount = MainAccount::find(projParmeters.DAXReimbursableEmpExpensePayAccount);
            str  mainaccountId  = LedgerDimensionFacade::getMainAccountFromLedgerDimension(projParmeters.DAXReimbursableEmpExpensePayAccount).MainAccountId;
            //MainAccount~CostCenter~ProfitCenter~Product_Family~UniqueProductID~Customer~Vendor
            container convalues = [mainaccountId, StagingTrans.Costcenter, projParmeters.DAXProfitCenter,'','','',''];
            refrecid ledgerdim  =  this.generateLedgerDimension(convalues, mainaccountId);

            ledgerJournalTrans.OffsetLedgerDimension    = LedgerDimensionFacade::serviceCreateLedgerDimension(ledgerdim,projTable.DefaultDimension);
            ledgerJournalTrans.modifiedField(fieldNum(ledgerJournalTrans ,OffsetLedgerDimension ));
            ledgerJournalTrans.insert();

            if (ledgerJournalTrans.RecId)
            {
                ledgerJournalTrans_Project.clear();
                ledgerJournalTrans_Project.RefRecId                         = ledgerJournalTrans.RecId;
                ledgerJournalTrans_Project.initValue();
                ledgerJournalTrans_Project.CategoryId                       = StagingTrans.Expensecategory;
                ledgerJournalTrans_Project.ProjId                           = projTable.ProjId;
                ledgerJournalTrans_Project.ProjTransDate                    = StagingTrans.JournalDate;
                ledgerJournalTrans_Project.modifiedField(fieldNum(ledgerJournalTrans_Project, CategoryId));
                ledgerJournalTrans_Project.Qty                              = 1;
                ledgerJournalTrans_Project.SalesCurrencyId                  = ledgerJournalTrans.CurrencyCode;
                ledgerJournalTrans_Project.CostPrice                        = amount;


                //select firstonly resourceView
                //    where resourceView.ResourceId == StagingTrans.EmployeeID;
                //ledgerJournalTrans_Project.Resource                         = resourceView.RecId; // If resource need to be filled uncomment the lines
                ledgerJournalTrans_Project.modifiedField(fieldNum(ledgerJournalTrans_Project, CostPrice));
                ledgerJournalTrans_Project.LinePropertyId = ProjLinePropertySetup::findLinePropertyId( projTable.ProjId,ledgerJournalTrans_Project.CategoryId );

                boolean priceFound;
                CostPrice costPriceMST = ProjCostSalesPrice::costPrice(ledgerJournalTrans,ledgerJournalTrans_Project, false);
                [ledgerJournalTrans_Project.SalesPrice, priceFound] = ProjCostSalesPrice::findCostSalesPrice(ledgerJournalTrans_Project.ProjId,ledgerJournalTrans_Project.Resource,ledgerJournalTrans_Project.CategoryId,costPriceMST,CompanyInfoHelper::standardCurrency(),ledgerJournalTrans_Project.SalesCurrencyId,ledgerJournalTrans_Project.ProjTransDate,ledgerJournalTrans_Project.ProjPriceGroupID,false);

                ledgerJournalTrans_Project.insert();
            }
        }

    }

}