Wednesday, 26 June 2019

How to customize customer/Sales order invoice email body and subject in Dynamics 365 F&O X++

In this post I'm going to show you how to send customer invoices with custom email subject and body .

For that I created below class to extend  SrsReportRunPrinter. I'm adding invoice ID in the subject and using HTML for body. Change the code according to your requirement.

[ExtensionOf(classStr(SrsReportRunPrinter))]
final class Class_SrsReportRunMailer_Extension
{
public void printReport()
    {
        SrsReportDataContract contract = reportContract;

        if(contract && SRSPrintMediumType::Email && contract.parmRdpContract() as salesInvoiceContract)
        {
            salesInvoiceContract salesInvoiceContract;
            CustInvoiceJour custInvoiceJour;
            ;

            salesInvoiceContract  = contract.parmRdpContract();
         
            str InvoiceId = CustInvoiceJour::findRecId(salesInvoiceContract.parmRecordId()).InvoiceId;
         
            SRSPrintDestinationSettings     printSettings = contract.parmPrintSettings();

            SrsReportEMailDataContract emailContract = printSettings.parmEMailContract();
         
            printSettings.fileName("Invoice #"+InvoiceId);
         
            str parmSubject = emailContract.parmSubject();

            emailContract.parmSubject(parmSubject +"  " +"#"+InvoiceId);

            str body;

            body = "<html><body>"+ strfmt("Dear Customer,")+ "<br/><br>"+
                strfmt("Please find your invoice attached.") + "<br/><br>"+
                strfmt("Regards,")+ "<br/>"+
                strfmt("Test Team")+ "<br/><br>";
         
            emailContract.parmBody(body);

            //contract.parmPrintSettings().emailSubject(body);
        }
     
        next printReport();

    }

}

That's it. You can contact me for any additional questions.

@Rahul

Thursday, 13 June 2019

Method Sequences when a Form is opened and Closed

An event method sequence is executed when a form is opened. The specific sequence depends on the set of controls and data sources that are associated with the form.

Open a Form

In this example, the user opens a form that contains a grid control, which is bound to a data source.
The executed events are distributed across two threads. The timing of event method execution between threads can vary.
The following table shows the sequence that event methods are executed in when a user opens a form.
Method
Where
Thread number
new
Form
init
Form
1
loadUserSetting
Form
2
run
Form
1
init
Data source
2
executeQuery
Data source
2
leaveRecord
Data source
2
leave
Data source
2
leaveRecord
Data source
2
firstField
Form
2
firstField
Form
1

Most forms in Microsoft Dynamics AX are closed when a user clicks the Close button (the standard button in the upper-right corner of most windows). Some forms can be closed by clicking either an OK or a Cancel button. When the form is closed, event methods are executed.

Close the Form by Using the Cancel Button

When a user closes a form by clicking the Cancel button, event methods are executed in the following sequence:
  1. closeCancel on the form.
  2. canClose on the form.
  3. close on the form.
 Note
The FormRun class has the closed method and the closedCancel method. These event methods are not executed when the Cancel button is clicked.
When a form is closed with the closeCancel event method, the user's changes are not saved.

Scenario

This scenario uses a form that contains one CheckBox control as its only control. Assume that the CheckBox control is bound to a form's data source and that the control can update the data source.

Aa602745.collapse_all(en-us,AX.60).gifClose the Form by Using the Close Button

When a user closes a form by clicking the Close button, event methods are executed in the sequence shown in the following lists. These lists are based on the previous scenario.
Following is the sequence of event methods when the form is closed—without the user clicking the check box.
  1. canClose on the form.
  2. leave on the check box.
  3. leave on the check box.
  4. leave on the data source.
  5. leaveValidate on the data source.
  6. leave on the check box.
  7. leave on the check box.
  8. close on the form.
  9. saveUserSetting on the form.
Following is the sequence of event methods when the form is closed—after the user has clicked a check box.
  1. canClose on the form.
  2. leave on the check box.
  3. leave on the check box.
  4. validateWrite on the data source.
  5. Write on the data source.
  6. update on the table.
  7. leaveRecord on the data source.
  8. leave on the data source.
  9. leaveRecord on the data source.
  10. leave on the check box.
  11. leave on the check box.
  12. close on the form.
  13. saveUserSetting on the form.

Aa602745.collapse_all(en-us,AX.60).gifClose the Form by Using the OK Button

Some forms can be closed by clicking an OK button. This leads to almost the same event method sequence as shown in the Close the Form by Using the Close Button section. The only difference is that clicking the OK button causes the Form.closeOK event method to be executed first.





1


Wednesday, 5 June 2019

Data management error descriptions D365 Finance & Operations

This topic documents the scenarios when a specific error will be seen. This is not a complete list of errors and scenarios, however this list will be continuously updated so keep checking back for updates. Any feedback on this page with regards to specific errors that should be covered are welcome. We will strive to prioritize your feedback requests so that this topic stays up to date.
This topic describes the error messages that you might encounter in data management.

Import to target failed due to an update conflict as more than one process is trying to update the same record at the same time

When you use recurring imports (enqueue API), if the files are sent to the end point at high frequency and the sequential processing of messages isn't enabled, data management will try to process the files in parallel. When files are processed in parallel, and multiple files have the same record, multiple threads will try to update the same record at the same time. If this is a data issue, you must update the data so that the same records don’t repeat across files. If this is not a data issue and the entity is expected to handle such cases, this might be a bug. For bugs, to mitigate the issue, you can choose to sequentially process the files. If this is not a data issue and the entity is not expected to process in parallel, then this entity must not be subjected to parallel processing. You should enable sequential processing of messages in the recurring job.

There are field(s) which are not mapped to Entity <EntityName>

It is a common practice to use the export functionality to generate the entity template file which can be later used for imports. However, while exporting the template, in fixed width format with 'First row header' set to 'No' (in source data formats set up), the exported template will not have the column names. When this file is imported, it will result in this error.

Data package download - Error downloading data package for job ''. Record for ID - {GUID} not found

One of the scenarios where this can happen is when the environment, such as the dev environment, points to the database in another environment, such as UAT, and the export job is run from the source environment. which is dev in this example. The exported file gets uploaded to the blob storage that is associated with the source environment (dev, in this example). However, this job will also show up in the target environment (UAT) since the database is shared. If a you try to download the exported file using the Download file option, this error will display because the file does not exist in the blob storage of the target environment (UAT) from where you are trying to download.

XML is not in correct format-Exception from HRESULT: 0xC0010009

This is a generic message that covers all XML formatting issues in the file. For example, the data project has mappings for columns that do not exist in the file that is being used for the operation. This can happen if certain columns were removed from the file and this file is now used. Either fix the mapping in the data project or fix the file to have all the columns as expected.

Tuesday, 4 June 2019

How to extend or overwrite a class method in D365 Finance and Operations X++?

In this example I will be showing how to extend or overwrite a class method.
In D365 7.1 and later versions Microsoft is not allowing to overwrite the standard objects. To overcome this, we need to use extensions.


Below example I'm overwriting/extending main method of SalesFormLetter class to add my custom logic to pop a dialog box while posting a picking slip.

Here, I'm executing my custom logic first.Then, executing standard logic.



[ExtensionOf(classStr(SalesFormLetter))]
final class TestClass_SalesFormLetter_Extension
{
    /// <summary>
    ///Rahul - on 06/04/2019
    /// Project @ TestClassForExtensions
    /// To display a dialogbox popup
    /// </summary>
    /// <param name = "args"></param>
    public static void main(Args  args)
    {
        RefRecId             record         = args.record().RecId;
        DocumentStatus     parmEnum       = args.parmEnum();
        Object             callerForm     = args.caller();
        MenuItemNameAction callerMenuItem = args.menuItemName();
        SalesTable         salesTable     = SalesTable::findRecId(record);
        DialogButton            diagBut;

        if(callerMenuItem == 'SalesFormLetter_PickingList_Action' || callerMenuItem == 'SalesFormLetter_PickingList')
        {
            if(SalesTable.SalesOriginId == 'CUSTOM' && SalesTable.PaymMode == 'Card' )
            {
                diagBut = Box::yesNo('Do you want to continue without charging this order', DialogButton::No, 'Title');
                if(diagBut == DialogButton::No)
                {
                    return;
                }
            }
        }

        next main(args);
    }

}


In the same way you can extend other methods as well.

How to extend or overwrite dataentity methods in D365 Finance and Operations X++?

In this example I will be showing how to extend or overwrite dataentity methods.

In D365 7.1 and later versions Microsoft is not allowing to overwrite the standard objects. To overcome this, we need to use extensions.

We follow the same concept for extending tables, forms and classes methods.


Below example I'm overwriting/extending postload method in SalesOrderHeaderV2Entity entity.

Here I'm assigning sales order createddatetime value to some custom field.


[ExtensionOf(tableStr(SalesOrderHeaderV2Entity))]
final class SWClass_SalesOrderHeaderV2Entity_Extension
{
   

    public void postload()
    {
        next postload();
       
        SalesOrderHeaderV2Entity SalesOrderHeaderV2Entity = this;
       

        SalesTable                  salesTable = SalesTable::find(SalesOrderHeaderV2Entity.SalesOrderNumber);

       
        SalesOrderHeaderV2Entity.customdate += date2Str(salesTable.createddateandtime, 213,
                                                                DateMonth::Digits2,
                                                                DateSeparator::Slash,
                                                                DateDay::Digits2,
                                                                DateSeparator::Slash,
                DateYear::Digits4);
        }
               
    }

}


In the same way you can extend other methods as well.

@Rahul 

Adding a newline into a string in C# and X++

Below is the sample code we can use for  adding a newline after every occurrence of "@" symbol in the string in C#   using System...