Send Email with invoice as attachment using Electronic Reporting – Microsoft Dynamics 365 for Finance and Operation

Scenario:

Send Email with invoice as attachment thru electronic reporting

Solution:

Follow the below steps:

  1. Go to Electronic reporting workspace
  2. Click on the Electronic reporting destination

Screen Shot 2020-04-15 at 12.37.06 pm.png

3. Add new record in file destination grid settings type Émail’

Screen Shot 2020-04-15 at 12.38.33 pm.png

4.  Do the settings on the destination screen as below

Screen Shot 2020-04-15 at 12.41.05 pm.png

 

5. On To Field click Edit , click  and select print Management Email

Screen Shot 2020-04-15 at 12.42.43 pm

6. For above settings of Email Source account , click on link button before delete button ,it will open the formula designer , you need to select the field AccountNum (customer account number)

It will select the customer email defined on the customer Master contact details as primary

Screen Shot 2020-04-15 at 12.46.24 pm.png

 

7. click Save and close the formula designer form

8. click on the next two forms and now you can test the email by running the invoice print using print management

 

 

Leave your comments below  if you are facing any issue.

 

To send SSRS report in Email as attachment, please check below link

 

Send email thru code with Report as attachment – Dynamics 365 Finance and Operations

Copy attachments between different forms with data – Dynamics 365 for Finance and Operations

Scenario:

Sometime a requirement come that we need to copy the attachment from one form to another with the flow of data.

For example when purchase order creates from sales order then the attachment also need to be flow from sales order to purchase order

Solution:

First thing first -> Identify the relation between new and existing form(tables).

Then use the below code to achieve this.

I used the onInserted event ,you can use the same or whatever suitable for your scenario. Important thing is record should be created in new table then you can copy the attachment.

/// <summary>

    ///

    /// </summary>

    /// <param name=”sender”></param>

    /// <param name=”e”></param>

    [DataEventHandler(tableStr(PurchTable), DataEventType::Inserted)]

    public static void PurchTable_onInserted(Common sender, DataEventArgs e)

    {

        PurchTable purchTable = sender;

        SalesTable salesTable = SalesTable::find(purchTable.InterCompanyOriginalSalesId);

        DocuRef docuRef = DocuRef::findTableIdRecId(salesTable.DataAreaId, salesTable.TableId, salesTable.RecId);

        if (docuRef)

        {

            docuRef.RefTableId = purchTable.TableId;

            docuRef.RefRecId = purchTable.RecId;

            docuRef.insert();

        }

    }

 

//Leave your comments below if you have any query. I will try to help you to solve your problem

Data Entity Create Virtual Field – Microsoft Dynamics 365 for Finance and Operations

Scenario:
Requirement is to have a custom field showing Customer Number and Name.
Solution:
In that case instead of creating regular field on the Data entity and we will create a virtual field and fill the data at runtime when records are importing
Below are the steps needs to perform:
1. Create extension of the base entity (Example SalesOrderHeaderEntity) or your custom entity
2. Open the entity in designer and expand the fields
3. Right click and add new field -> StringUnmappedField
4. Set the Name property  of new field, in our case I put ‘CustomerNumberAndName’
5. Set the IsComputedField Property to No.
6. Leave the DataEntityViewMethod Empty
7.Use the virtual field to receive the information from outside(odata or excel) and parse the information
8. Use chain of command or pre-post event handler if its base entity or customise the method ‘mapEntityToDataSource’
‘example of mapEntityToDataSpurce’
9.
public void mapEntityToDataSource(DataEntityRuntimeContext entityCtx, DataEntityDataSourceRuntimeContext dataSourceCtx)
{
    next mapEntityToDataSource(entityCtx,dataSourceCtx);
    //Check if desired data source context is available
   switch (_dataSourceCtx.name())
{
case dataEntityDataSourceStr(SalesOrderHeaderV2Entity, SalesTable):
{
SalesTable salesTable = _dataSourceCtx.getBuffer();
this.CustomerNumberAndName = salesTable.InvoiceAccount + ‘ – ‘ salesTable.customerName();
}
break;
}
}
10. You can get the value from odata also to use it for different purpose as per request

Business Event Create and Implement – Dynamics 365 For Finance and Operations – X++

Introduction:

Business event introduced in Microsoft Dynamics 365 for Finance and operations to trigger the business process based events and to talk to external systems and by default Microsoft provide some default business(example VendorInvoicePostedBusinessEvent to understand how it works.

Scenario:

Whenever sales invoice is posted then business event should be trigger only in case of specific item. To implement this below is the procedure.

Implementation steps:

3 steps for every business event

1. Build the contract
2. Build the event
3. Code to send the event

Two Classes involves:

Business Event -This class extends the BusinessEventBase , supports constructing the business event, building payload and sending business event

Example of BusinessEvent Class (SalesOrderCreation, update, Delete in that case the BusinessEvent class name should be like SalesOrderCRUDOperation) same goes for Purchase order etc

Business Event Contract – This class extends the BusinessEventsContract class. it defines the payload of business event and allows for population of contract at runtime.

 

 

Implementation :

Example is on Creation of Customer Invoice Transactions return specific item number,name, quantity and amount
Define the contract class
[DataContract]
public final class CustomerInvoiceTransactionItem90Contract extends BusinessEventsContract
{
    private ProdName productName;
    private ItemId itemId;
    private int quantity;
    private amount itemAmount;
    /// <summary>
    /// Initialise method
    /// </summary>
    /// <param name = “_invoiceTrans”> </param>
    private void initialize(CustInvoiceTrans _invoiceTrans)
    {
        CustInvoiceJour custInvoiceJour =                CustInvoiceJour::findFromCustInvoiceTrans(_invoiceTrans.SalesId,_invoiceTrans.InvoiceId,_invoiceTrans.InvoiceDate,_invoiceTrans.numberSequenceGroup);
SalesTable salesTable = SalesTable::find(_invoiceTrans.SalesId);
CustTable custTable = CustTable::find(salesTable.CustAccount);
        // get the variable values
        productName =    EcoResProduct::findByProductNumber(_invoiceTrans.ItemId).productName();
 itemId = _invoiceTrans.itemId;
 quantity = _invoiceTrans.quantity;
 itemAmount = _invoiceTrans.LineAmount;
}
    /// <summary>
    ///
    /// </summary>
    /// <param name = “_invoiceLine”></param>
    /// <returns></returns>
    public static CustomerInvoiceTransactionItem90Contract newFromInvoice(CustInvoiceTrans _invoiceLine)
    {
           CustomerInvoiceTransactionItem90Contract contract = new
                                                                              CustomerInvoiceTransactionItem90Contract();
           contract.initialize(_invoiceLine);
           return contract;
    }
    private void new()
    {
    }
    [DataMember(‘ProductName’), BusinessEventsDataMember(“Product Name”)]
    public ProdName parmProdName(str _productName = productName)
    {
        productName = _productName;
        return productName;
    }
    [DataMember(‘itemId’), BusinessEventsDataMember(“Item Number”)]
    public str parmSerialNumber(str _itemId = itemId)
    {
        itemId = _itemId;
        return itemId;
    }
    [DataMember(‘quantity’), BusinessEventsDataMember(“Quantity”)]
    public str parmLineId(str _quantity = quantity)
    {
        quantity = _quantity;
        return quantity;
    }
    [DataMember(‘itemAmount’), BusinessEventsDataMember(“itemAmount”)]
    public str parmfoPartyType(str _itemAmount = itemAmount)
    {
        itemAmount = _itemAmount;
        return itemAmount;
    }
}
Define the Business Event Class
 [BusinessEvents(classStr(CustomerInvoiceTransactionItem90Contract),
    “Customer Invoice Transaction”,
    “This business event is triggered when an invoice is created.”,
    ModuleAxapta::SalesOrder)]
     public class CustInvoiceTransCreatedBusinessEvent extends BusinessEventsBase
 {
     CustInvoiceTrans custInvoiceTrans;
      private custInvoiceTrans parmInvoiceTrans(CustInvoiceTrans _custInvoiceTrans =              custInvoiceTrans)
     {
         custInvoiceTrans = _custInvoiceTrans;
         return custInvoiceTrans;
     }
     private void new()
     {
     }
     [Wrappable(true), Replaceable(true)]
     public BusinessEventsContract buildContract()
     {
         return      CustomerInvoiceTransactionItem90Contract::newFromInvoice(custInvoiceTrans);
     }
    static public CustInvoiceTransCreatedBusinessEvent    newFromInvoice(CustInvoiceTrans _custInvoiceTrans)
     {
         CustInvoiceTransCreatedBusinessEvent event = new       CustInvoiceTransCreatedBusinessEvent();
        event.parmInvoiceTrans(_custInvoiceTrans);
         return event;
     }
}
Code to invoke the event : below is the code that invoke the business event classes that we define above
 [DataEventHandler(tableStr(CustInvoiceTrans), DataEventType::Inserted)]
    public static void CustInvoiceTrans_onInserted(Common sender, DataEventArgs e)
    {
        CustInvoiceTrans invoiceTrans = sender as CustInvoiceTrans;
        boolean isEvent = BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(CustInvoiceTransCreatedBusinessEvent));
        if (isEvent)
        {
            if(invoiceTrans.itemid==’item90′)
            {
                CustInvoiceTransCreatedBusinessEvent::newFromInvoice(sender).send();
            }
        }
    }
  • After finishing the above code and rebuilding the project then you have to go business event catalogue in the system administration
  • You will find your newly created business event in the list
  • Then from your end point application register the business event , once successfully registered than you will find the end point in your business event catalog Endpoint tab
  • Activate the business event , you are ready to use the newly created business event.

 

Note: Business event can be activated only in 1 legal entity  or all , if you don’t selected any legal entity during activation then it will be activated for all else only for selected legal entity

General Electronic Reporting (GER) or Electronic Reporting (ER) in Dynamics 365 for Finance – Part 1

It is a configureable tool  for regulatory reporting, payments and electronic reporting.

The ER engine is targeted on the business users instead of developers. Because you configure formats instead of code.

ER supports :

  • TEXT
  • XML
  • PDF
  • Microsoft word document
  • Open XML Worksheets

 

The ER tool allows you to configure formats for electronic documents in accordance with the legal requirements of various countries or regions. ER lets you manage these formats during their life cycle.

 

ER engine capabilities:

  • single shared tool for electronic reporting in different domains, and replace more than 20 engines that do some electronic reporting for Finance.
  • Its reports formats is applicable to different versions of Finance means report dependancy not on the version of the finance.
  • Custom formats can be created based on original formats. Easily can change the format based on the requirement due its support for localisation.
  • It becomes the primary standard tool of electronic reporting for both Microsoft and Microsoft Partners.

 

 

 

Mark record in the grid get on the form data source – AX2012 R3 – Dynamics 365 for Finance and Operations

Scenario: You have 10 records in the grid and want to select(mark) on 5 and perform operations.  Then use below code to select mark records

Solution 1:

 

Hcmworker hcmWorker; // table

hcmWorker = this.getfirst(1);// 1 is reflecting the mark records

while (hcmworker)

{

//write custom code to perform operations

 

hcmworker = this.getNext()

}

 

Solution 2:

 

Hcmworker hcmWorker; // table

for(hcmWorker=hcmWorker_ds.getFirst(1);hcmworker;hcmworker=hcmworker_ds.getNext())

{

}

 

Batch job could not be found. Dynamics 365 for Finance and Operations, Ax2012 R3

Scenario/Problem:

Sometimes users facing an issue in the batch jobs when they delete the batch job in executing state from the back end or for any other reason(like batch job stuck in executing stage). Then they need to perform below steps to resolve the issue.

In my  case i was facing issue in the workflow batch job and my workflow are not working even after restarting the server or service.

Solution:

 

Perform select query on the below tables with caption filter by typing the keyword of the job you are looking for.

Batch and Batchjobs

Deleted batchjob has been deleted from Batchjob table but not from Batch table. So, I performed below query and my issue has been resolved.

 

First select query on both tables and then delete query to delete the records.

 

Screen Shot 2019-12-15 at 10.12.09 AM

The natural key for the table was not found. Microsoft Dynamics 365 for Finance and Operations – Microsoft Visual Studio

Scenario: Sometimes users facing the error ‘The natural key for the table was not found‘.

 

Screen Shot 2019-12-06 at 4.16.23 PM.png

 

Solution:

Open the table on which you are facing error. Then add the primary index like below

 

Screen Shot 2019-12-06 at 4.19.25 PM.png

 

After adding index synchronize the table and then try to create Data entity again.

Warning: Package folder already exists in deployment pipeline azure devops – Dynamics 365 For Finance and Operations

Issue:

When package creation is in routine work or often then users will receive below warning.

“Package folder already exists in deployment pipeline azure devops””

Resolution:

This is just a warning so users can ignore this message and check the other errors in the log file.

A financial dimension value is based on the ” record and has been used on a transaction. You cannot delete the ” record – Dynamics 365 for finance and operations – AX2012 R3

Scenario:

Sometime user trying to delete a record from the customer master or any data that relates to financial dimension. So, user is facing above error upon deletion.

Reason:

Error occurred because data exists in the table DimensionAttributeLevelValue

Solution:

  1. Access the open the table DimensionAttributeLevelValue 
  2. filter the record by Display Value field with the desired record to delete like customer number or employee number etc etc
  3. Select the filtered records
  4. Delete the selected records
  5. Then go back to customer master or where you facing the error
  6. Now try to delete you will be able to delete

 

AX 2012: you can directly delete the record by opening table

D365 : you can delete by access the SQL or write the runnable class to delete