• Josh Davis 47
  • NEWBIE
  • 10 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 6
    Replies
I am working with events and cases but am having trouble on the concepts of joining two queries.  I need to query all events that:
  • completed yesterday
  • are related to a case (WhatId starts with 500)
  • are of event Type = 'Example'
Each of these are related to a case by definition of the original query, I now need to go through each of the cases and determine what the caseType__c is to determine the next_due_date__c which is a custom date field on the case which should calculate as:
  • Event Date + (If caseType__c = "Example" + 14, 60)

I am having a hard time figuring out how I work with values from two seperate arrays to come up with a calculation.  I was trying to use MAPs but I wasn't quite able to get it to work.

Can someone explain the approach?  Code examples would be great but I am more interested in the approach of how to do this...  So here is an example:

My SOQL Query to build the map between event and case
Map<WhatId, Event> eventCaseMap = new Map<WhatId, Event>([Select Id, WhatId, ActivityDate, Ended_Yesterday__c  From Event WHERE WhatId LIKE '500%' AND Type='Example' AND Ended_Yesterday__c = TRUE]);
Now that I have the map, I need to iterate through this to determine the caseType__c value to calculate the days until due, and then add that to the event ActivityDate so that I can update the case next_due_date__c.

If all the values existed on the same object I can get it to work, but trying to make a calculation off of two of them is where my problem is.  Thanks in advance for any help/direction.
 
Hey Everyone, I am having some issues with a Duplicate Rule and some APEX code.  The code itself works fine and I have no problems with its function, other than how it relates to the standard Duplicate Rules in Salesforce.

(illustration below) Through the Data Loader, I am inserting 227 Contacts with a batch size of 200, this splits into two batches, the 1st batch has a single record which matches according to the duplicate rule and so is prevented from being inserted resulting in a batch size of 199, the second batch has 27 contacts.  A trigger then passes Trigger.new into my AsyncProcessing class, which its only function is to take the batches of contacts, extract their IDs and comma seperate join them in groups of 100 and create a record on a custom object called 'AsyncRequests__c'.  

Everything functions correctly, if I System.Debug() the array sizes before and after insert, I show 2 AsyncRequest records for the first batch of 199 and 1 AsyncRequest record for the second batch of 27.  This is where things go sideways.  Even though there are no errors shown anywhere in the code (see the debug log below), the AsyncRequest__c records are not committed for the batch that has a duplicate error in it.  The contacts are successfully inserted (199) but my trigger/class that creates the AsyncRecords__c are not.  

My question is, how can I get around this or trap the error that is causing the roll back?  I am not sure why it successfully inserts the 199 contacts, my code takes those 199 then successfully inserts 2 AsyncRequest__c records, then ultimately rolls back the insert of the AsyncRequest__c records.  Since the record that was in error was never inserted why does it only affect my code of creating the custom records but the contacts themselves are inserted successfully?  Any direction would be great.  Thanks in Advance.
User-added image
Contact Trigger
trigger AsyncNPICall on Contact (after insert, after update) {
    System.debug(trigger.new);
    AsyncProcessing.handleNPITrigger(trigger.new, trigger.newMap,
        trigger.oldMap, trigger.operationType);
}

Class
public class AsyncProcessing {

	// Simple protection from workflows and triggers
	private static Boolean alreadyProcessed = false;	
	

	public static void handleNPITrigger(List<Contact> ContactList, 
		Map<ID, Contact> newMap, Map<ID, Contact> oldMap, 
		 TriggerOperation operation)
	{
		if(alreadyProcessed) return;
		alreadyProcessed = true;


		List<AsyncRequest__c> newAsyncRequests = new List<AsyncRequest__c>();
		List<String> textChangedIds = new List<ID>();

		System.debug('Total Contacts in Contact List: ' + ContactList.size());
		for(Contact co: ContactList)
		{
			if(operation == TriggerOperation.AFTER_INSERT && !String.isBlank(co.NPI__c) || co.NPI__c!= oldMap.get(co.id).NPI__c && !String.isBlank(co.NPI__c)) {
				textChangedIds.add(co.id); 
			}
			
			if(textChangedIds.size()>99) {
				newAsyncRequests.add(
					new AsyncRequest__c(
						AsyncType__c = 'NPI API Call',
						Params2__c = string.Join(textChangedIds,',')
					)
				);
				System.debug('Current Async Request Size in Loop: '+newAsyncRequests.size());
				textChangedIds.clear();
			}
		}

		if(textChangedIds.size()>0){
			newAsyncRequests.add(
				new AsyncRequest__c(
					AsyncType__c = 'NPI API Call',
					Params2__c = string.Join(textChangedIds,',')
				)
			);
		}
		System.debug('Async Request Size:' + newAsyncRequests.size());
		for( AsyncRequest__c a: newAsyncRequests){
			System.debug(a.Name + a.params2__c);
		}

		Database.SaveResult[] srList = database.insert(newAsyncRequests,false);
		system.debug(srList+'srList+++');
		for (Database.SaveResult sr : srList) {
		if (sr.isSuccess()) {
			// Operation was successful, so get the ID of the record that was processed
			System.debug('Successfully inserted AsyncRequest__c. AsyncRequest__c ID: ' + sr.getId());
		}else {
			for(Database.Error err : sr.getErrors()) {
				System.debug('The following error has occurred.');                    
				System.debug(err.getStatusCode() + ': ' + err.getMessage());
				System.debug('Error Ids: ' + err.getFields());
        	}
		}
		}


		for (AsyncRequest__c ar : newAsyncRequests) {
			System.debug(ar.id);
		}
	}

}

User-added image
Hey Everyone, I am having an issue with some code and can't find the answers I'm looking for, hopefully someone else has ran into this before.
Issue: Even though the code inserts the 'AsyncRequests__c' records and I can see in the debug log that they are inserted.  There is nothing in Salesforce that shows that they were.  If I go to the URL with the ID as specified it says 'Unfortunately, there was a problem. Please try again. If the problem continues, get in touch with your administrator with the error ID shown here and any other related details. The requested resource does not exist', there is no DML operations indicating deletion, there are no new records visible in the UI or anything in the recycling bin.  It is interesting to note that in my various tests

Trigger that Calls the Class, it is very simple and for the problem I am describing can be summed up by saying that 'Trigger.new' gets dumped into 'ContactList' used by the class.
trigger AsyncNPICall on Contact (after insert, after update) {
    AsyncProcessing.handleNPITrigger(trigger.new, trigger.newMap,
        trigger.oldMap, trigger.operationType);
}

Apex Class:
public class AsyncProcessing {

	// Simple protection from workflows and triggers
	private static Boolean alreadyProcessed = false;	

	public static void handleNPITrigger(List<Contact> ContactList, Map<ID, Contact> newMap, Map<ID, Contact> oldMap, TriggerOperation operation) {
		if(alreadyProcessed) return;
		alreadyProcessed = true;

		List<AsyncRequest__c> newAsyncRequests = new List<AsyncRequest__c>();
		List<String> textChangedIds = new List<ID>();

		System.debug('Total Contacts in Contact List: ' + ContactList.size());
		for(Contact co: ContactList)
		{
			// If the record is new and NPI != blank or if the NPI has changed
			if(operation == TriggerOperation.AFTER_INSERT && !String.isBlank(co.NPI__c) || co.NPI__c!= oldMap.get(co.id).NPI__c && !String.isBlank(co.NPI__c)) {
				textChangedIds.add(co.id); 
			}
			// Once 99 records have been looped, group them for Asynchronus Processing, join their IDs into a long text field on the custom object 'AsyncRequest__c'
			if(textChangedIds.size()>99) {
				newAsyncRequests.add(
					new AsyncRequest__c(
						AsyncType__c = 'NPI API Call',
						Params2__c = string.Join(textChangedIds,',')
					)
				);
				System.debug('Current Async Request Size in Loop: '+newAsyncRequests.size());
				textChangedIds.clear();
			}
		}
			// Whatever is left over after processing all the records if the amount never reached 99, create a final 'AsyncRequest__c' record to house them
		if(textChangedIds.size()>0){
			newAsyncRequests.add(
				new AsyncRequest__c(
					AsyncType__c = 'NPI API Call',
					Params2__c = string.Join(textChangedIds,',')
				)
			);
		}
		// System Debugging to ensure all values are present
		System.debug('Async Request Size:' + newAsyncRequests.size());
		for( AsyncRequest__c a: newAsyncRequests){
			System.debug(a.Name + a.params2__c);
		}

		insert(newAsyncRequests);
		
		// Debugging the final insert of the records
		for (AsyncRequest__c ar : newAsyncRequests) {
			System.debug(ar.id);
		}
	}
}

Debug Log:
User-added image

The final oddity in all of this is that even though there is no trace of the inserted records, the autonumbering in Salesforce does skip like the records were inserted.

I am at a loss for why this would be happening and wondering if someone might be able to point me in the right direction of what I am missing. Thanks in advance!
I am working with events and cases but am having trouble on the concepts of joining two queries.  I need to query all events that:
  • completed yesterday
  • are related to a case (WhatId starts with 500)
  • are of event Type = 'Example'
Each of these are related to a case by definition of the original query, I now need to go through each of the cases and determine what the caseType__c is to determine the next_due_date__c which is a custom date field on the case which should calculate as:
  • Event Date + (If caseType__c = "Example" + 14, 60)

I am having a hard time figuring out how I work with values from two seperate arrays to come up with a calculation.  I was trying to use MAPs but I wasn't quite able to get it to work.

Can someone explain the approach?  Code examples would be great but I am more interested in the approach of how to do this...  So here is an example:

My SOQL Query to build the map between event and case
Map<WhatId, Event> eventCaseMap = new Map<WhatId, Event>([Select Id, WhatId, ActivityDate, Ended_Yesterday__c  From Event WHERE WhatId LIKE '500%' AND Type='Example' AND Ended_Yesterday__c = TRUE]);
Now that I have the map, I need to iterate through this to determine the caseType__c value to calculate the days until due, and then add that to the event ActivityDate so that I can update the case next_due_date__c.

If all the values existed on the same object I can get it to work, but trying to make a calculation off of two of them is where my problem is.  Thanks in advance for any help/direction.
 
Hey Everyone, I am having some issues with a Duplicate Rule and some APEX code.  The code itself works fine and I have no problems with its function, other than how it relates to the standard Duplicate Rules in Salesforce.

(illustration below) Through the Data Loader, I am inserting 227 Contacts with a batch size of 200, this splits into two batches, the 1st batch has a single record which matches according to the duplicate rule and so is prevented from being inserted resulting in a batch size of 199, the second batch has 27 contacts.  A trigger then passes Trigger.new into my AsyncProcessing class, which its only function is to take the batches of contacts, extract their IDs and comma seperate join them in groups of 100 and create a record on a custom object called 'AsyncRequests__c'.  

Everything functions correctly, if I System.Debug() the array sizes before and after insert, I show 2 AsyncRequest records for the first batch of 199 and 1 AsyncRequest record for the second batch of 27.  This is where things go sideways.  Even though there are no errors shown anywhere in the code (see the debug log below), the AsyncRequest__c records are not committed for the batch that has a duplicate error in it.  The contacts are successfully inserted (199) but my trigger/class that creates the AsyncRecords__c are not.  

My question is, how can I get around this or trap the error that is causing the roll back?  I am not sure why it successfully inserts the 199 contacts, my code takes those 199 then successfully inserts 2 AsyncRequest__c records, then ultimately rolls back the insert of the AsyncRequest__c records.  Since the record that was in error was never inserted why does it only affect my code of creating the custom records but the contacts themselves are inserted successfully?  Any direction would be great.  Thanks in Advance.
User-added image
Contact Trigger
trigger AsyncNPICall on Contact (after insert, after update) {
    System.debug(trigger.new);
    AsyncProcessing.handleNPITrigger(trigger.new, trigger.newMap,
        trigger.oldMap, trigger.operationType);
}

Class
public class AsyncProcessing {

	// Simple protection from workflows and triggers
	private static Boolean alreadyProcessed = false;	
	

	public static void handleNPITrigger(List<Contact> ContactList, 
		Map<ID, Contact> newMap, Map<ID, Contact> oldMap, 
		 TriggerOperation operation)
	{
		if(alreadyProcessed) return;
		alreadyProcessed = true;


		List<AsyncRequest__c> newAsyncRequests = new List<AsyncRequest__c>();
		List<String> textChangedIds = new List<ID>();

		System.debug('Total Contacts in Contact List: ' + ContactList.size());
		for(Contact co: ContactList)
		{
			if(operation == TriggerOperation.AFTER_INSERT && !String.isBlank(co.NPI__c) || co.NPI__c!= oldMap.get(co.id).NPI__c && !String.isBlank(co.NPI__c)) {
				textChangedIds.add(co.id); 
			}
			
			if(textChangedIds.size()>99) {
				newAsyncRequests.add(
					new AsyncRequest__c(
						AsyncType__c = 'NPI API Call',
						Params2__c = string.Join(textChangedIds,',')
					)
				);
				System.debug('Current Async Request Size in Loop: '+newAsyncRequests.size());
				textChangedIds.clear();
			}
		}

		if(textChangedIds.size()>0){
			newAsyncRequests.add(
				new AsyncRequest__c(
					AsyncType__c = 'NPI API Call',
					Params2__c = string.Join(textChangedIds,',')
				)
			);
		}
		System.debug('Async Request Size:' + newAsyncRequests.size());
		for( AsyncRequest__c a: newAsyncRequests){
			System.debug(a.Name + a.params2__c);
		}

		Database.SaveResult[] srList = database.insert(newAsyncRequests,false);
		system.debug(srList+'srList+++');
		for (Database.SaveResult sr : srList) {
		if (sr.isSuccess()) {
			// Operation was successful, so get the ID of the record that was processed
			System.debug('Successfully inserted AsyncRequest__c. AsyncRequest__c ID: ' + sr.getId());
		}else {
			for(Database.Error err : sr.getErrors()) {
				System.debug('The following error has occurred.');                    
				System.debug(err.getStatusCode() + ': ' + err.getMessage());
				System.debug('Error Ids: ' + err.getFields());
        	}
		}
		}


		for (AsyncRequest__c ar : newAsyncRequests) {
			System.debug(ar.id);
		}
	}

}

User-added image
Hey Everyone, I am having an issue with some code and can't find the answers I'm looking for, hopefully someone else has ran into this before.
Issue: Even though the code inserts the 'AsyncRequests__c' records and I can see in the debug log that they are inserted.  There is nothing in Salesforce that shows that they were.  If I go to the URL with the ID as specified it says 'Unfortunately, there was a problem. Please try again. If the problem continues, get in touch with your administrator with the error ID shown here and any other related details. The requested resource does not exist', there is no DML operations indicating deletion, there are no new records visible in the UI or anything in the recycling bin.  It is interesting to note that in my various tests

Trigger that Calls the Class, it is very simple and for the problem I am describing can be summed up by saying that 'Trigger.new' gets dumped into 'ContactList' used by the class.
trigger AsyncNPICall on Contact (after insert, after update) {
    AsyncProcessing.handleNPITrigger(trigger.new, trigger.newMap,
        trigger.oldMap, trigger.operationType);
}

Apex Class:
public class AsyncProcessing {

	// Simple protection from workflows and triggers
	private static Boolean alreadyProcessed = false;	

	public static void handleNPITrigger(List<Contact> ContactList, Map<ID, Contact> newMap, Map<ID, Contact> oldMap, TriggerOperation operation) {
		if(alreadyProcessed) return;
		alreadyProcessed = true;

		List<AsyncRequest__c> newAsyncRequests = new List<AsyncRequest__c>();
		List<String> textChangedIds = new List<ID>();

		System.debug('Total Contacts in Contact List: ' + ContactList.size());
		for(Contact co: ContactList)
		{
			// If the record is new and NPI != blank or if the NPI has changed
			if(operation == TriggerOperation.AFTER_INSERT && !String.isBlank(co.NPI__c) || co.NPI__c!= oldMap.get(co.id).NPI__c && !String.isBlank(co.NPI__c)) {
				textChangedIds.add(co.id); 
			}
			// Once 99 records have been looped, group them for Asynchronus Processing, join their IDs into a long text field on the custom object 'AsyncRequest__c'
			if(textChangedIds.size()>99) {
				newAsyncRequests.add(
					new AsyncRequest__c(
						AsyncType__c = 'NPI API Call',
						Params2__c = string.Join(textChangedIds,',')
					)
				);
				System.debug('Current Async Request Size in Loop: '+newAsyncRequests.size());
				textChangedIds.clear();
			}
		}
			// Whatever is left over after processing all the records if the amount never reached 99, create a final 'AsyncRequest__c' record to house them
		if(textChangedIds.size()>0){
			newAsyncRequests.add(
				new AsyncRequest__c(
					AsyncType__c = 'NPI API Call',
					Params2__c = string.Join(textChangedIds,',')
				)
			);
		}
		// System Debugging to ensure all values are present
		System.debug('Async Request Size:' + newAsyncRequests.size());
		for( AsyncRequest__c a: newAsyncRequests){
			System.debug(a.Name + a.params2__c);
		}

		insert(newAsyncRequests);
		
		// Debugging the final insert of the records
		for (AsyncRequest__c ar : newAsyncRequests) {
			System.debug(ar.id);
		}
	}
}

Debug Log:
User-added image

The final oddity in all of this is that even though there is no trace of the inserted records, the autonumbering in Salesforce does skip like the records were inserted.

I am at a loss for why this would be happening and wondering if someone might be able to point me in the right direction of what I am missing. Thanks in advance!