• Kelly K
  • NEWBIE
  • 290 Points
  • Member since 2012
  • Salesforce Developer
  • Navicure

  • Chatter
    Feed
  • 7
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 28
    Questions
  • 98
    Replies
Hey all,

I have created the following Apex trigger that will create, update and delete Opportunity Contact Roles based on a Contact Lookup field placed on the Opportunity. Everything works great currently. I am just trying to figure out one final scenario. If John Doe already has a Contact Role but is not the Primary Contact Role and I want him to be. I want to be able to change my look up field to him and then have that check him as the primary. Currently it just creates a new one and checks them both as primary. So what I need to do is check the current Contact Roles and if there is already one with the same name as in the Lookup field then just check that one as primary, but if there isn't then create a new one. Below is the code. Please let me know if you need further description.

Thanks,
 
trigger CreateContactRole on Opportunity (after insert, after update) {
    
    List<OpportunityContactRole> newContactRoleList = new List<OpportunityContactRole>();
    List<OpportunityContactRole> oldContactRoleList = new List<OpportunityContactRole>();
    Set<Id> OppId = new Set<Id>();
    sET<Id> ContactId = new Set<Id>();
    
    if(Trigger.isInsert) {
        for(Opportunity opp : Trigger.new) {
          if(opp.Primary_Contact__c != null) {
              //Creating new Contact Role
              newContactRoleList.add(new OpportunityContactRole(ContactId=opp.Primary_Contact__c,OpportunityId=opp.Id,Role='Decision Maker',IsPrimary=true));
          }
      }
    }
    
    if(Trigger.isUpdate) {      
      for(Opportunity opp : Trigger.new) {
          if(opp.Primary_Contact__c != null && Trigger.oldMap.get(opp.Id).Primary_Contact__c == null) {
                //Creating new Contact Role
              newContactRoleList.add(new OpportunityContactRole(ContactId=opp.Primary_Contact__c,OpportunityId=opp.Id,Role='Decision Maker',IsPrimary=true));
          }
            else if(opp.Primary_Contact__c != null && Trigger.oldMap.get(opp.Id).Primary_Contact__c != null) {
                //Create New Contact Role make new CR Primary over the old CR
                Opportunity OldOpp = Trigger.oldMap.get(opp.Id);
                OppId.add(OldOpp.id);
                ContactId.add(OldOpp.Primary_Contact__c);
                newContactRoleList.add(new OpportunityContactRole(ContactId=opp.Primary_Contact__c,OpportunityId=opp.Id,Role='Decision Maker',IsPrimary=true));
            }
          else if(opp.Primary_Contact__c == null && Trigger.oldMap.get(opp.Id).Primary_Contact__c != null) {
                Opportunity OldOpp = Trigger.oldMap.get(opp.Id);
                OppId.add(OldOpp.id);
                ContactId.add(OldOpp.Primary_Contact__c);
                try {
                //Deleting old Contact Roles
                if(oldContactRoleList.size()>0) delete oldContactRoleList;
                }
                catch(Exception e) {
                    System.debug(e);
                    trigger.new[0].addError('An error has occurred. Please contact your system administrator.');
                }
          }
      }
    }
    
    try {
        //inserting new contact roles
        if(newContactRoleList.size()>0)insert newContactRoleList;
        
        //Selecting old Contact Roles
        if(OppId.size()>0) oldContactRoleList = [Select Id from OpportunityContactRole where ContactId in : ContactId and OpportunityId in : OppId];        
        
    }
    catch(Exception e) {
        System.debug(e);
        trigger.new[0].addError('An error has occurred. Please contact your system administrator.');
    }
}


 
I was trying to deploy some code this morning from sandbox to production, and I received this error on a test class that was written by someone else at my company. They copied it from somewhere online and have no idea what this error is. I am curious if someone can help me figure out what is wrong with this test class that is causing the following error: 


System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_EXECUTE_FLOW_TRIGGER, The record couldn’t be saved because it failed to trigger a flow. A flow trigger failed to execute the flow with version ID 301310000008shZ. Contact your administrator for help.: [] 
Stack Trace: Class.MyProfilePageControllerTest.testSave: line 34, column 1

Here is the full test class:
 
/**
 * An apex class that keeps updates of a portal user in sync with its corresponding contact.
   Guest users are never able to access this page.
 */
@IsTest public with sharing class MyProfilePageControllerTest {
    @IsTest(SeeAllData=true) static void testSetContactFields() {
        User u = [select title, firstname, lastname, email, phone, mobilephone, fax, street, city, state, postalcode, country
                           FROM User WHERE id =: UserInfo.getUserId()];

        Contact c = new Contact();

        MyProfilePageController.setContactFields(c, u);
        System.assertEquals(c.firstname, u.firstname, 'firstname should have been set as the firstname of the user for the contact');
        System.assertEquals(c.lastname, u.lastname, 'lastname should have been set as the lastname of the user for the contact');
    }

    @IsTest(SeeAllData=true) static void testSave() {
        // Modify the test to query for a portal user that exists in your org
        List<User> existingPortalUsers = [SELECT id, profileId, userRoleId FROM User WHERE UserRoleId <> null AND UserType='CustomerSuccess'];

        if (existingPortalUsers.isEmpty()) {
            User currentUser = [select id, title, firstname, lastname, email, phone, mobilephone, fax, street, city, state, postalcode, country
                                FROM User WHERE id =: UserInfo.getUserId()];
            MyProfilePageController controller = new MyProfilePageController();
            System.assertEquals(currentUser.Id, controller.getUser().Id, 'Did not successfully load the current user');
            System.assert(controller.getIsEdit() == false, 'isEdit should default to false');
            controller.edit();
            System.assert(controller.getIsEdit() == true);
            controller.cancel();
            System.assert(controller.getIsEdit() == false);

            Contact c = new Contact();
            c.LastName = 'TestContact';
            insert c;

            c.title = currentUser.title;
            c.firstname = currentUser.firstname;
            c.lastname = currentUser.lastname;
            c.email = currentUser.email;
            c.phone = currentUser.phone;
            c.mobilephone = currentUser.mobilephone;
            c.fax = currentUser.fax;
            c.mailingstreet = currentUser.street;
            c.mailingcity = currentUser.city;
            c.mailingstate = currentUser.state;
            c.mailingpostalcode = currentUser.postalcode;
            c.mailingcountry = currentUser.country;
            controller.save();
            System.assert(Page.ChangePassword.getUrl().equals(controller.changePassword().getUrl()));
        } else {
            User existingPortalUser = existingPortalUsers[0];
            String randFax = Math.rint(Math.random() * 1000) + '5551234';

            System.runAs(existingPortalUser) {
                MyProfilePageController controller = new MyProfilePageController();
                System.assertEquals(existingPortalUser.Id, controller.getUser().Id, 'Did not successfully load the current user');
                System.assert(controller.getIsEdit() == false, 'isEdit should default to false');
                controller.edit();
                System.assert(controller.getIsEdit() == true);

                controller.cancel();
                System.assert(controller.getIsEdit() == false);

                controller.getUser().Fax = randFax;
                controller.save();
                System.assert(controller.getIsEdit() == false);
            }

            // verify that the user and contact were updated
            existingPortalUser = [Select id, fax, Contact.Fax from User where id =: existingPortalUser.Id];
            System.assert(existingPortalUser.fax == randFax);
            System.assert(existingPortalUser.Contact.fax == randFax);
        }
    }
}

Any and all help will be greatly appreciated.
Hello,
My configure with Outlook.when i add an email from outlook to salesforce then the task is created on a perticular contact which is the existing functionlity of application.
there is workflow rule we are using here,
Workflow Rule: ABCUpdate ~ Salesforce - Unlimited Edition

AND( ISPICKVAL(Owner:User.BusinessUnit__c ,"ABC"), $User.BypassWorkflow__c = FALSE, ISPICKVAL( BusinessUnit__c,""))

then we are updating a field "BusinessUnit__c " with value as ABC

this value is updated as soon as task is created.

Now as currently WF rule doesn't trigger when task is craeted via outlook which is a bug in salesforce.
I need to create a trigger for this.
Can someone help me how to create a trigger when i add an email from outlook to salesforce,in the task,it should update the field "BusinessUnit__c " with value as ABC

It would be better if is explain with code example as I am new in apex coding.


 
I am trying to automate a data load using the Command Line tools and have everything working smoothly but it is taking 10x longer than if I do it through the Data Loader GUI.

Below is an exert from my process-conf.xml

>     <bean id="csvUpsertOrderItem"
>           class="com.salesforce.dataloader.process.ProcessRunner"
>           singleton="false">
>         <description>Upsert Transaction Headers into Orders standard object.</description>
>         <property name="name" value="csvUpsertOrderItem"/>
>         <property name="configOverrideMap">
>             <map>
>                 <entry key="sfdc.debugMessages" value="false"/>
>                 <entry key="sfdc.endpoint" value="CUSTOM ENDPOINT"/>
>                 <entry key="sfdc.username" value="USERNAME"/>
>                 <entry key="sfdc.password" value="ENCRYPTED PASSWORD"/>
>                 <entry key="process.encryptionKeyFile" value="C:\Program Files (x86)\salesforce.com\Data Loader\bin\key.txt"/>
>                 <entry key="sfdc.timeoutSecs" value="540"/>
>                 <entry key="sfdc.loadBatchSize" value="2000"/>
>                 <entry key="sfdc.entity" value="OrderItem"/>
>                 <entry key="process.operation" value="upsert"/>
>                 <entry key="sfdc.useBulkApi" value="true"/>
>                 <entry key="sfdc.bulkApiSerialMode" value="true"/>
>                 <entry key="sfdc.externalIdField" value="SlId__c"/>
>                 <entry key="process.mappingFile" value="C:\Users\User\Google Drive\Automation\OrdersLine21Jan.sdl"/>
>                 <entry key="process.outputError" value="C:\Users\User\downloads\Logs\errorUpsertOrderItem.csv"/>
>                 <entry key="process.outputSuccess" value="C:\Users\User\downloads\Logs\successUpsertOrderItem.csv"/>
>                 <entry key="dataAccess.name" value="C:\Users\User\Google Drive\Automation\JAEG_TransactionDetails.csv" />
>                 <entry key="dataAccess.type" value="csvRead" />
>             </map>
>         </property>     </bean>

From my research, it seems to be something to do with either the debug log (I think most likely) or batch size.

I have set the sfdc.debugMessages to 'false' so it is not writing the files but it does seem to write it to the command screen.  I feel this could be causing the problem, is there a default log setting?  Maybe a process command setting?

In the data loader document http://resources.docs.salesforce.com/200/6/en-us/sfdc/pdf/salesforce_data_loader.pdf it says the max sfdc.loadBatchSize is 200 but through the UI it sets it to 2000 when batch is true.  If that does restrict it, that could explain it.

I just cant find anything recent about this problem, anyone had any luck doing this at full pace recently?
Has anyone gotten the Excel Connector (https://code.google.com/p/excel-connector/) to work in Excel 2016? 

Hi,
 
I try to put a user as case owner but when I insert the case I see that the owner is the default case owner configured in the support setting.
To avoid this I tried to bypass assignment rules :
 
            
Case c = new Case();
c.ownerId = myUser.id;
Database.DMLOptions dmo = new Database.DMLOptions();
dmo.assignmentRuleHeader.useDefaultRule= false;
dmo.assignmentRuleHeader.assignmentRuleID = null;
c.setOptions(dmo);
insert(c);

Nevertheless, the default queue case is always owner.
When we create a case outside unit test, it's created with the good user.  

Thanks
 
I get the error "Custom read failed" when I try and retrieve anything from the IdeaComment object.

I've tried posting this in the Qlikview forums, but no one can help me so i figured it could be a Salesforce setting.

Hi All,

I've implemented a trigger on the task object that stamps a last activity date/time onto the lead & contact object whenever a task is created or updated. This has been working great - except it was recently reported to me that any tasks that are created via salesforce for outlook were not receiving the update from the trigger.

So I've poked into it: https://developer.salesforce.com/forums/ForumsMain?id=906F000000095HTIAY and found out that this is the reason why it's being bypassed.

So I updated my trigger to isolate records coming in with a blank who and what Id and sent them over to the @future method - this was working for a bit in my sandbox environment, but then it noticed it stopped pushing the updates as I cleaned up some of my code (cosmetic, not functional). Completing further testing, I see the following:

This is from the trigger:

10:22:18.145 (145723116)|USER_DEBUG|[35]|DEBUG|tasks created with blank Ids: 1

Then this is from the @future handler

10:22:18.043 (43643966)|USER_DEBUG|[43]|DEBUG|entering at future method
10:22:18.043 (43651600)|SYSTEM_METHOD_EXIT|[43]|System.debug(ANY)
10:22:18.046 (46422518)|SOQL_EXECUTE_BEGIN|[49]|Aggregations:0|select Id, WhoId, Prospecting_call_connected__c, Prospecting_call_affirmative__c, SystemModstamp from Task where Id = :tmpVar1
10:22:18.052 (52227113)|SOQL_EXECUTE_END|[49]|Rows:1
10:22:18.052 (52345117)|SYSTEM_METHOD_ENTRY|[52]|LIST<Task>.iterator()
10:22:18.052 (52462775)|SYSTEM_METHOD_EXIT|[52]|LIST<Task>.iterator()
10:22:18.052 (52485423)|SYSTEM_METHOD_ENTRY|[52]|system.ListIterator.hasNext()
10:22:18.052 (52505395)|SYSTEM_METHOD_EXIT|[52]|system.ListIterator.hasNext()
10:22:18.052 (52565994)|SYSTEM_METHOD_ENTRY|[53]|System.debug(ANY)
10:22:18.052 (52587658)|USER_DEBUG|[53]|DEBUG|null

I suspect that what is happening is that Salesforce for Outlook is filling out the who and what Id using an @future method. There's no way to determine or force the run order on @future methods.

Can anyone confirm that this is what occurs or has figured out a solution?

Hello all.  We have a trigger on the Task object that looks at the WhatId and/or WhoId to update certain fields on the related Account.  A user reported an issue to us when adding emails to Account and Contact records.  Upon taking a look at the debug logs, the WhatId and WhoId are both NULL in Before and After triggers.  However, after the Task record is saved, the WhatId and WhoId are properly set.  The logic of the trigger does not execute properly since the values are NULL when the trigger is executing.  Even if I perform a query in the After trigger for the WhatId and WhoId, they are still NULL.

 

How does Salesforce for Outlook work regarding the WhatId and WhoId?

 

System.debug commands:

	for (Task record : Trigger.new) {
		System.debug(record.WhoId);
		System.debug(record.WhatId);
		System.debug(record.Status);
		System.debug([SELECT Id, WhoId FROM Task WHERE Id = :record.Id].WhoId);

 Result in debug log:

15:26:09.682 (682782000)|USER_DEBUG|[13]|DEBUG|null
15:26:09.682 (682788000)|SYSTEM_METHOD_EXIT|[13]|System.debug(ANY)
15:26:09.682 (682839000)|SYSTEM_METHOD_ENTRY|[14]|System.debug(ANY)
15:26:09.682 (682850000)|USER_DEBUG|[14]|DEBUG|null
15:26:09.682 (682856000)|SYSTEM_METHOD_EXIT|[14]|System.debug(ANY)
15:26:09.682 (682940000)|SYSTEM_METHOD_ENTRY|[15]|System.debug(ANY)
15:26:09.682 (682953000)|USER_DEBUG|[15]|DEBUG|Completed
15:26:09.682 (682959000)|SYSTEM_METHOD_EXIT|[15]|System.debug(ANY)
15:26:09.683 (683169000)|SOQL_EXECUTE_BEGIN|[16]|Aggregations:0|select Id, WhoId from Task where Id = :tmpVar1
15:26:09.700 (700279000)|SOQL_EXECUTE_END|[16]|Rows:1
15:26:09.700 (700390000)|SYSTEM_METHOD_ENTRY|[16]|System.debug(ANY)
15:26:09.700 (700398000)|USER_DEBUG|[16]|DEBUG|null

 

 

I've been trying to use the Excel Connector for the last two weeks to manage the data in our organisation, but I'm having a problem where I get the following error in Excel which is preventing me from using this tool:

 

Error Generated by request::An internal server error has occured while processing your request.
Url:https://www.salesforce.com/services/Soap/c/13.0

ExceptionCode : 5103

The first couple of times I tried to use Excel Connector it worked fine. However I then started seeing this error every time I tried to use it - the error appears after I put in my password in Excel Connector and click Login.

 

We are on Salesforce Professional. I have tried uninstalling and reinstalling the toolkit and connector, but it hasn't made a difference. I'm using Excel 2010 32-bit on Windows 7 64-bit.

 

I can log in to Salesforce in my browser on the same computer.

 

I've checked that IE is not in Offline Mode, and verified that Excel can actually connect to the internet (pinged a URL using VBA script).

 

I've tried disabling my antivirus (MSE) and windows firewall.

 

I've tried changing the server url as suggested by this thread (had to modify registry keys to do this as that field was not editable in the connector.

 

None of these resolutions worked.

 

Has anyone experienced and managed to resolve this, or can anyone suggest any other possible resolutions?

I am using Upsert call for contacts. There are around 1800 contacts in my database table. However, upsert call inserts/updates around 1600 of them and the rest are coming back as null. When I take a look at the input data, I don't see anything wrong. Also there are no errors thrown by the API.

 

Under what circumstances would UpsertResult object in UpsertResult object array would be set to null?