• Big_B
  • NEWBIE
  • 0 Points
  • Member since 2012

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 1
    Replies
I have been tasked with implementing a method to only allow users to create opportunities from a contact record so we can track campaign and other contact related information.  My thought is to override the opportunity 'New' button so that it displays an error message to the user if they click the New button from any other page than the Contact page.

Does anyone have any sample code to do this?  I have seen Java used to pop up alerts from a button.  Would that be the route to go?  How can I tell what page/record the 'New' button is being clicked from?

I have done some VF and Apex coding and still very green but very willing to learn so I may need a bit more explaination of the code than the average poster.

Thanks in advance!
  • February 11, 2014
  • Like
  • 1

I am trying to validate that all opportunity products added to an opportunity are of the same category (custom field) and provide a user with an error if the category of subsequent opportunity products don't match the first one.

 

Here is my logic:

  1. Add the first opp product and the opp product WFR with field update takes the OppProductCategory value and plugs it into the OppCategory on the opportunity.
  2. Second opp product is added and the Validation rule compares the OppProductCategory value on the opp product with the new OppCategory on the opportunity.  If it matches, great.  If it doesn't then throw an error.

Everything works great unless 2 or more opp products with different category values are added during the initial 'Add Products' session.  It's almost like the WFR that should fire after each opp product is added isn't firing until after both records are added which renders the Validation rule for the 2nd opp product record useless.

 

Am I missing something with the timing or sequence of events?

 

Thanks!

Bryan

 

  • August 13, 2012
  • Like
  • 0

Hi Everyone!

 

I'm pretty new to Apex and am having an issue with bulkifying my Asset trigger code below.  Basically, I need to update account records based on information on the related asset records.  The code takes the Asset(s) from the trigger, creates a set for all the related accounts then uses that set in a SOQL query to pull a list of accounts and then pull a list of all active assets related to those accounts - which could include more asset records than the trigger asset(s).

 

I then have a for-loop to iterate through the accounts.  Inside that for-loop I then have another for-loop to iterate through the assets. If the account id in the asset for-loop == account in the account for-loop, use the asset info to update the account info.

 

Everything works fine until I do an update to the Asset object using data loader when there are a lot of records.  It successfully updates about 20 records and then the remaining records of the 200 record batch fail.  The error I get is:

 

'AssetTrigger: System.LimitException: Too many script statements: 200001'

 

I assume it is because I am iterating through ALL the asset records for each account id to look for a match that brings the statement count past the limit but I can't figure out a more efficient way to do it.  Is there a way to set up the asset for-loop to only iterate through the asset records where the account Id matches?  Could it be something else?  200000 statements seems REALLY high.

 

Any assistance would appreciated.  Don't be afraid to provide suggestions for improving any of the code - I can take it!

 

 

 

public with sharing class UpdateAcctFromAsset {

	public void updateAcctCustInfo(List<Asset> trigAssets)
	{	
		String sProdFam_TA = 'Recruitment';
		String sProdFam_TM = 'Talent Management';		
		String sProdFam_WCAD = 'Workforce Compliance';
		String sProdFam_VMS = 'Vendor Management';
		String sProdFam_LMS = 'Learning Management';
		String sProdFam_AQ = 'Aquire';
		String sProdFam_PRI = 'PRI';
		String sProdFam_Tablet = 'Tablet Application';
		
		//Get account id's from all Assets
		Set<Id> accountIds = new Set<Id>();
		for(Asset a: trigAssets){
			accountIds.add(a.AccountId);						
		}		
		//Get list of customer accounts so we can set the new values
		List<Account> custAccts = new List<Account>([Select Id, Type, TA_Client__c, TM_Client__c, WCAD_Client__c, 														LMS_Client__c, PRI_Client__c, VMS_Client__c, Aquire_Client__c, Tablet_Client__c
								from Account 
								where id IN :accountIds]);
														
		List<Asset> acctAssets	= new List<Asset>([Select Id, AccountId, Product_Family__c, System_Status__c 
								from Asset
								where AccountId IN :accountIds 
								AND (NOT System_Status__c = 'Inactive') 														AND (NOT System_Status__c = 'Cancelled')]);											
		
		//Cycle through accounts and update values		
		for(Account acct: custAccts){
			acct.TA_Client__c = false;
			acct.TM_Client__c = false;
			acct.WCAD_Client__c = false;
			acct.LMS_Client__c = false;
			acct.PRI_Client__c = false;
			acct.VMS_Client__c = false;
			acct.Aquire_Client__c = false;
			acct.Tablet_Client__c = false;
			Boolean bIsCustomer = false;		
			
			//Go through each Asset and update				
			for (Asset ast : acctAssets){
				if (ast.System_Status__c != 'Inactive' && ast.System_Status__c != 'Cancelled' && ast.AccountId == acct.Id){
					If (ast.Product_Family__c == sProdFam_TA){
						acct.TA_Client__c = true;
						bIsCustomer = true;
					}
					If (ast.Product_Family__c == sProdFam_TM){
						acct.TM_Client__c = true;
						bIsCustomer = true;
					}	
					If (ast.Product_Family__c == sProdFam_WCAD){
						acct.WCAD_Client__c = true;
						bIsCustomer = true;
					}
					
					If (ast.Product_Family__c == sProdFam_VMS){
						acct.VMS_Client__c = true;
						bIsCustomer = true;
					}
						
					If (ast.Product_Family__c == sProdFam_LMS){
						acct.LMS_Client__c = true;
						bIsCustomer = true;
					}
						
					If (ast.Product_Family__c == sProdFam_PRI){
						acct.PRI_Client__c = true;
						bIsCustomer = true;
					}
					
					If (ast.Product_Family__c == sProdFam_AQ){
						acct.Aquire_Client__c = true;
						bIsCustomer = true;
					}
						
					If (ast.Product_Family__c == sProdFam_Tablet){
						acct.Tablet_Client__c = true;
						bIsCustomer = true;
					}
				}									
			}
			//Update Account type status
			if (acct.Type != 'Partner' && bIsCustomer == true){
				acct.Type = 'Customer';			
			}
			if (acct.Type != 'Partner' && bIsCustomer == false){
				acct.Type = 'Prospect';
			}
		}					
		update custAccts;			
	}

 

  • March 21, 2012
  • Like
  • 0
I have been tasked with implementing a method to only allow users to create opportunities from a contact record so we can track campaign and other contact related information.  My thought is to override the opportunity 'New' button so that it displays an error message to the user if they click the New button from any other page than the Contact page.

Does anyone have any sample code to do this?  I have seen Java used to pop up alerts from a button.  Would that be the route to go?  How can I tell what page/record the 'New' button is being clicked from?

I have done some VF and Apex coding and still very green but very willing to learn so I may need a bit more explaination of the code than the average poster.

Thanks in advance!
  • February 11, 2014
  • Like
  • 1

Hi Everyone!

 

I'm pretty new to Apex and am having an issue with bulkifying my Asset trigger code below.  Basically, I need to update account records based on information on the related asset records.  The code takes the Asset(s) from the trigger, creates a set for all the related accounts then uses that set in a SOQL query to pull a list of accounts and then pull a list of all active assets related to those accounts - which could include more asset records than the trigger asset(s).

 

I then have a for-loop to iterate through the accounts.  Inside that for-loop I then have another for-loop to iterate through the assets. If the account id in the asset for-loop == account in the account for-loop, use the asset info to update the account info.

 

Everything works fine until I do an update to the Asset object using data loader when there are a lot of records.  It successfully updates about 20 records and then the remaining records of the 200 record batch fail.  The error I get is:

 

'AssetTrigger: System.LimitException: Too many script statements: 200001'

 

I assume it is because I am iterating through ALL the asset records for each account id to look for a match that brings the statement count past the limit but I can't figure out a more efficient way to do it.  Is there a way to set up the asset for-loop to only iterate through the asset records where the account Id matches?  Could it be something else?  200000 statements seems REALLY high.

 

Any assistance would appreciated.  Don't be afraid to provide suggestions for improving any of the code - I can take it!

 

 

 

public with sharing class UpdateAcctFromAsset {

	public void updateAcctCustInfo(List<Asset> trigAssets)
	{	
		String sProdFam_TA = 'Recruitment';
		String sProdFam_TM = 'Talent Management';		
		String sProdFam_WCAD = 'Workforce Compliance';
		String sProdFam_VMS = 'Vendor Management';
		String sProdFam_LMS = 'Learning Management';
		String sProdFam_AQ = 'Aquire';
		String sProdFam_PRI = 'PRI';
		String sProdFam_Tablet = 'Tablet Application';
		
		//Get account id's from all Assets
		Set<Id> accountIds = new Set<Id>();
		for(Asset a: trigAssets){
			accountIds.add(a.AccountId);						
		}		
		//Get list of customer accounts so we can set the new values
		List<Account> custAccts = new List<Account>([Select Id, Type, TA_Client__c, TM_Client__c, WCAD_Client__c, 														LMS_Client__c, PRI_Client__c, VMS_Client__c, Aquire_Client__c, Tablet_Client__c
								from Account 
								where id IN :accountIds]);
														
		List<Asset> acctAssets	= new List<Asset>([Select Id, AccountId, Product_Family__c, System_Status__c 
								from Asset
								where AccountId IN :accountIds 
								AND (NOT System_Status__c = 'Inactive') 														AND (NOT System_Status__c = 'Cancelled')]);											
		
		//Cycle through accounts and update values		
		for(Account acct: custAccts){
			acct.TA_Client__c = false;
			acct.TM_Client__c = false;
			acct.WCAD_Client__c = false;
			acct.LMS_Client__c = false;
			acct.PRI_Client__c = false;
			acct.VMS_Client__c = false;
			acct.Aquire_Client__c = false;
			acct.Tablet_Client__c = false;
			Boolean bIsCustomer = false;		
			
			//Go through each Asset and update				
			for (Asset ast : acctAssets){
				if (ast.System_Status__c != 'Inactive' && ast.System_Status__c != 'Cancelled' && ast.AccountId == acct.Id){
					If (ast.Product_Family__c == sProdFam_TA){
						acct.TA_Client__c = true;
						bIsCustomer = true;
					}
					If (ast.Product_Family__c == sProdFam_TM){
						acct.TM_Client__c = true;
						bIsCustomer = true;
					}	
					If (ast.Product_Family__c == sProdFam_WCAD){
						acct.WCAD_Client__c = true;
						bIsCustomer = true;
					}
					
					If (ast.Product_Family__c == sProdFam_VMS){
						acct.VMS_Client__c = true;
						bIsCustomer = true;
					}
						
					If (ast.Product_Family__c == sProdFam_LMS){
						acct.LMS_Client__c = true;
						bIsCustomer = true;
					}
						
					If (ast.Product_Family__c == sProdFam_PRI){
						acct.PRI_Client__c = true;
						bIsCustomer = true;
					}
					
					If (ast.Product_Family__c == sProdFam_AQ){
						acct.Aquire_Client__c = true;
						bIsCustomer = true;
					}
						
					If (ast.Product_Family__c == sProdFam_Tablet){
						acct.Tablet_Client__c = true;
						bIsCustomer = true;
					}
				}									
			}
			//Update Account type status
			if (acct.Type != 'Partner' && bIsCustomer == true){
				acct.Type = 'Customer';			
			}
			if (acct.Type != 'Partner' && bIsCustomer == false){
				acct.Type = 'Prospect';
			}
		}					
		update custAccts;			
	}

 

  • March 21, 2012
  • Like
  • 0