Find your content:

Search form

You are here

If it doesn't exist auto-create Organization level Custom Settings in my APEX code

 
Share

We have created a hierarchy custom setting to store some data instead of hard-coding it into our managed package.

Had I known that SF only auto-deploys the setting itself and NOT an Organization level record I would have NOT made that decision. But the beauty of Managed Packages is I am stuck with all previous incorrect decisions made so here I am.

But I digress...

In my APEX code that needs the setting to exist I want to check if there is an Org-level setting for the custom setting and if not get it created and set the fields to the values that I wanted to deploy with the managed package.

At first I tried:

       Equipment_Chatter_Settings__c ecs = Equipment_Chatter_Settings__c.getInstance();
       if(ecs == null)
       {
           ecs = new Equipment_Chatter_Settings__c(setupOwnerId = System.Userinfo.getOrganizationId());
           ecs.Assignment_Chatter__c = TRUE;
           ecs.Loan_Return_Chatter__c = TRUE;
           ecs.Assignment_Body__c = 'Equipment ~1~ ~2~ was assigned on ~3~';
           ecs.Assignment_Return_Body__c = 'Assigned Equipment ~1~ ~2~ was returned on ~3~';
           ecs.Loan_Body__c = 'Equipment ~1~ ~2~ was loaned on ~3~';
           ecs.Loan_Return_Body__c = 'Loaned Equipment ~1~ ~2~ was returned on ~3~';
           insert ecs;
       }

It appears that my 'ecs' object is not null because I never get into the IF that would create the record.

So I did some reading and tried something different - tried 'getOrgDefaults' and then check each field in my custom setting and if it is null update it to the appropriate value.

       ecsupdate = FALSE;
       Equipment_Chatter_Settings__c ecs = Equipment_Chatter_Settings__c.getOrgDefaults();
       if (ecs.ELTON__Assignment_Chatter__c == null) {ecs.ELTON__Assignment_Chatter__c = TRUE; ecsupdate = true;}
       if (ecs.ELTON__Loan_Return_Chatter__c == null) {ecs.ELTON__Loan_Return_Chatter__c = TRUE; ecsupdate = true;}
       if (ecs.ELTON__Assignment_Body__c == null) {ecs.ELTON__Assignment_Body__c = 'Equipment ~1~ ~2~ was assigned on ~3~'; ecsupdate = true;}
       if (ecs.ELTON__Assignment_Return_Body__c == null) {ecs.ELTON__Assignment_Return_Body__c = 'Assigned Equipment ~1~ ~2~ was returned on ~3~'; ecsupdate = true;}
       if (ecs.ELTON__Loan_Body__c == null) {ecs.ELTON__Loan_Body__c = 'Equipment ~1~ ~2~ was loaned on ~3~'; ecsupdate = true;}
       if (ecs.ELTON__Loan_Return_Body__c == null) {ecs.ELTON__Assignment_Body__c = 'Loaned Equipment ~1~ ~2~ was returned on ~3~'; ecsupdate = true;}                      
       if (ecsupdate == TRUE) {update ecs;}

That was significantly worse - it compiles clean but when I try to run it I get...

Apex script unhandled exception Visualforce Page: /apex/elton__Assign_Equipment caused by: System.LimitException: ELTON:DML currently not allowed Class.ELTON.Assign_Equipment.Init: line 94, column 1 Class.ELTON.Assign_Equipment.: line 43, column 1 (The error is referring to the last line in the above code snippet)

One thing that I do NOT want to do is start creating User or Profile level custom setting records. Our customers if they choose are more than welcome to use those types of records in their instance of our application but all I need is a default org level record if one doesn't already exist (the likelihood of a customer wanting anything but an org level record for this is slim-to-none)

Can anyone point me in the right direction?


Attribution to: AngiB

Possible Suggestion/Solution #1

Very hacky but... Can you experiment with treating your custom setting as a normal sObject?

SELECT Id, Name, SetupOwnerId
FROM Equipment_Chatter_Settings__c
WHERE (NOT (Name LIKE '%(User)')) AND (NOT (Name LIKE '%(Profile)'))

No rows returned -> insert new one. Even better would be to be able to filter WHERE SetupOwnerId LIKE '00D%' (doesn't work) or just WHERE SetupOwnerId = :UserInfo.getOrganizationId() (see notes below). You could also retrieve them all (sorted?) and filter by Id manually.

Couple of points to consider:

  1. I have absolutely no idea if any magic happens to values in org-level custom setting when you refresh a (full) sandbox from prod. I've had a peek at my dev. sandbox and while the top level setting was there, the org id stayed with production value.
  2. Name fields used in WHERE don't seem to be affected by user's language (appear always in English).
  3. Check Install Handler interface, might be useful :)

Attribution to: eyescream

Possible Suggestion/Solution #2

If I'm understanding correctly, I think this will work:

   Equipment_Chatter_Settings__c ecs = Equipment_Chatter_Settings__c.getInstance( UserInfo.getOrganizationId() );
   if(ecs.Id == null)
   {
       ecs.Assignment_Chatter__c = TRUE;
       ecs.Loan_Return_Chatter__c = TRUE;
       ecs.Assignment_Body__c = 'Equipment ~1~ ~2~ was assigned on ~3~';
       ecs.Assignment_Return_Body__c = 'Assigned Equipment ~1~ ~2~ was returned on ~3~';
       ecs.Loan_Body__c = 'Equipment ~1~ ~2~ was loaned on ~3~';
       ecs.Loan_Return_Body__c = 'Loaned Equipment ~1~ ~2~ was returned on ~3~';
       insert ecs;
   }

Attribution to: Phil Hawthorn
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/3973

My Block Status

My Block Content