The trigger code is having lot of redundancy, So I modified it.
before posting the modified code few lines of explanation what I changed.
you collected account Ids twice and did the condition check twice where once is more enough. I am also made changes to the test class, where Task data is provided which is not required because the trigger has to create it once the necessary conditions are met.
I am expecting this trigger should work for you, if there is any errors feel free to post as a comment.
trigger OpportunityAfter on Opportunity (after update){
Set AccountIDs = new Set();
for(Opportunity o : trigger.new){
if(opp.StageName == 'Closed - Lost' && opp.Business_Line__c == 'Workforce' &&
opp.Survey_Type__c != 'APulse' && trigger.oldMap.get(opp.Id).StageName != opp.StageName){
AccountIDs.add(o.AccountId);
}
}
Task[] tasksToInsert = new Task[]{};
for (Account acc : [Select Id, Name, OwnerId from Account where Id IN :AccountIds]){
for (Opportunity opp : trigger.new){
if(opp.AccountId == acc.Id){
Task tas = new Task();
tas.WhatId=acc.Id;
tas.OwnerId=opp.OwnerId;
tas.Subject='Follow-up: ' + opp.name + ' - ' + acc.name;
tas.ActivityDate=(opp.CloseDate + 180);
tas.Description='Follow up to see how engagement initiatives are going and if Avatar can help. Refer to lost opportunity: ' + opp.name;
tasksToInsert.add(tas);
}
}
}
if(tasksToInsert != null && !tasksToInsert.isEmpty())
Database.insert(tasksToInsert);
}
@isTest
public class TestClass {
static testMethod void myUnitTest() {
//Set up user
User u1 = [SELECT Id FROM User WHERE Email='abc@sampleemail.com'];
test.startTest();
//Run As U1
System.RunAs(u1){
System.debug('Testing trigger... (single record validation)');
//NEW Account record
Account acc = new account();
acc.Name = 'Test Account';
acc.Industry = 'Healthcare';
insert acc;
//NEW Opportunity record
Opportunity opp = new Opportunity();
opp.Name = 'Test Opportunity';
opp.CloseDate = System.today();
opp.StageName = 'S1 - Investigative';
opp.Type = 'Repeat Business - Wrkforce HC';
opp.AccountId = acc.Id;
opp.Survey_Type__c = 'Product Name';
insert opp;
opp.StageName = 'Closed - Lost';
opp.Reason_Won_Lost__c = 'Relationship';
opp.Business_Line__c = 'Workforce' //added this line to meet the if condition while collecting the set of id in the trigger.
update opp;
test.stopTest();
// Here I am expecting the task has been inserted and doing a query for it and check it in the assert statement.
Task testTask=[Select Id, WhatId from Task where WhatId=:acc.Id];
//Validate single insert
System.assertEquals(acc.Id, testTask.WhatId);
}
}
}
I have a similar problem getting the same error message as described above, first let me explain my case:
I have a visual force page with an extension "without sharing" that list cases that the current logged in customer community user has not access to.
I use a apex:dataTable with this column:
<apex:column>
<apex:commandLink value="{!c.CaseNumber}" action="{!SetCaseSharing}">
<apex:param name="setCaseSharing" value="{!c.Id}" assignTo="{!caseIdSelected}"/>
</apex:commandLink>
</apex:column>
When the user selects a case clicking on the commandLink this method runs (a bit simplified):
public Id caseIdSelected {get; set;}
public SetCaseSharing()
{
Case c = [SELECT Id FROM Case WHERE Id = :caseIdSelected];
CaseShare caseShare = new CaseShare();
caseShare.CaseId = c.Id;
caseShare.UserOrGroupId = UserInfo.getUserId();
caseShare.RowCause = 'Manual';
caseShare.CaseAccessLevel = 'Edit';
upsert(caseShare);
}
I know about the limitation that the current record owner cannot be added using manual apex sharing, and you cannot limit the access granted using sharing rules only add permission. These issues are not the problem in my case.
When logging in as a customer commmunity user using "Manage External Users" and then select a case from the list the problem occurs.
My code worked perfectly however when logging into the community as an administrator or "normal" user (instead of customer community user) and then adding a "normal" user (not a customer community user) to the manual sharing.
PROBLEM 1
I was not allowed to set manual sharing to a customer community user, even logged in as administrator, returning:
Upsert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: unknown (invalid user or group: 00511000002Hgs3): [unknown]
I guess the first problem might be solved using the more expensive "partner community license" or "customer community plus license" instead of "customer community license".
PROBLEM 2
I was not allowed to set manual sharing to a "normal" user when logged in as a customer community user, returning:
Upsert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []
Not sure if it is possible to add sharing rules from the community when the logged in user is a customer community user not having access to the case in the first place. Moving this to a trigger or a scheduled job running separate from the community might solve it.
Best Answer
Your trigger is a Before Insert/Update. Try:
trigger DoNotDeleteAccountHavingRelatedContact on Account (before delete)
And do replace
Trigger.new
withTrigger.old
** UPDATE **
Another commenter raised the issue that there was also a code problem. Please find an updated sample below