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
DevSFDevSF 

Apex Trigger to make a check box false, when other check box are true

Hello everyone,

I have 1 custom object (Dimensions__c) which has a lookup relationship with Account standard object (Dimensions__c is Child).

There is a chechbox on Dimension__c (Repayment_Enabled__c).

Now wehenever i create a dimension this check box is made true automatically.

What my need is that, there should be only one check box true on for a record related to account.
Even though there may be 5 dimension records which are related to 1 account but checkbox should be true for only 1 dimension record. 

I have tried this one, But struck.
As i am new to development Please help me.


trigger paymentcheck on Account (before insert,before update,after insert) {
List<Account> acct = new List<Account>();
    List<Dimensions__c> vwo = new List<Dimensions__c>();   // my custom object
    for(Account a : trigger.new){
       if(Repayment_Enabled__c[0] == 'true'){   // this is the check box field which needs to be true for only one record related account
            Repayment_Enabled__c[1] = false;
        }
            }

}
How to solve this one.
 
Lucian Mihai CiobanuLucian Mihai Ciobanu
Hi!
I presume you need to have checked the last inserted Dimension.

First of all, the trigger needs to be on the object that initiates the action. In this case, inserting a Dimension si the action, so the trigger needs to be on Dimension, not on Account. It should be AFTER INSERT, because inserting is the action and you are changing a field on other records than the ones in the trigger.

Now, in your trigger you need to set to false any Dimension related to the account that is true, different than what you have in your trigger now. So your trigger flow will look like this:
1. Go through all trigger.new and gather into a set all the account ids the dimensions are related to.
2. Query into the database all dimensions where account__c IN the set build above AND Id NOT IN trigger.new
3. With a for loop, go through all these records and set the value to false
4. Update the list of records above

Thank should be it.

Now, to dig deeper, if you also expect people to sometimes DELETE the last inserted Dimension, then things complicate. You need to update the trigger (in case of delete) to search for the previous Dimension and mark it back as true.

Also, if you update an older dimension and you need that one to become marked, it gets even more complicated.

Let me know your use case or if you need further help.
mritzimritzi
I am assuming that you want to keep the most recently updated/inserted Dimensions__c record to have checkbox=true & all other records to have checkbox = false.
trigger paymentcheck on Dimensions__c(after update,after insert) {
    // trigger on Dimensions__c object, not on Account
    // works only AFTER update & insert, so that we can have record's Id
    List<Dimensions__c> vwo = new List<Dimensions__c>();   // my custom object
    // Sets holding account ids (unique) and dimensions ids (unique) respectively
	Set<Id> accountIds = new Set<Id>();
	Set<Id> dimensionsIds = new Set<Id>();
    for(Dimensions__c d : trigger.new){
       if(d.Repayment_Enabled__c == true){
            // replace "lookupfieldApiName" with actual lookup field Api name
            accountIds.add(d.lookupFieldApiName);
			dimensionsIds.add(d.id);
        }
    }
    // get those records from Dimensions__c object that have their parent Account Id's record...
    // stored in accountIds and their id not present in dimensionsIds
	vwo = [SELECT id,Repayment_Enabled__c FROM Dimensions__c 
	      WHERE Repayment_Enabled__c=true AND lookupFieldApiName IN:accountId AND Id NOT IN:dimensionsIds];
	for(Dimensions__c d:vwo)
		d.Repayment_Enabled__c=false;
    update vwo;
}


Mark this as Best Answer, if this solves your problem.
DevSFDevSF
Thank you, Thanks a lot mritzi for your response. It Worked. :)
DevSFDevSF
Hi Mritzi,

There needs to b a change in the code (i.e., if the checkbox is true for the existing record, then for newely inserting record the checkbox should be false)

If already a record exists in account, then the new dimension which is added to account, its checkbox should be false.

Can you please make any required changes in the code that you have provided.



Thanks,
Devender
mritzimritzi
trigger paymentcheck on Dimensions__c(after update,after insert) {
    List<Dimensions__c> vwo = new List<Dimensions__c>();   // my custom object
    // Sets holding account ids (unique) and dimensions ids (unique) respectively
	Set<Id> accountIds = new Set<Id>();
	Set<Id> dimensionsIds = new Set<Id>();
    for(Dimensions__c d : trigger.new){
       if(d.Repayment_Enabled__c == true){
            // replace "lookupfieldApiName" with actual lookup field Api name
            accountIds.add(d.lookupFieldApiName);
			dimensionsIds.add(d.id);
        }
    }
    // get those records from Dimensions__c object that have their parent Account Id's record...
    // stored in accountIds and their id not present in dimensionsIds
	vwo = [SELECT id,Repayment_Enabled__c,lookupFieldApiName FROM Dimensions__c 
	      WHERE Repayment_Enabled__c=true AND lookupFieldApiName IN:accountId AND Id NOT IN:dimensionsIds];
	//map holding AccountId, Dimensions__c record pair
​    Map<Id,Dimensions__c> dimMap = new Map<Id,Dimensions__c>();
    for(Dimensions__c d:vwo){
		if(!dimMap.containskey(d.lookupFieldApiName))
			dimMap.put(d.lookupFieldApiName,d);
	}
	//loop through trigger data once again to set picklist values to false
	for(Dimensions__c d:trigger.new){
		if(dimMap.containskey(d.lookupFieldApiName))
			d.Repayment_Enabled__c = false;
	}
}

Mark this as Best Answer, if this solves your problem.
DevSFDevSF
Hi mirtzi,



I am getting this error when i try to add 2nd dimension to account using the latest code that u have provided. 


Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger paymentcheck caused an unexpected exception, contact your administrator: paymentcheck: execution of AfterUpdate caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Dimensions__c.Account__c: Trigger.paymentcheck: line 15, column 1.


Thanks,
mritzimritzi
This should work:
trigger paymentcheck on Dimensions__c(after update,after insert) {
    List<Dimensions__c> vwo = new List<Dimensions__c>();   // my custom object
    // Sets holding account ids (unique) and dimensions ids (unique) respectively
	Set<Id> accountIds = new Set<Id>();
	Set<Id> dimensionsIds = new Set<Id>();
    for(Dimensions__c d : trigger.new){
       if(d.Repayment_Enabled__c == true){
            accountIds.add(d.Account__c);
			// "Account__c" that's the lookup field api name, i think
			dimensionsIds.add(d.id);
        }
    }
    // get those records from Dimensions__c object that have their parent Account Id's record...
    // stored in accountIds and their id not present in dimensionsIds
	vwo = [SELECT id,Repayment_Enabled__c,Account__c FROM Dimensions__c 
	      WHERE Repayment_Enabled__c=true AND Account__c IN:accountIds AND Id NOT IN:dimensionsIds];
	//map holding AccountId, Dimensions__c record pair
​    Map<Id,Dimensions__c> dimMap = new Map<Id,Dimensions__c>();
    for(Dimensions__c d:vwo){
		if(!dimMap.containskey(d.Account__c))
			dimMap.put(d.Account__c,d);
	}
	//loop through trigger data once again to set picklist values to false
	for(Dimensions__c d:trigger.new){
		if(dimMap.containskey(d.Account__c))
			d.Repayment_Enabled__c = false;
	}
}

The error happened, because, you would have replaced lookupfieldApiName (line 15) with Dimensions__c.Account__c.

I have updated the trigger code with correct field api name that's Account__c.

Mark this as Best Answer, if this helps.
DevSFDevSF
Hi Mritzi,
 
I am sorry for the in-coinvenience, But still it is not solved.

I am getting this error while adding the second dimension to account.


Error :

Error:Apex trigger paymentcheck caused an unexpected exception, contact your administrator: paymentcheck: execution of AfterUpdate caused by: System.FinalException: Record is read-only: Trigger.paymentcheck: line 20, column 1


Thanks,
mritzimritzi
The code should work fine.

Problem that you are facing could potentially be due to insufficient field level access permission or object permissions.
You need to make sure that Users trying to create record have sufficient read/write access to all fields involved in this process.
Apart from that, I don't see any reason why this should not work.

Are you using the exact same code that i posted, or have you changed something??
If yes, post your code.

Few quick points:
i) Doing google search for the kind of error you get, always helps.
ii) you can always debug the code, simply by putting System.debug statements at relevant points and see the debug log looking for clues to solve the error.
DevSFDevSF
Hi Mritzi,

It is working if i give the DML as after insert and after update.

But the issue here is I also need to send an email to the Account record owner When he tries to add the new dimension.

I should include these things in mail.

1) Account Url for which all these dimensions belongs.

2) Dimension record url for which Repayment_Enabled__c == true

I need to send these 2 things as a mail to the record owner so that he can select the account and also the dimension which is already marked as true.


This is my code :


trigger paymentcheck on Dimensions__c(after update,after insert) {
    List<Dimensions__c> vwo = new List<Dimensions__c>();   // my custom object
    // Sets holding account ids (unique) and dimensions ids (unique) respectively
    Set<Id> accountIds = new Set<Id>();
    Set<Id> dimensionsIds = new Set<Id>();
    for(Dimensions__c d : trigger.new){
       if(d.Repayment_Enabled__c == true){
            accountIds.add(d.Account__c);
            // "Account__c" that's the lookup field api name, i think
            dimensionsIds.add(d.id);
        }
    }
    // get those records from Dimensions__c object that have their parent Account Id's record...
    // stored in accountIds and their id not present in dimensionsIds
    vwo = [SELECT id,Repayment_Enabled__c,Account__c FROM Dimensions__c 
          WHERE Repayment_Enabled__c=true AND Account__c IN:accountIds AND Id NOT IN:dimensionsIds];
    //map holding AccountId, Dimensions__c record pair
​    Map<Id,Dimensions__c> dimMap = new Map<Id,Dimensions__c>();
    for(Dimensions__c d:vwo){
        if(!dimMap.containskey(d.Account__c))
            dimMap.put(d.Account__c,d);
    }
    //loop through trigger data once again to set picklist values to false
    for(Dimensions__c d:trigger.new){
        if(dimMap.containskey(d.Account__c))
            d.Repayment_Enabled__c = false;

users=[select name,id,email from user where id in:ownerids];
           for(User us:users){
            sendTo.add(us.Email); 
               Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
               mail.setToAddresses(sendTo);
        VWO_Account__c  v1 = [select Id, Name from Dimensions__c where Repayment_Enabled__c = true AND Account__c IN:dimensionIds];
        //Account ac = [select Id, Name from Account where Id IN:accountIds limit 1];
               // VWO_Account__c v2 = [select Id, Name, Account__c from Dimensions__c where Repayment_Enabled__c AND Account__c IN:dimensionIds];
               mail.setTargetObjectId(us.Id);
               mail.setSubject('MultipleDimensions are not allowed');
             mail.setPlainTextBody(dName + '\n' + 'https://login.salesforce.com/'+ d.Id  + '\n' + d.Name + 'https://login.salesforce.com/'+ d.Id);
               mail.saveAsActivity = false;
               Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
    }
    }
}

Here in the above code ,

It is not allowing to insert a new Dimension into an account and showing the error as ("List has no rows from V1 query")

Another issue is like i should get the mail only wheen the user tries to insert the 2nd dimension with repayment as true. Here its happening everytime i insert a dimension.

Could you make any respective changes here.!

Context is :

I need to send an email with the account link and the existing dimension link (Repayment == true) to the owner mailId.



Thanks,
Dev
 
Snigdha ChennupalliSnigdha Chennupalli
Hi,
I'm trying to the do same... I have the below trigger written:

trigger PSIDefaultLocation on CustShipTo__c (after update,after insert) {
List<custShipTo__c> vwo = new List<CustShipTo__c>();
    set<Id> accountIds = new set<Id>();
    set<Id> custshiptoIds = new set<Id>();
    for(CustShipTo__c c : trigger.new){
        if(c.PSIDefaultLocation__c == true){
            accountIds.add(c.Account__c);
            custshiptoIds.add(c.id);
        }
    }
    vwo = [select id, PSIDefaultLocation__c, Account__c from CustShipTo__c 
           where PSIDefaultLocation__c = true and Account__C IN: accountIds And Id Not IN:custshiptoIds];
    Map<Id,custshipto__c> dimMap = new Map<Id,custshipto__c>();
    for(custshipto__c c:vwo){
        if(!dimMap.containskey(c.Account__C))
            dimMap.put(c.Account__c,c);
    }
    for(custshipto__C c:trigger.new){
        if(dimMap.containskey(c.Account__C))
            c.PSIDefaultLocation__c = false;
    }
}

I'm getting Unexpected token 'trigger' error.... Can you please guide me on this? I'm new to development.
Thanks,
Snigdha