пятница, 6 июня 2014 г.

Useful. Copy purchLines from one purch order to another

Copy purchLines from one purch order to another in Dynamics AX 2009, 2012.

Last time I get many question from new developer How to use ... I want to print simple but useful jobs to help newbie "Do their Things Faster With More Energy".

Standard functionality allow copy purch (sales) lines from one order to another using form \Forms\PurchCopying. If we try to see algorithm we can see construction like below.

AX2009

static void Job63(Args _args)
{
    PurchCopying            purchCopying = PurchCopying::construct(SalesPurchCopy::CopyAllLines);
    TmpFrmVirtual           tmpFrmVirtualLines;
    TmpFrmVirtual           tmpFrmVirtualHeader;
    PurchTable              purchTableFrom  = PurchTable::find('PO-0000597');
    PurchLine               purchLineFrom;
    PurchTable              purchTableTo    = PurchTable::find('PO-0000602');

    void writeTmpFrmVirtual(TmpFrmVirtual   _tmpFrmVirtual,
                            tableId         _tableId,
                            recId           _recId,
                            Num             _id,
                            LineNum         _lineNum = 0,
                            TransDate       _transDate = systemdateget(),
                            Qty             _qty = 0)

    //\Forms\PurchCopying\Methods\writeTmpFrmVirtual
    {
        _tmpFrmVirtual.TableNum     = _tableId;
        _tmpFrmVirtual.RecordNo     = _recId;
        _tmpFrmVirtual.Id           = _id;
        _tmpFrmVirtual.LineNum      = _lineNum;
        _tmpFrmVirtual.TransDate    = _transDate;
        _tmpFrmVirtual.Qty          = _qty;
        _tmpFrmVirtual.write();
    }
    ;
    // if we want to copy with header.
    //writeTmpFrmVirtual(tmpFrmVirtualHeader,
    //                   purchTableFrom.TableId,
    //                   purchTableFrom.RecId,
    //                   purchTableFrom.PurchId);
    while select purchLineFrom
        where purchLineFrom.PurchId == purchTableFrom.PurchId
    {
        tmpFrmVirtualLines.clear();
        tmpFrmVirtualLines.initValue();
        writeTmpFrmVirtual(tmpFrmVirtualLines,
                           purchLineFrom.TableId,
                           purchLineFrom.RecId,
                           purchLineFrom.PurchId,
                           purchLineFrom.LineNum,
                           systemdateget(),
                           purchLineFrom.PurchQty);
    }
    purchCopying.initParameters(purchTableTo, tmpFrmVirtualLines, tmpFrmVirtualHeader);
    purchCopying.copy(); // transaction will created inside method
}

AX2012

static void Job63(Args _args)
{
    PurchCopying            purchCopying = PurchCopying::construct(SalesPurchCopy::CopyAllLines);
    TmpFrmVirtual           tmpFrmVirtualLines;
    TmpFrmVirtual           tmpFrmVirtualHeader;
    PurchTable              purchTableFrom  = PurchTable::find('PO-000055');
    PurchLine               purchLineFrom;
    PurchTable              purchTableTo    = PurchTable::find('PO-000057', true /*not good selectforupdate within transaction, but otherwise standart 2012R2 work with error */);
    List                    tmpFrmVirtualLinesList = new List(Types::Record);
    List                    tmpFrmVirtualHeaderList = new List(Types::Record);   
    PurchCopyingPurchTableContract    contract;
    Qty                     qtyFactor         = 1;
    NoYes                   reverseSign       = NoYes::No;
    NoYes                   recalculateAmount = NoYes::No;
    NoYes                   copyMarkup        = NoYes::No;
    NoYes                   copyPrecisely     = NoYes::No;
    NoYes                   deleteLines       = NoYes::No;

    void writeTmpFrmVirtual(TmpFrmVirtual   _tmpFrmVirtual,
                            tableId         _tableId,
                            recId           _recId,
                            Num             _id,
                            LineNum         _lineNum = 0,
                            TransDate       _transDate = systemdateget(),
                            Qty             _qty = 0)

    //\Forms\PurchCopying\Methods\writeTmpFrmVirtual
    {
        _tmpFrmVirtual.TableNum     = _tableId;
        _tmpFrmVirtual.RecordNo     = _recId;
        _tmpFrmVirtual.Id           = _id;
        _tmpFrmVirtual.LineNum      = _lineNum;
        _tmpFrmVirtual.TransDate    = _transDate;
        _tmpFrmVirtual.Qty          = _qty;
        _tmpFrmVirtual.write();
    }
    ;

    // if we want to copy with header.
    //writeTmpFrmVirtual(tmpFrmVirtualHeader,
    //                   purchTableFrom.TableId,
    //                   purchTableFrom.RecId,
    //                   purchTableFrom.PurchId);
    //tmpFrmVirtualHeaderList.addEnd(tmpFrmVirtualHeader);
    while select purchLineFrom
        where purchLineFrom.PurchId == purchTableFrom.PurchId
    {
        tmpFrmVirtualLines.clear();
        tmpFrmVirtualLines.initValue();
        writeTmpFrmVirtual(tmpFrmVirtualLines,
                           purchLineFrom.TableId,
                           purchLineFrom.RecId,
                           purchLineFrom.PurchId,
                           purchLineFrom.LineNumber,
                           systemdateget(),
                           purchLineFrom.PurchQty);
        tmpFrmVirtualLinesList.addEnd(tmpFrmVirtualLines);
    }

    contract = PurchCopyingPurchTableContract::construct();   
    contract.parmCallingTable(purchTableTo);
    contract.parmPackedTmpFrmVirtualLines(tmpFrmVirtualLinesList.pack());
    contract.parmPackedTmpFrmVirtualHeader(tmpFrmVirtualHeaderList.pack());
    contract.parmQtyFactor(qtyFactor);
    contract.parmReverseSign(reverseSign);
    contract.parmRecalculateAmount(recalculateAmount);
    contract.parmCopyMarkup(copyMarkup);
    contract.parmCopyPrecisely(copyPrecisely);
    contract.parmDeleteLines(deleteLines);
    purchCopying.initParameters(contract);
    purchCopying.copy(); // transaction will created inside method
}