• BroncoBoy
  • NEWBIE
  • 290 Points
  • Member since 2013
  • Salesforce CRM Developer
  • Jackson

  • Chatter
    Feed
  • 3
    Best Answers
  • 2
    Likes Received
  • 0
    Likes Given
  • 37
    Questions
  • 45
    Replies
Hi
I want to understand a specific concept.
I have created​​ 2 batch apex classes say account and contact and now I need to run contact class only after account class fully completes(without any errors of course).

I schedule account class & then contact class, so when I click setup --> jobs --> scheduled jobs,   I can see both these jobs

As per documentation order of execution of jobs is not guaranteed.

so how do I make sure that contact batch job executes only successful execution of account batch job.

please be specific in replies.

sonali​​​
We have a visualforce page that displays meetings (events), we're hosting the VF page inside the Salesforce App but we want each meeting/event to be able to link to the calendar in the Salesforce App.  Is there any way to have a link that opens the Events section of the Salesforce App?  If so, can you provide a link or the syntax?  Thanks in advance!

Bronco
(https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm)
"The maximum number of asynchronous Apex method executions (batch Apex, future methods, Queueable Apex, and scheduled Apex) per a 24-hour period: 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater"

When we're talking about batch Apex, for example, are we just talking about start(), execute(), finish() methods being applied to that limit or are all methods - even custom methods - also included in that figure as well?

Also is there a way to see how close we are getting to that limit every day?  I looked at the Limits class but didn't see any direct methods there.  We have a couple of huge batch classes that run once a week and I want to make sure we're not getting too close to that limit.
Not sure if this is possible but I'm interested in creating a stacked vertical bar chart with 2 Y axes as follows:

1.  It has last 6 months on the X axis, e.g. January - June
2.  It has 2 Y Axes: on the left Sales in $$, on the right Applications - both as a decimal
3. For each month you have Product A Applications bar stacked on Product A Sales bar and then  Product B Applications bar​ stacked on Product B Sales bar.

So essentially it's like stacking/superimposing one bar chart on top of another and adding an extra y axis.  Is this even possible?  Thanks in advance! 
Bronco
Not sure why I 'm getting a null pointer error here in the batch process, any thoughts are appreciated :)

Code
public Database.QueryLocator start(Database.BatchableContext BC)  
{
    String query = 'SELECT Id,  (SELECT ContactId, IsPrimary FROM OpportunityContactRoles ORDER BY IsPrimary DESC) FROM Opportunity WHERE LastModifiedDate = LAST_N_DAYS:365';
    return Database.getQueryLocator(query); 
}

public void execute(Database.BatchableContext BC, List < sObject > s)
{
    List < Opportunity > oppsToUpdate = new List < Opportunity > ();
    for (sObject ssss: s)
    {
        Opportunity o = (Opportunity) ssss;
        List < OpportunityContactRole > opptys = new List < OpportunityContactRole > ();
        opptys = (List < OpportunityContactRole > ) o.getsobjects('OpportunityContactRoles'); //o.getsobjects will return a List<SObject>, in the same line we cast those into List<OpportunityContactRole>

        for (OpportunityContactRole optt: opptys) // HERE IS WHERE THE ERROR IS.  LOOPING THROUGH SUB QUERY LIST
        {
            String contId = '';
            contId = String.ValueOf(optt.ContactId);
            if (!String.IsBlank(contId))
            {
                o.Primary_Contact_Id__c = contId;
                oppsToUpdate.add(o);
                break;
            }
        }
    }

    update oppsToUpdate;

}
Trying to set up SAML for the first time.  The network person I am working has sent me the SAML Single Sign-On Settings using a metadata file he's set me.  Just wondering if I can turn on SAML in sandbox for only 3 users with 3 different profiles?  If so, how?

Thanks in advance!
Bronco
Background:
ValidateProduct is a method in my VF page extension that uses the productsToVerify property (with getters/setters) to return a boolean. Using <apex:param I'm trying to set the productsToVerify property each time the <apex:repeat  iterates  through a record, then execute ValidateProduct which returns boolean - thus deciding whether to render  <apex:outputLink

Problem:  <apex:param isn't setting the productsToVerify property...it just remains null.   Thanks in advance for your help!

VF Code:
<apex:pageBlockTable value="{!JNLCampaigns}" var="junc">
   <apex:column>
      <apex:facet name="header">View X</apex:facet>
      <apex:repeat value="{!junc.CampaignMarketingMaterials__r}" var="campMark">
         <apex:outputLink rendered="false">
            <apex:param name="prodsParam" value="{!campMark.MarketingMaterial__r.Product_Name__c}" assignTo="{!productsToVerify}"/>
         </apex:outputLink>
         <apex:outputLink rendered="{!ValidateProduct}" value="{!campMark.MarketingMaterial__r.Form_Number__c}">VIEW PREVIEW</apex:outputLink><br />
      </apex:repeat>
   </apex:column>
</apex:pageBlockTable>​

Extension code for getValidateProduct method:
​public String productsToVerify{get;set{productsToVerify=value;}
public boolean getValidateProduct()
{  
system.debug(' productsToVerify ' + productsToVerify + ' ss ' + ss);
Boolean result = false;
if(!String.IsBlank(productsToVerify) && productsToVerify.contains(ss))
{
result = true;
system.debug(' result a ');
break;
}
else if(String.IsBlank(productsToVerify))
{
system.debug(' result b ');
result = true;
break;
}
return result;
}
Anyone know how to re-format a number to currency (or at least have the commas) and display on a apex:barSeries chart?

Right now the left axis is displaying several #'s, for example: 10000.   I would prefer 10,000 or, even better, $10,000.

The source data is coming from a number type field from a custom object.  I'm also wondering if I convert the field to type: currency if that would help?

Thanks in advance!
Bronco
Any ideas on how to query for Opps created last month (for certain recordtypes only) and group by ContactId then by record type?

Query:  SELECT COUNT(Id) idSum, SUM(Consolidated_Opportunities_Count__c) consolidatedSum FROM Opportunity WHERE CreatedDate = LAST_MONTH AND (RecordType.Name = 'A' OR RecordType.Name = 'B' OR RecordType.Name = 'C') GROUP BY ContactId, RecordTypeId 

Thanks fo your help!
Bronco
Here's my SOQL:
SELECT Summary_Id__c, SUM(EA_App_Count__c) appCount FROM CustomObject__c WHERE Full_Date__c = THIS_MONTH GROUP BY Summary_Id__c';

Here's what I'm trying to do:
Trying to run this SOQL 6 separate times, based on the current month, once per month for the previous 6 months date range. So, in essence, after each run, the filter date range would dynamically change look something like:
  1. WHERE Full_Date__c = THIS_MONTH -1 //Previous month
  2. WHERE Full_Date__c = THIS_MONTH - 2 //2 months ago
  3. WHERE Full_Date__c = THIS_MONTH - 3 //3 months ago
  4. WHERE Full_Date__c = THIS_MONTH - 4 //4 months ago
  5. WHERE Full_Date__c = THIS_MONTH - 5 //5 months ago
  6. WHERE Full_Date__c = THIS_MONTH - 6 //6 months ago
So here's my dillema:  how to produce a date range that is the equivalent to THIS_MONTH - #?  Is there a Date Literal or function that I can use?

Thanks in advance for any help you can offer!
-Bronco
Objective:  The objective of my batch code is to iterate through a list users and their events.  I want iterate through this list of events (which originates from a query which orders the events by time) and, as we iterate through the list, if the event.IsAllDayEvent checkbox is checked/true, then I want that all day event to be the SECOND event in the evtsToReorder collection - not the first.  My code below is generating the following error:  Error: Cannot modify a collection while it is being iterated.

Not sure why I'm getting this error as I'm out of the for loop when I'm trying to re-order the collection.  Any help is appreciated!
-Bronco

CODE:
    for (sObject s : scope) 
        {
            User evtOwner = (User)s;
            Id evtOwnerId = evtOwner.Id;
            
            if(ownrIdsToEvents.containsKey(evtOwnerId))
            {
                List <Event> evtsToReorder = new Event[ownrIdsToEvents.get(evtOwnerId).size()];
                evtsToReorder = ownrIdsToEvents.get(evtOwnerId);
                Boolean userHasAllDayEvent = false;
                Boolean reOrderList = false;
                Event allDayEvent;
                Event zoneRotationEvent;

                for(Event ee: ownrIdsToEvents.get(evtOwnerId))//loop through each owners events
                {
                    if (ee.IsAllDayEvent && ee.RecordType.Name != 'Zone Rotation') 
                    {    
                        userHasAllDayEvent = true;
                         allDayEvent = ee;
                    }
                    if(ee.RecordType.Name == 'Zone Rotation' && userHasAllDayEvent)
                    {
                        reOrderList = true;
                        zoneRotationEvent = ee;
                        Event zoneRotationEventToMove = ee;
                        break;
                    }
                }
                if(reOrderList && userHasAllDayEvent && evtsToReorder.size() > 1)
                {
                    evtsToReorder.set(0, zoneRotationEvent);
                    evtsToReorder.remove(1);
                    evtsToReorder.add(1, allDayEvent);
                }
        }
    }
Ulitmate Goal:
Create a map of lists (contactIdsToOpportunities)  which maps a contact id to the list of opportunities that contact is associated with within the OpportunityContactRole object - all based on a limited # of contact id's, only opportunities within the last 30 days.

As I'm trying to access the subquery field values to build my map of lists, its generating the following error: 
Invalid aggregate relationship OpportunityContactRole for Opportunity


I'm trying to use this approach:  http://www.infallibletechie.com/2012/04/how-to-get-subquery-field-value-using.html

I'm grateful for any help, so thanks in advance!
-Bronco

CODE:
set <Id> evtsContactIds = new set <Id>{'0035000000yim1c’,’0035000000cin2f’};//insert contacts id's here
map <Id, List <Opportunity>> contactIdsToOpportunities = new Map <Id, List <Opportunity>>();

for (Opportunity o: [SELECT Id, CloseDate, Description, Name, (SELECT ContactId FROM OpportunityContactRoles WHERE ContactId IN: evtsContactIds) FROM Opportunity WHERE CloseDate >= LAST_N_DAYS: 30 AND Id IN(SELECT OpportunityId FROM OpportunityContactRole WHERE ContactId IN: evtsContactIds) ORDER BY CloseDate DESC])
{
    List < OpportunityContactRole > opptys = new List < OpportunityContactRole > ();
    opptys = o.getSObjects('OpportunityContactRole'); //very rarely used method, but this gets the records from the subquery, 
    Id oppContId;
    for (OpportunityContactRole opt: opptys)
    {
        oppContId = opt.ContactId;

        if (contactIdsToOpportunities.containsKey(oppContId))
        {
            List < Opportunity > contactsOpportunities = contactIdsToOpportunities.get(oppContId);
            if (contactsOpportunities.size() <= 3) //this is what determines that the code will only return the latest 3 opportunities
            {
                contactsOpportunities.add(o);
                contactIdsToOpportunities.put(oppContId, contactsOpportunities);
            }
        }
        else
        {
            contactIdsToOpportunities.put(oppContId, new List <Opportunity>{o});
        }
    }
}
I have a Task trigger on which I'm tyring to also reset the checkbox values to be unchecked in the before context but still use the initial values (prior to resetting) in the after context.  The idea is to reset them without having to execute a DML update later on in the trigger.  The problem is that the values are not being captured in the before context - they are all remaining false, so I can't use them for logic in the after context.  Thank you in advance for any help you can provide.

Code
 trigger EmailTaskDescription on Task(before insert, after insert, before update, after update)
 {
     Boolean nofityRIW = false;
     Boolean nofityREW = false;
     Boolean nofityBDC = false;
     Boolean nofityGIW = false;
     Boolean nofityGEW = false;

     if (trigger.isBefore)
     {
         Task tt = Trigger.new[0];
         //capture checkbox selections
         nofityRIW = tt.Notify_R_IW__c;
         nofityREW = tt.Notify_R_EW__c;
         nofityBDC = tt.Notify_BDC__c;
         nofityGIW = tt.Notify_G_IW__c;
         nofityGEW = tt.Notify_G_EW__c;
         //reset checkbox selections to unchecked
         tt.Notify_R_IW__c = false;
         tt.Notify_R_EW__c = false;
         tt.Notify_BDC__c = false;
         tt.Notify_G_EW__c = false;
         tt.Notify_G_IW__c = false;
     }
     if (trigger.isAfter)
     {
        //use initial values to execute logic 
        if (nofityRIW)
         {

         }
         else if (nofityREW)
         {

         }
     }
 }
My Visualforce page has an extension has a public method: TopOneHundred();  which returns a JSON string.  Though there are ways to execute the class method using Javascript, I'm not sure how to obtain the returned JSON string for use in my Javascript. The TopOneHundred() method uses other variables from the extension in order to return the correct string.  This is done because the user is interacting with some picklists on the VF page and we're executing the TopOneHundred() method using the picklists choices. 

Because of this, I can't use Javascript remoting nor can I use the AJAX toolkit/sforce.apex.execute method because both require static keywords and the instance variables are not visible to static methods.  I'm greatful for any advice.

FYI The JSON string is used to populate a Datatables  (https://datatables.net/" target="_blank) table on the VF page.
 
I'm using a couple of functions for filling a list of contacts.   This is done by passing a list of custom BD__c object records to another function (retrieveTopOneHundred) which, in short, uses the BD__c objects to retrieve a list of contacts.  Problem I'm trying to solve:  I want to keep fetching contacts using the retrieveTopOneHundred function until the contactsListB list reaches 100 contacts.  How can I rewrite the code below so that I can do this without having to write a bunch of nested "if(contactsListB.size() < 100)...find more contacts based on the next set of BD__c records"?  I was hoping to use a Do While loop or something simple, but I just couldn't arrive at anything that worked. Thanks in advance for your help!

CODE:
public String TopOneHundred()
{
    List < sObject > bd = StdSetControllerBD.getRecords();
    List < Contact > contactsListB = retrieveTopOneHundred(bd);
    if (contactsListB.size() < 100)
    {
        StdSetControllerBD.next(); //if we have less than 100 contact records then we will go get more by repeating the process, this time with the next set of bd records in the StdSetControllerBD
        List < BD__c > nextRoundOfBdRecords = new List < BD__c > ();
        for (sObject sob: StdSetControllerBD.getRecords())
        {
            BD__c sobd = (BD__c) sob;
            nextRoundOfBdRecords.Add(sobd);
        }
        contactsListB.addAll(retrieveTopOneHundred(nextRoundOfBdRecords));
        if (contactsListB.size() < 100)
        {
            StdSetControllerBD.next(); //if we have less than 100 contact records then we will go get more by repeating the process, this time with the next set of bd records in the StdSetControllerBD
            List < BD__c > thirdRoundOfBdRecords = new List < BD__c > ();
            for (sObject sob: StdSetControllerBD.getRecords())
            {
                BD__c sobdd = (BD__c) sob;
                thirdRoundOfBdRecords.Add(sobdd);
            }
            contactsListB.addAll(retrieveTopOneHundred(nextRoundOfBdRecords));
        }
    }

    String contactsJSON = JSON.serializePretty(contactsListB);
    return contactsJSON;​
}
Ultimate goal:  I need to end up with a list of 100 Contacts based on two other related objects and certain criteria.  
Background:  The Account object is related to two other objects Contact (lookup, 1 Account can have many Contacts) and I have another object, a custom object, BD__c, with a master detail relationship to the Account object (1 Account can have many BD__c's).   

To start with, I return a list of these BD__c and I want to order them by Opportunity_Amount__c (descending):

BD__c record #1 Opportunity_Amount__c = $100,000.
BD__c record #2 Opportunity_Amount__c = $50,000.
BD__c record #3 Opportunity_Amount__c = $20,000.
BD__c record #4 Opportunity_Amount__c = $0.

Problem to solve:  Since each BD__c is associated to an Account I want the contacts from the associated account from BD record #1, record #2, record #3 (and so forth) until the total # of contacts reaches 100. In other words I want the first 100 contacts associated with accounts related to the BD__c records who have the highest Opportunity_Amount__c.

So far the code I have is:  

Set<Id> setOfBDIds = new Set<Id>();
for (BD__c bbb : [SELECT b.Account__r.Id  FROM BD__c WHERE Opportunity_Amount__c > 0 ORDER BY Opportunity_Amount__c DESC]) 
{
    setOfBDIds.add(bbb.Account__r.Id);
}
List<Contacts> contacts = [SELECT AccountId, Name FROM Contact WHERE AccountId IN =: setOfBDIds LIMIT 100];

The problem is that, with this structure, the contacts in the list won't necessarily be from the BD__c/Accounts who have the highest Opportunity_Amount__c - they can be from any account.

I thought about trying this using SOQL but according to this:  https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_query_limits.htm (https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_query_limits.htm" target="_blank)

"In each specified relationship, only one level of parent-to-child relationship can be specified in a query"

Any thoughts on how this can be acheived? 

Thanks in advance!
Trying to retrieve several user Ids and assign them to variables of Id type - but I am generally curious as to the best approach here - so I'm looking for opinions.  Thanks in advance!

In my view C) works but only if the SOQL returns records, otherwise you get a 'now rows returned' error.  A)  A works but again will return a "list out of bounds error if the SOQL returns 0 records  B) seems the best to me because if there is no key it simply returns null...but I'd like to hear your opinions.

So, which approach is the more efficient - which one is the best practice below, A, B or C (or Other) - is B the best? 
A)
list<User> jnldGenericId = [SELECT Id FROM User WHERE Name = '1' LIMIT 1];
list<User> rbdGenericId = [SELECT Id FROM User WHERE Name = '2' LIMIT 1];
list<User> imgGenericId = [SELECT Id FROM User WHERE Name = '3' LIMIT 1];
list<User> cclGenericId = [SELECT Id FROM User WHERE Name = '4' LIMIT 1];

Id Owner1 = rbdGenericId[0].Id;
Id Owner2 = imgGenericId[0].Id;
Id Owner3 = cclGenericId[0].Id;
Id Owner4 = jnldGenericId[0].Id;

OR

B)
map<String, Id> userNameIdMap = new map<String, Id>();

for(user u : [SELECT Id FROM User WHERE Name = '1' OR Name = '2' OR  Name = '3' OR Name = '4'])
{
    userNameIdMap.put(u.Name, u.Id);
}

Id Owner1 = userNameIdMap.get('1');
Id Owner2= userNameIdMap.get('2');
Id Owner3 = userNameIdMap.get('3');
Id Owner4= userNameIdMap.get('4');

OR

C)
Id Owner1= [SELECT Id FROM User WHERE Name = '1' LIMIT 1].Id;
Id Owner2 = [SELECT Id FROM User WHERE Name = '2' LIMIT 1].Id;
Id Owner3 = [SELECT Id FROM User WHERE Name = '3' LIMIT 1].Id;
Id Owner4 = [SELECT Id FROM User WHERE Name = '4' LIMIT 1].Id;
 
We have Account records with a field of FS_ID__c (text).  Several accounts may have the same FS_ID__c.  I would like to generate a map of the reverse:  a map of lists where we show which account ID's  are associated to each particular FS_ID__c.  I want the map to include all FS_ID__c's.  Is that possible?  If so, how can I poplulate the map?  My intent is to use MyMap.get() method to give me the accounts for FS_ID__c '1234'. The purpose:  to avoid running a query each time I want to know the accounts associated to each FS_ID__c.  Thanks in advance for your help - alternative suggestions/approaches are welcome as well.

Example of desired effect:
public map <String, list <String>> MyMap = new map <String, list <String>>
{
   'FSID1234' => new list<String> {'a0yW0000000zC177', 'a0yW0000000zC178', 'a0yW0000000zC179'},
   'FSID5678' => new list<String> {'a0yW0000000zC187', 'a0yW0000000zC188', 'a0yW0000000zC189'},,
   'FSID5678' => new list<String> {'a0yW0000000zC197', 'a0yW0000000zC198', 'a0yW0000000zC199'},
};

Referernce:
http://www.davehelgerson.com/?p=379

Scenario:
In this example (not a batch process) I have a list of 100 contact records:  List <Contact> contactsToUpdate = new List <Contact> ();
// contactsToUpdate.size() = 100

I loop through these using a for loop,  I update a few records. Then I upsert them using DML.  Result:  a few records have been updated and a few are new & are inserted.  
if (contactsToUpdate.size() > 0) 
        {
            try 
            {
                upsert contactsToUpdate;
            } 
            catch(DmlException e) 
            {
                system.debug('The following exception has occurred: ' + e.getMessage());
            } 
        }

Here are my questions:

1)  If only 1 of those 100 records cannot be inserted do to something like a validation rule failing, will the entire insert fail or just the one record?
2)  Is there a way in the Catch that I could email myself only the records that fail and the reason - can I use the database.upsert in a try catch?
 

Thank you!
Brandon

Question: The developer console indicates that  I need to test every if statment in my for loop below.  Can you suggest how to do that?  Thanks in advance for your help!

Code"

@RemoteAction
    global static list <Marketing_Material__c> retrieveAllMaterialsList(String userDivision)
{
    List<String> imgAudience = new List<String> {'AMC', 'WMC'};
    List<String> jnldAudience = new List<String> {'AMC', 'WMC'};
    List<String> jnlAudience = new List<String> {'AMC', 'WMC'};
    List<String> jnldgAudience = new List<String> {'AMC', 'WMC'};
    List<String> rbdAudience = new List<String> {'AMC', 'WMC'};
    List<String> cclAudience = new List<String> {'CURIAN', 'CURIAN RIA', 'CURIAN SELECT'};
    List<String> siiAudience = new List<String> {'NPH'};
    List<String> npcAudience = new List<String> {'NPH'};
    List<String> icaAudience = new List<String> {'NPH'};
    List<String> investAudience = new List<String> {'NPH'};
    List<String> wAudience = new List<String> {'NPH'};
    Map<String, List<String>> audienceMap = new Map<String, List<String>>();
   
    audienceMap.put('IMG', imgAudience);
    audienceMap.put('JNLD', jnldAudience);
    audienceMap.put('JNL', jnlAudience);
    audienceMap.put('JNLDG', jnldgAudience);
    audienceMap.put('RBD', rbdAudience);
    audienceMap.put('CCL', cclAudience);
    audienceMap.put('SII', siiAudience);
    audienceMap.put('NPC', npcAudience);
    audienceMap.put('ICA', icaAudience);
    audienceMap.put('INVEST', investAudience);
    audienceMap.put('W1', wAudience);

     List <String> finalAudienceListB = new List <String> (audienceMap.get(userDivision)); //e.g. 'WMC, AMC'
     audienceMap.clear();

     Map <Id, Marketing_Material__c> materialListC = new Map <Id, Marketing_Material__c> ();
     List <Marketing_Material__c> finalMaterialList = new List <Marketing_Material__c> ();
     try
     {
         for (Marketing_Material__c mmmm: [SELECT Name, Marketing_Material_Name__c, Form_Number__c, PieceLink__c, PictureLink__c, Approved_Firms__c, Not_Approved_Firms__c, Approved_States__c, Not_Approved_States__c, Item_Cost__c, Audience__c, Product_Line__c, Audience_Groups_Multi_picklist__c, IsObsoleted__c FROM Marketing_Material__c WHERE IsObsoleted__c = false AND(Viewabillity__c = 'Viewable And Orderable' OR Viewabillity__c = 'Viewable Not Orderable')])
         {
             String audC = mmmm.Audience_Groups_Multi_picklist__c; //e.g. 'WMC, AMC, SSU'
             if (!String.isBlank(audC))
             {
                 Integer audienceMatchesC = 0;
                 for (String tt: finalAudienceListB)
                 {
                     //you're finding a matching in the Audience_Groups_Multi_picklist__c(aud) with each item the user is qualified to see based on the user division in the
                     //above hard-coded map.
                     audienceMatchesC = audienceMatchesC + audC.countMatches(tt);
                 }
                 if (audienceMatchesC > 0) //if there's a match then we're good to return the record for the user to see
                 {
                     materialListC.put(mmmm.Id, mmmm); //we add to a map which, by default, prevents duplicates from being added;
                 }
             }
         }
         finalMaterialList = materialListC.values();
     }
     catch (Exception e)
     {
         ApexPages.addMessages(e);
     }
     return finalMaterialList;
}
I'm trying to avoid getting a "Too many SOQL queries" -error in a trigger I'm writing.  Does anyone have a suggestion on how I can remove the queries from for-loop within the trigger below using maps or something else? Thank you in advance for your help!

Here's my code:

trigger UpdateEventDescription on Event (before insert, before update)
{
Map<Id, User> usersMap = new Map<Id, User>([SELECT Cost_Center__c FROM User WHERE IsActive = true]);
private String iwEmailAddress;
private String bdcEmailAddress;

    if (trigger.isInsert)
    {
     for (Event e: Trigger.new)
        {
         String descrip = e.Description;
         String ownCC = usersMap.get(e.OwnerId).Cost_Center__c;
         if(e.Email_Description_to_BDC__c || e.Email_Description_to_IW__c)//if either checkbox (Email_Description_to_BDC__c or e.Email_Description_to_IW__c) is are checked, proceed
         {         
          if(e.Email_Description_to_BDC__c && ownCC != '' && ownCC != null)
          {       
           //Retrieve the BDC-users email address based on the event-owner's cost center
           bdcEmailAddress = [SELECT Cost_Center__c, Email FROM User WHERE Cost_Center__c =:ownCC AND (ProfileId = '1234' OR ProfileId = '1234') LIMIT 1].Email;  //is there a way to removed this from the for loop so that I can avoid the too many queries error?
          }          
          if(e.Email_Description_to_IW__c && ownCC != '' && ownCC != null)
          {
           //Retrieve the IW-users email address based on the event-owner's cost center
           iwEmailAddress =  [SELECT Cost_Center__c, Email FROM User WHERE Cost_Center__c =:ownCC AND (ProfileId = '5678' OR ProfileId = '8940') LIMIT 1].Email;
          }
          //Will add code here to update the description
         }        
        } 
    }
}
I've seen several posts out there about this but can't get any of them to work: The expected behavior is that the save completes and then the window/tab closes.

Code:

<apex:outputPanel id="outBottom">
  <apex:commandButton oncomplete="window.close();" action="{!createTask}" value="Save Task" status="closer" rerender="outBottom"/>
   <apex:actionStatus startText="(Saving...)" stopText="" onstop="window.close(); return false;" id="closer"/>                       
</apex:outputPanel>

Has anyone found a solution to this or is there an error in my code?  Thank you in advance!

I am new to apex programming and have been asked to look into an issue within a batch apex class created by an senior apex developer (s.a.d.). 

 

The setup:

 

My understanding of the execute method used with batch apex is that this method takes 2 things:

-A reference to the Database.BatchableContext object.
-A list of sObjects, such as List<sObject>, which is passed to the method for each batch of records

 

You can see both being passed into the s.a.d.'s code below:

 

The code:

 

global void execute(Database.BatchableContext BC, List<sObject> scope)
    {
        Set<String> branchZips = new Set<String>();
        Set<Id> branchPIds = new Set<Id>();

        
        // First, we collect all the unique zips from the branches into a set.
        for (sObject s : scope) {   
            Account a = (Account)s;
            if (a.Branch_Office_Zip_Code__c != null && a.Branch_Office_Zip_Code__c.length() == 5) {
                branchZips.add(a.Branch_Office_Zip_Code__c);
                branchPIds.add(a.ParentId);
            }
        }

 

My question:

 

Regarding list of sObjects (List<sObject> scope) being passed to the method I'm simply trying to understand what the developer is doing within the code.  My question:  Does it appear to you that the developer was passing list of sObjects in a variable "scope", taking each record from the  "scope", storing it in an sObject "s" and then casting that "s" sObject into an account object "a" with this code:  Account a = (Account)s?  If so, I've been trying to find information regarding this casting "technique" and why it's used and, more importantly, other examples.  This whole topic of casting appears to be widly used not just in apex programming but in other programming like java,  and I would like to understand it better.  I have been unable to find resources that clearly explain what it is and why you would do it and examples.   Thanks in advance!

(https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm)
"The maximum number of asynchronous Apex method executions (batch Apex, future methods, Queueable Apex, and scheduled Apex) per a 24-hour period: 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater"

When we're talking about batch Apex, for example, are we just talking about start(), execute(), finish() methods being applied to that limit or are all methods - even custom methods - also included in that figure as well?

Also is there a way to see how close we are getting to that limit every day?  I looked at the Limits class but didn't see any direct methods there.  We have a couple of huge batch classes that run once a week and I want to make sure we're not getting too close to that limit.
Hello all, 
 
I'm trying to run the Dataflow and getting this error: 
 
Error executing node 133: Invalid schema: Error, Invalid key name: %!(EXTRA string=WhatId(Account).Name) (02K32000000CdmREAS_03C32000000TNDQEA4)
 
I can't find a knowledge article on this particular error. 
 
Can anybody speak to this? 
 
Thanks in advance. 
Not sure if this is possible but I'm interested in creating a stacked vertical bar chart with 2 Y axes as follows:

1.  It has last 6 months on the X axis, e.g. January - June
2.  It has 2 Y Axes: on the left Sales in $$, on the right Applications - both as a decimal
3. For each month you have Product A Applications bar stacked on Product A Sales bar and then  Product B Applications bar​ stacked on Product B Sales bar.

So essentially it's like stacking/superimposing one bar chart on top of another and adding an extra y axis.  Is this even possible?  Thanks in advance! 
Bronco
Not sure why I 'm getting a null pointer error here in the batch process, any thoughts are appreciated :)

Code
public Database.QueryLocator start(Database.BatchableContext BC)  
{
    String query = 'SELECT Id,  (SELECT ContactId, IsPrimary FROM OpportunityContactRoles ORDER BY IsPrimary DESC) FROM Opportunity WHERE LastModifiedDate = LAST_N_DAYS:365';
    return Database.getQueryLocator(query); 
}

public void execute(Database.BatchableContext BC, List < sObject > s)
{
    List < Opportunity > oppsToUpdate = new List < Opportunity > ();
    for (sObject ssss: s)
    {
        Opportunity o = (Opportunity) ssss;
        List < OpportunityContactRole > opptys = new List < OpportunityContactRole > ();
        opptys = (List < OpportunityContactRole > ) o.getsobjects('OpportunityContactRoles'); //o.getsobjects will return a List<SObject>, in the same line we cast those into List<OpportunityContactRole>

        for (OpportunityContactRole optt: opptys) // HERE IS WHERE THE ERROR IS.  LOOPING THROUGH SUB QUERY LIST
        {
            String contId = '';
            contId = String.ValueOf(optt.ContactId);
            if (!String.IsBlank(contId))
            {
                o.Primary_Contact_Id__c = contId;
                oppsToUpdate.add(o);
                break;
            }
        }
    }

    update oppsToUpdate;

}
Anyone know how to re-format a number to currency (or at least have the commas) and display on a apex:barSeries chart?

Right now the left axis is displaying several #'s, for example: 10000.   I would prefer 10,000 or, even better, $10,000.

The source data is coming from a number type field from a custom object.  I'm also wondering if I convert the field to type: currency if that would help?

Thanks in advance!
Bronco
Here's my SOQL:
SELECT Summary_Id__c, SUM(EA_App_Count__c) appCount FROM CustomObject__c WHERE Full_Date__c = THIS_MONTH GROUP BY Summary_Id__c';

Here's what I'm trying to do:
Trying to run this SOQL 6 separate times, based on the current month, once per month for the previous 6 months date range. So, in essence, after each run, the filter date range would dynamically change look something like:
  1. WHERE Full_Date__c = THIS_MONTH -1 //Previous month
  2. WHERE Full_Date__c = THIS_MONTH - 2 //2 months ago
  3. WHERE Full_Date__c = THIS_MONTH - 3 //3 months ago
  4. WHERE Full_Date__c = THIS_MONTH - 4 //4 months ago
  5. WHERE Full_Date__c = THIS_MONTH - 5 //5 months ago
  6. WHERE Full_Date__c = THIS_MONTH - 6 //6 months ago
So here's my dillema:  how to produce a date range that is the equivalent to THIS_MONTH - #?  Is there a Date Literal or function that I can use?

Thanks in advance for any help you can offer!
-Bronco
Hi ,

My user running his mobile Salesforce1 then showing this Error.

"There's a problem saving this record. You might not have permission to edit, or might have been deleted or archived."

​I also checked his profile, he is Salesforce 1 User. How can help this user to edit/ Save  via Salesforce1 on the case ?
Ulitmate Goal:
Create a map of lists (contactIdsToOpportunities)  which maps a contact id to the list of opportunities that contact is associated with within the OpportunityContactRole object - all based on a limited # of contact id's, only opportunities within the last 30 days.

As I'm trying to access the subquery field values to build my map of lists, its generating the following error: 
Invalid aggregate relationship OpportunityContactRole for Opportunity


I'm trying to use this approach:  http://www.infallibletechie.com/2012/04/how-to-get-subquery-field-value-using.html

I'm grateful for any help, so thanks in advance!
-Bronco

CODE:
set <Id> evtsContactIds = new set <Id>{'0035000000yim1c’,’0035000000cin2f’};//insert contacts id's here
map <Id, List <Opportunity>> contactIdsToOpportunities = new Map <Id, List <Opportunity>>();

for (Opportunity o: [SELECT Id, CloseDate, Description, Name, (SELECT ContactId FROM OpportunityContactRoles WHERE ContactId IN: evtsContactIds) FROM Opportunity WHERE CloseDate >= LAST_N_DAYS: 30 AND Id IN(SELECT OpportunityId FROM OpportunityContactRole WHERE ContactId IN: evtsContactIds) ORDER BY CloseDate DESC])
{
    List < OpportunityContactRole > opptys = new List < OpportunityContactRole > ();
    opptys = o.getSObjects('OpportunityContactRole'); //very rarely used method, but this gets the records from the subquery, 
    Id oppContId;
    for (OpportunityContactRole opt: opptys)
    {
        oppContId = opt.ContactId;

        if (contactIdsToOpportunities.containsKey(oppContId))
        {
            List < Opportunity > contactsOpportunities = contactIdsToOpportunities.get(oppContId);
            if (contactsOpportunities.size() <= 3) //this is what determines that the code will only return the latest 3 opportunities
            {
                contactsOpportunities.add(o);
                contactIdsToOpportunities.put(oppContId, contactsOpportunities);
            }
        }
        else
        {
            contactIdsToOpportunities.put(oppContId, new List <Opportunity>{o});
        }
    }
}
I have a Task trigger on which I'm tyring to also reset the checkbox values to be unchecked in the before context but still use the initial values (prior to resetting) in the after context.  The idea is to reset them without having to execute a DML update later on in the trigger.  The problem is that the values are not being captured in the before context - they are all remaining false, so I can't use them for logic in the after context.  Thank you in advance for any help you can provide.

Code
 trigger EmailTaskDescription on Task(before insert, after insert, before update, after update)
 {
     Boolean nofityRIW = false;
     Boolean nofityREW = false;
     Boolean nofityBDC = false;
     Boolean nofityGIW = false;
     Boolean nofityGEW = false;

     if (trigger.isBefore)
     {
         Task tt = Trigger.new[0];
         //capture checkbox selections
         nofityRIW = tt.Notify_R_IW__c;
         nofityREW = tt.Notify_R_EW__c;
         nofityBDC = tt.Notify_BDC__c;
         nofityGIW = tt.Notify_G_IW__c;
         nofityGEW = tt.Notify_G_EW__c;
         //reset checkbox selections to unchecked
         tt.Notify_R_IW__c = false;
         tt.Notify_R_EW__c = false;
         tt.Notify_BDC__c = false;
         tt.Notify_G_EW__c = false;
         tt.Notify_G_IW__c = false;
     }
     if (trigger.isAfter)
     {
        //use initial values to execute logic 
        if (nofityRIW)
         {

         }
         else if (nofityREW)
         {

         }
     }
 }
Hi
I want to understand a specific concept.
I have created​​ 2 batch apex classes say account and contact and now I need to run contact class only after account class fully completes(without any errors of course).

I schedule account class & then contact class, so when I click setup --> jobs --> scheduled jobs,   I can see both these jobs

As per documentation order of execution of jobs is not guaranteed.

so how do I make sure that contact batch job executes only successful execution of account batch job.

please be specific in replies.

sonali​​​
My Visualforce page has an extension has a public method: TopOneHundred();  which returns a JSON string.  Though there are ways to execute the class method using Javascript, I'm not sure how to obtain the returned JSON string for use in my Javascript. The TopOneHundred() method uses other variables from the extension in order to return the correct string.  This is done because the user is interacting with some picklists on the VF page and we're executing the TopOneHundred() method using the picklists choices. 

Because of this, I can't use Javascript remoting nor can I use the AJAX toolkit/sforce.apex.execute method because both require static keywords and the instance variables are not visible to static methods.  I'm greatful for any advice.

FYI The JSON string is used to populate a Datatables  (https://datatables.net/" target="_blank) table on the VF page.
 
I'm using a couple of functions for filling a list of contacts.   This is done by passing a list of custom BD__c object records to another function (retrieveTopOneHundred) which, in short, uses the BD__c objects to retrieve a list of contacts.  Problem I'm trying to solve:  I want to keep fetching contacts using the retrieveTopOneHundred function until the contactsListB list reaches 100 contacts.  How can I rewrite the code below so that I can do this without having to write a bunch of nested "if(contactsListB.size() < 100)...find more contacts based on the next set of BD__c records"?  I was hoping to use a Do While loop or something simple, but I just couldn't arrive at anything that worked. Thanks in advance for your help!

CODE:
public String TopOneHundred()
{
    List < sObject > bd = StdSetControllerBD.getRecords();
    List < Contact > contactsListB = retrieveTopOneHundred(bd);
    if (contactsListB.size() < 100)
    {
        StdSetControllerBD.next(); //if we have less than 100 contact records then we will go get more by repeating the process, this time with the next set of bd records in the StdSetControllerBD
        List < BD__c > nextRoundOfBdRecords = new List < BD__c > ();
        for (sObject sob: StdSetControllerBD.getRecords())
        {
            BD__c sobd = (BD__c) sob;
            nextRoundOfBdRecords.Add(sobd);
        }
        contactsListB.addAll(retrieveTopOneHundred(nextRoundOfBdRecords));
        if (contactsListB.size() < 100)
        {
            StdSetControllerBD.next(); //if we have less than 100 contact records then we will go get more by repeating the process, this time with the next set of bd records in the StdSetControllerBD
            List < BD__c > thirdRoundOfBdRecords = new List < BD__c > ();
            for (sObject sob: StdSetControllerBD.getRecords())
            {
                BD__c sobdd = (BD__c) sob;
                thirdRoundOfBdRecords.Add(sobdd);
            }
            contactsListB.addAll(retrieveTopOneHundred(nextRoundOfBdRecords));
        }
    }

    String contactsJSON = JSON.serializePretty(contactsListB);
    return contactsJSON;​
}