Created
August 28, 2018 11:20
-
-
Save escgeek/c9eb3eda6f885f0f07735deb1f80dd2c to your computer and use it in GitHub Desktop.
Apex Class Methods used to build out a child object with Approval and Custom Date metrics in order to do Turn Around Time calculations.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PO_Approval_Milestones_Helper_Class { | |
// Test Class: Global_Test_Class | |
public static void addTime(List<PO_Approval_Milestones__c> newTrigger){ | |
// Class to calculate the difference in Start and Completed Date/Time Fields | |
// Doing it at the PO Approval Milestone level in order to cut down on the redundent and complex queries | |
// 08Dec2017 - ESC | |
Id bhId; | |
Id bhDefaultId; | |
string bhName; | |
decimal bizDays = 0.0; | |
set<Id> actorIds = new set<Id>(); | |
map<Id, BusinessHours> tzMap = new map<Id, BusinessHours>(); | |
map<String, BusinessHours> bhMap = new map<String, BusinessHours>(); | |
list<PO_Approval_Milestones__c> updateList = new list<PO_Approval_Milestones__c>(); | |
// Step 1 - Determine if works needs to be done | |
// Look for records that have an approver and the start and end dates and add them to a 'work' list | |
for(PO_Approval_Milestones__c po : newTrigger) | |
{ | |
if( | |
po.Approver__c != NULL | |
&& po.Start__c != NULL | |
&& po.Completed__c != NULL | |
){ | |
actorIds.add(po.Approver__c); | |
updateList.add(po); | |
} | |
} | |
// Step 2 - Pull together the data needed to update the records | |
// Determine if there's work to be done using the updateList size | |
if(updateList.size() > 0){ | |
// Pull all Business Hour records in to a map - Should only be a couple records | |
for(BusinessHours bhours : [SELECT Id, Name, IsDefault | |
FROM BusinessHours]) | |
{ | |
bhMap.put(bhours.Name, bhours); | |
// Set the 'default' Business Hour Id in case the user does not have the 'Business Hours Time Zone' picklist set | |
if(bhours.IsDefault){ | |
bhDefaultId = bhours.Id; | |
} | |
} | |
system.debug('bhMap: ' + bhMap); | |
system.debug('bhDefaultId: ' + bhDefaultId); | |
// Create a UserId to Business Hours mapping to understand which time zone to apply to the business hours and start/completed dates | |
for(User u : [SELECT Id, Business_Hours_Time_Zone__c | |
FROM User | |
WHERE Id = :actorIds | |
AND Business_Hours_Time_Zone__c != NULL]) | |
{ | |
if(u.Business_Hours_Time_Zone__c != NULL && bhMap.containsKey(u.Business_Hours_Time_Zone__c)){ | |
tzMap.put(u.Id, bhMap.get(u.Business_Hours_Time_Zone__c)); | |
} | |
} | |
system.debug('Time Zone Map: ' + tzMap); | |
// Step 3 - Put it all together | |
for(PO_Approval_Milestones__c poam : updateList) | |
{ | |
bhid = NULL; | |
// Make sure we will get a positive number else set 'Time' to zero | |
if(poam.Completed__c > poam.Start__c || poam.Completed__c == poam.Start__c){ | |
// Set the Business Hours based on Time Zone | |
if(tzMap.containsKey(poam.Approver__c)){ | |
bhid = tzMap.get(poam.Approver__c).Id; | |
bhName = tzMap.get(poam.Approver__c).Name; | |
system.debug('Setting Business Hours to: ' + tzMap.get(poam.Approver__c).Name); | |
if(poam.Business_Hours__c != tzMap.get(poam.Approver__c).Id){ | |
poam.Business_Hours__c = tzMap.get(poam.Approver__c).Id; | |
} | |
} | |
else{ | |
system.debug('Setting Business Hours to Default (Central) - Need to set user Business Hours Time Zone'); | |
bhid = bhDefaultId; | |
poam.Business_Hours__c = bhDefaultId; | |
bhName = 'Default'; | |
} | |
// Calculate the time | |
if(bhid != NULL){ | |
bizDays = BusinessHours.diff(bhid, poam.Start__c, poam.Completed__c); | |
poam.Time_Raw__c = bizDays; // Capture the raw time - ESC 21Mar2018 | |
bizDays = bizDays / 1000; //milliseconds | |
bizDays /= 60; //seconds | |
bizDays /= 60; //minutes | |
if(bhName == 'Ireland'){ | |
bizDays /= 8.5; //hours | |
} | |
else{ | |
bizDays /= 9; //hours | |
} | |
poam.Time__c = bizDays; | |
} | |
} | |
else{ | |
system.debug('Completed Date is before Start Date'); | |
poam.Time__c = 0; | |
} | |
} | |
} | |
} | |
public static void cancelApproval(List<Purchase_Order__c> newTrigger){ | |
set<Id> poSet = new set<Id>(); | |
for(Purchase_Order__c po : newTrigger){ | |
if(po.Approval_Status__c == 'Cancelled'){ | |
poSet.add(po.Id); | |
} | |
} | |
if(poSet.size() > 0){ | |
List<Approval.ProcessWorkitemRequest> requests = new List<Approval.ProcessWorkitemRequest>(); | |
for(ProcessInstanceWorkitem piw : [SELECT Id, ProcessInstanceId | |
FROM ProcessInstanceWorkitem | |
WHERE ProcessInstance.TargetObjectId = :poSet]) | |
{ | |
Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest(); | |
req.setWorkitemId(piw.Id); | |
//Valid values are: Approve, Reject, or Removed. | |
//Only system administrators can specify Removed. | |
req.setAction('Reject'); | |
req.setComments('Approval Cancelled!'); | |
requests.add(req); | |
} | |
if(requests.size() > 0){ | |
Approval.ProcessResult[] processResults = Approval.process(requests); | |
} | |
} | |
} | |
public static void toggleUpdate(List<Purchase_Order__c> newTrigger){ | |
system.debug('Toggle Update!'); | |
Blob blobKey = crypto.generateAesKey(128); | |
String updateKey = EncodingUtil.base64encode(blobKey); | |
updateKey = updateKey.left(10); | |
for(Purchase_Order__c po : newTrigger){ | |
if(system.isFuture()){ | |
system.debug('Setting: OK'); | |
po.Update_Status_Text__c = 'Ok'; | |
} | |
else{ | |
system.debug('Setting: Future'); | |
po.Update_Status_Text__c = 'Future'; | |
po.Update_Key__c = updateKey; | |
} | |
} | |
} | |
public static void addOpportunityBefore(List<Purchase_Order__c> newTrigger){ | |
map<Id, Id> oppMap = new map<Id, Id>(); | |
for (Purchase_Order__c po : [SELECT Id, Opportunity__c, Quote__r.OpportunityId | |
FROM Purchase_Order__c | |
WHERE Id = :newTrigger | |
AND Quote__r.OpportunityId != NULL]) | |
{ | |
oppMap.put(po.Id, po.Quote__r.OpportunityId); | |
} | |
if(oppMap.size() > 0){ | |
for (Purchase_Order__c po : newTrigger){ | |
if(oppMap.containsKey(po.Id) && po.Opportunity__c != oppMap.get(po.Id)){ | |
po.Opportunity__c = oppMap.get(po.Id); | |
} | |
} | |
} | |
} | |
public static void customMilestones(List<Purchase_Order__c> newTrigger){ | |
string pKey; | |
string dType; | |
Date startDate; | |
Datetime startDateTime; | |
Date completedDate; | |
Datetime completedDateTime; | |
integer lcount = 1; | |
map<String, PO_Approval_Milestones__c> poMAP = new map<String, PO_Approval_Milestones__c>(); // Map of existing PO Milestones | |
map<Id, Date> poStartDate = new map<Id, Date>(); // Map of PO's to the date they first entered the first approval process | |
list<PO_Approval_Milestones__c> poamList = new list<PO_Approval_Milestones__c>(); // List used to update the records | |
PO_Approval_Milestones__c updatePOAM = new PO_Approval_Milestones__c(); // PO Milestone record used/reused to update and added to the update list | |
// Load all of the custom milestones | |
list<Custom_Milestones__c> cmList = Custom_Milestones__c.getall().values(); | |
// Create the map of existing records | |
for(PO_Approval_Milestones__c po : [SELECT Key__c, ProcessNodeId__c, ProcessInstanceId__c, Start__c, Completed__c, Purchase_Order__c, | |
Step_Name__c, Step_Status__c, Completed_By__c, Comments__c, Type__c, Start_Date__c, Start_Date_Time__c, | |
Completed_Date__c, Completed_Date_Time__c, Purchase_Order__r.Update_Key__c, | |
Custom_Milestone__c, Custom_Milestone_Fields__c | |
FROM PO_Approval_Milestones__c | |
WHERE Purchase_Order__c = :newTrigger | |
ORDER BY Start__c DESC]) | |
{ | |
poMAP.put(po.Key__c, po); | |
} | |
// This is used to determine what the start time of the first approval process related to that PO | |
// Creates a map using the PO Id and the first date/time | |
for(ProcessInstanceNode pi : [SELECT CreatedDate, ProcessInstance.TargetObjectId | |
FROM ProcessInstanceNode | |
WHERE ProcessInstance.TargetObjectId = :newTrigger | |
ORDER BY CreatedDate]) | |
{ | |
// Set the Start Date - Takes the first instance | |
if(!poStartDate.containsKey(pi.ProcessInstance.TargetObjectId)){ | |
system.debug('Adding Start Date: ' + pi.CreatedDate.date()); | |
poStartDate.put(pi.ProcessInstance.TargetObjectId, pi.CreatedDate.date()); | |
} | |
} | |
// Determines whether fields are date or date/time fields | |
Purchase_Order__c poFields = new Purchase_Order__c(); | |
for(Purchase_Order__c pOrder : newTrigger){ | |
poFields = pOrder; // Just need a record in order to get the metadata, does not matter which | |
} | |
Map<String, Object> fieldsToValue = poFields.getPopulatedFieldsAsMap(); | |
Map<String, String> dtMap = new map<String, String>(); | |
for(String fieldName : fieldsToValue.keySet()){ | |
if(fieldsToValue.get(fieldName) instanceOf Date){ | |
dtMap.put(fieldName, 'Date'); | |
System.debug('Date field name is ' + fieldName + ', value is ' + fieldsToValue.get(fieldName)); | |
} | |
else if(fieldsToValue.get(fieldName) instanceOf DateTime){ | |
dtMap.put(fieldName, 'DateTime'); | |
System.debug('DateTime field name is ' + fieldName + ', value is ' + fieldsToValue.get(fieldName)); | |
} | |
} | |
// We use sObject instead of Purchase_Order__c so that we can use dynamic fields with the Custom Milestone custom setting | |
for(SObject po : newTrigger){ | |
for(Custom_Milestones__c m : cmList){ | |
system.debug('[' + lcount + '] Starting Milestone: ' + m); | |
if((Boolean) m.get('Active__c') == TRUE){ | |
/*Datetime approvalStart = NULL; | |
Datetime approvalEnd = NULL; | |
approvalStart = (Datetime) po.get(m.Start_Date_Field__c); | |
if(m.End_Date_Field__c == 'poStartDate' && poStartDate.containsKey(po.Id)){ // A hack to allow us to calculate all of the dates | |
approvalEnd = poStartDate.get(po.Id); | |
} | |
else{ | |
approvalEnd = (Datetime) po.get(m.End_Date_Field__c); | |
}*/ | |
// Validate that the dates both set with data | |
//if(approvalStart != NULL && approvalEnd != NULL){ | |
// Magik Time! | |
//pKey = (Id) po.get('Id') + '-' + m.Name; | |
pKey = po.Id + '-' + m.Name; | |
//datetime startDT = datetime.newInstance(approvalStart.year(), approvalStart.month(),approvalStart.day(), 00, 00, 00); | |
//datetime completedDT = datetime.newInstance(approvalEnd.year(), approvalEnd.month(),approvalEnd.day(), 00, 00, 00); | |
//date startDT2 = approvalStart.dateGmt(); | |
//date startDT2 = date.newInstance(approvalStart.year(), approvalStart.month(),approvalStart.day()); | |
if(poMAP.containsKey(pKey)){ // Record Exists - Let's Update | |
// Only thing that could change is the Date PO Received which we will update | |
system.debug('[CM] -- Record Exists - Updating!'); | |
updatePOAM = poMAP.get(pKey); // Set the Active Record | |
updatePOAM.Update_Key__c = updatePOAM.Purchase_Order__r.Update_Key__c; // Update the Key from the parent to determine if the child record was updated or needs to be deleted | |
updatePOAM.Custom_Milestone__c = m.Name; | |
updatePOAM.Custom_Milestone_Fields__c = 'Start: ' + m.Start_Date_Field__c + ' End: ' + m.End_Date_Field__c; | |
/* | |
if(dtMap.containsKey(m.Start_Date_Field__c) && dtMap.get(m.Start_Date_Field__c) == 'Date'){ | |
startDate = (Date) po.get(m.Start_Date_Field__c); | |
startDateTime = datetime.newInstanceGMT (startDate.year(), startDate.month(), startDate.day(), 00, 00, 00); | |
updatePOAM.Start__c = startDateTime; | |
updatePOAM.Start_Type__c = 'Date'; | |
updatePOAM.Start_Date__c = (Date) po.get(m.Start_Date_Field__c); | |
updatePOAM.Start_Date_Time__c = NULL; | |
} | |
else{ | |
startDateTime = (Datetime) po.get(m.Start_Date_Field__c); | |
updatePOAM.Start__c = startDateTime; | |
updatePOAM.Start_Type__c = 'DateTime'; | |
updatePOAM.Start_Date__c = NULL; | |
updatePOAM.Start_Date_Time__c = startDateTime; | |
} | |
if(dtMap.containsKey(m.End_Date_Field__c) && dtMap.get(m.End_Date_Field__c) == 'Date'){ | |
completedDate = (Date) po.get(m.End_Date_Field__c); | |
completedDateTime = datetime.newInstanceGMT (completedDate.year(), completedDate.month(), completedDate.day(), 00, 00, 00); | |
updatePOAM.Completed__c = completedDateTime; | |
updatePOAM.Completed_Type__c = 'Date'; | |
updatePOAM.Completed_Date__c = completedDate; | |
updatePOAM.Completed_Date_Time__c = NULL; | |
} | |
else{ | |
updatePOAM.Completed_Type__c = 'DateTime'; | |
if(m.End_Date_Field__c == 'poStartDate'){ // A hack to allow us to calculate all of the dates | |
completedDateTime = poStartDate.get(po.Id); | |
updatePOAM.Completed__c = completedDateTime; | |
updatePOAM.Completed_Date_Time__c = completedDateTime; | |
updatePOAM.Completed_Date__c = NULL; | |
} | |
else{ | |
completedDateTime = (Datetime) po.get(m.End_Date_Field__c); | |
updatePOAM.Completed__c = completedDateTime; | |
updatePOAM.Completed_Date_Time__c = completedDateTime; | |
updatePOAM.Completed_Date__c = NULL; | |
} | |
} | |
system.debug('[' + m.Name + '] - Date Fields - Start: ' + approvalStart + ' End: ' + approvalEnd); | |
system.debug('[' + m.Name + '] - Date/Time Fields - Start: ' + startDateTime + ' End: ' + completedDateTime); | |
if(completedDateTime > startDateTime){ | |
Long rawTime = completedDateTime.getTime() - startDateTime.getTime(); | |
updatePOAM.Time_Raw__c = rawTime; // Capture the raw time - ESC 21Mar2018 | |
updatePOAM.Comments__c = ''; | |
} | |
else{ | |
updatePOAM.Time__c = 0; | |
updatePOAM.Time_Raw__c = 0; | |
if(m.Error_Message__c != NULL){ | |
updatePOAM.Comments__c = m.Error_Message__c; | |
} | |
else{ | |
updatePOAM.Comments__c = 'Starting Date is later than the Ending Date'; | |
} | |
}*/ | |
//poMAP.put(pKey, updatePOAM); | |
} | |
else{ | |
system.debug('[CM] -- New Record -- Inserting!'); | |
updatePOAM = new PO_Approval_Milestones__c( | |
//Start__c = startDateTime, | |
//Completed__c = completedDateTime, | |
//Type__c = 'Date', | |
Approval_Name__c = m.Name, | |
Key__c = pKey, | |
Approver__c = UserInfo.getUserId(), | |
Submitted_By__c = UserInfo.getUserId(), | |
Approval_Status__c = 'Completed', | |
Purchase_Order__c = po.Id, | |
Step_Name__c = m.Name, | |
Step_Status__c = 'Completed', | |
Custom_Milestone__c = m.Name, | |
Custom_Milestone_Fields__c = 'Start: ' + m.Start_Date_Field__c + ' End: ' + m.End_Date_Field__c | |
); | |
/* | |
if(completedDateTime > startDateTime){ | |
Long rawTime = completedDateTime.getTime() - startDateTime.getTime(); | |
updatePOAM.Time_Raw__c = rawTime; // Capture the raw time - ESC 21Mar2018 | |
updatePOAM.Comments__c = ''; | |
} | |
else{ | |
updatePOAM.Time__c = 0; | |
updatePOAM.Time_Raw__c = 0; | |
if(m.Error_Message__c != NULL){ | |
updatePOAM.Comments__c = m.Error_Message__c; | |
} | |
else{ | |
updatePOAM.Comments__c = 'Starting Date is later than the Ending Date'; | |
} | |
}*/ | |
//poMAP.put(pKey, updatePOAM); | |
} | |
if(dtMap.containsKey(m.Start_Date_Field__c) && dtMap.get(m.Start_Date_Field__c) == 'Date'){ | |
startDate = (Date) po.get(m.Start_Date_Field__c); | |
startDateTime = datetime.newInstanceGMT (startDate.year(), startDate.month(), startDate.day(), 00, 00, 00); | |
dtype = 'Date'; | |
updatePOAM.Start__c = startDateTime; | |
updatePOAM.Start_Type__c = 'Date'; | |
updatePOAM.Start_Date__c = (Date) po.get(m.Start_Date_Field__c); | |
updatePOAM.Start_Date_Time__c = NULL; | |
} | |
else{ | |
startDateTime = (Datetime) po.get(m.Start_Date_Field__c); | |
dtype = 'DateTime'; | |
updatePOAM.Start__c = startDateTime; | |
updatePOAM.Start_Type__c = 'DateTime'; | |
updatePOAM.Start_Date__c = NULL; | |
updatePOAM.Start_Date_Time__c = startDateTime; | |
} | |
if(dtMap.containsKey(m.End_Date_Field__c) && dtMap.get(m.End_Date_Field__c) == 'Date'){ | |
completedDate = (Date) po.get(m.End_Date_Field__c); | |
completedDateTime = datetime.newInstanceGMT (completedDate.year(), completedDate.month(), completedDate.day(), 00, 00, 00); | |
if(dtype != 'Date'){ | |
dType = 'Date/DateTime'; | |
} | |
updatePOAM.Completed__c = completedDateTime; | |
updatePOAM.Completed_Type__c = 'Date'; | |
updatePOAM.Completed_Date__c = completedDate; | |
updatePOAM.Completed_Date_Time__c = NULL; | |
} | |
else{ | |
if(dtype != 'DateTime'){ | |
dType = 'Date/DateTime'; | |
} | |
updatePOAM.Completed_Type__c = 'DateTime'; | |
if(m.End_Date_Field__c == 'poStartDate'){ // A hack to allow us to calculate all of the dates | |
completedDateTime = poStartDate.get(po.Id); | |
updatePOAM.Completed__c = completedDateTime; | |
updatePOAM.Completed_Date_Time__c = completedDateTime; | |
updatePOAM.Completed_Date__c = NULL; | |
} | |
else{ | |
completedDateTime = (Datetime) po.get(m.End_Date_Field__c); | |
updatePOAM.Completed__c = completedDateTime; | |
updatePOAM.Completed_Date_Time__c = completedDateTime; | |
updatePOAM.Completed_Date__c = NULL; | |
} | |
} | |
updatePOAM.Type__c = dtype; | |
//system.debug('[' + m.Name + '] - Date Fields - Start: ' + approvalStart + ' End: ' + approvalEnd); | |
system.debug('[' + m.Name + '] - Date/Time Fields - Start: ' + startDateTime + ' End: ' + completedDateTime); | |
if(completedDateTime > startDateTime){ | |
Long rawTime = completedDateTime.getTime() - startDateTime.getTime(); | |
//Long rawTime = completedDT.getTime() - startDT.getTime(); -- Old Way - 01Aug2018 | |
//datetime.newInstanceGMT (startDate.year(), startDate.month(), startDate.day(), 00, 00, 00) | |
updatePOAM.Time_Raw__c = rawTime; // Capture the raw time - ESC 21Mar2018 | |
updatePOAM.Comments__c = ''; | |
} | |
else{ | |
updatePOAM.Time__c = 0; | |
updatePOAM.Time_Raw__c = 0; | |
if(m.Error_Message__c != NULL){ | |
updatePOAM.Comments__c = m.Error_Message__c; | |
} | |
else{ | |
updatePOAM.Comments__c = 'Starting Date is later than the Ending Date'; | |
} | |
} | |
if(completedDateTime != NULL && startDateTime != NULL){ | |
poMAP.put(pKey, updatePOAM); | |
} | |
} | |
//} | |
system.debug('[' + lcount + '] Completed Milestone: ' + m); | |
++lcount; | |
} // End Custom Milestone Loop | |
} // End sObject Loop | |
// Upsert PO Milestones | |
system.debug('poMap: ' + poMAP); | |
if(poMAP.size() > 0){ | |
poamList.addAll(poMAP.values()); | |
upsert poamList; | |
} | |
} | |
public static void updateMilestones(List<Purchase_Order__c> newTrigger){ | |
set<Id> futureIds = new Map<Id,Purchase_Order__c>(newTrigger).keySet(); // Nifty way of converting a list to a set of Id's : https://salesforce.stackexchange.com/questions/8910/how-can-i-efficiently-generate-a-setid-from-a-listsobject-structure | |
if(!system.isFuture()){ // This Prevents looping future calls | |
updateMilestonesFuture(futureIds); | |
} | |
} | |
@future | |
public static void updateMilestonesFuture(set<Id> newTrigger){ | |
string pKey; | |
integer aNum = 0; | |
decimal bizDays = 0.0; | |
map<String, PO_Approval_Milestones__c> poMAP = new map<String, PO_Approval_Milestones__c>(); | |
map<String, Purchase_Order__c> orderMap = new map<String, Purchase_Order__c>(); | |
list<ProcessInstance> piList = new list<ProcessInstance>(); | |
list<PO_Approval_Milestones__c> poamList = new list<PO_Approval_Milestones__c>(); | |
PO_Approval_Milestones__c updatePOAM = new PO_Approval_Milestones__c(); | |
BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true]; | |
// Legacy Class | |
string stepName; | |
List<Purchase_Order__c> updPos = new List<Purchase_Order__c>(); | |
list<Purchase_Order__c> poList = new list<Purchase_Order__c>(); | |
map<Id, ProcessInstanceNode> piMap = new map<Id, ProcessInstanceNode>(); | |
map<Id, Date> poStartDate = new map<Id, Date>(); | |
// End Legacy | |
// Create the map of existing records | |
for(PO_Approval_Milestones__c po : [SELECT Key__c, ProcessNodeId__c, ProcessInstanceId__c, Start__c, Completed__c, Purchase_Order__c, | |
Step_Name__c, Step_Status__c, Completed_By__c, Comments__c, Type__c, | |
Purchase_Order__r.Update_Key__c | |
FROM PO_Approval_Milestones__c | |
WHERE Purchase_Order__c = :newTrigger | |
ORDER BY Start__c DESC]) | |
{ | |
poMAP.put(po.Key__c, po); | |
} | |
// Create map and list of Purchase Orders | |
for(Purchase_Order__c p : [SELECT Id, Name, Quote__r.Opportunity_Id__c, Approval_Status__c, | |
Current_Approval_Step__c, Date_PO_Received__c, Date_of_First_Payment_Received__c, | |
Sales_Order_Acknowledged__c, Reason_for_Delay__c, Update_Status_Text__c, Update_Key__c | |
FROM Purchase_Order__c | |
WHERE Id = :newTrigger]) | |
{ | |
orderMap.put(p.Id, p); | |
poList.add(p); | |
} | |
for(ProcessInstance pi : [SELECT CreatedDate, CompletedDate,ProcessDefinitionId,Status,TargetObjectId, | |
(SELECT ProcessInstanceId, ProcessNodeId, StepStatus, Comments, ActorId, Actor.Name, OriginalActorId, OriginalActor.Name FROM StepsAndWorkitems WHERE ProcessNodeId != NULL ORDER By Id), | |
(SELECT ProcessInstanceId, ProcessNodeId, NodeStatus, ProcessNodeName, CompletedDate, CreatedDate FROM Nodes ORDER By Id) | |
FROM ProcessInstance | |
WHERE TargetObjectId = :newTrigger | |
ORDER By CreatedDate]) | |
{ | |
system.debug('pi: ' + pi); | |
aNum++; | |
for(ProcessInstanceHistory pih : pi.StepsAndWorkitems){ | |
//system.debug('Steps: ' + pih); | |
pKey = pih.ProcessInstanceId + '-' + pih.ProcessNodeId; | |
string bigComments; | |
if(poMAP.containsKey(pKey)){ | |
updatePOAM = poMAP.get(pKey); | |
updatePOAM.Approver__c = pih.ActorId; | |
updatePOAM.Update_Key__c = poMAP.get(pKey).Purchase_Order__r.Update_Key__c; | |
updatePOAM.Submitted_By__c = pih.OriginalActorId; | |
updatePOAM.ProcessNodeId__c = pih.ProcessNodeId; | |
updatePOAM.ProcessInstanceId__c = pih.ProcessInstanceId; | |
bigComments = pih.Comments; | |
if(bigComments != NULL){ | |
bigComments = bigComments.left(255); | |
} | |
updatePOAM.Comments__c = bigComments; | |
updatePOAM.Type__c = 'Approval'; | |
if(pi.Status == 'Removed'){ | |
updatePOAM.Approval_Status__c = 'Recalled'; | |
} | |
else{ | |
updatePOAM.Approval_Status__c = pi.Status; | |
} | |
poMAP.put(pKey, updatePOAM); | |
} | |
else{ | |
updatePOAM = new PO_Approval_Milestones__c( | |
Approval_Status__c = pi.Status, | |
Approval_Name__c = 'Approval #' + aNum, | |
Purchase_Order__c = pi.TargetObjectId, | |
Approver__c = pih.ActorId, | |
Submitted_By__c = pih.OriginalActorId, | |
ProcessNodeId__c = pih.ProcessNodeId, | |
ProcessInstanceId__c = pih.ProcessInstanceId, | |
Comments__c = pih.Comments, | |
Update_Key__c = orderMap.get(pi.TargetObjectId).Update_Key__c, | |
Key__c = pKey, | |
Type__c = 'Approval' | |
); | |
if(pi.Status == 'Removed'){ | |
updatePOAM.Approval_Status__c = 'Recalled'; | |
} | |
poMAP.put(pKey, updatePOAM); | |
} | |
} | |
for(ProcessInstanceNode pin : pi.Nodes){ | |
//Long bizDays = BusinessHours.diff(bh.id, Start__c, Completed__c); | |
//system.debug('Nodes: ' + pin); | |
pKey = pin.ProcessInstanceId + '-' + pin.ProcessNodeId; | |
if(poMAP.containsKey(pKey)){ | |
updatePOAM = poMAP.get(pKey); | |
updatePOAM.Step_Name__c = pin.ProcessNodeName; | |
if(pin.NodeStatus == 'Removed'){ | |
updatePOAM.Step_Status__c = 'Recalled'; | |
} | |
else{ | |
updatePOAM.Step_Status__c = pin.NodeStatus; | |
} | |
updatePOAM.Completed__c = pin.CompletedDate; | |
updatePOAM.Start__c = pin.CreatedDate; | |
system.debug('bizDays: ' + bizDays); | |
if(bizDays >= 2 && orderMap.containsKey(pi.TargetObjectId) && orderMap.get(pi.TargetObjectId).Reason_for_Delay__c != NULL){ | |
string rfd = orderMap.get(pi.TargetObjectId).Reason_for_Delay__c; | |
rfd = rfd.left(255); | |
if(updatePOAM.Reason_for_Delay__c != NULL){ | |
updatePOAM.Reason_for_Delay__c = rfd; | |
} | |
} | |
poMAP.put(pKey, updatePOAM); | |
} | |
else{ | |
system.debug('Ooops - Missing #2'); | |
} | |
} | |
} | |
for(ProcessInstanceNode pi : [SELECT id, ProcessNodeName, CreatedDate, ProcessInstance.TargetObjectId, | |
ProcessNode.DeveloperName, ProcessNode.Name | |
FROM ProcessInstanceNode | |
WHERE ProcessInstance.TargetObjectId = :newTrigger | |
ORDER BY CreatedDate]) | |
{ | |
piMap.put(pi.ProcessInstance.TargetObjectId, pi); | |
} | |
for(Purchase_Order__c po : poList){ | |
// Legacy Code Re-written | |
if(po.Approval_Status__c != 'Approved' && piMap.containsKey(po.Id)){ | |
stepName = piMap.get(po.Id).ProcessNode.Name; // Setting to variable since we use this over and over again. | |
if( | |
po.Approval_Status__c.containsIgnoreCase('New') || | |
po.Approval_Status__c.containsIgnoreCase('Cancelled') || | |
po.Approval_Status__c.containsIgnoreCase('Rejected') || | |
po.Approval_Status__c.containsIgnoreCase('Recalled') | |
){ | |
System.debug('*** New, Cancelled ***'); | |
po.Current_Approval_Step__c = ''; | |
} | |
else{ | |
po.Current_Approval_Step__c = stepName; | |
po.Start_Date_Current_Approval_Step__c = piMap.get(po.Id).CreatedDate; | |
} | |
System.debug('*** po.Current_Approval_Step__c *** ' + po.Current_Approval_Step__c); | |
// Legacy Dates | |
if(stepName.containsIgnoreCase('DOC Control')){ | |
System.debug('*** DOC Control ***'); | |
po.Doc_Control_Start_Date__c = piMap.get(po.Id).CreatedDate; | |
} | |
else if(stepName.containsIgnoreCase('Planning')){ | |
System.debug('*** Planning ***'); | |
po.Planning_Start_Date__c = piMap.get(po.Id).CreatedDate; | |
} | |
else if(stepName.containsIgnoreCase('TSM')){ | |
System.debug('*** TSM ***'); | |
po.TSM_Revision_Start_Date__c = piMap.get(po.Id).CreatedDate; | |
} | |
updPos.add(po); | |
}//END If | |
}//END of FOR loop | |
// Update Purchase Orders | |
if(updPos.size() > 0){ | |
update updPos; | |
} | |
else{ | |
for(Id i : newTrigger){ | |
Purchase_Order__c po = new Purchase_Order__c( | |
Id = i, | |
Update_Status_Text__c = 'Ok' | |
); | |
updPos.add(po); | |
} | |
update updPos; | |
} | |
// Upsert PO Milestones | |
system.debug('poMap: ' + poMAP); | |
if(poMAP.size() > 0){ | |
poamList.addAll(poMAP.values()); | |
upsert poamList; | |
} | |
} // End Method | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment