Showing posts with label tips. Show all posts
Showing posts with label tips. Show all posts

Friday, July 23, 2010

SysQueryRangeUtil class - use method name as query criteria

This is a cool new feature in AX 2009 - you can now use a method name instead of literal value in query criteria!

For example, if you run a report every month, previously you need to change the date criteria in each month you running the report (ie. “01/06/2010..30/06/2010”,  “01/07/2010..31/07/2010”, etc).
Now you only need to enter (monthRange(0, 0)) which will automatic return the correct first day and last day of the month.

Refer to the SysQueryRangeUtil class – there are other useful methods such as dateRange(), currentEmployeeId(), etc. It’s also possible to create new method on this class for special purpose!

Tuesday, July 6, 2010

strFmtLB and the newline character (\n) in label files

You want to split your info message into multiple lines, so you use the \n newline character.
You write the following code:-
info("Line1\nLine2");
You tested it's working and the output message is split into 2 lines as below:-
Line1
Line2

Now you've converted the string into a label, so you update your code such as the one below:-
info("@WKN1");
But when you re-run the code, you realised that the newline character is no longer working and printed directly on screen. The message is displayed as one line instead of two as below:-
Line1\nLine2

To display the message correctly, you need to use the global method strFmtLB:-
info(strFmtLB("@WKN1"));
If your string message contains placeholders (%1, %2, etc.), then you can use both strFmtLB and strFmt methods together:-
info(strFmtLB(strFmt("@SYS39890", "Line1", "Line2")));
Result of running the above code:-
Line1
 Line2

Saturday, June 26, 2010

Sending emails from Dynamics AX

It’s a common requirement to have Dynamics AX to send emails as part of the business processes such as delivering the invoice/statement to customers by email. Out of box Dynamics AX already has the framework provided in X++ classes for developers to send email using X++ code. There are currently three ways to do so and each has its own features/limitation as described below:-

1) SysInetMail class
This is used in the standard MorphX report if E-mail recipient is selected as Print medium. It requires an email program to be installed at the AX client computer and the mail message will be sent using the email program. The advantage using this method is it provides the flexibility for users to edit the email before it get sent out, but also means you can’t use it automate the sending of email because it requires the user’s intervention to manually click the Send button.
One workaround for this is you can modify the reportSendMail() method in the Info class. This method is called when the report’s print medium is specified as E-mail recipient. So you can modify this method to email the report automatically using the two other following options instead of SysInetMail class.
SysINetMail m = new SysINetMail();
m.sendMailAttach(..);

2) SysEmailTable::sendMail(..) table method
This method uses the SysMailer class and the underlying framework which utilise the CDO COM object to send email. It is commonly used by standard Dynamics AX system when emailing function is required such as the sending of Alert email, Workflow, etc.
To use this method, you need to set up two things:-i) SMTP relay server information in the E-mail parameters (Administration > Setup > E-mail parameters), ii) Email template that specify the subject and the body of email, supported in plain text or HTML format (Basic > Setup > E-mail templates), and the use of placeholders.
There are a lot of advantages using this way of sending email:- The email body is user-definable using Email template and placeholders, the email could be sent without user intervention, the email sending process can be scheduled in batch job and retry sending when failed, and you also can attach file to the email (although it only support one file attachment).
SysEmailId sysEmailId = 'Alerts';
str  recipientEmail = 'john@contoso.com';
;
SysEmailTable::sendMail(
    sysEmailId,
    SysEmailTable::find(sysEmailId).DefaultLanguage,
    recipientEmail,
    null,
    '',
    '',
    true,
    curuserid(),
    true);

3) System.Net.Mail .NET class
The last option is to use the .NET classes to send email. It is very simple to use and yet it provides a lot of flexibilities. You can specify multiple recipients, cc and bcc, attach multiple files, turn on the email delivery notification and read receipt notification, and you can also archive the mail message in .eml file format.
System.Net.Mail.MailMessage mailMessage;
System.Net.Mail.SmtpClient smtpClient;
System.Net.Mail.MailAddress mailFrom;
System.Net.Mail.MailAddress mailTo;
str    smtpServer;
;

mailFrom = new System.Net.Mail.MailAddress('sender@contoso.com',"Sender name");
mailTo  = new System.Net.Mail.MailAddress('recipient@contoso.com',"Recipient name");

smtpServer = SysEmaiLParameters::find(false).SMTPRelayServerName;// using the SMTP server ip setup in Email Parameters
mailMessage = new System.Net.Mail.MailMessage(mailFrom,mailTo);
mailmessage.set_Subject('This is email subject');
mailmessage.set_Body('This is email body');

smtpClient = new System.Net.Mail.SmtpClient(smtpServer);
smtpClient.Send(mailmessage); 
mailMessage.Dispose();

If you want to use Email template instead of hard code the email body, consider using the following approach:-
System.Net.Mail.MailMessage mailMessage;
SysEmailMessageTable  message;
str    messageBody;
SysEmailId   sysEmailId = 'Alerts';
Map    mappings = new Map(Types::String, Types::String);
;
...
mappings.insert('message', 'This is the message');
message = SysEmailMessageTable::find(sysEmailId, SysEmailTable::find(sysEmailId).DefaultLanguage);
messageBody = SysEmailMessage::stringExpand(message.Mail, SysEmailTable::htmlEncodeParameters(mappings));
messageBody = WebLet::weblets2Html4Help(messageBody, '');
mailMessage.set_Body(messageBody);
mailMessage.set_IsBodyHtml(true);
...
To enable the Delivery Notification feature:-
System.Net.Mail.DeliveryNotificationOptions deliveryOptions;
;
...
deliveryOptions = ClrInterop::parseClrEnum('System.Net.Mail.DeliveryNotificationOptions', 'OnSuccess');
mailMessage.set_DeliveryNotificationOptions(deliveryOptions);
...
To save the mail message to .eml file instead of sending the email:-
System.Net.Mail.SmtpClient              smtpClient;
System.Net.Mail.SmtpDeliveryMethod      stmpDeliveryMethod;
;
...
stmpDeliveryMethod = ClrInterop::parseClrEnum('System.Net.Mail.SmtpDeliveryMethod', 'SpecifiedPickupDirectory');
smtpClient.set_DeliveryMethod(stmpDeliveryMethod);
smtpClient.set_PickupDirectoryLocation('C:\\Temp');
...
smtpClient.Send(mailMessage);  // Save to file instead of sending

Now you have created the codes and want to test the email sending job. You can use the Windows SMTP virtual server for the quick test if you do not have a SMTP server. After installing the SMTP server, you need to go to IIS Manager -> Default SMTP Virtual Server -> right-click Properties -> Access tab -> Relay button -> Select All except the list below, to enable to relay all e-mail messages through the current server.
Note: For Windows Server, you need to open IIS 6.0 Manger.

To specify the SMTP settings in AX, go to Administration -> Setup -> E-mail parameters, specify the 'localhost' in Outgoing mail server and 25 in SMTP port number.
If you are using the method 2 above (SysEmailTable), after calling the sendMail(..) method, you can check the email sending status in Administration -> Periodic -> E-mail processing -> E-mail sending status. To activate the actual email sending process, go to Administration -> Periodic -> E-mail processing -> Batch.

Saturday, June 12, 2010

Keyboard shortcuts for date field

There are two keyboard shourtcut keys that you could use to enter today's date in Dynamics AX date field, namely the 'd' and 't' keys. The difference between these two keys is 't' is the machine date from Windows and 'd' is the session date which could be changed in Dynamics AX client Tools menu -> Session date. From the development perspective, 't' is the same as the today() method, and 'd' is same as the systemDateGet() method.