I want to run a trigger on Contact if a checkbox on Contact object goes from unchecked state to checked state and then do some processing on the records. I have this trigger on after insert and after update. The code works fine for update but if I check the box while creating a new contact record, the trigger does not detect the below condition in the code and therefore sends an empty list to contactTriggerHandler class.
if (Trigger.oldMap.get(con.Id).checkbox==false && con.checkbox== true)
trigger Contact on Contact (after update, after insert) {
List<Contact> listofContacts = new List<Contact>();
List<Contact> usersToCreate= new List<Contact>();
if (Trigger.isAfter) {
if(trigger.isInsert){
System.debug('After insert');
if(RecursiveTriggerHandler.isFirstTime){
RecursiveTriggerHandler.isFirstTime = false;
for (Contact con : Trigger.new) {
Contact contacttoUpdate = con.clone(true,true);
contacttoupdate.Nickname__c=contacttoUpdate.firstname;
listofContacts.add(contacttoUpdate);
}
System.debug(listofContacts);
ContactTriggerHandler.AfterInsert(listofContacts);
update listofContacts;
}
}
else if(trigger.isUpdate){
System.debug('After insert and update function');
if(RecursiveTriggerHandler.isFirstTime){
RecursiveTriggerHandler.isFirstTime = false;
for (Contact con : Trigger.new) {
Contact contacttoUpdate = con.clone(true,true);
contacttoupdate.Nickname__c=contacttoUpdate.firstname;
listofContacts.add(contacttoUpdate);
if (Trigger.oldMap.get(con.Id).checkbox==false && con.checkbox== true) {
usersToCreate.add(contacttoUpdate);
}
}
ContactTriggerHandler.AfterInsert(usersToCreate);
update listofContacts;
}
}
}
}
Here is the recursive handler class:
public class RecursiveTriggerHandler{
public static Boolean isFirstTime = true;
}
Related
I am converting a custom List JS button to support lighting. So, I've made changes to existing class and created a VF page and added that to the list view button. But when I run the functionality nothing seems to happen and debug logs returned Id as 000000.. Pls suggest.
global class AddUserToTeam{
public Opportunity objOpp;
global AddUserToTeam(ApexPages.StandardSetController stdcontroller) {
objOpp = (Opportunity)stdController.getRecord();
system.debug(objOpp );
}
public pagereference addTeam(){
List<Id> opportunityIds = new List<Id>();
opportunityIds.add(objOpp.Id);
system.debug('oppid'+ opportunityIds);
addTeamMember(opportunityIds);
//return new pagereference(url.getsalesforcebaseurl().toexternalform()+'/'+objOpp.Id);
return new PageReference('/006/o');
}
webservice static boolean addTeamMember(List<Id> opptyIds)
{
// some logic to add a user to teams
}
VF
<apex:page standardController="Opportunity" recordSetVar="Opportunities" extensions="AddUserToTeam" action="{!addTeam}">
</apex:page>
[enter image description here][1]
[1]: https://i.stack.imgur.com/2V3vp.png
I fixed the issue, check the below code
global class AddUserToTeam{
public Opportunity objOpp;
public String accIds{get;set;}
global AddUserToTeam(ApexPages.StandardSetController stdcontroller) {
System.debug('Get Selected');
objOpp = stdcontroller.getSelected();
accIds = '';
for(Opportunity acc : objOpp){
accIds += acc.Id + ',';
System.debug('Opp ID : '+accIds);
}
accIds = accIds.removeEnd(',');
}
}
public pagereference addTeam(){
List<Id> opportunityIds = new List<Id>();
opportunityIds.add(accIds );
system.debug('oppid'+ opportunityIds);
addTeamMember(opportunityIds);
return new pagereference(url.getsalesforcebaseurl().toexternalform()+'/'+accIds );
//return new PageReference('/006/o');
}
webservice static boolean addTeamMember(List<Id> opptyIds)
{
// some logic to add a user to teams
}
In Microsoft Dynamics 365, I want to delete an account record but prevent the deletion of any child contacts that are in an active state. Contacts in inactive state should be deleted as normal. How can I achieve this using a plugin?
Unfortunately, Dynamics does not allow us to change the Cascading Delete in the Account to Contact 1-N relationship, which means that every time you delete an Account all the Contacts related to it will be deleted. This relationship cannot be deleted as well.
EDIT: Register the plugin below as a PreValidation Delete and it will work (Credit to #Sxntk for the idea of disassociating child records)
public class AccountPreDeletePlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
var pluginExecutionContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var organizationServiceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var organizationService = organizationServiceFactory.CreateOrganizationService(pluginExecutionContext.UserId);
if (pluginExecutionContext.InputParameters.Contains("Target") && pluginExecutionContext.InputParameters["Target"] is EntityReference entityReference)
{
var query = new QueryExpression("contact") { NoLock = true };
query.Criteria.AddCondition("parentcustomerid", ConditionOperator.Equal, entityReference.Id);
query.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0);
var entityCollection = organizationService.RetrieveMultiple(query);
if (entityCollection?.Entities?.Count > 0)
{
foreach (var entity in entityCollection.Entities)
{
entity["parentcustomerid"] = null;
organizationService.Update(entity);
}
}
}
}
}
I've been going nuts over this. Nothing in my IF loop is firing through my test class and I cannot figure out why. I have done a lot of reading online and it appears that I am doing things correctly but it still hasn't solved my code coverage. This is the last line that runs:
If (isWithin == True){
after that I can't get anything to run within that IF loop, I have reversed the logic and it still doesn't run. I feel like I will kick myself when someone points it out but here is my code:
trigger caseCreatedDurringBusinessHours on Case (after insert) {
//Create list and map for cases
List<case> casesToUpdate = new List<case>();
Map<Id, case> caseMap = new Map<Id, case>();
// Get the default business hours
BusinessHours bh = [SELECT Id FROM BusinessHours WHERE IsDefault=true];
// Create Datetime on for now in the local timezone.
Datetime targetTime =System.now();
// Find whether the time now is within the default business hours
Boolean isWithin;
if ( Test.isRunningTest() ){
Boolean isWithin = True;
}
else{
Boolean isWithin = BusinessHours.isWithin(bh.id, targetTime);
}
// Update cases being inserted if during business hours
If (isWithin == True){
// Add cases to map if not null
For(case newcase : trigger.new) {
if(newcase.id != null){
caseMap.put(newcase.Id, newcase);
}
}
// Check that cases are in the map before SOQL query and update
If(caseMap.size() > 0){
// Query cases
casesToUpdate = [SELECT Id, Created_During_Business_Hours__c FROM case WHERE Id IN: caseMap.keySet()];
// Assign new value for checkbox field
for (case c: casesToUpdate){
c.Created_During_Business_Hours__c = TRUE;
}
// if the list of cases isnt empty, update them
if (casesToUpdate.size() > 0)
{
update casesToUpdate;
}
}
}
}
and here is my test class:
#isTest
private class BusinessHoursTest {
#isTest static void createCaseNotInBusinessHours() {
case c = new case();
c.subject = 'Test Subject';
insert c;
}
}
I think you can just copy the main logic to the apex class and just call the method of apex class from the apex trigger.
So it will make it more easy to write the test class.
Let me know if you need more help in this.
I'm sure you've figured this out by now but this block of code is re-defining the isWithin variable inside of the if/else blocks:
Boolean isWithin;
if (Test.isRunningTest()) {
Boolean isWithin = True;
} else {
Boolean isWithin = BusinessHours.isWithin(bh.id, targetTime);
}
That needs to be:
Boolean isWithin;
if (Test.isRunningTest()) {
isWithin = True;
} else {
isWithin = BusinessHours.isWithin(bh.id, targetTime);
}
Or rather a ternary operator for the cleanest code:
Boolean isWithin = !Test.isRunningTest() ? BusinessHours.isWithin(bh.id, targetTime) : true;
I am passing all test coverage in salesforce apex in sandbox but in deploying to live getting the
error in subject, i dont know how to handle it.
my test class code is:
#isTest(SeeAllData=true)
public class myLeadTest{
public static testMethod void testMyController5() {
Account acc= new Account(name='test');
acc.Order__c='wee';
insert acc;
Campaign camp = new Campaign(Name='test');
insert camp;
Company__c cm= new Company__c();
cm.Company_Id__c=12;
cm.Name='234';
cm.Account__c=acc.id;
insert cm;
Lead l= new Lead();
l.Campaign__c=camp.Id;
l.LastName='test';
l.Company='cmpny';
l.Company_Id__c=cm.Company_Id__c;
l.Email='test#yahoo.com';
l.Status='Closed - Converted';
l.Order__c=acc.Order__c;
// l.Auto_Convert__c=true;
// l.IsConverted=false;
//l.ConvertedAccountId=acc.Id;
Lead[] l2= new Lead[]{l};
insert l2;
Opportunity op= new Opportunity ();
op.StageName='Won (Agency)';
op.Name='test';
op.CloseDate=Date.valueOf('2015-04-28');
op.AccountId=acc.id;
op.LeadSource='web';
op.StageName= 'Won (Agency)';
op.CampaignId=camp.id;
op.TrialStart__c=Date.valueOf('2012-04-28');
insert op;
Contact cnt= new Contact();
cnt.LastName='test';
cnt.AccountId=acc.id;
cnt.ASEO_Company_Id__c=12;
cnt.Email=l.Email;
cnt.Company__c=cm.id;
insert cnt;
///////////////
/* Lead l5= new Lead();
l5.Campaign__c=camp.Id;
l5.LastName='test';
l5.Company='cmpny';
l5.Company_Id__c=12;
l5.Email='test#yahoo.com';
l5.Status='Closed-Converted';
l5.isConverted=false;
//l.ConvertedAccountId=acc.Id;
insert l5; */
Contact cnt1= new Contact();
cnt1.LastName='test';
cnt1.AccountId=acc.id;
cnt1.ASEO_Company_Id__c=12;
cnt1.Email=l.Email;
insert cnt1;
Database.LeadConvert leadConvert = new Database.LeadConvert();
leadConvert.setLeadId(l2[0].Id);
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
leadConvert.setConvertedStatus(convertStatus.MasterLabel);
leadConvert.setOpportunityName(op.Name);
leadConvert.setConvertedStatus('Closed - Converted');
Database.LeadConvertResult lcResult = Database.ConvertLead(leadConvert);
// MyLead.addCampaign(l2[0], camp.Name);
// MyLead.updateOpportunity(l2[0], lcResult);
// MyLead.updateContact( l2[0], lcResult, cm) ;
// myLead.addCampaignMembers(l2);
}
}
and class code which i call in trigger :
public class MyLead {
public static void convertLead(Lead[] leads) {
Database.LeadConvert leadConvert = new Database.LeadConvert();
for (Lead lead :leads) {
if (!(lead.IsConverted)) {
// Check if an account exists with email. Attach Contact and Account, convert Lead.
Contact[] myContacts = [SELECT Id, AccountId FROM Contact WHERE Email = :lead.Email Limit 1];
if (myContacts.size() == 1) {
System.debug('Existing Contact');
MyLead.attachExistingConvert(lead, myContacts[0]);
}
else {
System.debug('No existing contact');
if (lead.Auto_Convert__c) {
MyLead.addCampaign(lead, lead.Campaign__c);
leadConvert.setLeadId(lead.Id);
leadConvert.setConvertedStatus('Closed - Converted');
Database.LeadConvertResult lcResult = Database.ConvertLead(leadConvert);
// Populate the newly created records with extra data.
MyLead.updateOpportunity(lead, lcResult);
Company__c myCompany = [SELECT Id FROM Company__c WHERE Company_Id__c = :lead.Company_Id__c];
MyLead.updateContact(lead, lcResult, myCompany);
// Must update the Company before Account otherwise the Account lookup will fail.
MyLead.updateCompany(lead, lcResult, myCompany);
MyLead.updateAccount(lead, lcResult, myCompany);
}
}
}
}
}
// Attaches Lead to Contact and Account if matched by Email, converts Lead and creates opportunity if it doesn't exist.
public static void attachExistingConvert(Lead lead, Contact contact) {
MyLead.addCampaign(lead, lead.Campaign__c);
Database.leadConvert leadConvert = new Database.LeadConvert();
leadConvert.setLeadId(lead.Id);
leadConvert.setConvertedStatus('Closed - Converted');
leadConvert.setContactId(contact.Id);
leadConvert.setAccountId(contact.AccountId);
leadConvert.setSendNotificationEmail(True);
// Do not create an opportunity if any exist.
Opportunity[] myOpportunity = [SELECT Id FROM Opportunity WHERE AccountId = :contact.AccountId];
if (myOpportunity.size() > 0) {
leadConvert.setDoNotCreateOpportunity(True);
}
leadConvert.setLeadId(lead.Id);
Database.LeadConvertResult leadConvertResult = Database.convertLead(leadConvert);
// If we created an opportunity, update it with extra stuff.
if (leadConvert.isDoNotCreateOpportunity() == False) {
MyLead.updateOpportunity(lead, leadConvertResult);
}
}
// Updates the newly created Opportunity with extra data
public static void updateOpportunity(Lead lead, Database.LeadConvertResult lcResult) {
Opportunity myOpportunity = [SELECT Id, StageName FROM Opportunity WHERE Id = :lcResult.opportunityId];
myOpportunity.Name = 'Online Upgrade';
myOpportunity.TrialStart__c = lead.CreatedDate.date();
//myOpportunity.Amount = lead.Monthly_Revenue__c;
myOpportunity.Amount = lead.Amount__c;
myOpportunity.Type = 'New Business';
myOpportunity.LeadSource = 'Website';
myOpportunity.Order__c = lead.Order__c;
DateTime dt = System.now();
Date d = dt.date();
myOpportunity.CloseDate = d;
myOpportunity.StageName = lead.Agency__c ? 'Won (Agency)' : 'Won (End User)';
myOpportunity.Probability = 100;
update myOpportunity;
}
// Updates the newly created Account with extra data
public static void updateAccount(Lead lead, Database.LeadConvertResult lcResult, Company__c myCompany) {
Account myAccount = [SELECT Id FROM Account WHERE Id = :lcResult.accountId];
myAccount.Type = 'Customer';
myAccount.ASEO_Company_Id__c = lead.Company_Id__c;
myAccount.Company__c = myCompany.Id; // Setting the company will cause the company account lookup to fail
myAccount.Order__c = lead.Order__c;
update myAccount;
}
// Updates the newly created Contact with extra data
public static void updateContact(Lead lead, Database.LeadConvertResult lcResult, Company__c myCompany) {
Contact myContact = [SELECT Id FROM Contact WHERE Id = :lcResult.contactId];
myContact.ASEO_Company_Id__c = lead.Company_Id__c;
myContact.Company__c = myCompany.Id;
update myContact;
}
// Updates the Company with extra data
public static void updateCompany(Lead lead, Database.LeadConvertResult lcResult, Company__c myCompany) {
myCompany.Account__c = lcResult.accountId;
update myCompany;
}
// Adds a lead to a campaign
public static void addCampaign(Lead lead, String campaign) {
Campaign[] myCampaigns = [Select Id FROM Campaign WHERE Name = :campaign LIMIT 1];
if (myCampaigns.size() == 1) {
CampaignMember campaignMember = new CampaignMember (campaignId=myCampaigns[0].Id, leadId=lead.Id);
insert campaignMember;
}
}
// Create campaign members from leads. Campaign comes from lead.Campaign__c.
public static void addCampaignMembers(Lead[] leads) {
for (Lead lead :leads) {
// Might want to query Campaigns table instead.
//Set<String> campaigns = new Set<String>();
//campaigns.add('Freemium');
Campaign[] myCampaigns = [SELECT Id FROM Campaign WHERE Name = :lead.Campaign__c LIMIT 1];
//if (campaigns.contains(lead.Campaign__c)) {
if (myCampaigns.size() == 1) {
MyLead.addCampaign(lead, lead.Campaign__c);
}
}
}
}
and my lead trigger is:
trigger LeadTrigger on Lead (after insert, after update) {
Lead[] leads = Trigger.new;
//MyLead.createOpportunity(leads);
MyLead.convertLead(leads);
Please any one can help me, i tries 25 times but in deploying to production give me error in the given subject, or any one give code coverage of this class, thank you in advance
Looks like the issue is based on a soql query that is not included in your code. You try to query a field called "Address" but this field doesn't exist. Address is still in beta...
Try to adjust your query and use the fields City, Street, Country and PostalCode.
You can learn more about sObject fields there: http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_lead.htm
Just in case someone else get to this question with this problem.
As Christian said, the code is trying to access the "Address" field from Lead in a SOQL query. Starting from API version 30, the compound fields are available to use in queries (http://www.salesforce.com/us/developer/docs/api/Content/compound_fields_address.htm).
So, if you run into this issue with a query in your code, check for the API version of the class and the visualforce page. Both must be 30 or greater.
I'm working on a trigger/test class and i can't figure out how to get the test class to work. I know that i need to update my opportunity to use the trigger but i'm not sure how to and then how to verify that my trigger is working.
Trigger:
trigger add_primary_advisor on Opportunity(before update) {
for(Opportunity o: Trigger.new){
if (o.IsClosed && !Trigger.oldMap.get(o.id).IsClosed) {
OpportunityContactRole contactRole =
[select ContactID from OpportunityContactRole where IsPrimary = true and OpportunityId = :o.id];
if (contactRole != null) {
o.Primary_Advisor__c=contactRole.ContactID;
}
}
}
}
Test class:
#isTest
private class primary_advisor_test {
static testMethod void primary_advisor(){
Opportunity opp = new Opportunity(Name='test opp', StageName='stage', Probability = 95, CloseDate=system.today());
insert opp;
update opp;
}
}
Before going into the solution for the test class I would like to point out the trigger is not builkified as you have a SOQL query inside you for loop which is not a best practice.
I am not aware of the exact functionality of the opportunityContactRole object, I am just assuming that it is a object which will hold the contact id and the opportunityID, more or less like a junction object.
#isTest
private class primary_advisor_test {
static testMethod void primary_advisor(){
//Create a contact that will be added to the opportunityCOntactRole.
contact con = new contact(name='testCon');// add all the required field as per your org settings
insert Con;
Opportunity opp = new Opportunity(Name='test opp', StageName='stage', Probability = 95, CloseDate=system.today());
insert opp;
//Create the opporunityContactRole.
opportunityCOntactRole oppCOn = new new opportunityCOntactRole(OpportunityId=opp.id, contactId= con.Id, isPrimary=true);
insert oppCon;
//update the opportunity so that it is closed and enters the if conditon in your trigger.
opp.stageName='Closed';
update opp;
}
}
The problem is you didn't changed any fields before calling update try this
opp.Probability = 90;
update opp;