Month: December 2015

AX 2012: Cancel product receipt journal in X++

Posted on Updated on

Purpose:

The purpose of this document is to illustrate how we can cancel a posted product receipt in X++.

Business requirement:

Ability to cancel product receipt journal automatically. As of now Standard AX offers manual product receipt cancellation by clicking Procurement and sourcing > Inquiries > Journals > Product receipt > Cancel.

Assumptions:

Product receipt is posted.

Development:

Please find below the job to correct product receipt journal in X++:

// Developed on 28 Dec 2015 by Muhammad Anas Khan
// Blog: dynamicsaxinsight.wordpress.com
// LinkedIn: pk.linkedin.com/in/muhammadanaskhan
// Description: Ability to cancel product receipt journal
static void makPurchPackingSlipCancel(Args _args)
{
    PurchTable           purchTable = PurchTable::find("0000-000187");
    VendPackingSlipJour  vendPackingSlipJour;
    PurchFormLetter      purchFormLetter;

    //Retrieve existing vend packingslip
    select firstOnly vendPackingSlipJour
    where vendPackingSlipJour.PackingSlipId == "MAK3101";

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);

    //If the correct VersioningUpdateType is not set
    //the system will try to create a new packingslip
    PurchFormLetter.parmVersioningUpdateType(VersioningUpdateType::Cancel);
    PurchFormLetter.parmCallerTable(vendPackingSlipJour);

    //The rows bellow are very important. Not really sure why
    PurchFormLetter.allowEmptyTable(true);
    PurchFormLetter.initAllowEmptyTable(true);
    PurchFormLetter.multiForm(true);
    purchFormLetter.update( purchTable,     // Purchase record buffer
        vendPackingSlipJour.PackingSlipId,  // Packingslip Number
        VendPackingSlipJour.DeliveryDate,   // Transaction Date
        PurchUpdate::ReceiveNow,            // Quantity update
        AccountOrder::None,
        NoYes::No,
        NoYes::No,
        NoYes::Yes);
}

Testing:

After running the job, you can see below the canceled product receipt journal:

Untitled

After comparing the last 2 product receipt journal versions:

Untitled

AX 2012: Correct product receipt journal in X++

Posted on Updated on

Purpose:

The purpose of this document is to illustrate how we can correct a posted product receipt in X++ using PurchParmTable and PurchParmLine tables.

Business requirement:

Ability to correct product receipt journal automatically. As of now Standard AX offers manual product receipt correction by clicking Procurement and sourcing > Inquiries > Journals > Product receipt > Correct.

Assumptions:

Product receipt is posted.

Development:

Please find below the job to correct product receipt journal in X++

// Developed on 28 Dec 2015 by Muhammad Anas Khan
// Blog: dynamicsaxinsight.wordpress.com
// LinkedIn: pk.linkedin.com/in/muhammadanaskhan
// Description: Ability to correct product receipt journal
static void makPurchPackingSlipCorrect(Args _args)
{
    PurchFormLetter         purchFormLetter;
    PurchFormletterParmData purchFormLetterParmData;
    PurchParmUpdate         purchParmUpdate;
    PurchParmTable          purchParmTable;
    PurchParmLine           purchParmLine;
    PurchTable              purchTable;
    PurchLine               purchLine;
    PurchId                 purchId;
    Num                     packingSlipId;
    VendPackingSlipJour     vendPackingSlipJour;
    VendPackingSlipTrans    vendPackingSlipTrans;

    purchId       = "0000-000187";
    packingSlipId = "MAK3101";

    purchTable = PurchTable::find(purchId);

    select firstOnly vendPackingSlipJour
        where vendPackingSlipJour.PurchId == purchId
            && vendPackingSlipJour.PackingSlipId == packingSlipId;

    ttsBegin;

    // Instantiate PurchFormLetterParmData
    purchFormLetterParmData = PurchFormletterParmData::newData(
        DocumentStatus::PackingSlip,
        VersioningUpdateType::Correction);

    purchFormLetterParmData.parmOnlyCreateParmUpdate(true);
    purchFormLetterParmData.createData(false);
    purchParmUpdate = purchFormLetterParmData.parmParmUpdate();

    // Set PurchParmTable table
    purchParmTable.clear();
    purchParmTable.TransDate             = SystemDateGet();
    purchParmTable.Ordering              = DocumentStatus::PackingSlip;
    purchParmTable.ParmJobStatus         = ParmJobStatus::Waiting;
    purchParmTable.ParmId                = purchParmUpdate.ParmId;
    purchParmTable.Num                   = packingSlipId;
    purchParmTable.ReCalculate           = true;
    purchParmTable.PurchId               = purchTable.PurchId;
    purchParmTable.PurchName             = purchTable.PurchName;
    purchParmTable.DeliveryName          = purchTable.DeliveryName;
    purchParmTable.OrderAccount          = purchTable.OrderAccount;
    purchParmTable.InvoiceAccount        = purchTable.InvoiceAccount;
    purchParmTable.CurrencyCode          = purchTable.CurrencyCode;
    purchParmTable.DeliveryPostalAddress = purchTable.DeliveryPostalAddress;
    purchParmTable.VendPackingSlipJour   = vendPackingSlipJour.RecId;
    purchParmTable.insert();

    // Set PurchParmLine table
    while select purchLine
        where purchLine.PurchId == purchTable.purchId
    {
        select firstOnly vendPackingSlipTrans
            where vendPackingSlipTrans.OrigPurchid == purchLine.PurchId
                && vendPackingSlipTrans.PurchaseLineLineNumber == purchLine.LineNumber;

        purchParmLine.ParmId = purchParmTable.ParmId;
        purchParmLine.TableRefId = purchParmTable.TableRefId;
        purchParmLine.InitFromPurchLine(purchLine);
        purchParmLine.ReceiveNow = 1000;
        purchParmLine.modifiedReceiveNow();
        purchParmLine.PreviousReceiveNow = vendPackingSlipTrans.Qty;
        purchParmLine.PreviousInventNow = vendPackingSlipTrans.InventQty;
        purchParmLine.setQty(DocumentStatus::PackingSlip, false);
        purchParmLine.setLineAmount();
        purchParmLine.insert();
    }

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
    purchFormLetter.parmVersioningUpdateType(VersioningUpdateType::Correction);
    purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());
    purchFormLetter.parmCallerTable(vendPackingSlipJour);
    purchFormLetter.parmParmTableNum(purchParmTable.ParmId);
    purchFormLetter.parmId(purchParmTable.ParmId);
    purchFormLetter.specQty(PurchUpdate::ReceiveNow);
    purchFormLetter.transDate(systemDateGet());
    purchFormLetter.proforma(false);
    purchFormLetter.run();

    ttsCommit;
}

Testing:

After running the job, you can see below the correction posted by comparing the last 2 versions of the product receipt journal:

Untitled

AX 2012: Confirm Purchase Order in X++

Posted on Updated on

Purpose:

The purpose of this document is to illustrate how we can confirm purchase orders in X++ using PurchParmTable table and PurchFormLetter class.

Business requirement:

Ability to confirm purchase order automatically. As of now Standard AX offers manual purchase order confirmation by clicking Procurement and sourcing > Common > Purchase orders > All purchase orders > Purchase > Generate > Confirm.

Assumptions:

The purchase order is created, lines are added and the Approval status is “Approved”.

Development:

Please find below the job to create and post product receipt against a purchase order in X++:

// Developed on 28 Dec 2015 by Muhammad Anas Khan
// Blog: dynamicsaxinsight.wordpress.com
// LinkedIn: pk.linkedin.com/in/muhammadanaskhan
// Description: Ability to confirm purchase order
static void makPurchPurchaseOrderConfirm(Args _args)
{
    PurchFormLetter             purchFormLetter;
    PurchFormletterParmData     purchFormLetterParmData;
    PurchParmUpdate             purchParmUpdate;
    PurchParmTable              purchParmTable;
    PurchParmLine               purchParmLine;
    PurchTable                  purchTable;
    PurchLine                   purchLine;
    PurchId                     purchId;
    Num                         packingSlipId;

    purchId       = "000441";
    packingSlipId = "MAK3001";
    purchTable = PurchTable::find(purchId);

    ttsBegin;

    // Create PurchParamUpdate table
    purchFormLetterParmData = PurchFormletterParmData::newData(
        DocumentStatus::PurchaseOrder,
        VersioningUpdateType::Initial);

    purchFormLetterParmData.parmOnlyCreateParmUpdate(true);
    purchFormLetterParmData.createData(false);
    purchParmUpdate = purchFormLetterParmData.parmParmUpdate();

    // Set PurchParmTable table
    purchParmTable.clear();
    purchParmTable.TransDate                = SystemDateGet();
    purchParmTable.DocumentDate             = SystemDateGet();
    purchParmTable.Ordering                 = DocumentStatus::PurchaseOrder;
    purchParmTable.ParmJobStatus            = ParmJobStatus::Waiting;
    purchParmTable.PurchId                  = purchTable.PurchId;
    purchParmTable.PurchName                = purchTable.PurchName;
    purchParmTable.DeliveryName             = purchTable.DeliveryName;
    purchParmTable.DeliveryPostalAddress    = purchTable.DeliveryPostalAddress;
    purchParmTable.OrderAccount             = purchTable.OrderAccount;
    purchParmTable.CurrencyCode             = purchTable.CurrencyCode;
    purchParmTable.InvoiceAccount           = purchTable.InvoiceAccount;
    purchParmTable.ParmId                   = purchParmUpdate.ParmId;
    purchParmTable.insert();

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PurchaseOrder);
    purchFormLetter.transDate(systemDateGet());
    purchFormLetter.proforma(false);
    purchFormLetter.specQty(PurchUpdate::All);
    purchFormLetter.purchTable(purchTable);

    // This is the ID we hard code as the product receipt ID, if we do the posting via UI
    // user would have the option to manually enter this value
    purchFormLetter.parmParmTableNum(purchParmTable.ParmId);
    purchFormLetter.parmId(purchParmTable.ParmId);
    purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());
    purchFormLetter.run();

    ttsCommit;
}

AX 2012: AIF Document Service Invalid Data Container Type

Posted on

Error:

Invalid data container type.

Resolution:

Compile forward AfStronglyTypedDataContainer class.