Wednesday, June 15, 2011

Mark Customer Invoices for settlement with AX 2009 - Mark Invoices

After creating a payment journal (http://axwonders.blogspot.com/2011/06/create-axapta-payment-journal.html ), you might want to mark the invoices for settlement. This task is done by looping through the just created Payment Journal and then by querying the CustTransOpen Table and instantiating the CustTrans table from the CustTransOpen.CustTrans() method.


The following is the code to mark invoices. Also, the code loops through each payment journal transaction.

Also, the logic behind it is that the SpecTrans table needs to have two records in order to offset an open invoice with a transaction. So the code below inserts two records to the SpecTrans table. One is for all the open transactions (invoices - Sales) and the other is for all the payment transactions (paymet - Payment)

For example:

select firstonly invCustTrans where invCustTrans.AccountNum == custTable.AccountNum
            && invCustTrans.TransType == LedgerTransType::Sales
            && !invCustTrans.LastSettleDate;


the code above will select all the customer transactions with a TransType of Sales.

On the other hand, the code below will select all the customer transaction with a TransType of Payment.

select firstonly payCustTrans where payCustTrans.AccountNum == custTable.AccountNum
            && payCustTrans.TransType == LedgerTransType::Payment
            && !payCustTrans.LastSettleDate;


Then we need to insert the two instances of CustTrans into the SpecTrans table:

specOffsetVoucher.insert(invCustTrans.dataAreaId, invCustTrans.TableId, invCustTrans.RecId, invCustTrans.AmountCur, invCustTrans.CurrencyCode, NoYes::No);

specOffsetVoucher.insert(payCustTrans.dataAreaId, payCustTrans.TableId, payCustTrans.RecId, payCustTrans.AmountCur, payCustTrans.CurrencyCode, true);
The following is the whole code:


protected void MarkInvoiceRecords()
{
    LedgerJournalEngine_CustPayment LedgerJournalEngine;
    LedgerJournalCheckPost          ledgerJournalCheckPost;
    LedgerJournalTable              ledgerJournalTable;
    LedgerJournalTrans              journalTrans;
    CustVendTransData               transData;
    SpecTransManager                specOffsetVoucher;
    CustTransOpen                   custTransOpen, custTransOpen2;
    InvoiceId                       invoiceId;
    CustTable                       custTable;
    CustTrans                       invCustTrans, payCustTrans;
    boolean                         changePaymentAmount;
    boolean                         breakProcess;
    Common                          common;
    Amount                          amount;
    Amount                          amountLeft = 0.00;
    ;
    try
    {
        //Select each record from the created (from file) Payment Journal
        while select forupdate journalTrans where journalTrans.JournalNum == ledgerJournalId
        {
            custTable = CustTable::find(journalTrans.AccountNum);
            changePaymentAmount = false;
            breakProcess = false;
            select firstonly invCustTrans where invCustTrans.AccountNum == custTable.AccountNum
            && invCustTrans.TransType == LedgerTransType::Sales
            && !invCustTrans.LastSettleDate;
                            
            if(!invCustTrans)
                  throw error("@COL4567");
           
            select firstonly payCustTrans where payCustTrans.AccountNum == custTable.AccountNum
            && payCustTrans.TransType == LedgerTransType::Payment
            && !payCustTrans.LastSettleDate;
    
             if(!payCustTrans)
                  throw error("@COL4567");
            specOffsetVoucher = SpecTransManager::construct(custTable);
            specOffsetVoucher.insert(invCustTrans.dataAreaId, invCustTrans.TableId, invCustTrans.RecId, invCustTrans.AmountCur, invCustTrans.CurrencyCode, NoYes::No);
            specOffsetVoucher.insert(payCustTrans.dataAreaId, payCustTrans.TableId, payCustTrans.RecId, payCustTrans.AmountCur, payCustTrans.CurrencyCode, true);
            specOffsetVoucher.updateMarkedPayment(payCustTrans.dataAreaId, payCustTrans.TableId, payCustTrans.RecId, true);

        }
    }
    catch(Exception::Error)
    {
        this.createErrorMessages(KMN_CustPaymentJournalErrorType::EmptyString, '0');
    }
}

           

And, finally we update the Payment CustTrans instance into the specTrans table:
specOffsetVoucher.updateMarkedPayment(payCustTrans.dataAreaId, payCustTrans.TableId, payCustTrans.RecId, true);

4 comments:

  1. Or:

    invCustTrans = CustTrans::find(this.recidInvoice);
    payCustTrans = CustTrans::find(this.recidPayment);
    custTable = CustTable::find(this.CustAccount);

    invCustTrans.transData().markForSettlement(custTable);
    payCustTrans.transData().markForSettlement(custTable);
    custtrans::settleTransact(custTable);

    ReplyDelete
  2. Hi,

    I write below code for payment settlement, this code is executing successfully but when i am checking record from Customer details ---> transaction that time i am not able to see settlement. below is the code which i am using:-

    static void settlePayment(Args _args)
    {
    CustTable custTable;
    CustTrans invCustTrans, payCustTrans;
    SpecTransManager manager;
    CustVendTransData custVendTransData;
    ;
    custTable = CustTable::find("2114");

    select firstonly invCustTrans
    order by TransDate asc
    where invCustTrans.AccountNum == custTable.AccountNum && invCustTrans.TransType == LedgerTransType::Sales && !invCustTrans.LastSettleDate;

    select firstonly payCustTrans
    order by TransDate asc
    where payCustTrans.AccountNum == custTable.AccountNum && payCustTrans.TransType == LedgerTransType::Payment && payCustTrans.LastSettleDate;
    ttsbegin;

    custVendTransData = CustVendTransData::construct(invCustTrans);
    custVendTransData.markForSettlement(CustTable);

    custVendTransData = CustVendTransData::construct(payCustTrans);
    custVendTransData.markForSettlement(CustTable);
    ttscommit;

    if(CustTrans::settleTransact(custTable, null, true,SettleDatePrinc::DaysDate, systemdateget()))
    info("Transactions settled");
    }

    Thanks,
    Pooja

    ReplyDelete
    Replies
    1. I think you are missing this line and /or logic. If you think about it you are using the object without the transdata.

      payCustTrans.transData().markForSettlement(custTable);

      Delete

Thank you for your thoughts. Your comment will appear in my blog shortly after review.

Have a great day!