Auto assembly / disassembly kit order based on the sales order

Automatically assembly / disassembly kit order based on the sales order state.
The kit should have only one configuration.

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





 

Search

About

DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics AX.

Authors are allowed to set their own AdSense units and "buy me a coffee" link.
Join us.

Blog Tags