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);
}
}
}
}
/// 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;
}
}
}