Tuesday, January 18, 2022

Capturing the event handler for validation before posting vendor payment journal: D365 classes

 This is my first blog post in 2022, I would like to share with you related to validation and payment control for payment journals and would share with you peace of code to capture the event handler for validating the payment journals - Just to give you a bit of overview of payment journal. Payment journal consists of method of payment where you can control payments and its basic validations. For instance given below we have method of payment set as "Check".

Going into the detail of this method of payment we can see we can also set the payment control, where few of the basic validations can be configured. for instance if check number is mandatory before posting the payment journal or not.


Also one thing to be noted that in order to add any "check number" to payment journal, check number setup is required and it is mandatory to generate the payments before it is posted. And "Generate payment" button  is disabled if any associated workflow is initiated and payment journal is not approved yet. Once it is approved, you can generate payments.  also you can refer this blog for configuring the workflow for payment journals.


Now let's come to little code to capture the event handler before posting the payment journals. Here you go.


I hope this blog will help you understand, how do we control payments and validations for payment journal. Would like to know about your feedback further.


Thursday, January 16, 2020

Catch weight item in D365

Introduction

You could have a scenario particularly in manufacturing industry where a finished good or a product can vary in size, weight or both. In this case, you would have two units of measures for these sort of products (i.e. Catch weight unit and Inventory Unit.). Catch weight unit is the unit in which inventory transactions are performed, for example sold, received, transferred, picked, and shipped etc. The inventory unit is the unit of measure when the product is weighed and invoiced. .  The nominal quantity is the conversion between the catch weight unit and the inventory unit. These items are called catch weight items

Table Schema 

There are many important tables used in product information and management module. Few of the important tables and classes are listed in this blog .
Except all these important tables such as EcoResProduct, InventTable we do have a separate table for catch weights items that is PDSCatchWeightItem.

How do we identify the Released Item marked as catch weight item?

You can search a release item that is also a catch weight item adding a new field named, “CW product” and filter the grid with marked checked.


Or using the database you can use the SQL query
SELECT PDSCATCHWEIGHTITEM.* FROM PDSCATCHWEIGHTITEM
JOIN INVENTTABLE
ON INVENTTABLE.ITEMID = PDSCATCHWEIGHTITEM.ITEMID
AND PDSCATCHWEIGHTITEM.DATAAREAID = 'usmf'

How to create a catch weight item in D365?

Since the catch weight item was introduced in AX in version 2012 and all the steps that are almost same as mentioned in the blog - Creating a Product using the Catch Weight functionality in Microsoft Dynamics AX 2012. Also one thing you have to make sure transfer the appropriate inventory quantity to newly created catch weight item and also make sure to assign the important accounts to item group of the item. Otherwise it will block you using that item in sales and purchase orders. I hope this blog post will give you a brief view of catch weight item, let me know your feedback and queries via comments.



References:

Catch weight functionality a critical requirement for food manufacturing.

Friday, January 10, 2020

How to send that attachments as an email in D365

Normally in D365, there is a common table where your attachments are saved that is DocuRef, and it also stores the reference of table in field "RefTableId" field. Suppose we want to retrieve all the attachments specific to a table. We can simple achieve this using the RefTableId. Next important this is using the buffer of DocuRef table, we have multiple available options using this buffer. for example we can simple retrieve the container using the function as below:

 container _data = DocumentManagement::getAttachmentAsContainer(docRef)"

This container can further be passed on to method as provided below

public static void sendPDFEamilAttachment( SysEmailId      _emailId,
        LanguageId      _language,
        SysEmailAddress             _emailAddr,
        Map             _mappings,container _data,str _fileName)
    {
        SysEmailItemId                   nextEmailItemId;
        SysEmailTable                    sysEmailTable;
        SysEmailMessageTable             sysEmailMessageTable;
        SysEmailContents                 sysEmailContents;
        SysOutgoingEmailTable            outgoingEmailTable;
        SysOutgoingEmailData             outgoingEmailData;
        Filename filename, FileExtension;
      
        FileExtension=".pdf";
       
        select sysEmailTable
               join    sysEmailMessageTable
                where sysEmailMessageTable.EmailId==sysEmailTable.EmailId
                    && sysEmailMessageTable.EmailId== _emailId
                    && sysEmailMessageTable.LanguageId==_language;
       
        if(sysEmailTable.RecId>0)
        {
            sysEmailContents=SysEmailMessage::stringExpand(sysEmailMessageTable.Mail, _mappings);
            nextEmailItemId = EventInbox::nextEventId();
      
            filename =strFmt("%1_%2.pdf",nextEmailItemId,_fileName);
    
    
            outgoingEmailTable.clear();
            outgoingEmailTable.Origin=sysEmailTable.Description;
            outgoingEmailTable.EmailItemId = nextEmailItemId;
            outgoingEmailTable.IsSystemEmail = NoYes::Yes;
            outgoingEmailTable.Sender = sysEmailTable.SenderAddr;
            outgoingEmailTable.SenderName = sysEmailTable.SenderName;
            outgoingEmailTable.Recipient = _emailAddr;
            outgoingEmailTable.Subject =SysEmailMessage::stringExpand(sysEmailMessageTable.Subject, _mappings);
            outgoingEmailTable.Priority = eMailPriority::High;
            outgoingEmailTable.WithRetries = NoYes::NO;
            outgoingEmailTable.RetryNum = 0;
            outgoingEmailTable.UserId = curUserId();
            outgoingEmailTable.Status = SysEmailStatus::Unsent;
            outgoingEmailTable.Message =  sysEmailContents;
            outgoingEmailTable.LatestStatusChangeDateTime =DateTimeUtil::getSystemDateTime();
            outgoingEmailTable.TemplateId= _emailId;
            outgoingEmailTable.insert();


            if(conLen(_data)>0)
            {
                outgoingEmailData.clear();

                outgoingEmailData.EmailItemId = nextEmailItemId;
                outgoingEmailData.DataId = 1;
                outgoingEmailData.EmailDataType = SysEmailDataType::Attachment;
                outgoingEmailData.Data = _data;
                outgoingEmailData.FileName = filename;
                outgoingEmailData.FileExtension =FileExtension;

                outgoingEmailData.insert();
            }
        }
    }

}