I've made such button in the past and actually I'm not too happy with it:
- Users have to be trained to click the non-standard button
- A formula text field with "TODO list" sits right next to the data and is reportable on. And you might be better off referencing this formula field in entry criteria in approval if they're very complex
- A small embedded VF page is easier to maintain if your colleagues aren't too good with AJAX toolkit
Here goes:
{!REQUIRESCRIPT("/soap/ajax/24.0/connection.js")}
var poId = '{!Purchase_Order__c.Id}';
if(poId == ''){
poId = window.location.pathname.replace("/","");
}
var results = sforce.connection.query("SELECT PO_Validation__c, Requestor__c, Approved_Amount__c, Total_Amount__c, PO_Item_Count__c, Required_Delivery_Date__c,Total_Exceeds_Approved_Budget__c, Reason_for_Discrepancy__c FROM Purchase_Order__c WHERE Id = '" + poId + "'");
var po = results.records;
if(po.PO_Validation__c != 'Valid'){
var msg = 'This Purchase Order cannot be sent for approval before following errors are amended: \r\n\r\n';
if(po.Requestor__c == null){
msg += '"Requestor" is blank\r\n';
}
if(po.Approved_Amount__c == null){
msg += '"Approved Amount" is blank\r\n';
}
if(po.Total_Amount__c == 0){
msg += '"Total Amount" is 0\r\n';
}
if(po.PO_Item_Count__c == 0){
msg += 'There are no PO Items\r\n';
}
if(po.Required_Delivery_Date__c == null){
msg += '"Required Delivery Date" is blank\r\n';
}
if(po.Total_Exceeds_Approved_Budget__c == 'Yes' && po.Reason_for_Discrepancy__c == null){
msg += 'Total exceeds the budget but "Reason for Discrepancy" is blank\r\n';
}
alert(msg);
} else {
// Part based on standard Submit for approval button
if ((Modal.confirm && Modal.confirm('Once you submit this record for approval, you might not be able to edit it or recall it from the approval process depending on your settings. Continue?')) || (!Modal.confirm && window.confirm('Once you submit this record for approval, you might not be able to edit it or recall it from the approval process depending on your settings. Continue?')))
navigateToUrl('/p/process/Submit?retURL=%2F' + poId + '&id=' + poId,'DETAIL','submit');
}
I an confused why you are querying ProcessInstance. Are you not setting a status field when the record is approved? If you have one, just use an after trigger to look for it changing to Approved (or whatever) then query for the parent and update that.
Strictly speaking a status field isn't necessary, but I have never implemented an approval process where the business didn't want a status field on the object. I suppose your proposed way would work, but I hope you have a strong reason to avoid adding a status field. If not, you are just creating a headache for yourself!
Best Answer
It's just the
Status
field. You can also get the individual step statuses fromProcessInstanceStep
.