• Greg H
  • SMARTIE
  • 1028 Points
  • Member since 2005
  • Interactive Ties


  • Chatter
    Feed
  • 30
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 23
    Questions
  • 421
    Replies
Trigger UpdateParentAcct_OldOrg on Account ( after update) {
    
 // the line below fails;
Account a;

     
}
Hi,

I have a simple trigger and test class where I need some help to get from the 62% coverage and up to at least 90%.  The lines which are not covered are the ones after the 'IF' statement. 

Can someone please help me with the remaining test class code?

The trigger is as follows:

trigger contactCreateCommunityUser on Contact (before insert) {
    String currentuser = UserInfo.getUserId();
    String emailAddress = UserInfo.getUserEmail();
    
    ID contactId = [Select contactid from User where id =: Userinfo.getUserid()].contactId;
    List <User> systemAdm = [SELECT Id
                               FROM User
                              WHERE Name like '%Systemadministrator%'];
    system.debug('Systemadmin ID ' + systemAdm);
    If(contactId != null) {
        ID AccID = [Select AccountID from Contact where id =: contactid].AccountId;
        for(Contact con : trigger.new){
            con.OwnerId = systemAdm.get(0).Id;
        }
    }
}


Test class:
@isTest
private class contactCreateCommunityUserTest {       
    static testmethod void contactCreateCommunity() {
        Account acc = [SELECT Id
                        FROM  Account
                        Limit 1];
        
        Contact con = new contact();
        con.lastName = 'TestLastName';
        con.AccountId = acc.Id;
        Insert con;
    }
}
Good afternoon, folks.

I'm in the process of trying to consolidate the SOQL calls within a trigger of a particularly difficult sObject.  This sObject has enough code running on it that we're pretty regularly hitting the 101 error--so it's time to clean up and bulkify where possible.

I've run the following to fill a map with an sobject, and the children of that sobject.  Let's assume for the moment that Service_Order_Line is a child of Service_Order with a many-to-one relationship, and I've filtered this down so I'm only getting one Service_Order and maybe 5 or 10 Service_Order_Lines:

map<ID, Service_Order__c> testResults = new map<ID, Service_Order__c>([select ID, Name, (select ID, Name from Service_Order_Line__r) from Service_Order__c']);

Further down in the trigger, I'll need to reference the child objects, but I can't seem to find a syntax to make it work.  How would I write the following to loop through the children of testResults?

for(Service_Order_Line childrenOfTestResults : testResults.Service_Order_Line__r) {
    system.debug(childrenOfTestResults.Name);
}
Do Apex Callouts (Call from Apex to External Rest/SOAP services) count against Org API Limits. 
I know they are limited by Governor limits but do they count against the org API Limits.
The salesforce documentation is not very clear and not sure how to get official confirmation from Salesforce on this.


http://resources.docs.salesforce.com/200/9/en-us/sfdc/pdf/salesforce_app_limits_cheatsheet.pdf. Page 41 of the document (page 37 based on Numbering in the document) clearly says Apex callouts are excluded.

But the latest document link does not have such Note
https://resources.docs.salesforce.com/222/latest/en-us/sfdc/pdf/salesforce_app_limits_cheatsheet.pdf (No Note at Page 9)
I want to delete the Error_Log__c in production.  However, my "deactivated" trigger still has a handle as follows,

trigger UpdateErrorLog on Error_Log__c (before insert) {...}

Again the above trigger was deactivated thru change set but I cannot delete the Error_Log__C.  I submitted a case to Salesforce and directed me to here.   How can I dereference Error_Log__c from UpdateErrorLog trigger?
Hello,

I exeucte a postman request to get the token.

I was writing a code for authenticating the API in slaesforce, but found that the headers are not correct.

I tried to get the headers by other way.

User-added image

How can i write the code for first part of the screen shot,  ?
I had a simple question. I want to check if an email entered in the form is the right format. How do you splice in apex? In other words I want to see that after the @ symbol, we only have gmail.com. I was going to write something like 
if(email__c.contains('@gmail.com'){} but then I realized that this may not be enough because someone could potentially enter an email of gmail.com@hotmail.com for example. So I want to see what I can write in apex to check if the email is in the format ###@gmail.com
Thank you

Hello,

I am trying to create new authetication through my application and I am getting {"error":"invalid_grant","error_description":"authentication failure"} error when trying to call the Token Request: "https://eu5.salesforce.com/services/oauth2/token"

Can u help me out why I'm getting this error ?
Best Regards , 
Raneen Khoury

I'm trying to use two soql queries to grab the relevant information for an email class, but it is failing when it tries to run the second query when running the test class. I'm actively stumped as to why it's not finding the created product. I'm not super experienced and mostly cut/paste things for apex, so I'm sure there's something goofed along the way. Code below:
Class:

global class EmailPTRAttWearplates implements Messaging.InboundEmailHandler {
	  global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {
		  Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
          
          Production_Tracking_Record__c ptr;
          Product2 prod;
          
           ptr = 
              [select id, Product__c from Production_Tracking_Record__c
              where Name = :email.subject];
          
           prod =
              [select Wearplate__c, Wearplate_Thickness__c, Pre_Order_Wearplates__c from Product2
              where Name = :ptr.Product__c];
          
          if(prod.Pre_Order_Wearplates__c=false)
          {
           PTR_Attachment__c Att = new PTR_Attachment__c(Name=email.subject,
                                                         PTR__c=ptr.Id,
                                                         Component__c='Wearplate',
                                                         Quantity__c=2,
                                                         Thickness__c=prod.Wearplate_Thickness__c,
                                                         Material__c=prod.Wearplate__c,
                                                         Directory_Link_Text__c='R:\\Parts Orders\\Internal Laser Parts');
          insert Att;
          }
       return result;
      }
}



Test Class:

@IsTest
public class EmailPTRAttWearplates_Test {
 public static list<Production_Tracking_Record__c> PTRlist;
    static testMethod void myTest() {
   		Messaging.InboundEmail email  = new Messaging.InboundEmail();
        Messaging.InboundEnvelope env = new Messaging.InboundEnvelope();
    
    		email.fromAddress = 'test@test.com';
    		email.subject = '12345';
   
    Test.startTest();
    
        
        Account acct = new Account(Name='Test Account',
                                   Type='Direct Customer',
                                   Shipping__c='Prepaid',
                                   Ship_Via__c='UTS',
                                   Sales_Discount__c=0);
        insert acct;
        
        Product2 prod = new Product2(Name='Test Product',
                                     Rotor_Configuration__c='Closed Adjustable',
                                     Inboard_or_Outboard__c='Outboard',
                                     Endcap_Face_Preparation__c='Wearplate',
                                     Wearplate__c='Mild Steel',
                                     Wearplate_Thickness__c='.375',
                                     Pre_Order_Wearplates__c=false,
                                     Vane_Thickness__c='.375',
                                     Vane_Material__c='AR500',
                                     Shroud_Mat__c='Mild Steel',
                                     Shroud_Thickness__c='.375',
                                     Adjustable_Blade_Thickness__c='0.3125',
                                     Blade_Mat__c='Mild Steel');
        insert prod;
        
        Opportunity opp = new Opportunity(Name='12345',
                                          RA__c='12345',
                                          StageName='Quote Sent',
                                          CloseDate=System.today(),
                                          AccountId=acct.Id,
                                          Make__c='Kice',
                                          Model__c='VJ 14x10x10',
                                          Product__c=prod.Id,
                                          Max_Temp__c='120',
                                          Serial__c='N/A',
                                          Cold_Clr_Radial__c='.004-.007',
                                          Cold_Clr_Side__c='.004-.007');
        
        insert opp;
    		
        Production_Tracking_Record__c ptr = new Production_Tracking_Record__c(Name = '12345',
        																	  RA__c = opp.Id,
            																  Product__c = prod.Id);
        insert ptr; 
        
        EmailPTRAttWearplates paw = new EmailPTRAttWearplates();
        
        Messaging.InboundEmailResult result = paw.handleInboundEmail(email, env);
        
    Test.stopTest();
    
        System.assert (result.success, 'InboundEmailResult returned a failure message');
    
    }
}

 
Having a problem getting a salesforce access token. Getting the access token works fine in postman, but what I'm trying to do it in C# i'm getting an error.
I've tried to doing the equivlent to what I was doing in postman but I'm not sure if getting this right.
 
var client = new HttpClient();
        string baseAddress = @"https://test.salesforce.com/services/oauth2/token";

        string grant_type = "authorization_code";
        string client_id = "client_id here";
        string client_secret = "client_secret here";
        string auth_url = "https://test.salesforce.com/services/oauth2/authorize";
        string callback_url = "https://app.getpostman.com/oauth2/callback";
        string redirect_uri = "https://app.getpostman.com/oauth2/callback";

        var form = new Dictionary<string, string>
            {
                {"grant_type", grant_type},
                {"client_id", client_id},
                {"client_secret", client_secret},
                {"auth_url", auth_url},
                {"callback_url", callback_url},
                {"redirect_uri", redirect_uri}
            };

        HttpResponseMessage tokenResponse =  client.PostAsync(baseAddress, new FormUrlEncodedContent(form)).GetAwaiter().GetResult();
        var jsonContent =  tokenResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();



This is the error I'm getting:
{ 
"error": "invalid_grant", 
"error_description":"invalid authorization code" 
}

 

I discovered geocodes could be added to Accounts without needing code but for the sake of learning, could someone provide a newbie with constructive feedback on this trigger? I'd really like to figure this out.

I have two sales reps splitting California for their sales territory. One owns anything above Santa Barbara and one owns everything else. I created a custom object labeled 'Cities' with fields for City__c and Latitude__c, and imported this data for all California cities.

Whenever an Account is created or updated, I want my trigger to query the custom object 'Cities', match the Account BillingCity to the City__c field on my custom object, and evaluate if the corresponding Latitude__c field on my custom object is greater than Santa Barbara's latitude.  

If the latitude is greater than Santa Barbara's, add the Account to a list which will be updated with the Northern Sales Rep as the Owner. If the latitude is not greater than Santa Barbara's, add the Account to a list which will be updated with the Southern Sales Rep as the Owner.

When I test the trigger, I get the dreaded "System.NullPointerException: Attempt to de-reference a null object ()" error which confuses me because I check to see if BillingCity is null and confirmed I have all California cities and latitudes imported into my custom object. I have a feeling the error is somewhere around line 13 where I query my custom object and try to find the corresponding latitude...

Thanks to anyone for taking the time to help me learn! 

Here is my trigger:

trigger CaliSalesTerritory on Account (before insert, before update) {

    List <Account> caliAccts; // A List to hold all California Accounts
    List <Account> norCalCities; // A List to hold all Northern California Accounts
    List <Account> soCalCities; // A List to hold all Southern California Accounts
    
    for (Account acct : Trigger.new) { 
        if (acct.BillingState == 'California' && acct.BillingCity != null) {
            caliAccts.add(acct); 
// For all Accounts being inserted or updated, if the BillingState is "California" and the BillingCity isn't null, add the Account to the caliAccts list    
        }
    } 
   
    for (Account acct2 : caliAccts) {
        Cities__c caliLatitude = [Select Latitude__c FROM Cities__c WHERE City__c = :acct2.BillingCity]; 
 // For all Accounts in the caliAccts list, query the Cities__c object and return the Latitude based on the Account's BillingCity
       
    if (caliLatitude.Latitude__c > 34.4285) {
           norCalCities.add(acct2);
// If the Latitude is greater than Santa Barbara's latitude, add the Account to the norCalCities list            
        }    
            else {
                soCalCities.add(acct2);
// If the Latitude is not greater than Santa Barbara's latitude, add the Account to the soCalCities list                            
            }
    }
           
    for (Account northRepAcct : norCalCities) {
        northRepAcct.OwnerId = '0050f0000097wqI'; //Northern Sales Rep UserId
// Assign all Accounts in the norCalCities list to the Northern Sales Rep
    }  
    update norCalCities;
    
    for (Account southRepAcct : soCalCities) {
        southRepAcct.OwnerId = '0050f000009K2kr'; //Souther Sales Rep UserId
// Assign all Accounts in the soCalCities list to Southern Sales Rep        
    } 
    update soCalCities;
}
Hi Guys,
can anyone pls suggest how to get a certain value from nested list<map's>
 List<Map<String,Object>> newl =  new List<Map<String,Object>>();
                         for(Object itrObj : l){
                             newl.add((Map<String, Object>)itrObj); // got all records here
//how to get certain values from the collection
                             
                             system.debug('id val==>'+ newl);
                         }
               
Hi all,

I would really need your help. :(

I need to generate for my organization a PDF document (Order Insertion for our advertising campaigns). I would need to add different fields that the SF users could fill in, like: Campaign Name: xxxx , Campaign Start Date: xx/xxx/xxxx, Price: xx/CPM, etc.

Also, I need to add a header (picture- logo of the company) and a footer (contact, signature, etc).

Basically, I have the Order Insertion in a .xlsx format and I would like to transfer all the info from the Excel in Salesforce. As I understood, it could work with VisualPage creation and customization but I think I need some programmatic help.

Thank you very much for your answer,
Otilia

I'm new to developing and trying to determine if I will get errors thrown in my batch apex code. The purpose is to: upon deactivation of a user (trigger, which I understand isn't best practice but don't know another way the batch can be automatically started w/o checking for deactivated users every night), all of the leads of deactivated user are queried to change the OwnerId to a catchall user. The trick is that one user may have as many as 200,000 leads that need to be updated, hence why I am using batch apex. Two questions:

1. How many batch jobs will be activated with each deactivated user? (I think the answer is one?)

2. Will the batch job be sent to the Flex Queue as 'holding' and then to active, giving the org 105 possible batch jobs to be held/processed at once before throwing errors, or will it bypass Flex Queue, thereby limiting the org to only 5 batch jobs at a time?

I hope my questions make sense, and I appreciate any help. I have spent many hours researching this as a newbie. In case it's relevant, my code is below:

Trigger:

trigger BatchUpdateTrigger2 on User (after update)  {

//Map will keep deactivated users and their Id's, to be used later in batch Apex
	 Map<id, User> DeactivatedUsers = new Map<id, User>();
//Check all users in trigger, first if the IsActive button has been newly changed and if it now says that the user is not active    
for (Integer i=0;i<Trigger.new.size();i++) {
    
if (Trigger.new[i].IsActive!=Trigger.old[i].IsActive &&
   Trigger.new[i].IsActive == false) {
	DeactivatedUsers.put(Trigger.new[i].Id, Trigger.new[i]);
   }
}
// Make sure that there are users to be processed
if (DeactivatedUsers.size() > 0) {

            BatchUpdateLeads objBatchUpdateLeads=new BatchUpdateLeads(DeactivatedUsers);
            Database.executeBatch(objBatchUpdateLeads);
}
}


Batch Apex Class:

global class BatchUpdateLeads implements Database.Batchable<SObject> {
   
        //Save a public variable to hard-code the catchall user that will become lead owner
  	public Id GenericUserId = '0054P000009pLkrQAE';
    
    //map of userid - user that retrieves deactivated user(s) from previous trigger
    Map<Id, User> DeactivatedUsersMap = new Map<Id, User>();
    
    global BatchUpdateLeads(Map<Id, User> DeactivatedUsers) {
    DeactivatedUsersMap = DeactivatedUsers;
    }
    
//Search for the leads whose OwnerId is the deactivated user(s)
    global Database.QueryLocator start(Database.BatchableContext BC) {
    return DataBase.getQueryLocator([SELECT Id, OwnerId FROM Lead WHERE OwnerId IN : DeactivatedUsersMap.keySet()]);
    }
    
    //For leads whose owner was deactivated, change OwnerId to the catchall user
    global void execute(Database.BatchableContext BC, List<sObject> scope){
              List<Lead> leads = (List<lead>)scope;
                for (Lead l: leads){
                    l.OwnerId = GenericUserId;}
        
//Check that there are leads to be updated, then update
            if (leads.size() > 0){
              update leads;
            }
    	}
    global void finish(Database.BatchableContext BC) {
        
    //Send an email to system admin after the batch completes (fill in email)
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    String[] toAddresses = new String[] {'xxxxxxx@gmail.com'};
    mail.setToAddresses(toAddresses);
    mail.setSubject('Apex Batch Job is done');
    mail.setPlainTextBody('The Batch Apex Job Processed Successfully');
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}
I am trying to update a custom event field, sales_within_1_year__c, when a custom contact field, sales__c, changes. For example:

Event 1: tied to Contact A & Contact B; sales_within_1_year = $0
Event 2: tied to Contact A & Contact C; sales_within_1_year = $10

Contact A sales changes from $100 to $200.
Event 1: new sales_within_1_year = $100
Event 2: new sales_within_1_year = $110

If the sales for Contact B or C changed, it would only affect the event they are tied to.

I thought my trigger would work, and it does when I change a contact's sales number individually. But when I bulk update contacts, none of the sales_within_1_year numbers change. I was wondering if someone could help me through this. Thanks!

Here is my trigger:

trigger EventSales on Contact (before update) {
                //Create a list of contact IDs that have updating sales
                List<Id> contactIds = new List<Id>();
    for(Contact con : trigger.new) {
        if(Trigger.newMap.get(con.Id).Sales__c == NULL) return;
        else if(trigger.newMap.get(con.Id).Sales__c == 0) return;
        else if(trigger.oldMap.get(con.Id).Sales__c == NULL) {
            contactIds.add(con.Id);
        }
        else if(trigger.newMap.get(con.Id).Sales__c !=
                trigger.oldMap.get(con.Id).Sales__c) {
            contactIds.add(con.Id);
        }
    }
   
    //Create a list of event relations (contact-event pairs) for updating contacts
    List<EventRelation> evRel = [SELECT EventId, RelationId
                                FROM EventRelation
                                WHERE RelationId IN :contactIds];
   
    //Create a map of the updating contacts and their related events
    Map<Id, List<Id>> contactEvents          = new Map<Id, List<Id>>();
   
    //Create a list of event Ids that are going to be updated
    List<Id> eventIds = new List<Id>();
   
    //Put the contact Id and event Id in the map for events that have updating contacts
    for(EventRelation rel :evRel) {
        if(contactEvents.containsKey(rel.RelationId)) {//If the contact is already in the map
            List<Id> relatedEv = contactEvents.get(rel.RelationId);//Grab the list of events tied to the contact
            relatedEv.add(rel.EventId);//Add the new event to the list
            contactEvents.put(rel.RelationId, relatedEv);//Put the updated list into the map
        }
        else {//If the contact isn't in the map
            contactEvents.put(rel.RelationId, new List<Id>{rel.EventId});//Put the contact and event into the map
        }
        //Add the updating event to the eventIds list
        if(eventIds.contains(rel.EventId)) return;
        else eventIds.add(rel.EventId);
    }
   
    //Create a list of events that are going to be updated
    List<Event> listEventsMaker = [SELECT Id, Sales_within_1_year__c
                                   FROM Event
                                   WHERE Id IN :eventIds
                                   AND EndDateTime = LAST_N_DAYS:365];
   
    List<Event> listEvents = new List<Event>();
    for(Event ev :listEventsMaker) {
        if(listEvents.contains(ev)) return;
        else listEvents.add(ev);
    }
   
    //Keep a list of events to update
    List<Event> changedEvents = new List<Event>();
   
    //Update the sales amounts for the events
    for(Id con :contactEvents.keySet()) {//For each contact in the map
        List<Id> thisContact = new List<Id>();//Create a list of events tied to this specific contact
        Contact oldCon = trigger.oldMap.get(con); //create a record for the contact pre-update
        Contact newCon = trigger.newMap.get(con); //create a record for the contact post-update
        if(newCon.Sales__c == NULL) return;
        else if(newCon.Sales__c == 0) return;
        else if(oldCon.Sales__c == NULL) {
            for(Id event :contactEvents.get(con)) {
                thisContact.add(event);
            }
            for(Event ev :listEventsMaker) {
                if(thisContact.contains(ev.Id)) {
                    changedEvents.add(ev);
                    if(ev.Sales_within_1_Year__c == NULL) {
                        ev.Sales_within_1_Year__c = newCon.Sales__c;
                    }
                    else ev.Sales_within_1_Year__c += newCon.Sales__c;
                }
            }
        }
        else if(oldCon.Sales__c
                != newCon.Sales__c) {
            for(Id event :contactEvents.get(con)) {
                thisContact.add(event);
            }
            for(Event ev :listEventsMaker) {
                if(thisContact.contains(ev.Id)) {
                    changedEvents.add(ev);
                    if(ev.Sales_within_1_Year__c == NULL) {
                        ev.Sales_within_1_year__c = (newCon.Sales__c
                                                     - oldCon.Sales__c);
                    }
                    else ev.Sales_within_1_Year__c += (newCon.Sales__c
                                                       - oldCon.Sales__c);
                }
            }
        }
    }
    update changedEvents;
}
 
I get sent emails with data in both the bodies and as a csv attachment with contact information that I need to update.  Currently I use the dataloader or the data import wizard and manually upload the information into our Org.  From the research I have done on the forums it appears that I can write an Apex class to parse the information from both the body of the email or an attachment and update the contact records with the appropriate information.  Looking for some examples or resources to write this in Apex so that my external partners can email an address and have the data update in my organzation.  Hopefully this makes sense on this post like it does in my head.  Any information or references would be greatly appreciated.