• 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
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 having a issue with my trigger. When i try to do a mass update on account records I get this error message.  Too many SOQL queries: 101 Trigger_CasePrimaryContact: line 7, column 1 

my trigger code is below, any help with issue would be greatly appreciated. 
 
trigger Trigger_CasePrimaryContact on Account (before insert, before update) {


   for (Account a : Trigger.new) {
   
       AccountContactRole[] contactRoleArray =
       [select ContactID, Role from AccountContactRole where AccountId = :a.id AND Role='Asset Management Service Contact' ];
       if (contactRoleArray.size() > 0) {
         
        
           a.Account_Case_Contact__c = contactRoleArray[0].ContactID;
          
       }else{
      
           // IF NO CONTACT ROLES EXIST RETURN NULL...
           a.Account_Case_Contact__c = null;
         
       }
   }
    


}
  • January 26, 2016
  • Like
  • 0
Hi,

I am trying to add a validation rule in trigger that if

Details status = 'In Progress" then Tracker status cannot be updated to Closed.

I get this error "Comparison arguments must be compatible types: Schema.SObjectField​"
 
trigger Tracker_AfterUpdate on Tracker__c (After Update) 
{   
       
        if(Trigger.IsAfter && Trigger.IsUpdate)
        {           
            Set<Id> TrackerIDs = new set<Id>();   
                        
            for(Tracker__c Tempdata : trigger.new)
            {                 
                if(Tempdata.Status__c=='Closed' && details__c.status__c=='In progress')
                {
                Tempdata.Status__c.adderror ('not allowed');
                }                        
            }           
                      
        }
    }

Please help
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 was wondering if I could get someone to verify or clarify that one transaction/execution context is the equivalent of the order of exeuction running once and only once?

A little context - 
Back in 2013, I set up a process where whenever a record is a created, a workflow rule will run to fill out a field (grabs the id of the record for tracking if it's cloned later). I have a validation rule that ensures that this field is filled in whenever an update occurs, new records tell the validation rule to evaluate to false.

For this particular object, I have one trigger that calls apex classes & methods as needed (we have several). 
No issues, everything works as expected, until this last January came around and my validation rule starts to evaluate to true on new records. So I log a case, I didn't make any changes to this process and things don't start failing unless something changed on the back end.

The response I'm getting back from t2 support is this:

"There are two operations on the same record in the same transaction. The record is inserted first. The after insert trigger is fired. It invokes an apex class. There is a DML statement ( update ) in the apex class which updates the same record.

When the record is inserted, the order of execution triggers for the first time. The validation rule is invoked for the first time. When we reach the update statement, the apex class updates the same record again.

This update forces the order of execution to trigger again. As a result, the validation rule fires again.

The events are shown in a single transaction in Debug logs, but the order of execution has been fired twice. "


Based on the documentation, it doesn't seem like you can have two order of executions and only a single transaction?
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_transaction.htm 
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm

 

Hi All,

I'm about at my wits end with this as there seems to be no documentation or other posts that comes close to this topic.

I'd like to make some changes to an HTML page that is hosted on our company's domain (not salesforce's - www.navicure.com) that we use as a log in page for our portal users. In doing so, I'm trying to connect to the AJAX toolkit so I can leverage sforce.connection.login(username, password).

When I was running it locally, I got the error: XMLHttpRequest cannot load file:///C:/services/Soap/u/35.0. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

Fine. So I move it to be hosted under my local tomcat server so it'll be hosted from http.

Now when trying to run it on the localhost, I'm getting the error POST http://localhost:8080/services/Soap/u/35.0 404 (Not Found). 

What am I doing wrong?

<!DOCTYPE html>
<head>
	<script type="text/javascript" src="https://na19.salesforce.com/soap/ajax/35.0/connection.js"></script>		
	<link href="bootstrap.css" rel="stylesheet">			

	<!--Override the sforce.Transport function due to an error in the AJAX toolkit for "user-agent"-->
	<script>
		sforce.Transport = function(url) {
		this.url = url;
		this.connection = null;

		this.newConnection = function() {
			try {
				this.connection = new ActiveXObject('Msxml2.XMLHTTP');
			} catch(e) {
				try {
					this.connection = new ActiveXObject('Microsoft.XMLHTTP');
				} catch(e) {
					this.connection = new XMLHttpRequest();
				}
			}

			return this.connection;
		};

		this.send = function (envelope, callback, async, timeout) {
			this.newConnection();
			if (async) {
				this.connection.onreadystatechange = this.httpConnectionCallback;
			}
			var holder = new sforce.internal.ConnectionHolder(this.connection, callback);
			sforce.internal._connections.push(holder);
			this.connection.open("POST", this.url, async);
			this.connection.setRequestHeader("Content-Type", "text/xml; charset=UTF-8");
			this.connection.setRequestHeader("SOAPAction", "\"\"");
			this.connection.setRequestHeader("Accept", "text/xml");
		 //   this.connection.setRequestHeader("User-Agent", "SFAJAX 1.0");
			this.connection.send(envelope);
			if (async && typeof(timeout) !== "undefined") {
				this.setTimeoutOn(holder, timeout);
			}
			if (!async) {
				this.httpConnectionCallback();
			}
		};

		this.setTimeoutOn = function (holder, timeout) {
			function abortConnection() {
				if (holder.connection.readyState !== 4) {
					holder.timedout = true;
					holder.connection.abort();
				}
			}
			setTimeout(abortConnection, timeout);
		};

		this.httpConnectionCallback = function () {

			for (var i = 0; i < sforce.internal._connections.length; i++) {
				var holder = sforce.internal._connections[i];
				if (holder !== null) {
					if (holder.timedout) {
						sforce.internal._connections[i] = null;
						sforce.internal._connections.slice(i,1);
						holder.callback.httpCallback("Remote invocation timed out", false);
					} else  if (holder.connection.readyState == 4) {
						sforce.internal._connections[i] = null;
						sforce.internal._connections.slice(i,1);
						var success = holder.connection.status == 200;
						if (sforce.debug.trace) {
							sforce.debug.log("Response : status - " + holder.connection.status);
							sforce.debug.logXml(holder.connection.responseText);
						}
						if (sforce.debug.apexTrace) {
							sforce.debug.logApex(holder.connection.responseText);
						}
						if (holder.connection.responseXML && holder.connection.responseXML.documentElement) {
							holder.callback.httpCallback(holder.connection.responseXML.documentElement, success);
						} else {
							holder.callback.httpCallback("Remote invocation failed, due to: " + holder.connection.responseText +
														 " status code: ", holder.connection.status);
						}
					}
				}
			}
		};
	};
	</script>
	
	<script type="text/javascript">		
		function login() {		
			var username = "";
			var password = "";
			var username = document.getElementById("username").value;
			var password = document.getElementById("password").value;
			var returnURL = "https://na19.salesforce.com/apex/portalMain";
			
			if(username.length > 0 || password.length > 0) {
				try {
					console.log("username: " + username);
					console.log("password: " + password);
					var result = sforce.connection.login(username, password);
					
				}
				catch(error) {
					if (error.faultcode.indexOf("INVALID_LOGIN") != -1) {
						//$("#notification").text("Your login attempt has failed. The username or password may be incorrect, or your location or login time may be restricted. Please contact the administrator at your company for help");
						alert("log in invalid");
						return false;
					} else {
						alert(error);
					}
				}
				
				window.location = "https://na19.salesforce.com/secur/frontdoor.jsp?sid=" + result.sessionId + "&retURL=" + returnURL;
			}
		
			return false;
		}		
	</script>
</head>
 

 

 

Hi All,

We have a customer portal (yes, I'm aware communities is the new thing - but we are not migrating to communities for several reasons). Some time ago, when another administrator originally went through and implemented it, he set up a log in page on our company's domain for the customer portal - I noticed recently it wasn't comprehensive and only masked the log in page, but used SF's default reset password & error pages. I'm trying this as a concept before I get our web admins to update our pages, so there's 3 pages currently involved: Login.html, PasswordReset.html, and PasswordResetConfirm.html. The override on the log in page works (if there's no error) and I'm able to reset the password from a custom page. What I'm having trouble with is overriding the page presenting the confirmation of the reset password: 

User-added image
Here's what I've got for the form on the PasswordReset.html, but it does not appear to be working. I've tried adding a "saveURL", but it seems that it will prepend "https://na19.salesforce.com/" in every case. Is there any way to change where the page redirects to for the confirmation?
 
<form  style="margin-left: 320px; margin-top: 20px;" action="https://na19.salesforce.com/secur/forgotpasswordp.jsp" id="editPage" method="post" name="editPage" onsubmit="if (window.ffInAlert) { return false; }" >
	<input type="hidden" name="cancelURL" id="cancelURL" value="Login.html" />						
	<input type="hidden" name="orgId" id="orgId" value="00D300000000Q4e" />
	<input type="hidden" name="portalId" id="portalId" value="06030000000cXQh" />
	<input type="hidden" name="retURL" id="retURL0" value="Login.html" />
	<input type="hidden" name="retURL" id="retURL1" value="PasswordResetConfirm.html" />
	<input type="hidden" name="save_new_url" id="save_new_url" value="https://na19.salesforce.com/secur/forgotpasswordp.jsp?retURL=PasswordResetConfirm.html&amp;orgId=00D300000000Q4e&amp;portalId=06030000000cXQh" />

Thanks,
Kelly
Hi All,

I have a batch class that sends an email in the finish() method whenver errors are present. The email distribution list is set up under custom settings so it can be easily adjusted without having to directly modify the code in a sandbox, turn off the batch schedule, push the new code in, and turn the schedule back on.

I'm being a bit anal about this, but I would like to see 100% code coverage for my batch class - but I'm not sure how to write it up in my test class approrpriately. 

Here's the finish method:
global void finish(Database.BatchableContext BC) {
		AsyncApexJob job = [SELECT Id, ApexClassId, JobItemsProcessed, TotalJobItems, NumberOfErrors, CreatedBy.Email
							FROM AsyncApexJob WHERE Id = :BC.getJobId()];

		if(failedUpdates > 0 || job.NumberOfErrors > 0) {
			String emailMessage = 'Batch Job TaskUpdateActivityInfo has errors. <br/><br/>'
								 +'Number of batches: ' + job.TotalJobItems + '<br/>'
								 +'Number of successful batches: ' + job.JobItemsProcessed + '<br/>'
								 +'Number of unsuccessful batches: ' + job.NumberOfErrors + '<br/>'
								 +'Number of unsucessful record updates: ' + failedUpdates + '<br/><br/>'
								 +'For more details, please review the Apex Errors tab.';

			Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

			//Uses custom setting to add other email addresses
			String[] toAddresses = new String[] {job.CreatedBy.email};

			Map<String, Apex_Distribution_List__c> distList = Apex_Distribution_List__c.getAll();
	        String serverhost = URL.getSalesforceBaseUrl().getHost().left(2);

	        for(Apex_Distribution_List__c record : distList.values()) {
	            //If it's a produciton environment, add only system admin emails
	            if(serverHost == 'na')
	            	if(record.System_Admin_Email__c)
	            		toAddresses.add(record.Email__c);
	            //Otherwise, only add those that are enabled for sandbox alerts
	            else
	                if(record.Enabled_for_Sandbox_Alerts__c)
	                	toAddresses.add(record.Email__c);
	        }

			mail.setToAddresses(toAddresses);
			mail.setReplyTo('kkorynta@navicure.com');
			mail.setSenderDisplayName('Salesforce Apex Batch Job Summary');
			mail.setSubject('Salesforce Batch Job Summary: Task Update Activity Info');
			mail.setHTMLBody(emailMessage);
			Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
		}
	}

These are the lines I'm not able to get coverage on:
//If it's a produciton environment, add only system admin emails
	            if(serverHost == 'na')
	            	if(record.System_Admin_Email__c)
	            		toAddresses.add(record.Email__c);
	            //Otherwise, only add those that are enabled for sandbox alerts
	            else
	                if(record.Enabled_for_Sandbox_Alerts__c)
	                	toAddresses.add(record.Email__c);


Does anyone have any suggestions on how to get coverage on this? I'm at 91% currently.

Thanks,
Kelly

Hi All, 

I'm currently writing a test batch class and I'm scratching my head trying to figure out why my SOQL query is not returning the requested fields:

Here's the condensed version of the class:

@isTest static void testTaskUpdateActivityInfoBatchTest() {
		DateTime olderTime = system.now().addMinutes(-5);
		DateTime newestTime = system.now().addMinutes(-3);
		//Pull a random active sales guy
		User testUser = [SELECT Id FROM User WHERE ProfileId ='00e30000001Ghun' AND IsActive = true LIMIT 1];
		List<Task> tasks = new List<Task>();

		//Create test Leads
		Lead[] testLeads = new Lead[]{};
		for(Integer i = 0;  i < 10; i++) {
			testLeads.add(new Lead(LastName = 'kktest-'+i, Company='test', Date_Requested_Sales_Follow_Up__c = system.now()));
		}
		insert testLeads;

		//Create 60 tasks associated to these leads
		for(Integer i = 0; i < 30; i++) {
			Integer j = math.mod(i, 10);
			tasks.add(new Task(OwnerId = testuser.Id, Subject = 'Apex Test '+i, ActivityDate = system.today(), Status = 'Completed', WhoId = testLeads[j].id, In_Queue_for_Processing__c = true, Date_Time_Processed__c = newestTime, Prospecting_call_affirmative__c = true, Prospecting_call_connected__c = true, Email_Connection__c = true));
			tasks.add(new Task(OwnerId = testuser.Id, Subject = 'Apex Test '+i, ActivityDate = system.today(), Status = 'Completed', WhoId = testLeads[j].id, In_Queue_for_Processing__c = true, Date_Time_Processed__c = olderTime, Prospecting_call_affirmative__c = true, Prospecting_call_connected__c = true, Email_Connection__c = true));
		}
		system.assertEquals(60, tasks.size());

		Test.startTest();
			Database.executeBatch(new TaskUpdateActivityInfoBatch());
		Test.stopTest();

		//Asserts
		List<Lead> leadsToCheck = [SELECT Id, First_Activity_Id__c, First_Activity_Date_Time__c, First_Connection_Date_Time__c, Last_Connection_Date_Time__c, Second_to_Last_Activity_Date_Time__c, Last_Activity_Date_Time__c FROM Lead WHERE Id =:testLeads];
		system.debug('leadsToCheck: ' + leadsToCheck);
		for(Lead lead : leadsToCheck) {
			//Cannot assert Id with this set up
			system.assertEquals(olderTime, lead.First_Activity_Date_Time__c);
			system.assertEquals(olderTime, lead.First_Connection_Date_Time__c);
			system.assertEquals(newestTime, lead.Last_Connection_Date_Time__c);
			system.assertEquals(olderTime, lead.Second_to_Last_Activity_Date_Time__c);
			system.assertEquals(newestTime, lead.Last_Activity_Date_Time__c);
		}
	}


The last query

List<Lead> leadsToCheck = [SELECT Id, First_Activity_Id__c, First_Activity_Date_Time__c, First_Connection_Date_Time__c, Last_Connection_Date_Time__c, Second_to_Last_Activity_Date_Time__c, Last_Activity_Date_Time__c FROM Lead WHERE Id =:testLeads];


When I observe it in the debug logs is only returning the Ids:

16:22:42:080 USER_DEBUG [74]|DEBUG|leadsToCheck: (Lead:{Id=00Q8A000001HaZ6UAK}, Lead:{Id=00Q8A000001HaZ7UAK}, Lead:{Id=00Q8A000001HaZ8UAK}, Lead:{Id=00Q8A000001HaZ9UAK}, Lead:{Id=00Q8A000001HaZAUA0}, Lead:{Id=00Q8A000001HaZBUA0}, Lead:{Id=00Q8A000001HaZCUA0}, Lead:{Id=00Q8A000001HaZDUA0}, Lead:{Id=00Q8A000001HaZEUA0}, Lead:{Id=00Q8A000001HaZFUA0})

Why are the other fields not returning and how do I fix it? 

Thanks,
Kelly

 

Hi All,

Is there a way to get a successful test for an @future method called from creating/updating a user?

Here's the scenario - when we enable a customer portal user, there are several items (such as an account heirarchy) that need to be shared through apex in order to ensure that the user has access to relevant records. The @future method gets fired when a user is created or when a user is reactivated. 

The problem is, updating sharing is considered a non-setup item and updating a user is considered a set-up item, so I end up with Mixed_DML errors galore.

I ended up settling on something like this:

static testMethod void userActivateTest() {
    	User user = [SELECT Id, FirstName, LastName, ContactId, AccountId, IsActive FROM User WHERE  IsActive=true AND IsPortalEnabled=true LIMIT 1];

    	List<User> userList = new List<User>();
    	userList.add(user);

    	Test.startTest();
    		CP_SharingHandler.user_Add_Shares_Prep(userList);
    	Test.stopTest();
    }

While it does generate the code coverage I need, I feel like this is sloppy coding since I cannot use any assert statements to ensure that the @future method is doing what it actually needs to do.

Has anyone had any success in testing shares being generated when setting up a portal user? If so, what approach did you take?

Thanks,
Kelly

I think I'm stuck between a rock and a hard place and I'm hoping someone here with a bit more experience in batch classes can give me some direction.

My batch class is relatively simple: determine the max lead score across contacts within an account and update the account.

The start method is as followed:

global Database.QueryLocator start(Database.BatchableContext BC) {
		return Database.getQueryLocator([SELECT Id, Max_Lead_Score__c , (SELECT Id, mkto2__Lead_Score__c, AccountId FROM Contacts WHERE IsDeleted = false) FROM Account WHERE IsDeleted = false]);
}

And the execute method of my code like this:
global void execute(Database.BatchableContext BC, List<sObject> scope) {
        List<Account> accounts = (List<Account>) scope;        
	    Map<Id, Account> accountsForUpdate = new Map<Id, Account>();
        Id[] accountIds = new Id[]{};
	    Integer maxLeadScore;        
        
	for(Account account : accounts) {
		maxLeadScore = null;

		//Iterate through all contacts and find the max lead score
	       	if(account.Contacts.size > 0) {
	                for(Contact contact : account.Contacts) {				
        	            if(contact.mkto2__Lead_Score__c > maxLeadScore || maxLeadScore == null)
                	        maxLeadScore = (Integer)contact.mkto2__Lead_Score__c;					
                	}
    		}

		//Some contacts have a null lead score, in the event that's the only option available, populate with a 0 value on the account.
		if(maxLeadScore == null)
			maxLeadScore = 0;

		account.Max_Lead_Score__c = maxLeadScore;
		accountsForUpdate.put(account.Id, account);
	}
        
        //This is used for debug tracking - the save results array should line up
        for(Id id : accountsForUpdate.keySet())
            accountIds.add(id);

	List<Database.SaveResult> saveResults = Database.update(accountsForUpdate.values(), false);
        List<Apex_Error__c> apexErrors = new List<Apex_Error__c>();
        
        for(Integer i = 0; i < saveResults.size(); i++) {
            if(!saveResults.get(i).isSuccess()) {
                failedUpdates++;
                
                for(Database.Error error : saveResults.get(i).getErrors()) 
                	apexErrors.add(new Apex_Error__c(Apex_Class__c = 'AccountMaxContactLeadScore', Error_Record__c = accountIds.get(i), Error_Details__c = error.getMessage()));                
            }
        }
		if(apexErrors.size() > 0)
        	insert apexErrors;
}
 

The first issue I ran into was First error: Aggregate query has too many rows for direct assignment, use FOR loop. Fine. So I restructured my contact loop to not do the size check:

//Iterate through all contacts and find the max lead score
            for(Contact contact : account.Contacts) {				
       	        if(contact.mkto2__Lead_Score__c > maxLeadScore || maxLeadScore == null)
            	        maxLeadScore = (Integer)contact.mkto2__Lead_Score__c;					
    		}
 

Then I run into this error: First error: invalid query locator. Did some research, found this, restructured my code based on his advice. http://www.interactiveties.com/b_batch_apex_invalid_query_locator.php#.VNPK953F-4J
 

for(SObject s : scope) {
    Account account = (Account) s;
    maxLeadScore = null;

	//Iterate through all contacts and find the max lead score
	Contact[] contacts = account.getSObjects('Contacts');
        	
        if(contacts != null) {
                for(Contact contact : contacts) {				
                    if(contact.mkto2__Lead_Score__c > maxLeadScore || maxLeadScore == null)
                        maxLeadScore = (Integer)contact.mkto2__Lead_Score__c;					
                }
    	}
 

Then I got First error: Aggregate query has too many rows for direct assignment, use FOR loop. So similar to the first method, I remove the check for nulls. Then I get null pointer errors.

So I tried removing the subquery in the start method and then doing a direct query in the excute method and I get First error: Too many query rows: 50001 - which means I have to use the subquery method.

Any advice on how to get this optimized to hit zero errors?
 

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?

I haven't seen this before and I'm having trouble figuring out why this isn't working. I have a class that handles adding OpportunityContactRoles to an opportunity on create, on account Id change, and on close of an opportunity - the test class for that passes, no issues has been working great for a few years.

I was working on new code that involves updating the opportunity record type, owner, and a few other fields and in some cases cloning the opportunity. My test class for this is failing. The error I'm getting is

System.DmlException: Update failed. First exception on row 0 with id 006180000023YfvAAE; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Upsert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: []: []: []

If I turn off the OpportunityContactRoles class I mentioned, my new test class passes 100%. So I've added comments all the way through the contact roles class and I've found that once it hits the upsert statement is what is causing this to happen. 

Is there any particular reason why an opportunity being created using the .clone() method would cause issues with opportunityContactRoles?

Opportunity clonedOpp = opportunity.clone(false, false, true, false);
I'm having trouble figuring out why the following code is not returning an Id so I can get to the point of refreshing my tab. I'm in debug mode and basically what I'm finding is that sforce.console.getEnclosingPrimaryTabId() is returning null. The event listener is firing correctly, so I know it's not an issue with that.

Does anyone see an obvious error that I don't or know of a bug that could be affecting this? Even if I rip the code straight out of Salesforce's documentation, I found that no results are returned.
<apex:page standardController="Account" extensions="FC_AccountExtension" title="{!account.Name}">
    <apex:detail relatedList="true"/>

    <apex:includeScript value="/support/console/31.0/integration.js"/>
    <script type='text/javascript'>
        //Set the title of the tab of the VF page to match the account
        sforce.console.setTabTitle('{!account.Name}');
        
        var listener = function (result) {
            alert('Message received from event: ' + result.message);
        };

        function refreshDetailListener() {
            console.log('refreshDetailListener fired!');

            var enclosingPrimaryTabId = sforce.console.getEnclosingPrimaryTabId();                
            console.log('enclosingPrimaryTabId: ' + enclosingPrimaryTabId );
            
            var enclosingTabId = sforce.console.getEnclosingTabId();    
            console.log('enclosingTabId: ' + enclosingTabId);
        }       
        
        //Add listeners
        sforce.console.addEventListener('SampleEvent', listener);
        sforce.console.addEventListener('refreshDetail', refreshDetailListener);
    </script>
</apex:page>


Hi All,

I have a very frustrating refresh issue that I've been trying to figure out and I've gotten nowhere.

Essentially, I'm coding for the service cloud console where my components are custom visualforce pages leveraging the standard controller with a custom extension to handle custom actions and page redirects.

Ideally, if the user saves the record, the entire record should refresh. This is accomplished with javascript pretty easily - I just have to specify in my apex code that the pageRefrence returns null to ensure the javascript gets invoked.

However, the problem is if the record isn't successfully saved, then I need an error message to display. If I let the javascript refresh the page, then it the error message is not displayed and the whole thing refreshes and wipes out any information the user may have typed (making it look like a successful save to boot). If I set the returned pageReference to CurrnentPage(), then the error will not display unless I remove the javascript function out of the apex:commandButton tag - but then I don't get the refreshes on a successful save.

How do I get my javascript and apex to play nicely? I tried using a boolean variable to tell the javascript to run, but it seems that even if I tell it not to refresh, just the javascript running removes the error message from displaying on the page. I also tried saving the error message to a public variable to see if I could let it refresh anyways, but shortly scratched that idea after realizing there was no way to reset the user's values. Here's where I left off at...

Any suggestions might bring back some of my sanity on this topic.

Here's my visualforce page:
<apex:page standardController="Account" extensions="FC_AccountExtension">

    <style type="text/css">
        .bPageBlock .detailList .labelCol {
            width: 4%;
        }
    </style>

    <apex:sectionHeader title="Task" subtitle="New Task" />
 
    <apex:form >
    <apex:pageBlock title="Task Edit" mode="Edit">
        <apex:pageBlockButtons location="top">
            <apex:commandButton action="{!saveTask}" oncomplete="doRefreshPage({!refreshConsole}); return false;" value="Save" id="save"/>
            <!--oncomplete="doRefreshPage(); return false;"  oncomplete="doRefreshPage({!refreshConsole}); return false;" -->
            <apex:commandButton action="{!cancelTask}" value="Cancel" immediate="true"/>
        </apex:pageBlockButtons>
        
        <br/><br/>
        <apex:pageMessages />
        <apex:pageMessage severity="ERROR" summary="{!errorMessage}" rendered="{!errorMessage != null}" strength="3" />        
        <apex:pageBlockSection title="Task Information" columns="2">
            <apex:pageBlockSection columns="1" showHeader="false">
                <apex:inputField value="{!task.OwnerId}" required="true"/>
                <apex:inputField value="{!task.Subject}" required="true"/>
                <apex:inputfield value="{!task.ActivityDate}"/>
                <apex:inputField value="{!task.Priority}" required="true"/>
                <apex:inputField value="{!task.Demo__c}"/>
                <apex:inputField value="{!task.Pre_Call__c}"/>
                <apex:inputField value="{!task.Call_attempted_no_message_left__c}"/>
                <apex:inputField value="{!task.Prospecting_call_connected__c}"/>
                <apex:inputField value="{!task.Prospecting_call_left_message__c}"/>
                <apex:inputField value="{!task.Prospecting_call_affirmative__c}"/>
                <apex:inputField value="{!task.Add_to_Campaign__c}"/>
                <apex:inputField value="{!task.Promotion_Campaign__c}"/>
                <apex:inputField value="{!task.Billable_Docs__c}"/>                                                                                                                                                
            </apex:pageBlockSection>
            <apex:pageBlockSection columns="1" showHeader="false">
                <apex:inputField value="{!task.Status}"/>
                <apex:inputField value="{!task.Type}"/>
                <apex:inputField value="{!task.WhoId}"/>
                <apex:inputField value="{!task.WhatId}"/>
                <apex:inputField value="{!task.Promo__c}"/>
                <apex:inputField value="{!task.No_Promo__c}"/>
                <apex:inputField value="{!task.On_site_call_connected__c}"/>
                <apex:inputField value="{!task.On_site_call_dropped_lit__c}" label="On site call, dropped it?"/>
                <apex:inputField value="{!task.Unknown_PM_System_Call__c}"/>
            </apex:pageBlockSection>            
        </apex:pageBlockSection>     
        <apex:pageBlockSection columns="1" title="Additional Comments">
            <apex:inputField value="{!task.Description}" style="width:98%;"/>
        </apex:pageBlockSection>   
    </apex:pageBlock>
    </apex:form>

    <apex:includeScript value="/support/console/31.0/integration.js"/>    
    <script type='text/javascript'>
        //This function allows the user to press enter to search
        var refreshPrimaryTab = function showTabId(result) {
            var tabId = result.id;
            sforce.console.refreshPrimaryTabById(tabId, true);
        }
        function doRefreshPage(refreshConsole) {
            if(refreshConsole == true)
                sforce.console.getEnclosingPrimaryTabId(refreshPrimaryTab);
        }
    </script>      
</apex:page>

And the part of the controller that's relevant:
public pageReference saveTask() {
        PageReference pageRef = null;
        refreshConsole = false;
        
        try {
            //upsert for updating/inserting new contact
            upsert task;
            
            //Allow the javascript to refresh the page
            refreshConsole = true;

            //clear the task for next action
            //pageRef = new PageReference('/apex/SCC_Task_Related_List?id=' + task.WhatId);
            //pageRef.setRedirect(true);
            task = null;
        }
        catch(system.DMLException e) {
            //ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, e.getDmlMessage(0)));
            errorMessage = e.getDMLMessage(0);
            pageRef = ApexPages.CurrentPage();
        }
        
        //Do not need to set a page redirect here otherwise it overrides the javascript to refresh            
        return pageRef;
    }


Hi All,

I've been pulling my hair out trying to figure out why changing the Case.Type drop down to 'Remove Providers' will not display the apex:pageMessage with a required disclaimer that we need. I don't see anything in the documentation that would otherwise suggest that this will not work. Any ideas? I've tried using a controller as well to update boolean variable and that had no effect either.

Here's my code:

<apex:page standardController="Case" extensions="CP_Case_Extension">
    <apex:sectionHeader title="Case Edit" subtitle="New Case"/>

    <apex:outputPanel id="disclaimerBlock" >
        <apex:pageMessage severity="info" strength="3" escape="false" rendered="{!Case.Type = 'Remove Providers'}"
            summary="By clicking &quot;Accept,&quot; you acknowledge that you may no longer bill for a provider once the provider has been removed. Please complete all outstanding AR before finalizing this change. If applicable, billing changes will be reflected in the invoice for the next full billing cycle."/>
    </apex:outputPanel>    
    
    <br/>

    <apex:form >
        <apex:pageBlock title="Case Edit" mode="Edit" >
            <apex:pageBlockButtons location="top" >
                <apex:commandButton value="Submit" action="{!Save}"/>
                <apex:commandButton value="Cancel" action="{!Cancel}"/>
            </apex:pageBlockButtons>  
            
            <apex:actionRegion>
            <apex:pageBlockSection title="Case Information" columns="1" >
                <apex:inputField required="true" value="{!Case.Subject}"/> 
                <apex:inputField required="true" value="{!Case.Type}">
                    <apex:actionSupport event="onchange" rerender="disclaimerBlock"/>                               
                </apex:inputField> 
            </apex:pageBlockSection> 
            </apex:actionRegion> 
                                         
            <apex:pageBlockSection title="Description Information" columns="1">
                <apex:inputField required="true" value="{!Case.Case_Notes__c}"/>
            </apex:pageBlockSection>   
        </apex:pageBlock>
    </apex:form>
</apex:page>
Thanks!
Kelly
  • September 26, 2014
  • Like
  • 0
Hi All,

I'm trying to make an added VF element to a page layout line up in our customer portal and I'm having issues.

For the CSS, I've found using inspect element that this piece of code controlls it:

.bPageBlock .detailList td.data2Col.last {
            padding: 2px 2px 2px 10px;
            text-align: left;
            width: 82%;
        }

Once I change the 10px in chrome to 2px, it aligns correctly. However, when I apply that to my visualforce code, the update doesn't stick. Does anyone know why? Any help is greatly appreciated...
User-added image

Here's my vf code:
<apex:page standardController="Account" extensions="CP_AccountExtension" >
    <style type="text/css">
        .bPageBlock .detailList td.data2Col.last {
            padding: 2px 2px 2px 2px;
            text-align: left;
            width: 82%;
        }  
        .pageBlockTable {
            font-size:11.5px;           
        }
        .pageBlockTableHeader {
            font-size:9.5px;
            border-color: white;
        }
        .bPageBlock,
        .individualPalette .bPageBlock {           
            border-bottom:0px;
            border-left:0px;
            border-right:0px;
            border-top:0px;
        }
        .bPageBlock .pbBody{
            padding:0px 0px 0px 0px;
        }

    </style>

    <apex:pageBlock id="pageBlock" rendered="{!filteredContacts.size!=0}">
        <apex:pageBlockTable id="pageBlockTable" styleclass="pageBlockTableHeader" border="0" value="{!filteredContacts}" var="Contacts" >
            <apex:column value="{!Contacts.FirstName} {!Contacts.LastName}" styleClass="pageBlockTable "><apex:facet name="header">Contact Name</apex:facet></apex:column>
            <apex:column value="{!Contacts.Title}" styleClass="pageBlockTable "/>
            <apex:column value="{!Contacts.Email}" styleClass="pageBlockTable "/>
            <apex:column value="{!Contacts.Phone_Ext__c}" styleClass="pageBlockTable "><apex:facet name="header">Phone</apex:facet></apex:column>
            <apex:column value="{!Contacts.Primary__c}" styleClass="pageBlockTable "/>
        </apex:pageBlockTable>       
    </apex:pageBlock>
</apex:page>
Hi All,

Our org is about to go through a server split and I have almost all of the server references updated with the exception of some of our links that display in our customer portal.

If I have a link like this, where id is a document and oid is the org id, how can I make the c.na13 be dynamic to where it always pulls the current server instance?
https://c.na13.content.force.com/servlet/servlet.ImageServer?id=015a0000002B4pK&oid=00D300000000Q4e&lastMod=1358282384000

The link is located in a visualforce page.

I've looked at these links, but none of them describe how to handle c.naX.content.force
https://help.salesforce.com/apex/HTViewSolution?urlname=How-to-prepare-for-a-Split&language=en_US&elq_mid=5931&elq_cid=8761032
https://developer.salesforce.com/page/Best_Practices_When_Referencing_Server_Endpoints#How_to_find_hard-coded_references_using_the_Force.com_IDE 

Thanks!
Hi All,

Last week, we some of our users using our service cloud console reported having issues viewing tasks on our custom Accounting object and kept repeatedly getting 'data not available.' I opened a case with Salesforce and they were less than helpful and said we can replicate the error, but we can't help you because you're not premier support and this is an apex/visualforce error. They wouldn't explain why and I've sat on the phone trying to get a hold of someone for about 40 minutes now.

So I looked a little further into it, and found that only archived tasks were having an issue. Also, I've had a simple visualforce page that has been used in our service cloud console since 2012 that merely displays the mini page layout correclty in the service cloud console.

This is my visualforce code:

<apex:page standardController="Task">   
    <script type="text/javascript">
        window.location = '/{!Task.WhatId}/m?isdtp=vw';
    </script>
</apex:page>

Can anyone tell me if they've changed something on the back end that no longer allows the standard controller to access archived tasks? I found this, but I have no idea when it was published: http://help.salesforce.com/apex/HTViewSolution?id=000003859&language=en_US

Outside of building a custom controller, is there another way I should consider building this?

Thanks!
Kelly
Hi All,

This article has been helpful on getting me started: http://salesforce.stackexchange.com/questions/4193/update-a-records-using-generic-fields 

For my application I'm trying update several fields on a contract based on the products that are selected on an opportunity.  I'm using a crosswalk object that has information on which field to update and with what kind of value. Here's a snippet of the code I'm working with and I know it works:

//Update Opportunity Products & Opportunity
  for(Opportunity opportunity : opportunitiesMap.values()) {
   //Update Opportunity with Contract Number
   Opportunity opportunityForUpdate = new Opportunity(Id = opportunity.Id, Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id);
   opportunitiesToUpdate.add(opportunityForUpdate);

   //Update Opportunity Products with Contract Number
   for(OpportunityLineItem oppProduct : opportunitiesToProductsMap.get(opportunity.Id)) {
    oppProduct.Contract_Number__c = opportunityToContractMap.get(opportunity.Id).Id;
    productsToUpdate.add(oppProduct);

    for(Product_to_Contract_Matrix__c p2cm : productsToMatrixMap.get(oppProduct.PriceBookEntry.Product2Id)) {
     Schema.SObjectField currentField = contractFields.get(p2cm.Contract_Field_to_Update__c);
     Contract contract = new Contract(Id = opportunityToContractMap.get(opportunity.Id).Id);

     if(p2cm.Update_Type__c == 'Text')
      contract.put(currentField, p2cm.Update_Value_With__c);
     else if(p2cm.Update_Type__c == 'Date')
      contract.put(currentField, system.today());
     else if(p2cm.Update_Type__c == 'Rate (String)')
      contract.put(currentField, String.valueOf(oppProduct.UnitPrice));
     else if(p2cm.Update_Type__c == 'Rate (Numeric)')
      contract.put(currentField, oppProduct.UnitPrice);
     //contractsToUpsert.put(contract.Id, contract);
     upsert contract;
    }
   }
  }

Problem is that the DML statement to update the contract is 3 for loops in and can potentially end up updating upwards of 30 to 50 fields for one contract record - easily hitting governor limits. I tried assigning it to a list as you can see with the commented out line just above, but I found that I using this method overwrites the previous field update in the loop.

Does anyone have any thoughts on how I can modify my code to where I only need 1 DML statement and still apply all the updates to my contract record?

Much appreciated!
Hi All,

I've created an apex controller that uses SOSL for a custom search and a related visualforce page to display the results. I've also created a home page HTML component that contains a text field and button that would ideally call the method from my controller and update the visualforce page with the results.

I'm new to this part of coding and I'm not sure how to get the javascript in the HTML component to speak to my controller and redirect to the page with the results. Does anyone have any documentation, examples, or a good website reference? Any help would be greatly appreciated!

My HTML code for the home page component looks like this:
<form>
<input type="text" name="searchText" size="18" onkeypress="return noenter(event)"><button type="button" onclick="openSearch()">Go!</button>
<br><input type="checkbox" value="itemsOwned">Limit to items I own
</form>

The controller is simple:
public with sharing class CustomSearch {

public String searchText {get; set;}
public Boolean itemsOwned {get; set;}

public Id currentUser {
  get {
    if (currentUser == null)
     currentUser = userInfo.getUserId();
   
    return currentUser;
   }
  set;
}

public Account[] accountResults {get; set;}
public Contact[] contactResults {get; set;}
public Lead[] leadResults {get; set;}
public Opportunity[] opportunityResults {get; set;}

public PageReference doSearch() { 
  String queryString;
 
  if(!itemsOwned)
   queryString = 'FIND \'' + searchText +'*'+'\' IN ALL FIELDS RETURNING ' +
        'Account (Id, Name, Customer_ID__c, Status__c, Phone, Billable_Docs_Original__c, BillingStreet, BillingCity, BillingState), ' +
        'Contact (Id, Name, Title, Phone, Email, Account_Status__c, AccountId, MailingStreet, MailingState, Inactive__c, Navicure_User_Entity__c), ' +
        'Lead (Id, Name, Company, Status_of_Lead__c, Title, Phone, Email, Street, City, State), ' +
        'Opportunity (Id, Name, Type, AccountId, StageName, CloseDate, OwnerId)';
  else
   queryString = 'FIND \'' + searchText +'*'+'\' IN ALL FIELDS RETURNING ' +
        'Account (Id, Name, Customer_ID__c, Status__c, Phone, Billable_Docs_Original__c, BillingStreet, BillingCity, BillingState WHERE OwnerId = \'' + currentUser + '\'), ' +
        'Contact (Id, Name, Title, Phone, Email, Account_Status__c, AccountId, MailingStreet, MailingState, Inactive__c, Navicure_User_Entity__c WHERE OwnerId = \'' + currentUser + '\'), ' +
        'Lead (Id, Name, Company, Status_of_Lead__c, Title, Phone, Email, Street, City, State WHERE OwnerId = \'' + currentUser + '\'), ' +
        'Opportunity (Id, OwnerId, Name, Type, AccountId, StageName, CloseDate, OwnerId WHERE OwnerId = \'' + currentUser + '\')';
   

  try {
   list<list<sObject>> query = search.query(queryString);

   accountResults = ((list<Account>) query[0]);
   contactResults = ((list<Contact>) query[1]);
   leadResults = ((list<Lead>) query[2]);
   opportunityResults = ((list<Opportunity>) query[3]);  
  
  }
      catch (QueryException ex){
      ApexPages.addMessages(ex);
      return null;
      }
     
      catch (Exception exx){
       ApexPages.addMessages(exx);
       return null;
      }     

  return null;
    }
}

I'm interested in migrating from eclipse into the developer console, but I'm struggling with how big the font is as well as the awkward coloring system. Is there a way where I can customize this? I didn't see any options in the console itself.

Hi All,

 

I've gone through a couple of sites including 

  1. http://blog.jeffdouglas.com/2011/08/12/roll-your-own-salesforce-lookup-popup-window/
  2. http://bobbuzzard.blogspot.com/2010/09/visualforce-lookup.html
  3. http://boards.developerforce.com/t5/Visualforce-Development/Overriding-lookup-icon/m-p/196802#M26504 (no solution found)

The jist of what I'm trying to do is override all of our lookup on the account detail for the "Go Forward PM System" object. The reason why is that sometimes the name of the GFPM is different than the vendor that sells it. I can add additional filters to the standard lookup page, but this only filters off of the 'recently' viewed, which is not helpful since we have quite a few GFPM records.

 

However, I do not want to completely override our standard account page since we have several record types and layouts with over 100 fields on each. I am able to override the lookup, but I am having trouble passing the Id of the selection back to the account page. In both of the examples by Jeff and Bob, they are able to pass it back by having the field element specified as apex:inputfield. With apex:detail, is there a way to get the field Id to pass it back? If so how can I pass it back? I also humored the idea of using a hiddenInput, but ideally, I would like the user to be able to see that they modified the page (standard feel).

 

I have very limited javascript expereince, so that's where the additional struggle is coming from. Any education you gurus can provide would be greatly helpful.

 

Here's what I have so far:

Detail Page:

<apex:page standardController="Account">
    <script type="text/javascript"> 
   	
		function openLookup(baseURL, width, modified, searchParam) {
			var lookupType = baseURL.substr(baseURL.length-3,3); //This is the value for lktp
			//var lookupFieldId = baseURL.substr(baseURL.length-38,17); //This is the value for lknm, renamed as txtId
			//var lookupFormId = escapeUTF("{!$Component.detail}"); //This is the value for the other half of lknm, identifying the form, renamed as frm
			
			if(lookupType == "a1i") {
				var urlArr = baseURL.split("&");				
				var txtId = '';
				if(urlArr.length > 2) {
					urlArr = urlArr[1].split('=');
					txtId = urlArr[1];
				}
				
				baseURL = "/apex/GFPMCustomLookupSearch?txt=" + txtId + "&frm=" + escapeUTF("{!$Component.detail}");  		
			}
			
			openPopup(baseURL, "lookup", 350, 480, "width="+width+",height=480,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no", true);
		}		
    </script>    
    <apex:form >
    	<apex:inputField value="{!account.Go_Forward_PM_System__c}"/>
    </apex:form>
    <apex:detail id="detail" inlineEdit="true"/>
</apex:page>

 

 

Lookup page: 

<apex:page controller="GFPMDynamicSearch" title="Search" showHeader="false" sideBar="false" tabStyle="Go_Forward_PM_System__c" id="pg">

	<apex:form id="form">
	<apex:actionFunction name="doSearchAF" action="{!searchGFPM}"/>
	<apex:outputPanel id="page" layout="block" style="margin:5px;padding:10px;padding-top:2px;">
		<apex:actionRegion >
			<apex:outputPanel id="top" layout="block" style="margin:5px;padding:10px;padding-top:2px;">
			<apex:outputLabel value="Search" style="font-weight:Bold;padding-right:10px;" for="txtSearch" />
				<apex:inputText id="txtSearch" value="{!searchText}" onkeypress="return noenter(event);" />
				<span style="padding-left:5px">
					<apex:commandButton id="btnSearch" value="Search" action="{!searchGFPM}" rerender="searchResults"/>
				    <apex:actionStatus id="status" startText="requesting..."/>
				</span>
			</apex:outputPanel>
			
			<apex:outputPanel id="pnlSearchResults" style="margin:10px;height:350px;overflow-Y:auto;" layout="block">
				<apex:pageBlock id="searchResults"> 
					<apex:pageBlockTable value="{!results}" var="result" id="tblResults">
						<apex:column headerValue="Go Forward PM System">
							<apex:outputLink value="javascript&colon;top.window.opener.lookupPick2('{!FormTag}','{!TextBox}_lkid','{!TextBox}','{!result.Id}','{!result.Name}', false)" rendered="{!NOT(ISNULL(result.Id))}">{!result.Name}</apex:outputLink>
						</apex:column>					
				    	<apex:column headerValue="Vendor Account" value="{!result.Vendor_Account__r.Name}"/>
				    	<apex:column headerValue="Status" value="{!result.Status__c}"/>
					</apex:pageBlockTable>
				</apex:pageBlock>
			</apex:outputPanel>			
		</apex:actionRegion>			
	</apex:outputPanel>
	</apex:form>
	
	<script type='text/javascript'>
		//This function allows the user to press enter to search
		function noenter(ev) {
			if (window.event && window.event.keyCode == 13 || ev.which == 13) {
				doSearchAF();
				return false;
			} else {
				return true;
			}
		}
	</script>	
</apex:page>

 

  • September 30, 2013
  • Like
  • 0

Hi All,

 

I'm trying to bump up the code coverage on one of my triggers and I'm finding that my negative test case is not providing code coverage and I'm not sure why. Still new to negative case testing, can anyone shed some light on what I'm overlooking?

 

Also, can anyone point me to an article or explain what exactly the Exception class includes (I'm not sure why you would use catch(Exception e) versus any of the ones listed here: http://www.salesforce.com/us/developer/docs/apexcode/index.htm)

 

Appreciate the help. - Kelly

 

Here's what's in the trigger I'm trying to test:

            catch (System.DMLException e) {
                for (Contract contract : trigger.new) 
                    contract.adderror(e.getMessage());
            }

 

Here's my test method (it passes, just doesn't cover the above code on my trigger). I attempt to throw the DMLexcpetion by leaving a required field (by validation rule) blank.

	//Leave Client Diagnostic intentionally blank to see if it catches an error
	static testMethod void errorCheck(){
    	Account vendorAccount = new Account(Name = 'Vendor Acct', Status__c = 'Vendor', Type__c = 'Vendor');
    	insert vendorAccount;
    	
    	Go_Forward_PM_System__c goForwardPM = new Go_Forward_PM_System__c (Name = 'Greenway', Status__c = 'Partner', Client_Type__c = 'Channel', 
    		Vendor_Account__c = vendorAccount.Id);
    	insert goForwardPM;
    	
    	Account account = new Account(Name = 'Test Account', Status__c = 'Backlog', Type = 'Medical Practice', Go_Forward_PM_System__c = goForwardPM.Id, 
    		Number_of_Docs__c = 1, Leaving_Which_Clearinghouse__c = 'Cerner', Current_Clearinghouse__c = 'Cerner');
    	insert account;

		Opportunity opportunity = new Opportunity(Name='Test Opportunity', AccountId = account.Id, CloseDate=System.today(),
					Type='New Sale (Bundle)',StageName = 'Demo Scheduled',Sales_Commit__c='Commit', RecordTypeId ='01230000000Jcoh',
					Client_Services_select_one__c ='Not Applicable');
		insert opportunity;
		
		//Insert contract with a product election value
		Contract contract = new Contract(AccountId = account.Id, Opportunity_Name__c = opportunity.Id, Product_Election__c = 'Connect');
		
		try {
			insert contract;
		}
		catch(DMLException e) {
			system.assertEquals(StatusCode.FIELD_CUSTOM_VALIDATION_EXCEPTION, e.getDmlType(0));
		}
	}	

 

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?