Skip to main content

Email D365


To send an email in D365 there are some standard libraries used for this. In this below code we have used email templates for email. but there are some points which you need to make sure 

1. email parameters ------- add your email and smtp

2. email batch job used to send email. 

3. Class SysmailerBuilder (used below) doesnt require above 2 points. it sends email automatically



[Control("Button")]
class SendEmail
{
/// <summary>
/// sends email on click to respective vendors
/// </summary>
public void clicked()
{

DialogButton diagBut;
str strMessage = "@SLD_Label:ContinueOrNot";
str strTitle = "@SLD_Label:EmailNotification";
diagBut = Box::yesNo(strMessage, DialogButton::Yes, strTitle);
if (diagBut == DialogButton::Yes)
{
this.getRecords();
}
}


public void getRecords ()
{
MultiSelectionHelper selectionHelper = MultiSelectionHelper::construct();
Set selectedRecords = new Set(Types::Record);
VendTrans vendTran, vendTranss;
Email email;
boolean istrue;
VendTable vendTab;
SLD_EmailNotification emailNotification;



selectionHelper.parmDatasource(VendTrans_DS);

vendTran = selectionHelper.getFirst();


if (vendTran.RecId)
{
while (vendTran)
{
selectedRecords.add(vendTran);


select vendTab
join vendTranss
where vendTab.AccountNum == vendTranss.AccountNum
&& vendTranss.Voucher == vendTran.Voucher;



istrue = this.isEmailAlreadySent(vendTran);

if(istrue || !(vendTran.EmailSent))
{
this.processEmailNotification(vendTab.PaymMode, vendTran, vendTab);
}
vendTran = selectionHelper.getNext();
}
}
}


public void processEmailNotification (VendPaymMode _paymMode, VendTrans _vendTrans, VendTable _vendTab)
{
VendPaymModeTable vendpaymMode;
SysEmailTable sysEmailTable;
SLD_EmailNotification emailNotifiation = new SLD_EmailNotification();
Map map = new Map (Types::String,Types::String);
Boolean isSuccess;
str EmailTableValue;



select sysEmailTable
join vendpaymMode
where vendpaymMode.PaymMode == _paymMode
&& vendpaymMode.SLDEmailId == sysEmailTable.EmailId;



EmailTableValue= this.initEmailTableContents(_vendTrans);
isSuccess = this.processEmail(EmailTableValue, vendpaymMode.SLDEmailId, _vendTab, _vendTrans);

if(isSuccess==true)
{
info(strFmt('@SLD_Label:EmailSuccess', _vendTrans.AccountNum,_vendTrans.Voucher));


select forupdate _vendTrans
where _vendTrans.EmailSent == NoYes::No;
_vendTrans.EmailSent = NoYes::Yes;
_vendTrans.update();

}

}


public boolean processEmail (str _emailtablevalue, SysEmailId _emailId, VendTable _vendTable, VendTrans _vendtrans)
{
SysMailerMessageBuilder messageBuilder = new SysMailerMessageBuilder();
boolean istrue = false;

try
{
SysEmailTable sysEmailTable = SysEmailTable::find(_emailId);


if(!sysEmailTable)
{
throw error(strFmt("@SLD_Label:EmailTempNotSet",_vendtrans.Voucher));
}


SysEmailMessageTable sysEmailMessageTable = SysEmailMessageTable::find(sysEmailTable.EmailId, sysEmailTable.DefaultLanguage);

str messageBody = sysEmailMessageTable.Mail;
str subject = sysEmailMessageTable.Subject;


Map placeholderMap = new Map(Types::String, Types::String);


placeholderMap.insert("Amount", num2Str(netamountpayment,0,0,0,0));
placeholderMap.insert("EmailTable", _emailtablevalue);


messageBody = SysEmailMessage::stringExpand(messageBody, placeholderMap);
subject = SysEmailMessage::stringExpand(subject, placeholderMap);

messageBuilder.addTo(_vendTable.email());


if(!(_vendTable.email()))
{
throw error(strFmt("@SLD_Label:EmailNotSet",_vendtrans.Voucher));
}

messageBuilder.setFrom(sysEmailTable.SenderAddr, sysEmailTable.SenderName);

messageBuilder.setSubject(subject);
messageBuilder.setBody(messageBody);
var message = messageBuilder.getMessage();
SysMailerFactory::sendNonInteractive(message);
netamountpayment = 0;
istrue = true;
}
catch (Exception::Error)
{
throw error(strFmt("@SLD_Label:FailedEmail", _vendTrans.AccountNum,_vendTrans.Voucher));
}

return istrue;
}

public boolean isEmailAlreadySent (VendTrans _vendTrans)
{
boolean istrue = false;


if(_vendTrans.EmailSent == NoYes::Yes)
{
DialogButton diagBut;
str strMessage = strFmt("@SLD_Label:EmailAlreadySent", _vendTrans.AccountNum,_vendTrans.Voucher);
str strTitle = "@SLD_Label:EmailNotification";
diagBut = Box::yesNo(strMessage, DialogButton::No, strTitle);


if (diagBut == DialogButton::Yes)
{
istrue = true;
}

}
return istrue;
}

public str initEmailTableContents (VendTrans _vendTrans)
{
RecId lastProcessedBankChequePaymTrans = 0;
RecId recIdToProcessFrom = lastProcessedBankChequePaymTrans;
BankChequePaymTrans bankChequePaymTrans;
Query query;
QueryRun queryRunn;
TaxWithholdTrans taxWithholdTrans;
TaxWithholdTable taxWithholdTable;
TaxTrans taxTrans;
TaxTable taxTable;
TaxWithholdAmountCur withHeldGST;
AmountCur amountGSTWHT, amountDeductionWHT, NetAmount;
List emailtablecontents = new List (Types::String);
int counter = 1;
boolean flag = false;
str EmailTable, Header, emailTablerows, netAmountPaid;
chequeTmp chequeTmp, chequeTmpTable;


while select bankChequePaymTrans
order by bankChequePaymTrans.RecId
where bankChequePaymTrans.Voucher == _vendTrans.Voucher
&& bankChequePaymTrans.RecId > recIdToProcessFrom
{
amountGSTWHT = 0;
amountDeductionWHT = 0;
withHeldGST = 0;


chequeTmp.SLDInvoiceVoucher = bankChequePaymTrans.InvoiceVoucher ;
chequeTmp.SLDInvoiceId = bankChequePaymTrans.InvoiceId;
chequeTmp.SLDInvoiceDate = date2Str(bankChequePaymTrans.InvoiceDate,
123,
2,
DateSeparator::Dot,
2,
DateSeparator::Dot,
4);


chequeTmp.SLDInvoiceAmountCur = bankChequePaymTrans.PaymentAmountCur != 0 ? -bankChequePaymTrans.PaymentAmountCur : -bankChequePaymTrans.InvoiceAmountCur;
chequeTmp.SLDSr = counter;
flag = true ;


query = new Query(queryStr(SLDChequeWithHoldAmount));
query.dataSourceTable(tableNum(TaxWithholdTrans))
.addRange(fieldNum(TaxWithholdTrans, Voucher))
.value(_vendTrans.Voucher) ;


query.dataSourceTable(tableNum(TaxWithholdTrans))
.addRange(fieldNum(TaxWithholdTrans, VoucherInvoice))
.value(chequeTmp.SLDInvoiceVoucher);


queryRun = new QueryRun(query);
if (SysQuery::countLoops(queryRun) > 0) // check if transaction has Item witholding tax
{
while(queryRun.next())
{
taxWithholdTrans = queryRun.get(tableNum(TaxWithholdTrans));
taxWithholdTable = queryRun.get(tableNum(TaxWithholdTable));

if (taxWithholdTable.SLD_WithholdingOf == 0)
{
amountGSTWHT += taxWithholdTrans.PaymTaxWithholdAmount;
}
else if (taxWithholdTable.SLD_WithholdingOf == 1)
{
amountDeductionWHT += taxWithholdTrans.PaymTaxWithholdAmount;
}


withHeldGST += taxWithholdTrans.SLD_STWH;
chequeTmp.SLDInvoiceAmountCur = taxWithholdTrans.InvoiceAmount;
}

chequeTmp.SLDGSTWithholdAmount = amountGSTWHT;
chequeTmp.SLDDeductionWithholdAmount = amountDeductionWHT;

chequeTmp.SLDGSTWithholdAmount = abs(withHeldGST);
chequeTmp.SLDPaymentAmountCur = chequeTmp.SLDInvoiceAmountCur - chequeTmp.SLDGSTWithholdAmount - chequeTmp.SLDDeductionWithholdAmount;
}
else
{
while select TaxCode, TaxAmountCur
from taxTrans
where taxTrans.Voucher == bankChequePaymTrans.InvoiceVoucher
&& taxTrans.TransDate == bankChequePaymTrans.InvoiceTransDate
{
taxTable = TaxTable::find(taxTrans.TaxCode);

if (taxTable.SLD_STWHCode == NoYes::Yes)
{
withHeldGST += taxTrans.TaxAmountCur;
}
}

chequeTmp.SLDGSTWithholdAmount = abs(withHeldGST);
chequeTmp.SLDInvoiceAmountCur += chequeTmp.SLDGSTWithholdAmount;
chequeTmp.SLDInvoiceAmountCur += chequeTmp.SLDDeductionWithholdAmount;


chequeTmp.SLDPaymentAmountCur = chequeTmp.SLDInvoiceAmountCur - chequeTmp.SLDGSTWithholdAmount - chequeTmp.SLDDeductionWithholdAmount;

}

chequeTmp.insert();


chequeTmp.SLDGSTWithholdAmount = 0;
chequeTmp.SLDDeductionWithholdAmount = 0;


counter = counter + 1 ;
lastProcessedBankChequePaymTrans = bankChequePaymTrans.RecId;

}


if (flag == false)
{
LedgerJournalTrans ledgerJournalTrans = LedgerJournalTrans::findJournalForVoucher
(_vendTrans.Voucher, _vendTrans.TransDate),
sumLedgerJournalTransInvoiceAmt,
sumLedgerJournalTransWHTAmt;


select sum(AmountCurDebit)
from sumLedgerJournalTransInvoiceAmt
where sumLedgerJournalTransInvoiceAmt.Voucher == _vendTrans.Voucher;

select sum(AmountCurDebit)
from sumLedgerJournalTransWHTAmt
where sumLedgerJournalTransWHTAmt.Voucher == _vendTrans.Voucher
&& sumLedgerJournalTransWHTAmt.SLD_AdvanceWHT == NoYes::Yes;

chequeTmp.SLDSr = counter;
chequeTmp.SLDInvoiceId = "@SLD_Label:AdvancePayment";
chequeTmp.SLDInvoiceDate = date2Str(ledgerJournalTrans.TransDate, 123, 2, DateSeparator::Dot, 2,DateSeparator::Dot, 4);
chequeTmp.SLDInvoiceAmountCur = sumLedgerJournalTransInvoiceAmt.AmountCurDebit;
chequeTmp.SLDDeductionWithholdAmount = sumLedgerJournalTransWHTAmt.AmountCurDebit ;
chequeTmp.SLDPaymentAmountCur = chequeTmp.SLDInvoiceAmountCur - chequeTmp.SLDDeductionWithholdAmount - chequeTmp.SLDPaymentAmountCur;


chequeTmp.insert();
}


Header = '<table border="1"><tr><th> S.No. </th><th> Document No. </th><th> Invoice Reference </th><th> Invoice Date </th><th> Invoice Value </th><th> GST Withheld </th><th> Deduction WHT </th><th> Net Amount </th></tr>';
emailtablecontents.addEnd(Header);


while select SLDSr, SLDInvoiceId, SLDInvoiceDate, SLDInvoiceAmountCur,
SLDDeductionWithholdAmount, SLDGSTWithholdAmount, SLDPaymentAmountCur from chequeTmp
{
EmailTable = strFmt('<tr><td> %1 </td><td> %2 </td><td> %3 </td><td> %4 </td><td> %5 </td><td> %6 </td><td> %7 </td><td> %8 </td></tr>',chequeTmp.SLDSr, _vendTrans.Voucher, chequeTmp.SLDInvoiceId, chequeTmp.SLDInvoiceDate, chequeTmp.SLDInvoiceAmountCur, chequeTmp.SLDGSTWithholdAmount, chequeTmp.SLDDeductionWithholdAmount,chequeTmp.SLDPaymentAmountCur);
netamountpayment +=chequeTmp.SLDPaymentAmountCur;
emailtablecontents.addEnd(EmailTable);
}
netAmountPaid = strFmt('<tr><td colspan=7 style="text-align:right"> Net amount paid </td><td> %1 </td></tr></table>', netamountpayment);
emailtablecontents.addEnd(netAmountPaid);
emailTablerows = strList2str(emailtablecontents);
return emailTablerows;
}
}

 

 

HEY HEY HEY!! HACK OF THE DAY !!! 
SysMailerFactory::sendNonInteractive(message); 
This can be sendInteractive(message) 
It will open email for you to check details and send by your self


Comments

Popular posts from this blog

Edit Method on Form

Edit Method D365 for a form Data Source 1. To create an edit method first create a controller class. with following properties  public static edit MainAccountNum LedgerJournalTransLedger(LedgerJournalTrans _ledgerjournal, boolean _set, MainAccountNum _id) { MainAccountNum accountId = _id; MainAccount mainAccount = MainAccount::findByMainAccountId(_id); if(_set) { if(_ledgerjournal.AccountType== LedgerJournalACType::Ledger) { mainAccount = MainAccount::findByMainAccountId(accountId); if(_ledgerjournal.LedgerDimension) { DimensionDefault defaultDim = LedgerDimensionFacade::getDefaultDimensionFromLedgerDimension(_ledgerjournal.LedgerDimension); _ledgerjournal.LedgerDimension = LedgerDimensionDefaultingEngine::getLedgerDimensionFromAccountAndDim(mainAccount.RecId, DimensionHierarchy::getAccountStructure(mainAccount.RecId), defaultDim); } else { _ledgerjournal.LedgerDimension = LedgerDimensionDefaultingEngine::getLedgerDimensionFromAccountAndDim(mainAccount.RecId, DimensionHierarchy::ge...

Lookup and Mandatory fields on Form using Form event Handlers D365

Lookup and Mandatory fields on Form using Form event Handlers D365 [FormControlEventHandler(formControlStr(VendBankAccounts, VendBankAccount_SLD_BankCode), FormControlEventType::Lookup)] public static void VendBankAccount_SLD_BankCode_OnLookup(FormControl sender, FormControlEventArgs e)     {         Query query = new Query();         QueryBuildDataSource queryBuildDataSource;         FormControlCancelableSuperEventArgs event = e as FormControlCancelableSuperEventArgs;         QueryBuildRange queryBuildRange;         SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(SLD_BankCodes), sender);         sysTableLookup.addSelectionField(fieldNum(SLD_BankCodes, BankCodes));         sysTableLookup.addLookupField(fieldNum(SLD_BankCodes, BankCodes));         sysTableLookup.addLookupField(fieldNum(SLD_BankCode...

Field Level Security In Ax 2012

FIELD LEVEL SECURITY IN AX 2012 In this blog we will discuss field level security applied in  Ax 2012. 1. Field level security is added on form level as well in Ax 2012 its bit different then field level security in D365 2. This also requires privileges to be applied on form specific fields only. Step #1 :  Change datasource property of the field which need to be added in security. Step #2 : Now add these 2 fields in form --- > permissions --- > Read Step #3 : Now finally create privilege and add these fields explicitly in it.       HEY HEY HEY !!!! HACK OF THE DAY  Add Fields in Entry point privilege section of form  Explicitly.