Packing Slip

AX 2012: Post product receipt of purchase order in X++

Posted on Updated on

Purpose:

The purpose of this document is to illustrate how we can create and post product receipts of purchase orders in X++.

Business requirement:

Ability to post product receipts of purchase order automatically. As of now Standard AX offers manual product receipt posting by clicking Procurement and sourcing > Periodic > Purchase orders > Product receipt

Assumption:

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

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 post product receipt
static void makPurchPackingSlipPost(Args _args)
{
    PurchFormLetter             purchFormLetter;
    PurchFormletterParmData     purchFormLetterParmData;
    PurchParmUpdate             purchParmUpdate;
    PurchParmTable              purchParmTable;
    PurchParmLine               purchParmLine;
    PurchTable                  purchTable;
    PurchLine                   purchLine;
    PurchId                     purchId;
    Num                         packingSlipId;

    purchId       = "0000-000187";
    packingSlipId = "MAK3101";
    purchTable    = PurchTable::find(purchId);

    ttsBegin;
    // Create PurchParamUpdate table
    purchFormLetterParmData = PurchFormletterParmData::newData(
        DocumentStatus::PackingSlip,
        VersioningUpdateType::Initial);
    
    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.Num                      = packingSlipId;
    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();

    // Set PurchParmLine table
    while select purchLine
        where purchLine.PurchId == purchTable.purchId
    {
        purchParmLine.InitFromPurchLine(purchLine);

        purchParmLine.ReceiveNow    = PurchLine.PurchQty;
        purchParmLine.ParmId        = purchParmTable.ParmId;
        purchParmLine.TableRefId    = purchParmTable.TableRefId;
        purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
        purchParmLine.setLineAmount();
        purchParmLine.insert();
    }

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
    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;
}

Testing

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

Product receipt journal

AX 2012: Packing Slips

Posted on Updated on

Business Purpose

When a sales order is ready to be picked, a picking list is created. Warehouse employees pick items from the inventory and prepare them for shipment. When the order has been shipped, a packing slip is sent from the warehouse to get it posted in Dynamics AX against that particular sales order which triggers the order status to be updated.

The document direction is inbound i.e. it is received by Dynamics AX. New packing slips are received and posted through the Posting packing slip form.

Generate Sales Order Packing Slip

  1. Open Sales and marketing > Common > Sales orders > All sales order.
  2. Select the sales order to generate the packing slip.
  3. In the Pick and pack tab of the Action Pane, click Packing slip in the Generate group. The Packing slip posting form opens.
  4. In the Posting packing slip form, in the Quantity field, select the All option.
  5. Select the Print packing slip check box to print the packing slip.
  6. Click OK on the Posting dialog box.

If the quantities on the packing slip update equal the ordered quantities, the value in the sales order Status field changes to Delivered. If there is a back order on one or more items, the sales order status remains as Open order.