Enhancing Transaction Marking in Dynamics 365 with Custom Service Classes
Monal Rode
Data Analyst -Power BI, DAX, Excel Expertise, Technical Consultant - D365 F&O ERP
In this article, I'll walk you through a custom service class in Dynamics 365 that handles marking transactions based on specific criteria. This class ensures that transactions are marked only if they aren't already, preventing duplicate markings and ensuring accurate data processing.
The Challenge
Our objective was to develop a functionality that checks if a transaction has already been marked and, if not, mark it accordingly. This was necessary to streamline our financial processes and ensure data consistency across our system.
The Solution
To achieve this, I created a custom service class named TenderMarkingServiceClass. The class contains two primary methods:
领英推荐
Key Components of the Class
Here's a brief overview of the key components and logic within the class:
public class TenderMarkingServiceClass extends SysOperationServiceBase
{
public void checkRecordMarked(InvoiceId _invoice, LedgerJournalTrans _ledgerJournalTrans, AccountNum _accountNum)
{
CustVendOpenTransManager manager;
CustTransOpen custTransOpen;
CustTrans custTrans;
SpecTransManager specTransManager;
ttsBegin;
try
{
// Select the CustTransOpen and CustTrans records
select firstonly custTransOpen
join custTrans
where custTransOpen.AccountNum == _accountNum &&
custTransOpen.RefRecId == custTrans.RecId &&
custTrans.Invoice == _invoice;
if (custTransOpen && custTrans)
{
// Check if the record is already marked
specTransManager = SpecTransManager::construct(null);
boolean isMarked = specTransManager.existForOtherSpec(
custTransOpen.company(),
custTransOpen.TableId,
custTransOpen.RecId
);
if (!isMarked)
{
// Mark the transaction if not already marked
manager = CustVendOpenTransManager::construct(_ledgerJournalTrans);
if (manager)
{
manager.updateTransMarked(custTransOpen, true);
info("Transaction marked successfully.");
}
}
}
ttsCommit;
}
catch (Exception::Error)
{
ttsAbort;
error("Error marking transaction. Transaction aborted.");
}
}
public void MarkOpenTransaction()
{
Tender tender;
LedgerJournalTrans ledgerJournalTrans;
CustInvoiceJour custInvoiceJour;
CustTransOpen custTransOpen;
CustTable custTable;
ttsBegin;
try
{
while select RecId, AccountNum, PaymentJournalNum, SalesId, TenderAmount from tender
where tender.PaymentJournalNum != ''
{
// Select the latest invoice for the SalesId in the tender
select firstonly RecId, InvoiceId, InvoiceDate, InvoiceAmount from custInvoiceJour
where custInvoiceJour.SalesId == tender.SalesId;
if (custInvoiceJour)
{
// Check if the transaction is already open
select firstonly count(RecId) from custTransOpen
where custTransOpen.RefRecId == custInvoiceJour.RecId;
if (custTransOpen.RecId == 0)
{
// Get the customer account number from SalesTable
select firstonly custTable where custTable.AccountNum == tender.AccountNum;
if (custTable)
{
// Select the custTrans record
select firstonly custTrans
where custTrans.Invoice == custInvoiceJour.InvoiceId &&
custTrans.AccountNum == custTable.AccountNum;
if (custTrans)
{
// Iterate over the ledger journal transactions and mark them
while select ledgerJournalTrans
where ledgerJournalTrans.JournalNum == tender.PaymentJournalNum
{
this.checkRecordMarked(custInvoiceJour.InvoiceId, ledgerJournalTrans, tender.AccountNum);
}
}
}
}
}
}
ttsCommit;
}
catch (Exception::Error)
{
ttsAbort;
error("Error processing tenders. Transaction aborted.");
}
}
}
Customizing Dynamics 365 can significantly enhance its capabilities to better suit specific business needs. By implementing the TenderMarkingServiceClass, we streamlined our transaction marking process, ensuring efficiency and accuracy. If you have similar requirements or are looking to customize your Dynamics 365 environment, understanding and leveraging these development techniques can be incredibly beneficial.