Pages

Wednesday, November 13, 2013

AX Retail 2012 R2: POS cannot create customer order due to voucher already exists

In first version of AX 2012 R2, there is a bug when create customer order in POS with error: 

POSApp.CustomerOrderRecovery(): The order could not be saved at this time.Voucher <<voucher number>> is already used as at date <<dd/mm/yyyy>>.
Posting has been cancelled.

When check Voucher Transaction, above <<voucher number>> already exists. But when check the Status List of related number sequence, that number appears with "Free" status.  The Next number is also higher.   

It seems like after posting a Sales Order, that voucher has been posted but not released from number sequence list (Status is still Free).





Then, I provided 2 solutions to my colleague who supports that customer: 


Create RunBaseBatch class

It's such temporary solution, if the error rarely occurs.  It will open RunBaseBatch dialog for inputting number series of payment voucher (in Demo Database is Acc_30).  Then, it will lock number sequence status from "Free" to "Active" if it has been posted.     



private void update()
{
    //NumberSequenceTable     numberSequenceTable = NumberSequenceTable::findByNaturalKey('Acco_30');
    NumberSequenceTable     numberSequenceTable = NumberSequenceTable::find(ecoResNumberSequence);
    NumberSequenceList      numberSequenceList;
    GeneralJournalEntry     generalJournalEntry;
    boolean                 updateData;
    Num                     formattednumber;



    if (numberSequenceTable.RecId)
    {
        ttsBegin;
        while select forupdate numberSequenceList
        where numberSequenceList.NumberSequenceId == numberSequenceTable.RecId &&
              numberSequenceList.Status == NumStatus::Free &&
              numberSequenceList.NextRec < numberSequenceTable.NextRec
        {
            formattednumber = numberSequenceList.formattednumber();
            select generalJournalEntry
                where generalJournalEntry.SubledgerVoucher == formattednumber;
            if (generalJournalEntry.RecId)
            {
                numberSequenceList.Status = NumStatus::Active;
                numberSequenceList.update();
                updateData = true;
            }
        }
        ttsCommit;
    }
}

Release number sequence before generate new payment voucher 

Just in case, the error occurs too often.  I will check number sequence.  If it's in use, release it first.  Customize this in table CustParameters


client server static NumberSequenceReference numRefCustPaymVoucher()
{
      CustParameters::pkaCheckNumberSequenceNextRec(extendedTypeNum(CustPaymVoucher));
      return NumberSeqReference::findReference(extendedTypeNum(CustPaymVoucher));

client server static void pkaCheckNumberSequenceNextRec(extendedTypeId _edt)
{
    NumberSequenceTable             numberSequenceTable;
    RecId                           numberSequenceId = NumberSeqReference::findReference(_edt).NumberSequenceId;
    NumberSequenceList              numberSequenceList;
    Num                             formattedNumber;
    GeneralJournalEntry             generalJournalEntry;

    numberSequenceTable = NumberSequenceTable::find(numberSequenceId);

    if (numberSequenceTable.RecId)
    {
        //active unused number sequence
        ttsBegin;

        switch (_edt)
        {
            case extendedTypeNum(CustPaymVoucher) :  //Payment voucher
                while select forupdate numberSequenceList
                      where  numberSequenceList.NumberSequenceId == numberSequenceTable.RecId &&
                             numberSequenceList.Status           == NumStatus::Free &&
                             numberSequenceList.NextRec          < numberSequenceTable.NextRec
                {
                    formattedNumber = numberSequenceList.formattednumber();
                    select generalJournalEntry
                        where generalJournalEntry.SubledgerVoucher == formattednumber;
                    if (generalJournalEntry.RecId)
                    {
                        numberSequenceList.Status       = NumStatus::Active;
                        numberSequenceList.update();
                    }
                }

                break;
        }
        ttsCommit;
    }


However, I just use one of above solutions when not able to update CU6 (can't offline all outlets for update the hotfix).  I don't see this error with R2+CU6 version.       


3 comments:

  1. I am very thankful to all your teamepos systems for small retailers sharing such inspirational information

    ReplyDelete
  2. very Interesting and useful information epos uk you have shared and keep sharing the blogs....

    ReplyDelete
  3. Thanks for sharing unique information, epos good post to share.

    ReplyDelete