You need to sign in to do that
Don't have an account?
tgk1
Apex trigger on Task
Hi everyone-
I believe I'm coming pretty close to finalizing my apex code. Unfortunately I'm getting a compile error and could use some help. I have included comments within the code to show exactly what I'm trying to accomplish. Can somebody please take a look and see what modifications need to be made?
trigger LastSWDate on Task (before insert, before update) { //To do - If the subject of a completed task contains "SW", put the date of the completed task in the //the "Last_SW_Activity__c" field on the account object //Create a set of related account ID's Set <ID> acctIDs = new Set <ID> (); //For every task, add it's related to account ID to the set for (Task t: Trigger.new){ acctIDs.add(t.accountID); //Create a map to match the task related to ID's with their corresponding account ID's Map<ID, Account> acctMap = new Map<ID, Account> ([Select ID, Last_SW_Activity__c from Account where ID in :acctIDs]); //Create the account object Account acctRec = acctMap.get(t.accountID); //If the account ID isn't null, the subject line starts with "sw", and the task has been marked as completed If (t.accountID =!null && t.subject.indexOf('sw') && t.Status == 'Completed') //Check to see if the Last_SW_Activity__c field is current compared with the latest completed activity If (acctMap.get.(t.accountID).Last_SW_Activity__c < t.endDateTime || acctMap.get(t.accountID).Last_SW_Activity ==null){ //Update the Last_SW_Activity__c field on the account object with the task's end date acctrec.Last_SW_Activity__c = t.endDatetime; } } }
The error I'm getting states "Invalid field endDatetime for SObject Task". It's refering to the last line of code. Does anybody have any idea why it's giving me that error?
t.accountID =!null in your code should be
t.accountID!=null
you had the ! and the = switched.
All Answers
Can you please verify in the Task schema, Task is not having field "endDatetime", is this custom field your reffering in your object ? , If not filed name should be change. I guess it may be "LastModifiedDate".
what do you mean by Task end date???
FYI,
Select t.SystemModstamp, t.Status, t.LastModifiedDate, t.ActivityDate From Task t
The task object, as far as I can tell, does not have a field called endDatetime. An Event has endDatetime, but not an activity. See below for more information on the available fields for a task.
http://www.salesforce.com/us/developer/docs/api/index_Left.htm#CSHID=sforce_api_objects_event.htm|StartTopic=Content%2Fsforce_api_objects_event.htm|SkinName=webhelp
Oops! Sorry about the double post!
Thanks for the help guys. I did modify the code from an event trigger, so that makes sense that endDateTime isn't being referenced on the task object. Here's the code I have now, and I'm getting an error message: "Initial term of field expression must be a concrete Sobject: Map <ID, Account>
I'm essentially trying to do the following:
I have a field on the account object called "Last SW Activity", and it's a date field.
I want the apex trigger to look at the tasks associated with an account record, and pull the date of the last completed task - and put it into the "Last SW Activity" field.
Is that error on the same line or a different one?
Sorry- the error is on this line:
If (acctMap.get.(t.accountID).Last_SW_Activity__c < t.LastModifiedDate || acctMap.get(t.accountID).Last_SW_Activity ==null){
without looking to much in details on your code i noticed a typpo
acctMap.get.(t.accountID).Last_SW_Activity__c
should be: acctMap.get(t.accountID).Last_SW_Activity__c
further more you should be able to use activitydatetime on task which is the "due date" of the task if i remeber right
If (acctMap.get.(t.accountID).Last_SW_Activity__c < t.LastModifiedDate || acctMap.get(t.accountID).Last_SW_Activity ==null){
Has one too many .'s
This:
acctMap.get.(t.accountID).Last_SW_Activity__c < t.LastModifiedDate
Should be:
acctMap.get(t.accountID).Last_SW_Activity__c < t.LastModifiedDate
I made the extra dot big so I could be sure you saw the difference as it took me a minute to find it.
try like this.
If this is not, then DateTime.valueOf((acctMap.get.(t.accountID)).Last_SW_Activity__c) < DateTime.valueOf(t.LastModifiedDate) do like this.
So close yet so far- I made the modification to the last line, now I'm getting a compile error on this line:
If (t.accountID =!null && t.subject.indexOf('sw') && t.Status == 'Completed')
The error is "The AND operator can only be used with boolean expressions". Since the condition of the if statement is boolean why would it be giving me this error?
t.subject.indexOf('sw') does not appear to be a boolean expression. You need something like t.subject.indexOf('sw') == aValue because indexOf returns an integer
try with this now.
Really appreciate everyones effort on this. Seems to be the never ending saga with this:
My own I tried that out but it's still giving me errors on the line that you wrote stating that the AND and NOT operators can only be used for boolean expressions.
See my reply above. This (t.subject.indexOf('sw')) is still not a boolean expression. It returns an integer not a TRUE or FALSE. I am not sure what you are trying to check with it, but I am guessing that 'sw' appears in the same place in every subject that you want, so you would need (t.subject.indexOf('sw')) == 4 or whatever number that place would be.
Oh okay I see what you're referring to. How could I change that statement so it would be - task subject starts with 'sw'
If ((t.accountID =!null) && (t.subject.indexOf('sw')>0) && (t.Status == 'Completed'))
(t.subject.indexOf('sw') == 0)
That should do the trick because the first index is always 0
My Own
(t.subject.indexOf('sw') > 0) would give you tasks that contain 'sw' but not at the begining.
So close....
Jake I updated it with your code, but now it's giving me a similar error for the =! operator for the account ID. Is there a way to convert it to an integer and state that if it's greater > 0 ? Or do you think there's a better way?
Its telling you that (t.accountID != NULL) is not a boolean expression?
Exactly - that's the same error it's giving me
If you take that block out of your code temporarily, will it compile, cause that should work.
I took that chunk of code out and it did compile. Unfortunately it's not working - it's not updating the Last SW Activity date field on the account object.
OK two things:
t.accountID =!null in your code should be
t.accountID!=null
you had the ! and the = switched.
You are the man! Thanks so much to everyone for their help.
Here is the working code for inquiring minds:
Jake can you let me know where I should add the additional code so it doesn't throw exceptions? Also I'm not 100% sure how I can do the test class for this one so the code is covered. I don't want to ask too much of you though, you've been a huge help.
OK, I've cleaned up the code a bit, I will explain below. This is just the for loop and right after:
I have made three main changes:
1. You had 2 if statements one after the other and I combined them into one. You can leave it the way you had it and it should work, but this looks a little cleaner and can be easier to read.
2. I moved this check: if(t.accountID != NULL), to the top of the for loop. Essentially, if there is no associated account we are just ignoring the rest of the code in that iteration of the loop.
3. I moved update acctRec outside of the for loop. When you call Update (or insert, or delete for that matter) on a collection, in this case a map, it will update all the records in that collection. So you were updating every account each iteration. This will let you run into governor limits with bulk processing. So now, you will be just changing all the records in your for loop and then updating them all once, at the same time.
As for the test, here is the logic it should follow:
1. Create and insert an account
2. Create and insert a task associating it with the account.
3. Query the Account from the database, this should give you the updated value in Last_SW_Activity__c
4. Do the same for the task
5. Use system.assertEquals or similar to check and see if the task that you queryed has the same value in lastmodifieddate as the account does in Last_SW_Activity__c.
That will give you the test coverage that you need, but to be through you should check two more cases with similar logic:
1. Insert 200 tasks instead of one - will check for bulk inserts/updates
2. Insert a task that is not associated with an account and make sure an exception is not thrown.
Although these tests are not necessary to get the code working, they may serve you well later by ensuring that your code can not be broken by a later update.
1. The error message "Invalid field endDatetime for SObject Task" is occurring because you have a typo in the variable name. It should be `t.endDateTime` (with a capital 'D'), not `t.endDatetime`. So, update the last line like this:
```apex
acctRec.Last_SW_Activity__c = t.endDateTime;
```
2. The if statement for checking if the subject of the task contains 'sw' has an issue. You should use the `contains()` method to check if the subject contains 'sw'. Also, you need to make sure it's a completed task before proceeding. Update this part as follows:
```apex
if (t.AccountId != null && t.Subject != null && t.Subject.toLowerCase().contains('sw') && t.Status == 'Completed') {
```
3. The creation of `acctMap` and `acctRec` should be moved outside of the loop for efficiency. You can create the map and get the account records before the loop. I am also facing this problem in my Jobs in pakistan today (http://www.pakistanjobslatest.pk) wordpress site
Here's an updated version of your code:
```apex
trigger LastSWDate on Task (before insert, before update) {
// Create a set of related account IDs
Set<ID> acctIDs = new Set<ID>();
// For every task, add its related account ID to the set
for (Task t : Trigger.new) {
acctIDs.add(t.AccountId);
}
// Create a map to match the task related to IDs with their corresponding account IDs
Map<ID, Account> acctMap = new Map<ID, Account>([SELECT ID, Last_SW_Activity__c FROM Account WHERE ID IN :acctIDs]);
for (Task t : Trigger.new) {
if (t.AccountId != null && t.Subject != null && t.Subject.toLowerCase().contains('sw') && t.Status == 'Completed') {
// Get the account record from the map
Account acctRec = acctMap.get(t.AccountId);
// Check if the Last_SW_Activity__c field is current compared with the latest completed activity
if (acctRec.Last_SW_Activity__c < t.endDateTime || acctRec.Last_SW_Activity__c == null) {
// Update the Last_SW_Activity__c field on the account object with the task's end date
acctRec.Last_SW_Activity__c = t.endDateTime;
}
}
}
}
```
Make sure to use the corrected variable names, check for null values, and use the `toLowerCase()` method to make the 'sw' check case-insensitive. This code should help you avoid the compile error and correctly update the Last_SW_Activity__c field on the account object.