• Norm Copeland
  • NEWBIE
  • 40 Points
  • Member since 2014
  • Goodmanrobot Solutions

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 6
    Questions
  • 7
    Replies
Hi, I've only dabbled in Apex in the past but am keen to get a better understanding. I'm building a flow that I would like to have pass a collection of strings (which happen to be URLs to PDFs) to an an Apex action.

In that Apex action I want to send the list of URLs off to an api called API2PDF in order to merge the PDFs. I then need to send the resulting PDF back to the flow.

API2PDF provides the following Apex as an example:
 
String[] urls = new List<String>();
urls.add('http://www.orimi.com/pdf-test.pdf');
urls.add('http://www.orimi.com/pdf-test.pdf');
Api2PdfResponse pdfResponse = a2pClient.mergePdf(urls, true, 'test.pdf');
String pdfUrl = pdfResponse.getPdf();

I've been struggling to put together an invocable apex class that will take a collection of strings (URLS) that will then get added to the apex list urls which is passed to AP2PDF and returns the URL of the merged PDF.

Would anyone be able to give me some direction putting together the apex class? It's a bit beyond me at this point but I know I'll learn a lot picking apart some functioning code. Thank you!

 
Hi all, 

I have written a basic trigger that is meant to match it to a custom object that has two date fields; a start date and an end date. The closedate of the opportunity should be >= the start date and <= the end date. A custom field on the opp will then be updated with info from the custom object record. Because of the way that custom object is set up, there's only one record that will match each opportunity. My trigger works but with the SOQL query in the for loop, will not scale. With my SOQL query searching in a range, I'm having trouble bulkifying this (I am new to bulkifying and haven't written too many triggers). I'll paste my original un-bulkified code below. Thank you community for the help!
 
trigger emp_summary_at_time_of_donation on opportunity (before insert, before update) {

	for (Opportunity newOpp : Trigger.new) {

		// variables set
		Decimal account_num = decimal.valueOf(newOpp.Project_Account_Number__c);
		Date OppCloseDate = newOpp.CloseDate;

		system.debug (account_num);
		
		// SOQL Query finds matching member history record
		List<Member_History__c> MemberRecord = [SELECT Id,
										  			   Member__r.Sending_Country_NTMAA__c,
										  			   Start_Date__c,
										  			   End_Date__c,
													   Field__c,
													   Category_NTMAA__c,
													   Status_NTMAA__c
									 			  FROM Member_history__c
												 WHERE Member__r.Account_NTMAA__c = :account_num AND
										  			   Start_Date__c <= :OppCloseDate AND
										  			   End_Date__c >= :OppCloseDate
												 LIMIT 1];

		IF (MemberRecord.size() > 0){

			system.debug(MemberRecord.size());

			// Update opp with employee summary
			newOpp.employee_summary__c = 'SC:' +  MemberRecord.get(0).Member__r.Sending_Country_NTMAA__c +'|'+
										 'FLD:'+  MemberRecord.get(0).Field__c  +'|'+
										 'CAT:'+  MemberRecord.get(0).Category_NTMAA__c +'|'+
										 'STAT:'+ MemberRecord.get(0).Status_NTMAA__c;
		}
	}
}


 
Hi everyone, 

I'm using a great tool called Soapbox Mailer to send out mass emails in  Salesforce. Soapbox Mailer comes with a javascript button for the campaign object that sends the email using the following:
 
if (confirm('Are you sure you want to send this email?')) {
// Fire away!
window.location.href = "/apex/sbm__sbx_BatchEmailBlast?scontrolCaching=1&id={!Campaign.Id}";
} else {
// Go back to the Campaign page
}

I'd like to build a way to autmate the sending of the emails, based on a date field. Is there a way to use a Flow, Trigger or Process builder to launch /apex/sbm__sbx_BatchEmailBlast?scontrolCaching=1&id={!Campaign.Id} ? 

This would fire the email but I can's see any way to do this. It doesn't look like the class sbx_BatchEmailBlast is global. 

Would love to hear any suggestions on how/if this can work. Thank you!!
Hi all, I've just written my second trigger and it seems that I'm needing to learn more about how to optimize my code. My trigger runs through the campaign members of a campaign and changes the member status of any email duplicates (but leaves one) so  that an email isn't sent twice to one emails. As a nonprofit many of our donors share an email address in their household so we removing the email addresses from the contacts isn't possible. To help with this, I wrote the trigger below. It worked great in testing on a few hundred campaign members but when I tested it on a few thousand I recieved the dreaded 'System.LimitException: Apex CPU time limit exceeded'.

Could anyone help me optimize this code? I'd love to learn how and apply this knowledge to future triggers. Thank you!
 
trigger CleanEmailAddresses on Campaign (after update) {

	for (Campaign camp : Trigger.new) {
				
		// Check for clean email addresses trigger
		if (camp.clean_emails__c == true) {

			if (camp.IsActive && camp.Status != 'Completed' && camp.Status != 'Aborted') {

			// Counters used later
			Integer uniqueEmailCount = 0;
			Integer dupeCounter = 0;

			// Initialize list that will hold duplicate email addresses
			List<CampaignMember> theseAreTheDupes = new List<CampaignMember>();

			// Check to see if campaign has member status 'Email Duplicate'
			List<CampaignMemberStatus> campaignStatuses = [SELECT Id,
																  Label,
																  CampaignId
															 FROM CampaignMemberStatus
														    WHERE CampaignId = :camp.Id AND
														    	  Label 	 = 'Email Duplicate'];

			// No? Then create it
			if (campaignStatuses.size() == 0) {

				CampaignMemberStatus newCampaignMemberStatus = new CampaignMemberStatus();
				newCampaignMemberStatus.Label 				 = 'Email Duplicate';
				newCampaignMemberStatus.CampaignId 			 = camp.Id;
				insert newCampaignMemberStatus;

			}

			// Create list of email addresses already in campaign that do not have duplicate status
			List<CampaignMember> campaignMembers = [SELECT Id,
														   Email,
														   Status
													  FROM CampaignMember
													 WHERE CampaignId 	= :camp.Id AND
													 	   Status      != 'Email Duplicate' AND
													 	   HasResponded = false];

			
			// Initialize string set that will hold list of unique email addresses
			Set<string> uniqueEmails = new Set<string>();


			// Populate set with unique emails
			for (CampaignMember addToUniqueEmailSet : CampaignMembers) {
								
				uniqueEmails.add(addToUniqueEmailSet.Email);

			}

			// Loop through each unique email address
			for (String uniqueEmailList: uniqueEmails){
				
				// Loop through email campaign member
				for (Integer i = 0; i < campaignMembers.size(); i++) {
					

					// Check to see if current campaign member's email address matches unique address of current iteration
					if (campaignMembers.get(i).Email == uniqueEmailList) {

						// Count number of dupes
						uniqueEmailCount = uniqueEmailCount + 1;

						// Check to see if duplicate is the first one or note
						if (uniqueEmailCount > 1) {

							// If dupe is not the first, add to list of campaign members to change later
							theseAreTheDupes.add(campaignMembers.get(i));
							

						}

					}

				}
				
				// Reset counter
				uniqueEmailCount = 0;

			system.debug ('dupe list size: '+ theseAreTheDupes.size());	

			}

			if (theseAreTheDupes.isEmpty() == false) {

				for (CampaignMember cmChangeStatus : theseAreTheDupes) {

					theseAreTheDupes.get(dupeCounter).Status = 'Email Duplicate';
					dupeCounter = dupeCounter + 1;

				}

				update theseAreTheDupes;

			}

			} else {

				camp.addError('Whoa there partner! 🐴  Emails can not be cleaned from inactive, aborted or completed campaigns!');

			}

		}

	}

}

 
Hi, I've written a trigger and test class that will send out an email using the app SDocs (https://appexchange.salesforce.com/listingDetail?listingId=a0N30000003HeuPEAS).

It works perfectly when I code the trigger to use the running user (per Sdocs' examples) but we only have a limited number of sdocs licenses and so I'd like to set it to run using my username. According to the sdocs documentation (http://me2systemsllc.com/doc_category/s-docs-rest-api/) this is possible however SDocs only gives an example that grabs the username of the record owner. I'd like this trigger to always use the username one particular user. Here's what I have: 
 
trigger sendAdvocateAcceptanceNoticeReception on Program_Application__c (before update) {
	for (Program_Application__c l : Trigger.new){
		if (l.Send_Advocate_Notice_Reception__c){
			SDOC.SDBatch.CreateSDoc('norm_copeland@ntm.org.sandbox','id='+l.id+'&Object=Program_Application__c&doclist=a1d630000004DgQ&oneclick=1&sendEmail=1');
			l.Send_Advocate_Notice_Reception__c=false;
		}
	}
}


If you're at all familiar with SDocs I'd appreciate the help. Thank you! 
Hi, I'm a relatively new Salesforce admin (~ 1 yr) and this past weekend set up my first apex trigger that batch creates and emails them using the SDocs app. 

It works perfectly in my sandbox and I'm excited to use it in production however I'm struggling to set up and run the required test class before I deploy it. I've looked up Salesforce documentation related to creating Test Classes but haven't had any luck. Would anyone be able to help me create a test class for this apex trigger? I'd really appreciate it! Thanks in advance..

Here's the code for my apex trigger:
 
trigger SDocsSendForumReminder on Program_Application__c (before update) { 
for (Program_Application__c l : Trigger.new) 
if (l.SDocs_Send_Forum_Reminder__c){ 
SDOC.SDBatch.CreateSDoc(UserInfo.getSessionId(),'id='+l.id+'&Object=Program_Application__c&doclist=a1d170000000G1B&oneclick=1&sendEmail=1');
l.Sdocs_Forum_Reminder_Send_Time__c= datetime.now(); 
l.SDocs_Send_Forum_Reminder__c=false; 
}}

 
Hi, I've only dabbled in Apex in the past but am keen to get a better understanding. I'm building a flow that I would like to have pass a collection of strings (which happen to be URLs to PDFs) to an an Apex action.

In that Apex action I want to send the list of URLs off to an api called API2PDF in order to merge the PDFs. I then need to send the resulting PDF back to the flow.

API2PDF provides the following Apex as an example:
 
String[] urls = new List<String>();
urls.add('http://www.orimi.com/pdf-test.pdf');
urls.add('http://www.orimi.com/pdf-test.pdf');
Api2PdfResponse pdfResponse = a2pClient.mergePdf(urls, true, 'test.pdf');
String pdfUrl = pdfResponse.getPdf();

I've been struggling to put together an invocable apex class that will take a collection of strings (URLS) that will then get added to the apex list urls which is passed to AP2PDF and returns the URL of the merged PDF.

Would anyone be able to give me some direction putting together the apex class? It's a bit beyond me at this point but I know I'll learn a lot picking apart some functioning code. Thank you!

 
Hi all, 

I have written a basic trigger that is meant to match it to a custom object that has two date fields; a start date and an end date. The closedate of the opportunity should be >= the start date and <= the end date. A custom field on the opp will then be updated with info from the custom object record. Because of the way that custom object is set up, there's only one record that will match each opportunity. My trigger works but with the SOQL query in the for loop, will not scale. With my SOQL query searching in a range, I'm having trouble bulkifying this (I am new to bulkifying and haven't written too many triggers). I'll paste my original un-bulkified code below. Thank you community for the help!
 
trigger emp_summary_at_time_of_donation on opportunity (before insert, before update) {

	for (Opportunity newOpp : Trigger.new) {

		// variables set
		Decimal account_num = decimal.valueOf(newOpp.Project_Account_Number__c);
		Date OppCloseDate = newOpp.CloseDate;

		system.debug (account_num);
		
		// SOQL Query finds matching member history record
		List<Member_History__c> MemberRecord = [SELECT Id,
										  			   Member__r.Sending_Country_NTMAA__c,
										  			   Start_Date__c,
										  			   End_Date__c,
													   Field__c,
													   Category_NTMAA__c,
													   Status_NTMAA__c
									 			  FROM Member_history__c
												 WHERE Member__r.Account_NTMAA__c = :account_num AND
										  			   Start_Date__c <= :OppCloseDate AND
										  			   End_Date__c >= :OppCloseDate
												 LIMIT 1];

		IF (MemberRecord.size() > 0){

			system.debug(MemberRecord.size());

			// Update opp with employee summary
			newOpp.employee_summary__c = 'SC:' +  MemberRecord.get(0).Member__r.Sending_Country_NTMAA__c +'|'+
										 'FLD:'+  MemberRecord.get(0).Field__c  +'|'+
										 'CAT:'+  MemberRecord.get(0).Category_NTMAA__c +'|'+
										 'STAT:'+ MemberRecord.get(0).Status_NTMAA__c;
		}
	}
}


 
I have spent the last week working with Mailchimp to troubleshoot the MailChimp for Salesforce plugin, which is no loner syncing contacts from Salesforce onto our MailChimp list. MailChimp tech support has requested information from Salesforce Support in order to proceed with the troubleshooting. As a standard customer, I have been told the only way to access any support is through this forum, so I am hoping someone has insight!

What we know:
• Users of the MailChimp for Salesforce integration are experiencing an error that “a batch job is already in process”.
• From what we can see, these batch jobs are in a ‘holding’ state in the Apex flex queue, and are never moved to the Apex job queue for processing.
• In order to protect org resources, MailChimp integration will not start a second batch job if a MC4SF batch is already in the apex queue.
• We have established that there are no other apex jobs currently running that would cause the hold in the flex queue.
• Since we can verify that these batch jobs are being created successfully, the issue appears to be with how they are being handled for processing in these queues, which is a function controlled exclusively by Salesforce.

MailChimp support has asked me to find out:
• What could cause a job to remain in a ‘holding’ state in the flex queue?
• Is there anything that would prevent a batch job from being able to move from the flex queue to the job queue?
• Is there anything unique to this specific org or the Apex flex queue that would prevent these jobs from running as expected?
Hi, I'm a relatively new Salesforce admin (~ 1 yr) and this past weekend set up my first apex trigger that batch creates and emails them using the SDocs app. 

It works perfectly in my sandbox and I'm excited to use it in production however I'm struggling to set up and run the required test class before I deploy it. I've looked up Salesforce documentation related to creating Test Classes but haven't had any luck. Would anyone be able to help me create a test class for this apex trigger? I'd really appreciate it! Thanks in advance..

Here's the code for my apex trigger:
 
trigger SDocsSendForumReminder on Program_Application__c (before update) { 
for (Program_Application__c l : Trigger.new) 
if (l.SDocs_Send_Forum_Reminder__c){ 
SDOC.SDBatch.CreateSDoc(UserInfo.getSessionId(),'id='+l.id+'&Object=Program_Application__c&doclist=a1d170000000G1B&oneclick=1&sendEmail=1');
l.Sdocs_Forum_Reminder_Send_Time__c= datetime.now(); 
l.SDocs_Send_Forum_Reminder__c=false; 
}}