/// <summary>
/// Manages Kit orders in correspondance with Sales Order lines informaiton
/// </summary>
final class VKKitOrderManager
{
SalesId salesId;
/// <summary>
/// Constructor
/// </summary>
/// <param name = "_salesId">Sales id</param>
/// <returns>Instance of the calss</returns>
static VKKitOrderManager construct(SalesId _salesId)
{
return new VKKitOrderManager(_salesId);
}
protected void new(SalesId _salesId)
{
salesId = _salesId;
}
/// <summary>
/// Process Sales Order, will check sales order information and create relavant kit orders
/// </summary>
void process()
{
SalesLine salesLine;
SalesLine salesLineUpd;
SalesTable salesTable = SalesTable::find(salesId);
InventTable inventTable;
RetailKit retailKit;
Qty qtyDiff, salesQty;
if (!salesTable.VKAutoCreateAdvancedPacks)
{
return;
}
ttsbegin;
while select salesLine
where salesLine.SalesId == salesId
join inventTable
where inventTable.ItemId == salesLine.ItemId
join retailKit
where retailKit.ProductMaster == inventTable.Product
{
salesQty = salesLine.SalesQty;
if (salesLine.RemainSalesPhysical < salesQty)
{
salesQty = salesLine.RemainSalesPhysical;
}
if (salesLine.SalesStatus == SalesStatus::Canceled)
{
salesQty = 0;
}
qtyDiff = salesQty - salesLine.VKAdvancedPackCreated;
if (qtyDiff)
{
setPrefix(strFmt("Processing item %1", salesLine.ItemId));
this.createRetailKitOrder(
(qtyDiff > 0) ? RetailKitOrderType::AssemblyOrder : RetailKitOrderType::DisassemblyOrder,
qtyDiff,
salesLine,
inventTable.Product,
retailKit.RecId
);
update_recordset salesLineUpd
setting
VKAdvancedPackCreated = salesLine.VKAdvancedPackCreated + qtyDiff
where salesLineUpd.RecId == salesLine.RecId;
}
}
ttscommit;
}
/// <summary>
/// Processes sales line deletion and might create kit order disassembly for relevan line
/// </summary>
/// <param name = "_salesLine">Sales line</param>
void processDeleteSalesLine(SalesLine _salesLine)
{
SalesTable salesTable = SalesTable::find(salesId);
InventTable inventTable;
RetailKit retailKit;
Qty qtyDiff, salesQty;
if (!salesTable.VKAutoCreateAdvancedPacks)
{
return;
}
select firstonly inventTable
where inventTable.ItemId == _salesLine.ItemId
join retailKit
where retailKit.ProductMaster == inventTable.Product;
if (retailKit)
{
salesQty = _salesLine.SalesQty;
if (_salesLine.RemainSalesPhysical < salesQty)
{
salesQty = _salesLine.RemainSalesPhysical;
}
if (_salesLine.SalesStatus == SalesStatus::Canceled)
{
salesQty = 0;
}
qtyDiff = salesQty - _salesLine.VKAdvancedPackCreated;
if (qtyDiff)
{
setPrefix(strFmt("Processing item %1", _salesLine.ItemId));
this.createRetailKitOrder(
(qtyDiff > 0) ? RetailKitOrderType::AssemblyOrder : RetailKitOrderType::DisassemblyOrder,
qtyDiff,
_salesLine,
inventTable.Product,
retailKit.RecId
);
}
}
}
/// <summary>
/// Entry point for sales line deletion
/// </summary>
/// <param name = "_salesLine">Sales line</param>
static void deleteSalesLine(SalesLine _salesLine)
{
VKKitOrderManager kitOrderManager = VKKitOrderManager::construct(_salesLine.SalesId);
kitOrderManager.processDeleteSalesLine(_salesLine);
}
/// <summary>
/// Creates retail kit order
/// </summary>
/// <param name = "_orderType">Order type</param>
/// <param name = "_qty">Qty</param>
/// <param name = "_salesLine">sales line</param>
/// <param name = "_productMaster">product master</param>
/// <param name = "_kit">kit</param>
/// <returns>Kit order record</returns>
RetailKitOrder createRetailKitOrder(RetailKitOrderType _orderType, Qty _qty, SalesLine _salesLine, EcoResProductRecId _productMaster, RecId _kit)
{
RetailKitOrder retailKitOrder;
EcoResDistinctProductVariant currentEcoResDistinctProductVariant;
// only one configuration will be created. Needs to be adjusted for all other cases
select firstonly RecId, SearchName from currentEcoResDistinctProductVariant
where currentEcoResDistinctProductVariant.ProductMaster == _productMaster;
retailKitOrder.clear();
retailKitOrder.initValue();
retailKitOrder.Name = NumberSeq::newGetNum(RetailParameters::numRefAssemblyOrderName(), true).num();
retailKitOrder.OrderType = _orderType;
retailKitOrder.Quantity = abs(_qty);
retailKitOrder.InventDataAreaId = _salesLine.DataAreaId;
retailKitOrder.InventLocation = _salesLine.inventDim().InventLocationId;
retailKitOrder.Comments = _salesLine.SalesId;
retailKitOrder.Kit = _kit;
if (retailKitOrder.validateWrite())
{
retailKitOrder.insert();
}
info(strFmt("Kit order %1 has been created", retailKitOrder.Name));
RetailKitAssemblyOrder::processOrder(retailKitOrder, currentEcoResDistinctProductVariant.RecId, retailKitOrder.Quantity);
RetailKitAssemblyOrder::post(retailKitOrder);
RetailKitOrderStatus kitOrderStatus;
select firstonly Posted from kitOrderStatus where kitOrderStatus.RetailKitOrder == retailKitOrder.RecId;
// Verify posting for RetailKitOrder
if (!kitOrderStatus.Posted)
{
throw Error("Kit order not posted");
}
return retailKitOrder;
}
}
Handlers:/// <summary>
/// Class extension for SalesFormLetter_Confirm
/// </summary>
[ExtensionOf(classStr(SalesFormLetter_Confirm))]
final class VKSalesFormLetter_Confirm_Extension
{
/// <summary>
/// CoC for run method
/// </summary>
public void run()
{
ttsbegin;
next run();
SalesTable salesTable = salesFormLetterContract.parmSalesTable();
VKKitOrderManager kitOrderManager = VKKitOrderManager::construct(salesTable.SalesId);
kitOrderManager.process();
ttscommit;
}
}
/// <summary>
/// An extension class for SalesLine table
/// </summary>
[ExtensionOf(tableStr(SalesLine))]
final class VKSalesLine_Extension
{
public void delete(Common _childBuffer, boolean _updateOrderLineOfDeliverySchedule)
{
VKKitOrderManager::deleteSalesLine(this);
next delete(_childBuffer, _updateOrderLineOfDeliverySchedule);
}
}
/// <summary>
/// Class extension for SalesUpdateRemain class
/// </summary>
[ExtensionOf(classstr(SalesUpdateRemain))]
final class VKSalesUpdateRemain_Extension
{
/// <summary>
/// CoC for updateDeliverRemainder method
/// </summary>
/// <param name = "_salesLine">SalesLine buffer</param>
/// <param name = "_remainSalesPhysical">remainSalesPhysical</param>
/// <param name = "_remainInventPhysical">remainInventPhysical</param>
/// <param name = "_cWRemainInventPhysical">cWRemainInventPhysical</param>
/// <returns>true if everything is correct</returns>
public boolean updateDeliverRemainder(
SalesLine _salesLine,
InventQty _remainSalesPhysical,
InventQty _remainInventPhysical,
PdsCWInventQty _cWRemainInventPhysical)
{
ttsbegin;
ret = next updateDeliverRemainder(_salesLine, _remainSalesPhysical, _remainInventPhysical, _cWRemainInventPhysical);
VKKitOrderManager kitOrderManager = VKKitOrderManager::construct(_salesLine.SalesId);
kitOrderManager.process();
ttscommit;
return ret;
}
}
If you found value in what I share, I've set up a Buy Me a Coffee page as a way to show your support.
Buy Me a CoffeeNo comments. Be the first one to comment on this post.
DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics 365 FO.
Authors are allowed to set their own "buy me a coffee" link.
Join us.