function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
AnonTestQuestAnonTestQuest 

Trigger question on an object

I need to put a trigger on an a time off request object to pull all "future dated" time off requests (meaning all absence requests that have a future time off date and that have been entered PRIOR to the trigger running) and update the "department" field (on the same object) with the appropriate value for each worker. The department can be found on the user's Worker Record (another custom object). I'm not sure how to go about this. Any help is appreciated!
Best Answer chosen by AnonTestQuest
AnonTestQuestAnonTestQuest
Ok so this is my final code that solves this issue:
 
trigger futureAbsReq on Absence_Request__c (before insert, before update) {

List <Absence_Request__c> reqOff = trigger.new;

if (Trigger.isInsert) {

for (Absence_Request__c ar : reqOff) {
List <Worker__c> workerList = [Select Id, Department__c From VanaHCM__Worker__c 
										Where Id =: ar.Requested_By__c];
	for (Worker__c w : workerList) {

		if (w.Department__c != NULL) {
			ar.Department__c = w.Department__c;
			}
		}
	}
}
else if ( Trigger.isUpdate) {

for (Absence_Request__c ar : reqOff) {
List <Worker__c> workerList = [Select Id, Department__c From VanaHCM__Worker__c 
										Where Id =: ar.Requested_By__c];
	for (Worker__c w : workerList) {

		if (w.Department__c != NULL) {
			ar.Department__c = w.Department__c;
				}
			}
		}

	}
}

Thank you for your assistance!

All Answers

Krishna SambarajuKrishna Sambaraju
This doesn't look like a scenario for a trigger. It is better to create an apex job and schedule it.
AnonTestQuestAnonTestQuest
I was going to do a trigger to take care of all future requests that are input after today. There are only a few that exist now so I don't want to do a batch, I am going to manually update those.
Krishna SambarajuKrishna Sambaraju
Provided that the UserId and Department fields exisit on both TimeOff object and Worker object. Here is a sample code. Change the object names and field names accordingly.
 
trigger SetDepartmentOnFutureRequests on TimeOffRequest__c(before insert)
{
	List<Worker__c> workerList = [select User__c, Department__c from Worker__c];
	Map<Id, String> user2DeptMap = new Map<Id, String>();
	for (Worker__c w : workerList)
	{
		user2DeptMap.put(w.User__c, w.Department__c);
	}
	
	for (TimeOffRequest__c req : Trigger.new)
	{
		if (req.TimeOffRequestDate__c > System.today())
		{
			req.Department__c = user2DeptMap.get(req.User__c);
		}
	}
}
If the solution works for you, mark it as a best answer to help others.
 
AnonTestQuestAnonTestQuest
On the request off object there is a custom field (lookup field) to the worker object with a label 'worker' and I'm not sure what I would pull and use off the worker object for the query for User__c in this case.
AnonTestQuestAnonTestQuest
Should there be a matching API name on both objects that I use for that User__c?
Krishna SambarajuKrishna Sambaraju
Not necessary. You can use the ones that exist on the objects.For example the user field on the Worker object can be WorkUser__c. Change the field names as per your objects.
AnonTestQuestAnonTestQuest
I used this for my trigger and it works when a record is updated but does not work for new requests off. Should I change my before update to add in before insert as well? How would this change the code I have?
 
trigger futureAbsReq on Absence_Request__c (before update, before insert) {

List <Absence_Request__c> reqOff = trigger.new;

for (Absence_Request__c ar : reqOff) {
List <Worker__c> workerList = [Select Id, Department__c From Worker__c 
										Where Id =: ar.Requested_By__c];
	for (Worker__c w : workerList) {

		if (w.Department__c != NULL) {
			ar.Department__c = w.Department__c;
			}
		}
	}
}

 
AnonTestQuestAnonTestQuest
Ok so this is my final code that solves this issue:
 
trigger futureAbsReq on Absence_Request__c (before insert, before update) {

List <Absence_Request__c> reqOff = trigger.new;

if (Trigger.isInsert) {

for (Absence_Request__c ar : reqOff) {
List <Worker__c> workerList = [Select Id, Department__c From VanaHCM__Worker__c 
										Where Id =: ar.Requested_By__c];
	for (Worker__c w : workerList) {

		if (w.Department__c != NULL) {
			ar.Department__c = w.Department__c;
			}
		}
	}
}
else if ( Trigger.isUpdate) {

for (Absence_Request__c ar : reqOff) {
List <Worker__c> workerList = [Select Id, Department__c From VanaHCM__Worker__c 
										Where Id =: ar.Requested_By__c];
	for (Worker__c w : workerList) {

		if (w.Department__c != NULL) {
			ar.Department__c = w.Department__c;
				}
			}
		}

	}
}

Thank you for your assistance!
This was selected as the best answer
Krishna SambarajuKrishna Sambaraju
Using soql queries is not a good practice. Please find the update to the trigger as per data model in your code above.
 
trigger futureAbsReq on Absence_Request__c (before insert, before update) {
	Map <Id, VanaHCM__Worker__c> workerMap = new Map<Id, VanaHCM__Worker__c>([Select Id, Department__c From VanaHCM__Worker__c]);
	
	for (Absence_Request__c ar : reqOff) {
		if (workerMap.get(ar.Requested_By__c).Department__c != null) {
			ar.Department__c = workerMap.get(ar.Requested_By__c).Department__c;
		}
	}	
}

Do you have the lookup to VanaHCM__Worker__c object on the Absence_Request__c object. If it is then why don't you use the formula field on the Absence_Request__c object to get the Department from VanaHCM__Worker__c, instead of the trigger.
Krishna SambarajuKrishna Sambaraju
I mean, using soql queries in for loops is not a good practice and could reach the governor limits at some point. If the solution I have given helped can you mark it as a best answer.

Regards,
Krishna.