Copy attachments from sales order to production order while firming planned production order in D365FO

 In D36FO, it is common requirement to copy documents from one table to another table.

Here is an example to copy documents of type "Note" from Sales order to production order during firming and Also update/delete the records in planned order if the document attachment is updated/deleted in sales order.

code snippets:

/// <summary>
/// Extension methods for the <C>ReqTransPOMarkFirm</C> class.
/// </summary>
[ExtensionOf(classStr(ReqTransPOMarkFirm))]
internal final class ANI_ReqTransPoMarkFirm_Extension
{
    protected ProdTable createProdTable(
        ReqTrans    _reqTrans,
        ReqPO       _reqPO,
        ProdBOM     _prodBOMParent)
    {
        ProdTable prodTable = next createProdTable(_reqTrans,_reqPO,_prodBOMParent);
        if (prodTable && prodTable.InventRefType == InventRefType::Sales)
        {
             this.copyDocumentAttachmentFromSO(prodTable);
        }
        return prodTable;
    }
    /// <summary>
    /// Copy "Notes" from SO to production order.
    /// </summary>
    /// <param name = "_prodTable">The <c>ProdTable</c> buffer.</param>
    public void copyDocumentAttachmentFromSO(ProdTable _prodTable)
    {
        DocuRef     docuRef;
        DocuType    docuType;
        SalesTable salesTable = SalesTable::find(_prodTable.InventRefId);
        if (salesTable)
        {
            while select docuRef
                where docuRef.RefRecId == salesTable.RecId
                && docuRef.RefTableId == salesTable.TableId
                && docuRef.RefCompanyId == salesTable.dataAreaId
            join docuType
                where docuType.DataAreaId == docuRef.ActualCompanyId
                && docuType.TypeId == docuRef.TypeId
                  && docuType.TypeGroup == DocuTypeGroup::Note
            {
                DocuRef newDocuRef = DocuRef::createFromDocuRef(docuRef,_prodTable.RecId,tableNum(ProdTable));
                ANI_DocuRefExtensionEventHandler::updateRecIDReference(newDocuRef,docuRef.RecId);
            }
        }
    }
}


internal final class ANI_DocuRefExtensionEventHandler
{
    /// <summary>
    /// Copy "Notes" from sales order to related production orders.
    /// </summary>
    /// <param name="_docuRef">A <c>DocuRef</c> table record.</param>
    /// <param name="_interCompanyFromRecId">An intercompany record identifier.</param>
    [Hookable(false), SubscribesTo(classstr(DocuRefExtension), delegatestr(DocuRefExtension, OnPostInsert))]
    public static void DocuRef_OnInsert(DocuRef _docuRef, RefRecId _interCompanyFromRecId)
    {
        ProdTable   prodTable;
        DocuType    docuType = DocuType::find(_docuRef.TypeId);

        if(_docuRef.RefTableId == tablenum(SalesTable) 
            && _docuRef.RecId 
           && docuType.TypeGroup == DocuTypeGroup::Note)
        {
            SalesTable salesTable = SalesTable::findRecId(_docuRef.RefRecId);

            while select RecId,InventRefType,InventRefId from prodTable
                where prodTable.InventRefType == InventRefType::Sales
                    && prodTable.InventRefId == salesTable.SalesId
            {
                DocuRef newDocuRef = DocuRef::createFromDocuRef(_docuRef,prodTable.RecId,tableNum(ProdTable));
                ANI_DocuRefExtensionEventHandler::updateRecIDReference(newDocuRef,_docuRef.RecId);
            }
        }
    }

    /// <summary>
    /// Update "Notes" from sales order to related production orders.
    /// </summary>
    /// <param name="_docuRef">A <c>DocuRef</c> table record.</param>
    /// <param name="_interCompanyFromRecId">An intercompany record identifier.</param>
    [Hookable(false), SubscribesTo(classstr(DocuRefExtension), delegatestr(DocuRefExtension, OnPostUpdate))]
    public static void DocuRef_OnUpdate(DocuRef _docuRef, RefRecId _interCompanyFromRecId)
    {
        ProdTable   prodTable;
        DocuRef     newDocuRef;
        DocuType    docuType = DocuType::find(_docuRef.TypeId);

        if(_docuRef.RefTableId == tablenum(SalesTable)
            && docuType.TypeGroup == DocuTypeGroup::Note)
        {
            SalesTable salesTable = SalesTable::findRecId(_docuRef.RefRecId);

            while select forupdate newDocuRef
                where newDocuRef.ANI_DocuRefRecIdReference == _docuRef.RecId
            {
                ttsbegin;
                newDocuRef.Notes        = _docuRef.Notes;
                newDocuRef.Name         = _docuRef.Name;
                newDocuRef.Restriction  = _docuRef.Restriction;
                newDocuRef.update();
                ttscommit;
            }

        }
    }

    /// <summary>
    /// Delete "Notes" from production orders if it is deleted in sales order.
    /// </summary>
    /// <param name="_docuRef">A <c>DocuRef</c> table record.</param>
    /// <param name="_interCompanyFromRecId">An intercompany record identifier.</param>
    [SubscribesTo(classStr(DocuRefExtension), delegateStr(DocuRefExtension, OnPostDelete))]
    public static void DocuRefExtension_OnDelete(DocuRef _docuRef, RecId _interCompanyFromRecId)
    {
        DocuRef deleteDocuRef;
        DocuType docuType = DocuType::find(_docuRef.TypeId);

        if(_docuRef.RefTableId == tablenum(SalesTable)
            && docuType.TypeGroup == DocuTypeGroup::Note)
        {
            ttsbegin;
            delete_from deleteDocuRef where deleteDocuRef.AN_DocuRefRecIdReference == _docuRef.RecId;
            ttscommit;
        }
    }

    /// <summary>
    /// Update ANI_DocuRefRecIdReference field of <c>DocuRef</c> table with Recid.
    /// </summary>
    /// <param name = "_docuRef">A <c>DocuRef</c> table record</param>
    /// <param name = "_recidRef">The RecID to update.</param>
    public static void updateRecIDReference(DocuRef _docuRef,RefRecId _recidRef)
    {
        ProdTable prodTable = ProdTable::findRecId(_docuRef.RefRecId);

        if (_docuRef && prodTable)
        {
            ttsbegin;
            _docuRef.selectForUpdate(true);
            _docuRef.ANI_DocuRefRecIdReference = _recidRef;
            _docuRef.doUpdate();
            ttscommit;
        }
    }

}

Popular posts from this blog

Send Purchase Orders to Vendor collaboration for Vendor Review in D365FO

Remove Prefix from a String in D365FO

Odata Patch operation using Postman