This document provides a tutorial to customize the purchase order generation policy. Knowledge shared here can be used to gain a hands on idea to customize the PO generation policy as well as to get a similar idea about other policies coming under the umbrella of purchasing policy like requisition purpose rule and replenishment control rule etc.
ENTRY POINT:
Workflow (PurchReqReview) class,
completion event.FLOW:
At each status method, namely started, cancelled and completed, helper class
static methods are called.Class: PurchReqWFStatusTransitionHelper
As the name suggests, the class responsibility is to run seperate and specific logic per PurchReq. There is a method foe each status like In review, Draft, Approved etc.
At (C)
, at method for the status, "completed",
, the following line is calledPurchReqWFStatusTransitionHelper::setPurchReqTable2Approved
(_workflowEventArgs.parmWorkflowContext().parmRecId());
This method in its body calls for logic which first update each PurchReqLine flag after considering the configured Purch Req policy. Then it calls code to generate PO for all PurchReqLines of purpose. See code below:
RequisitionReleaseStrategy::updateManaulDocumentGeneration
(_purchReqTableRecId);
purchReqWFStatusTransitionHelper.doVersioning
(_purchReqTableRecId);
if (purchReqTable.RequisitionPurpose == RequisitionPurpose::Consumption)
{
PurchReqPurchaseOrderGenerationInSync::run(purchReqTable);
}
System Querying PurchReq PO generation policy
As per above,
(C)ReleaseStrategy
>> method
is called. This method updates each line field
based on query policy data read from DB. It is this flag field in each line in the end that ensures if the PO from this line is to be generated manually or automaticallyHOW IS POLICY DATA READ FOR EACH PR LINE ?
RequisitionREleaseStrategy
calls the boolean returning method in a conditional check to evaluate at runtime if the purchReqLIne field
be set to true or not. Consider the following line of code:PurchReqPurchaseOrderGenerationRule::
isManualCreatePurchaseOrderStatic(purchReqLine)
if (!purchReqLine.VendAccount ||
PurchReqPurchaseOrderGenerationRule::
isManualCreatePurchaseOrderStatic(purchReqLine))
{
purchReqLine.IsPurchaseOrderGenerationManual = true;
purchReqLine.update(false);
}
PurchReqPurchaseOrderGenerationRule::
isManualCreatePurchaseOrderStatic()
inits the class object, sets PurchReqLine buffer via parm method, initializes the policy (abstract from us, not in scope of the topic), and calss the instance method <>. See code below
PurchReqPurchaseOrderGenerationRulepurchReqPurchaseOrderGenerationRule;
purchReqPurchaseOrderGenerationRule = PurchReqPurchaseOrderGenerationRule::construct();
purchReqPurchaseOrderGenerationRule.parmPurchReqLine(_purchReqLine);
purchReqPurchaseOrderGenerationRule.initPolicy();
return purchReqPurchaseOrderGenerationRule.
isManualCreatePurchaseOrder();
The method then checks the line against the policy and returns a boolean, true for manual PO creation, false for auto.
Customizing the PO Generation Policy
isManualCreatePurchaseOrder method can be read to get an idea how to customize this policy to add custom fields and conditional checks and extend the logic to evaluate if PO from PR (WorkFlow) should be generated or not.
After reading the simple method, we come to the points as follows;
- The PO generation policy form is binded with table:
- The Table has 5 NoYes enum fields which are rendered on the PO generation policy config form as radio hierarchied buttons
- These fields are evaluated in the (C)PurchReqPurchaseOrderGenerationRule. isManualCreatePurchaseOrder() method.
- To add custom evaluation logic, you can add a field, a relation, or an instanceRelation extension to this table write valid evaluation code for the new schema in the aforementioned method.
HAPPY PR TO PO GENERATION POLICY EXTENSION