Thursday, May 5, 2022

Reversing general journal using x++ code in Dynamics 365 finance and operation


Hello Guys, 

Recently I had a requirement to reversing already posted general journal and below code will help you to create the same. copy the journal I have not mentioned posting logic below.

  /// <summary>

    /// Creates a reversing entry record in the <c>LedgerJournalTrans</c> table for the current journal

    /// number that is being posted.

    /// </summary>

    /// <param name="_numberSequenceTableRecId">

    /// The number sequence ID to use when you are retrieving voucher numbers for the reversing entries.

    /// </param>

    /// <remarks>

    /// For the current record being posted, each <c>LedgerJournalTrans</c> record that has a

    /// <c>ReverseEntry</c> field value of true and has a <c>ReverseDate</c> field value that is not empty

    /// will have a reversing entry created for it in the <c>LedgerJournalTrans</c> table. New vouchers

    /// will be created to hold the reversing entries. Each unique originating voucher will have a new

    /// reversing voucher created for it. If the journal is set up to use one voucher number only or Manual

    /// voucher numbers, the Voucher on each reversing line will be taken from its originating line. Each

    /// originating voucher line will be updated with a link to its corresponding new reversing line.

    /// </remarks>

    protected void createRevEntries(RefRecId _numberSequenceTableRecId, LedgerJournalId _journalIdToReverse, LedgerJournalId _journalId)

    {

        LedgerJournalTrans  updLedgerJournalTrans;

        NumberSeq           numberSeq;

        Voucher             newVoucher,

                            prevVoucher;

        TransactionTxt      transactionTxt;


        // get the text defined for ledger reversing entries

        transactionTxt = TransactionTxt::construct(LedgerTransTxt::LedgerReversingEntry);


        while select forupdate updLedgerJournalTrans 

            order by Voucher 

            where updLedgerJournalTrans.JournalNum == _journalIdToReverse

        {

            if (!prevVoucher || prevVoucher != updLedgerJournalTrans.Voucher)

            {

                numberSeq   = NumberSeq::newGetVoucherFromId(_numberSequenceTableRecId, false, false);

                newVoucher = numberSeq.voucher();

                numberSeq.used();

                

                prevVoucher = updLedgerJournalTrans.Voucher;


                // set the originating voucher into the transaction text defined for ledger reversing entries

                transactionTxt.setVoucher(updLedgerJournalTrans.Voucher);

                transactionTxt.setDate(DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));

                transactionTxt.setFormLetter(LedgerDimensionFacade::getMainAccountIdFromLedgerDimension(updLedgerJournalTrans.LedgerDimension));

                transactionTxt.setLanguage(currentUserLanguage());

            }


            this.createReverseEntryJournalLine(updLedgerJournalTrans, newVoucher, transactionTxt.txt(), _journalId);


            // Use doUpdate() instead of update() since the only value being

            // changed is the link to the reversing entry. Since that does not

            // impact taxes or the other validation done in the update() method,

            // that code can all be skipped to save processing time.

            updLedgerJournalTrans.doUpdate();

        }

    }


    /// <summary>

    ///    Creates a reversing entry <c>LedgerJournalTrans</c> record that uses the specified voucher and

    ///    transaction text that offsets the <c>LedgerJournalTrans</c> record.

    /// </summary>

    /// <param name="_ledgerJournalTrans">

    ///    The <c>LedgerJournalTrans</c> record for which to create the reversing entry

    ///    <c>LedgerJournalTrans</c> record.

    /// </param>

    /// <param name="_voucher">

    ///    The voucher to use when you are creating the reversing <c>LedgerJournalTrans</c> record.

    /// </param>

    /// <param name="_transactionTxt">

    ///    The transaction text to use when you are creating the reversing <c>LedgerJournalTrans</c> record.

    /// </param>

    /// <remarks>

    ///    This method also creates reversing child records in the <c>LedgerJournalTrans_Asset</c> table and

    ///    the <c>LedgerJournalTrans_Project</c> tables, if the <c>LedgerJournalTrans</c> record being

    ///    reversed had child records in those tables.

    /// </remarks>

    protected void createReverseEntryJournalLine(

        LedgerJournalTrans      _ledgerJournalTrans,

        Voucher                 _voucher,

        LedgerJournalTransTxt   _transactionTxt,

        LedgerJournalId _journalId)

    {

        LedgerJournalTrans ledgerJournalTransRE = this.populateReverseEntryJournalLine(_ledgerJournalTrans, _voucher, _transactionTxt, _journalId);


        ledgerJournalTransRE.insert();


        this.populateReverseEntryJournalLineForUpdate(_ledgerJournalTrans, ledgerJournalTransRE);

        

        ledgerJournalTransRE.doUpdate();


        // generate the taxes for the reversal based on the taxes of the original line to insure modified amounts are reversed.

        TaxReverse::reverseTaxUncommitted(_ledgerJournalTrans.TableId, _ledgerJournalTrans.RecId, ledgerJournalTransRE.TableId, ledgerJournalTransRE.RecId, _voucher, _ledgerJournalTrans.ReverseDate);


        _ledgerJournalTrans.RevRecId = ledgerJournalTransRE.RecId;

    }


    /// <summary>

    ///    Populates the reversing entry <c>LedgerJournalTrans</c> record that uses the specified voucher and

    ///    transaction text that offsets the <c>LedgerJournalTrans</c> record.

    /// </summary>

    /// <param name="_ledgerJournalTrans">

    ///    The <c>LedgerJournalTrans</c> record for which to base field values on the reversing entry

    ///    <c>LedgerJournalTrans</c> record.

    /// </param>

    /// <param name="_voucher">

    ///    The voucher to use when you are creating the reversing <c>LedgerJournalTrans</c> record.

    /// </param>

    /// <param name="_transactionTxt">

    ///    The transaction text to use when you are creating the reversing <c>LedgerJournalTrans</c> record.

    /// </param>

    protected LedgerJournalTrans populateReverseEntryJournalLine(

        LedgerJournalTrans      _ledgerJournalTrans,

        Voucher                 _voucher,

        LedgerJournalTransTxt   _transactionTxt,

        LedgerJournalId _journalId)

    {

        LedgerJournalTrans ledgerJournalTransRE;


        ledgerJournalTransRE.JournalNum         = _journalId;

        ledgerJournalTransRE.Voucher            = _voucher;

        ledgerJournalTransRE.TransDate          = _ledgerJournalTrans.ReverseDate;

        ledgerJournalTransRE.AccountType        = _ledgerJournalTrans.AccountType;

        ledgerJournalTransRE.LedgerDimension    = _ledgerJournalTrans.LedgerDimension;

        ledgerJournalTransRE.OffsetAccountType  = _ledgerJournalTrans.OffsetAccountType;

        ledgerJournalTransRE.OffsetLedgerDimension = _ledgerJournalTrans.OffsetLedgerDimension;

        ledgerJournalTransRE.SettleVoucher      = _ledgerJournalTrans.SettleVoucher ;

        ledgerJournalTransRE.CurrencyCode       = _ledgerJournalTrans.CurrencyCode;

        ledgerJournalTransRE.PaymReference      = _ledgerJournalTrans.PaymReference;

        ledgerJournalTransRE.Txt                = _transactionTxt ? _transactionTxt : _ledgerJournalTrans.Txt;

        ledgerJournalTransRE.OffsetTxt          = _transactionTxt ? _transactionTxt : _ledgerJournalTrans.OffsetTxt;

        ledgerJournalTransRE.ExchRate           = _ledgerJournalTrans.ExchRate;

        ledgerJournalTransRE.ReportingCurrencyExchRate = _ledgerJournalTrans.ReportingCurrencyExchRate;

        ledgerJournalTransRE.ReasonRefRecID = _ledgerJournalTrans.ReasonRefRecID;

        ledgerJournalTransRE.Approved = _ledgerJournalTrans.Approved;

        ledgerJournalTransRE.ExchRateSecond = _ledgerJournalTrans.ExchRateSecond;


        if (_ledgerJournalTrans.AmountCurCredit)

        {

            ledgerJournalTransRE.AmountCurDebit = _ledgerJournalTrans.AmountCurCredit;

        }

        else

        {

            ledgerJournalTransRE.AmountCurCredit = _ledgerJournalTrans.AmountCurDebit;

        }


        ledgerJournalTransRE.Qty                = -_ledgerJournalTrans.Qty;


        ledgerJournalTransRE.PostingProfile     = _ledgerJournalTrans.PostingProfile;

        ledgerJournalTransRE.PaymMode           = _ledgerJournalTrans.PaymMode;

        ledgerJournalTransRE.Payment            = _ledgerJournalTrans.Payment;

        ledgerJournalTransRE.Company            = _ledgerJournalTrans.Company;

        ledgerJournalTransRE.OffsetCompany      = _ledgerJournalTrans.OffsetCompany;

        ledgerJournalTransRE.DefaultDimension   = _ledgerJournalTrans.DefaultDimension;

        ledgerJournalTransRE.OffsetDefaultDimension = _ledgerJournalTrans.OffsetDefaultDimension;

        ledgerJournalTransRE.TransactionType    = _ledgerJournalTrans.TransactionType;

        ledgerJournalTransRE.DocumentDate       = _ledgerJournalTrans.DocumentDate;

        ledgerJournalTransRE.DocumentNum        = _ledgerJournalTrans.DocumentNum;

        ledgerJournalTransRE.Invoice            = _ledgerJournalTrans.Invoice;


        return ledgerJournalTransRE;

    }


    /// <summary>

    ///    Updates fields on the reversing entry <c>LedgerJournalTrans</c> record that need to be updated after the initial insert of the record.

    /// </summary>

    /// <param name="_ledgerJournalTrans">

    ///    The <c>LedgerJournalTrans</c> record for which to base field values on the updated version of the reversing entry

    ///    <c>LedgerJournalTrans</c> record.

    /// </param>

    /// <param name = "_ledgerJournalTransRE">

    ///     The <c>LedgerJournalTrans</c> record for the reversing entry.

    /// </param>

    protected void populateReverseEntryJournalLineForUpdate(

        LedgerJournalTrans _ledgerJournalTrans,

        LedgerJournalTrans _ledgerJournalTransRE)

    {

        // need to set the tax codes after the insert because the taxes are calculated during the insert if the tax codes are set.

        _ledgerJournalTransRE.TaxCode            = _ledgerJournalTrans.TaxCode;

        _ledgerJournalTransRE.TaxGroup           = _ledgerJournalTrans.TaxGroup;

        _ledgerJournalTransRE.TaxItemGroup       = _ledgerJournalTrans.TaxItemGroup;

    }

No comments:

Post a Comment