Skip to main content

Notifications

Microsoft Dynamics AX (Archived)

Sales Order Confirmation Error.

Posted on by 1,737

i am doing some customization is sales totals class for getting the summary of the sales order.

successfully iam getting the total summary of the sales order in the Summary fact box.

but i am trying to confirm the sales order, getting the debugger error.

i am trying to debug the class but no clue.

*This post is locked for comments

  • Suggested answer
    Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Sales Order Confirmation Error.

    Hi Srinivas,

    Please provide some more details for the problem. Because when this issue occurred to me, I sorted out that I have a non existing field which is pointing to another table.

    It would be helpful if you send me the .xpo of your customization.

    [address removed by moderator]

    Thanks & Regards,

    Gaurav Singhal

  • srinivas pamidi Profile Picture
    srinivas pamidi 1,737 on at
    RE: Sales Order Confirmation Error.

    Hi Gaurav,

    I am Checking all relations in the tables related to sales totals summary part.

    Again same error

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Sales Order Confirmation Error.

    Hi Srinivas,

    I stated this error above in previous answer. This is caused when you have a

    one or many non working relationships between tables.

    Use debugger to trace the mistake you have done. This will resolve the issue.

  • srinivas pamidi Profile Picture
    srinivas pamidi 1,737 on at
    RE: Sales Order Confirmation Error.

    Hi Gaurav Singhal,

    i am trying to run the incremental CIL  it is through error in the salesTotals_ParmTans methods.

    Error : Object Reference is not set to the instance of the object.

    "display height" means..

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Sales Order Confirmation Error.

    Hi Srinivas,

    Answer for first Question

    Yes you can create a Form Part for SalesTableListPage.

    Answer for second Question

    I saw your code, for creating summary fact box you have to create a separate form for summary and its related tables which you have already created correctly.

    Your code seems correct to me, as this is exactly same as that in PurchTableListPage summary factbox.

    Try this, add your summary form to "Parts" and then put a breakpoint in Summary form, you will get to know the "FieldId" for which you are getting debugger error. Also check the relations between tables, this also causes Debugger Error (usually "display height"). 

  • srinivas pamidi Profile Picture
    srinivas pamidi 1,737 on at
    RE: Sales Order Confirmation Error.

    Hi Gaurav,

    Please find below what i did the customization.

    I am created the two tables called salestotalssummary and SalesEncumbranceSummary with some fields related to summary of the sales order.

    then i add two table in the form called salestotalssummarypart

    in salestotalssummary datasource override the method execute query

    public void executeQuery()

    {

       SalesTable salesTableParent;

       salesTableParent = element.args().record() as SalesTable;

       if(salesTableParent.RecId)

       {

           SalesTotalsSummaryController::updateTotals(salesTableParent, tableNum(SalesTotalsSummary));

       super();

       }

    }

    then i created new class called slaestotalssummarycontroller.

    add the methods and code like this.

                                                       //class declaration

    /// <summary>

    ///     This class is responsible for calculating and storing sales order totals and encumbrance summary amounts

    ///     in <c>SalesTotalsSummary</c> and <c>SalesEncumbranceSummary</c> tables respectively. These amounts are displayed on

    ///     Sales order details and list pages in factboxes.

    /// </summary>

    class SalesTotalsSummaryController

    {

       SalesId salesId;

       boolean invalidateTotalsRecord;

    }

                                                           //checkFields

    /// <summary>

    ///     Checks if the fields that affect totals amounts have been updated and sets the result in a class level variable.

    /// </summary>

    /// <param name="_common">

    ///     Buffer for the record being updated

    /// </param>

    /// <remarks>

    ///     This class handles table record updates in two steps. First <c>checkFields()</c> is called from table <c>update()</c> method before the <c>super()</c> call

    ///     to check if any of the fields that affects sales order total amounts has been modified and a class level flag is set to indicate so.

    ///     Calling <c>checkFields()</c> before <c>super()</c> is needed becuase the <c>super()</c> call resets the original buffer. After the <c>super()</c> is called and

    ///     the updates have been written to the table a call to <c>onUpdate()</c> is made to write the class level varaible indicating the result from

    ///     <c>checkFields()</c> to <c>SalesTotalsSummary</c> table.

    /// </remarks>

    public void checkFields(Common _common)

    {

       SalesTable  salesTable;

       SalesLine   salesLine;

       MarkupTrans markupTrans;

       if(!_common || !SalesParameters::find().AutomaticFactBoxUpdateOnSO_PSN)

       {

           return;

       }

       switch(_common.TableId)

       {

           case tableNum(SalesTable):

               salesTable = _common as SalesTable;

               invalidateTotalsRecord = invalidateTotalsRecord || (salesTable.orig().CurrencyCode != salesTable.CurrencyCode);

               invalidateTotalsRecord = invalidateTotalsRecord || (salesTable.orig().InclTax != salesTable.InclTax);

               if(TaxParameters::find().JournalInclTax)

               {

                   invalidateTotalsRecord = invalidateTotalsRecord || (salesTable.orig().CashDisc != salesTable.CashDisc);

               }

               break;

           case tableNum(SalesLine):

               salesLine = _common as SalesLine;

               invalidateTotalsRecord = invalidateTotalsRecord || (salesLine.orig().LineAmount != salesLine.LineAmount);

               invalidateTotalsRecord = invalidateTotalsRecord || (salesLine.orig().SalesQty != salesLine.SalesQty);

               invalidateTotalsRecord = invalidateTotalsRecord || (salesLine.orig().SalesPrice != salesLine.SalesPrice);

               break;

           case tableNum(MarkupTrans):

               markupTrans = _common as MarkupTrans;

               invalidateTotalsRecord = invalidateTotalsRecord || (markupTrans.orig().MarkupCategory != markupTrans.MarkupCategory);

               invalidateTotalsRecord = invalidateTotalsRecord || (markupTrans.orig().Value != markupTrans.Value);

               invalidateTotalsRecord = invalidateTotalsRecord || (markupTrans.orig().CurrencyCode != markupTrans.CurrencyCode);

               break;

       }

    }

    private void new(SalesId _salesId)

    {

       salesId = _salesId;

    }

    /// <summary>

    ///     This method will invalidate the totals record if it was marked to be invalidated from the checkFields() and

    ///     then notifies the calling datasource about the invalid totals record.

    ///     This method gets called after the update() is called on the table.

    /// </summary>

    /// <param name="_common">

    ///     Table buffer to notify about the invalidation of the record

    /// </param>

    public void onUpdate(Common _common)

    {

       SalesTable  salesTable;

       SalesLine   salesLine;

       if(!_common || !SalesParameters::find().AutomaticFactBoxUpdateOnSO_PSN)

       {

           return;

       }

       if(invalidateTotalsRecord)

       {

           SalesTotalsSummaryController::setValidFlag(salesId, tableNum(SalesTotalsSummary), false);

           switch(_common.TableId)

           {

               case tableNum(SalesTable):

                   salesTable = _common as SalesTable;

                   SalesTotalsSummaryController::updateTotals(salesTable, tableNum(SalesTotalsSummary));

                   break;

               case tableNum(SalesLine):

                   salesLine = _common as SalesLine;

                   SalesTotalsSummaryController::updateTotals(SalesTable::find(salesLine.SalesId), tableNum(SalesTotalsSummary));

                   break;

               default:

                   break;

           }

           }

    }

    /// <summary>

    ///     Calculates or gets the totals for the sales order and inserts the data in the <c>SalesTotalsSummary</c> table.

    /// </summary>

    /// <param name="_salesTable">

    ///     <c>SalesTable</c> record buffer for which to update the totals.

    /// </param>

    /// <param name="_salesTotalsSummary">

    ///     <c>SalesTotalsSummary</c> record buffer that needs to be updated; optional.

    /// </param>

    /// <param name="_salesTotals">

    ///     <c>SalesTotals</c> object that carries the totals values calculated; optional.

    /// </param>

    /// <returns>

    ///     true - indiating that the <c>SalesTotalsSummary</c> record was updated.

    /// </returns>

    public server static boolean calculateAndUpdateTotalsSummary(SalesTable _salesTable, SalesTotalsSummary _salesTotalsSummary = null, SalesTotals _salesTotals = null)

    {

       ttsbegin;

       if(!_salesTotals)

       {

           _salesTotals = SalesTotals::newSalesTable(_salesTable, SalesUpdate::All);

           _salesTotals.calc();

       }

       if (!_salesTotalsSummary || !_salesTotalsSummary.selectForUpdate())

       {

           _salesTotalsSummary = SalesTotalsSummary::findBySalesId(_salesTable.SalesId,true);

       }

       _salesTotalsSummary.SalesId = _salesTable.SalesId;

       _salesTotalsSummary.CurrencyCode = _salesTotals.salesCurrency();

       _salesTotalsSummary.NetLines = _salesTotals.salesBalance();

       _salesTotalsSummary.LineDiscount = _salesTotals.salesLineDisc();

       _salesTotalsSummary.Discounts = _salesTotals.salesEndDisc();

       _salesTotalsSummary.SalesTax = _salesTotals.salesTaxTotal();

       _salesTotalsSummary.MiscCharges = _salesTotals.salesMarkup();

       _salesTotalsSummary.RoundOff = _salesTotals.salesRoundOff();

       _salesTotalsSummary.UseTax = _salesTotals.salesUseTax();

       _salesTotalsSummary.OtherCharges = _salesTotals.salesOtherMiscCharges();

       _salesTotalsSummary.TotalAmount = _salesTotals.salesTotalAmount();

       _salesTotalsSummary.CashDiscount = _salesTotals.salesCashDiscAmount();

       _salesTotalsSummary.IsValid = true;

       if(!_salesTotalsSummary)

       {

           _salesTotalsSummary.insert();

       }

       else

       {

           _salesTotalsSummary.update();

       }

       ttscommit;

       return true;

    }

    /// <summary>

    ///     Creates and returns an object of <c>SalesTotalsSummaryController</c> for the given sales order id.

    /// </summary>

    /// <param name="_salesId">

    ///     Sales order Id

    /// </param>

    /// <returns>

    ///     Object of <c>SalesTotalsSummaryController</c>

    /// </returns>

    public static SalesTotalsSummaryController construct(SalesId _salesId)

    {

       SalesTotalsSummaryController salesTotalsSummaryController = new SalesTotalsSummaryController(_salesId);

       return salesTotalsSummaryController;

    }

    /// <summary>

    /// Sets the <c>isValid</c> field of the <c>SalesEncumbranceSummary</c> table to false so

    /// that the next time the <c>updateTotals</c> method is called the table will be updated.

    /// </summary>

    /// <param name="_salesId">

    /// The <c>SalesId</c> value of the record to invalidate.

    /// </param>

    public static void invalidateEncumbranceSummaryRecord(SalesId _slaesId)

    {

       SalesTotalsSummaryController::setValidFlag(_slaesId, tableNum(SalesEncumbranceSummary), false);

    }

    /// <summary>

    ///     Checks the table buffer to see from which table record was deleted,

    ///     If a record is deleted from a table which affects totals then the totals record is invalidated.

    /// </summary>

    /// <param name="_common">

    ///     Buffer for delted record

    /// </param>

    public server static void onDelete(Common _common)

    {

       SalesTable          salesTable;

       SalesLine           salesLine;

       MarkupTrans         markupTrans;

       SalesTotalsSummary  salesTotalsSummary;

       if (!_common || !SalesParameters::find().AutomaticFactBoxUpdateOnSO_PSN)

       {

           return;

       }

       switch(_common.TableId)

       {

           case tableNum(SalesLine):

           salesLine = _common as SalesLine;

           salesTotalsSummary = SalesTotalsSummary::findBySalesId(salesLine.SalesId, true);

           SalesTotalsSummaryController::setValidFlag(salesLine.SalesId, tableNum(SalesTotalsSummary), false, salesTotalsSummary);

           SalesTotalsSummaryController::updateTotals(SalesTable::find(salesLine.SalesId), tableNum(SalesTotalsSummary), salesTotalsSummary);

           break;

           case tableNum(MarkupTrans):

           markupTrans = _common as MarkupTrans;

           salesTable = SalesTable::findRecId(markupTrans.TransRecId);

           SalesTotalsSummaryController::setValidFlag(salesTable.SalesId, tableNum(SalesTotalsSummary), false);

           break;

       }

    }

    /// <summary>

    ///     Checks the table buffer to see in which table record was inserted.

    ///     If a record is inserted in SalesTable then records in totals tables are created,

    ///     otherwise records are invalidated if the insertion is in some other table that affects totals

    /// </summary>

    /// <param name="_common">

    ///     Buffer for new record

    /// </param>

    public server static void onInsert(Common _common)

    {

       SalesTable          salesTable;

       SalesLine           salesLine;

       MarkupTrans         markupTrans;

       SalesTotalsSummary  salesTotalsSummary;

       if (!_common || !SalesParameters::find().AutomaticFactBoxUpdateOnSO_PSN)

       {

           return;

       }

       switch(_common.TableId)

       {

           case tableNum(SalesTable):

               salesTable = _common as SalesTable;

               SalesTotalsSummary::createRecord(salesTable.SalesId, salesTable.CurrencyCode);

               SalesEncumbranceSummary::createRecord(salesTable.SalesId, salesTable.CurrencyCode);

               break;

           case tableNum(SalesLine):

               salesLine = _common as SalesLine;

               SalesTotalsSummary = SalesTotalsSummary::findBySalesId(salesLine.SalesId, true);

               SalesTotalsSummaryController::setValidFlag(salesLine.SalesId, tableNum(SalesTotalsSummary), false, salesTotalsSummary);

               SalesTotalsSummaryController::updateTotals(SalesTable::find(salesLine.SalesId), tableNum(SalesTotalsSummary), salesTotalsSummary);

               break;

           case tableNum(MarkupTrans):

               markupTrans = _common as MarkupTrans;

               salesTable = SalesTable::findRecId(markupTrans.TransRecId);

               SalesTotalsSummaryController::setValidFlag(salesTable.SalesId, tableNum(SalesTotalsSummary), false);

               break;

       }

    }

    /// <summary>

    ///     Invalidates the <c>SalesEncumbranceSummary</c> record if some document related to sales orders is posted.

    /// </summary>

    /// <param name="_postedJournalSet">

    ///     A <c>Set</c> object containing posted journal entries

    /// </param>

    public server static void onPostingSuccess(Set _postedJournalSet)

    {

       SetEnumerator       enumerator;

       Common              commonBuffer;

       CustInvoiceJour     custInvoiceJourLocal;

       CustConfirmJour     custConfirmJourLocal;

       if (!SalesParameters::find().AutomaticFactBoxUpdateOnSO_PSN)

       {

           return;

       }

       if (_postedJournalSet)

       {

           enumerator = _postedJournalSet.getEnumerator();

           while (enumerator.moveNext())

           {

               commonBuffer = enumerator.current();

               switch (commonBuffer.TableId)

               {

                   case tableNum(CustConfirmJour):

                       custConfirmJourLocal = commonBuffer as CustConfirmJour;

                       SalesTotalsSummaryController::populateEncumbranceSummaryValues(custConfirmJourLocal.SalesId);

                       break;

                   case tableNum(CustInvoiceJour):

                       custInvoiceJourLocal = commonBuffer as CustInvoiceJour;

                       SalesTotalsSummaryController::populateEncumbranceSummaryValues(custInvoiceJourLocal.SalesId);

                       break;

               }

           }

       }

    }

    /// <summary>

    /// Populates the <c>SalesEncumbranceSummary</c> record with encumbrance and relieving amounts for the sales order.

    /// </summary>

    /// <param name="_salesId">

    /// Sales order id for which to populate the record.

    /// </param>

    private server static void populateEncumbranceSummaryValues(SalesId _salesId)

    {

       SalesTable salesTable;

       if (_salesId && SalesParameters::find().AutomaticFactBoxUpdateOnSO_PSN)

       {

           salesTable = SalesTable::find(_salesId);

           SalesTotalsSummaryController::updateTotals(salesTable, tableNum(SalesEncumbranceSummary));

           SalesTotalsSummaryController::setValidFlag(salesTable.SalesId, tableNum(SalesEncumbranceSummary), false);

       }

    }

    /// <summary>

    ///     Sets the summary record's IsValid flag only if the new value is different from the one already stored.

    /// </summary>

    /// <param name="_salesId">

    ///     Sales order id for which to update the record

    /// </param>

    /// <param name="_tableId">

    ///     Table id of the summary table

    /// </param>

    /// <param name="_isValid">

    ///     Value for the IsValid flag

    /// </param>

    /// <param name="_salesSummary">

    ///     SalesTotalsSummary or SalesEncumbranceSummary table whose record needs to be updated

    /// </param>

    private server static void setValidFlag(SalesId _salesId, tableId _tableId, boolean _isValid = true, Common _salesSummary = null)

    {

       SalesTotalsSummary      salesTotalsSummary;

       SalesEncumbranceSummary salesEncumbranceSummary;

       switch(_tableId)

       {

           case tableNum(SalesTotalsSummary):

               salesTotalsSummary = _salesSummary as SalesTotalsSummary;

               if (!salesTotalsSummary ||!salesTotalsSummary.selectForUpdate())

               {

                   salesTotalsSummary = SalesTotalsSummary::findBySalesId(_salesid, true);

               }

               if(salesTotalsSummary && salesTotalsSummary.IsValid!=_isValid)

               {

                   salesTotalsSummary.IsValid = _isValid;

                   ttsbegin;

                   salesTotalsSummary.update();

                   ttscommit;

               }

               break;

           case tableNum(SalesEncumbranceSummary):

               salesEncumbranceSummary = _salesSummary as SalesEncumbranceSummary;

               if (!salesEncumbranceSummary ||!salesEncumbranceSummary.selectForUpdate())

               {

                   salesEncumbranceSummary = SalesEncumbranceSummary::findBySalesId(_salesId, true);

               }

               if(salesEncumbranceSummary && salesEncumbranceSummary.IsValid!=_isValid)

               {

                   salesEncumbranceSummary.IsValid = _isValid;

                   ttsbegin;

                   salesEncumbranceSummary.update();

                   ttscommit;

               }

               break;

       }

    }

    /// <summary>

    ///     Updates the totals or encumbrance amounts for the sales order, if invalid, based on the table id passed.

    /// </summary>

    /// <param name="_salesTable">

    ///     <c>SalesTable</c> record buffer for which to update the totals

    /// </param>

    /// <param name="_tableId">

    ///     Table Id of the table whose record needs to be updated

    /// </param>

    /// <param name="_salesSummary">

    ///      SalesTotalsSummary or SalesEncumbranceSummary table whose record needs to be updated

    /// </param>

    /// <returns>

    ///     true if a summary record was updated, false otherwise

    /// </returns>

    public server static boolean updateTotals(SalesTable _salesTable, tableId _tableId, Common _salesSummary = null)

    {

       SalesTotalsSummary                      salesTotalsSummary;

       AccountingDistributionOrderSummaryCalc  accountingDistributionOrderSummaryCalc;

       SalesEncumbranceSummary                 salesEncumbranceSummary;

       boolean recordUpdated = false;

       if (!SalesParameters::find().AutomaticFactBoxUpdateOnSO_PSN)

       {

           return recordUpdated;

       }

       switch(_tableId)

       {

           case tableNum(SalesTotalsSummary):

               SalesTotalsSummary = _salesSummary as SalesTotalsSummary;

               recordUpdated = SalesTotalsSummaryController::calculateAndUpdateTotalsSummary(_salesTable, salesTotalsSummary);

               break;

           case tableNum(SalesEncumbranceSummary):

               salesEncumbranceSummary = _salesSummary as SalesEncumbranceSummary;

               if (!salesEncumbranceSummary ||!salesEncumbranceSummary.selectForUpdate())

               {

                   salesEncumbranceSummary = SalesEncumbranceSummary::findBySalesId(_salesTable.PurchId, true);

               }

               if(!salesEncumbranceSummary)

               {

                   salesEncumbranceSummary = SalesEncumbranceSummary::createRecord(_salesTable.SalesId, _salesTable.CurrencyCode);

               }

               if(!salesEncumbranceSummary.IsValid)

               {

                   accountingDistributionOrderSummaryCalc = new AccountingDistributionOrderSummaryCalc();

                   accountingDistributionOrderSummaryCalc.populateEncumbranceSummaryAmount(_salesTable.SalesId);

                   salesEncumbranceSummary.LastCalculatedOn = DateTimeUtil::getSystemDateTime();

                   salesEncumbranceSummary.CurrencyCode = _salesTable.CurrencyCode;

                   salesEncumbranceSummary.EncumberedAmount = accountingDistributionOrderSummaryCalc.parmTotalEncumbered();

                   salesEncumbranceSummary.RelievedAmount = accountingDistributionOrderSummaryCalc.parmTotalRelieved();

                   salesEncumbranceSummary.IsValid = true;

                   ttsbegin;

                   salesEncumbranceSummary.update();

                   ttscommit;

                   recordUpdated = true;

               }

               break;

       }

       return recordUpdated;

    }

  • srinivas pamidi Profile Picture
    srinivas pamidi 1,737 on at
    RE: Sales Order Confirmation Error.

    Hi Gaurav Singhal,

    Thanks for your reply.

    I have some questions for sales order.

    U r created the summary fact box for sales order same as purchase order?

    It is Possible to create the Summary part for sales order?

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Sales Order Confirmation Error.

    Hi Srinivas,

    I have faced this debugger issue before. I think your code is somehow disturbing the "AmountCur" field. If you can share the code here then I think we can sort out the issue you are facing.

    Regards,

    Gaurav Singhal

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

November Spotlight Star - Khushbu Rajvi

Congratulations to a top community star!

Forum Structure Changes Complete!

🔔 Be sure to subscribe to the new forums you are interested in to stay up to date! 🔔

Dynamics 365 Community Platform update – Oct 28

Welcome to the next edition of the Community Platform Update. This is a status …

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,113 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 229,918 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans