• SeanGorman
  • NEWBIE
  • 0 Points
  • Member since 2013

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 9
    Questions
  • 7
    Replies
I'm writing a class that fires on insert/update of a trigger on the OpportunityLineItem. This looks at a picklist field (Play__c) on Product2.

When Opportunity products are added (which may be in batches) I need to count the number of each possible variation in the picklist for each account.

Opp 1 has 5 products added. 2 are Red, 2 are Black and one is White. There are a number of fields on the Opp: isRed, isBlack and IsWhite into which those number must go.

My first take is that an aggregate function would do. My Primary key is Oppid and Play__c in order to count Play__c:

AggregateResult[] OppLineItemsPlays = [select OpportunityId, COUNT(id), PricebookEntry.Product2.Play__c
           from OpportunityLineItem
           where OpportunityId in: oppid
           group by OpportunityId, PricebookEntry.Product2.Play__c];
  System.debug('\n ------------------->OppLineItemsPlays = ' + OppLineItemsPlays);

for(AggregateResult OLIPlays: OppLineItemsPlays) {
   opportunityCount.put((ID) OLIPlays.get('OpportunityId'), (Integer)OLIPlays.get('expr0'));
   System.debug('\n ------------------->Opportunity id = ' + OLIPlays.get('OpportunityId'));
   System.debug('\n ------------------->Play__c = ' + OLIPlays.get('Play__c'));
   System.debug('\n ------------------->count = ' + OLIPlays.get('expr0'));
   System.debug('\n ------------------->OLIPlays = ' + OLIPlays);
//  }

This gives me a count of all of the times that each Play has been selected in Products in OLIs and gives me the name of the play.

Here is my issue and its a bit silly: how would you proceed from here?
My thoughts are to create a new map for every variation of Play and then add the Oppid, Count(Play__c). This means that I have to know every possible play (which I do) and can control the creation of new ones (which I can)
Alternatively a map of ids to a map of strings to integers: [map<id, map<string, integer>> opptyPlayCount = new map<id, map<string, integer>>();]


when I get to saving this I have the Oppids.
for(Id opptyId : summedOpptyIds) {
         opps.add(new Opportunity(
          Id = opptyId,
          Booking_Amount__c = totalBookingAmts.get(opptyId)
          isRed = .................
         ));
        }

Hi,

 

I have read a few posts on this but I have found that it isn't working:

 

I have a custom object with a field called Video_or_Image_link__c. The contents of this are posted onto a VF page on a Spotlights area. The Spotlights are built inside a component.

 

Page:

<body>
<div class="h-base">
    <div class="b-content">
        <div class="b-columns">
	     <c:Spotlights />

 

Component:

<apex:component controller="Spotlight_Controller" access="global">
            <div class="b-spotlight">
                <div class="b-spotlight-title">Learning Spotlights <div class="m-toggler"><span>Hide</span><span class="m-last">Show</span></div></div>
                <div class="b-spotlight-body">
                    <div class="b-spotlight-content">
                        <div class="b-spotlight-tabs">
                            <apex:repeat value="{!Spotlinks}" var="link">
                                <div class="b-spotlight-tab"> {!link.Link_Text__c} <span class="m-arrow"></span></div>
                            </apex:repeat>
                            <p> </p>
                            <p> </p>
                        </div>
                        <div class="b-spotlight-tab-bodies">
                            <apex:repeat value="{!Spotlights}" var="spot">
                                <div class="b-spotlight-tab-body">
                                    <p class="m-title">{!spot.Title__c}</p>

<!-- COMMENTED OUT VIDEO VALUE
<apex:iframe id="vids" width="640" height="360" src="//{!spot.Video_or_Image_link__c}"></apex:iframe> -->

                                    <apex:outputText value="{!spot.Message_Content__c}" escape="false"/>

                                </div>
                            </apex:repeat>
                        </div>
                    </div>
                </div>
            </div>

</apex:component>

 

The problem have is that, when uncommented, the space is taken up by pane that says URL NO LONGER EXISTS "You have attempted to reach a URL that no longer exists on salesforce.com.". The same happens in Firefox, Chrome and IE.

 

The link on the object is www.youtube.com/embed/9D8X82sbewQ .

 

What do I need to do? What have I missed?

 

 

The Controller just for holistic purposes - I know that the data is there...

public with sharing class Spotlight_Controller {
	
	public list<Spotlight__c> Spotlights;
	public list<Spotlight__c> Spotlinks;
	public date dtToday;

	public Spotlight_Controller() {
        dtToday = date.today();
        system.debug('\n ----------------> opening controller');
	}

    public List<Spotlight__c> getSpotlights()
    {
		Spotlights = [select Title__c, Message_Content__c, Video_or_Image_link__c from Spotlight__c where Active__c = TRUE and Publish_Date__c <= :dtToday and End_by__c >= :dtToday order by order__c asc Limit 6];
        system.debug('\n ----------------> opening Spotlights = ' + Spotlights);
        return Spotlights;
    }

 

THis is a repeat post but I cannot find any way of getting this done:

 

I have a VF email template.

 

<messaging:emailTemplate subject="Account Training Review Required" recipientType="User" relatedToType="Case">
<messaging:HTMLEmailBody >
<html>

----

{!if(relatedTo.Education_checkbox__c = true, " as identified by the Product Support case owner.", " as indicated by a relatively high percentage of support calls having been resolved as 'how to' questions.")}

 The above is what I want... But try that and you get this error:

	Error: EL Expression Unbalanced: ... #{if(relatedTo.Education_checkbox__c = true, " as identified by the Product Support case owner.", " as indicated by a relatively high percentage of support calls having been resolved as 'how to' questions.")} This client’s particular profile#{if(relatedTo.Account.Business_Size__c = "BB", ", an account classified as Big Business,", if(relatedTo.Account.Business_Size__c = "SMB", ", an account classified as Small Business,", if(relatedTo.Account.Business_Size__c = "MB", ", an account classified as Mid-Size Business, ", "")))} has submitted #{if(text(floor(relatedTo.Account.AccountCases__c)) != "", text(FLOOR(relatedTo.Account.AccountCases__c)) & " how to cases in the last 90 days ", "no other cases categorised as how-to")} #{if(text(relatedTo.Account.Account_Cases_last_90_days__c) != "", " out of a total of " & TEXT(relatedTo.Account.Account_Cases_last_90_days__c) & " Product Support calls", "")}, which puts it in the #{relatedTo.AccountTrainingStatusCode__c} zone according to calculated metrics #{if(relatedTo.Account.MinCaseThreshold__c="Red", if(relatedTo.AccountTrainingStatusCode__c = "Red", " and " & relatedTo.Account.MinCaseThreshold__c & " when measured against the number of how to cases that we allow.", " but " & relatedTo.Account.MinCaseThreshold__c & " when measured against the number of how to cases that we allow."),".")}

 

If you try this: \'how to\' then you can save but the same thing is displayed in the email:

\'how to\'

 

Surround the text in the condition with htmlencode() and you see this in the email:

\&#39;how to\&#39;

 

Use jsencode() and you see this:

\\\'how to\\\'

 

Clearly the system wants me to escape the character but it then doesn't do anything about it.

 

Please can someone help?

I'm not sure that this is even possible but:

 

The requirement is to look at the last 90 days of cases by account and determine the average number of cases by account. THis is meant to be a running total - trying to find the top n accounts that require training at any given time. This functionality fires on update of the case.

 

Then I need to check those cases that match a certain Resolution code. (Training Required)

 

so:

		for (Case c: cases){
			system.debug('beforeAccountUpdate -->: Case: OwnerId: ' + c.OwnerId + ' Account: ' + c.AccountId + ' LastModifiedById: ' + c.LastModifiedById + ' Updated: ' + c.Updated__c);
			if (c.AccountId != null && c.Status <> 'Cancelled' && c.Type == 'Support'){
				accountIds.add(c.AccountId);
			}
		}
system.debug('\n accountIds -->: ' + accountIds );
		 
		AggregateResult[] allCases = [select accountid, count(id) from Case where CreatedDate > :dtCreate group by accountid];
		for(AggregateResult ar : allCases) {
			System.debug('\n ------------------->intTtlCases = ' + intTtlCases);
			intTtlCases  = intTtlCases + (Integer) ar.get('expr0');
		}
			System.debug('\n ------------------->allCases = ' + allCases);
			System.debug('\n ------------------->allCases.size() = ' + allCases.size());
		
		decAverage = intTtlCases/allCases.size();
			System.debug('\n ------------------->decAverage = ' + decAverage);
		
		AggregateResult[] AccountCases = [select accountid, COUNT(id) from Case where CreatedDate > :dtCreate and accountid in: accountIds group by accountid];
		for(AggregateResult ar : AccountCases) {
			AccCases.put((ID) ar.get('Accountid'), (Integer)ar.get('expr0'));
			System.debug('\n ------------------->Account id = ' + ar.get('accountid'));
			System.debug('\n ------------------->count = ' + ar.get('expr0'));
			System.debug('\n ------------------->AccCases = ' + AccCases);
		}
	 	// find all cases for all of the accounts in the last 90 days
	    if(accountIds != null && accountIds.size() > 0){
	        List<Account> lstAccount = [select id, AccountCases__c, Account_Training_last_90_days__c, (select id from Cases where CreatedDate > :dtCreate and Resolution_Code__c in :lstResCodes) from Account where id in: accountIds];

system.debug('\n lstAccount -->: ' + lstAccount );
	        if(lstAccount.size() > 0){
	            for(Account acc: lstAccount){
	            	if(acc.Cases.size() > 0){
						acc.AccountCases__c = acc.Cases.size();
						acc.Account_Cases_last_90_days__c = AccCases.get(acc.id);
	            	}
				}
system.debug('\n lstAccount -->: ' + lstAccount );
			 	// update the accounts with the number	            
	            update lstAccount;
			}
		}

 What I see is that the AggregateResult gets the first n results - not the whole database of <90 day old cases. That gives me an average which I know to be wrong from drawing a report into excel..

 

My question: How can I pull all of the cases, count them by account, get the average number for our client base then judge whether this account is in the top n, or not?

We have a trigger that, when a user is updated from Inactive to Active resets that persons password.

 

When I test in full sandbox it seems fine.

 

When I release it in a changeset it causes the below issue:

 

Failure Message: "System.DmlException: Update failed. First exception on row 0 with id 005800000059ETvAAM; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UserPasswordReset: execution of AfterUpdate caused by: System.UnexpectedException: UNKNOWN_EXCEPTION: An unexpected error occurred. Please include this ErrorId if you .

Trigger:

trigger UserPasswordReset on User (after update) {
   for (User u : Trigger.new){
      // Compares the new value of isActive flag on User table to the old value  
      if (u.isActive && !Trigger.oldMap.get(u.Id).isActive) {
         // If new value isActive is true and old value is false the user's 
         // password will be reset and an email notification will
         // be sent to them.
         System.resetPasswordResult rpr = System.resetPassword(u.Id, true);
      }
   } 
}

 

Test Class

@isTest(SeeAllData=TRUE) 
private class UserUpdateTriggerTest {

    static testMethod void UserTriggerTest() {

        Profile profile = [select id, Name from profile where name='Consumer Standard User'];
        User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
        List<User> uList = new List<User>();
        for (Integer i=0; i<10; i++){
            uList.add(new User(alias             = 'testu'+i
                    ,email             ='test_user_update'+i+'@test.com'
                    ,emailencodingkey  ='UTF-8'
                    ,lastname          ='test_user_update'+i
                    ,languagelocalekey ='en_US'
                    ,localesidkey      ='en_US'
                    ,profileid         = profile.Id
                    ,timezonesidkey    ='America/Los_Angeles'
                    ,username          ='test_user_update'+i+'@test.com'
                    ,Party_Id__c       = 'XX123'+i
                    ,isActive          = false
            ));
        }

        insert uList;

        system.runas(thisUser)
        {
            for (Integer i=0; i<10; i++) {
                uList[i].isActive = true;
            }
            update uList;
        }

    }

}

 

I have a very customised email in Visualforce.

 

I want to write quite complex sentences in it using IF statements but I have found that I get errors in the email template if I have a comma in the comment:

 

{!if(var=true, "AA", "A,A")} breaks when I try to save the template.

{!if(var=true, "AA", "A A")} works fine.

I have an issue and I'm struggling to work it out.

 

Object: Training

Object: Training Attendee

Object: Contact

Object: Account

Object: Account Training

 

User creates Training and adds attendees (Contacts)

Trigger automatically create new relationship between Account and Training in Account Training.

NB. If 10 attendees from 'CompanyA' are added then there will be 1 row in AccountTrainee

 

If attendee is removed from training then we need to check to see if the row in AccountTrainee should be deleted too. This may happen in bulk so.... it's not very easy.

	public void RemovingTraining_Method(list<Training_Attendee__c> Attendees)
	{
		map<id, id> ContacttoAtt = new map<id, id>();
		map<id, id> AttToTraining = new map<id, id>();
		map<id, list<Training__c>> AttTrName = new map<id, list<Training__c>>();
		map<id, id> AccounttoTraining = new map<id, id>();
		map<id, id> TrainingtoAccount = new map<id, id>();
		map<id, id> AccounttoTraining_toDelete = new map<id, id>();

		list<Training_Attendee__c> Atts_forDelt = new list <Training_Attendee__c>();
		set<id> Contacts = new set<id>();
		set<id> trainingIds = new set<id>();
		set<id> attendsIds = new set<id>();
		set<id> accountIds = new set<id>();
		set<id> accountIds_toRemove = new set<id>();
		set<id> trainingIds_toRemove = new set<id>();

		list<id> Trainings = new list<id>();
		list<Contact> ConsToUpdate = new list<Contact>();

// find the last attendee record for the contact
		for(Training_Attendee__c att: Attendees)
		{
			Contacts.add(att.Attendee__c);
			attendsIds.add(att.Attendee__c);
			trainingIds.add(att.Training__c);
			accountIds.add(att.AccountID__c);
			AccounttoTraining.put( att.AccountID__c, att.Training__c);
			TrainingtoAccount.put( att.Training__c, att.AccountID__c);
		}
		system.debug('accountIds from all deleted attendees' + accountIds);
		system.debug('trainingIds from all deleted attendees ' + trainingIds);

		Atts_forDelt = [select id, Attendee__c, Training__c, AccountID__c from Training_Attendee__c where AccountID__c in: accountIds and Training__c in :trainingIds ];

		system.debug('All attendees Atts_forDelt ' + Atts_forDelt);
		if(Atts_forDelt.size() > 0)
		{
			for(Training_Attendee__c attendee : Atts_forDelt)
			{
				if(1==0)
				{
					accountIds_toRemove.add(attendee.AccountID__c);
				}
				{
					system.debug('in the else');
				}
			}
		}
		else
		{
			for(Training_Account__c AccTrains :[select id, Training__c, Accounts__c from Training_Account__c where Accounts__c in :accountIds and Training__c in :trainingIds order by Accounts__c desc])
			{
				accountIds_toRemove.add(AccTrains.id);
			}
		}

		system.debug('Those account training we plan to delete ' + accountIds_toRemove);

// account training

		for(Training_Account__c AccTrains :[select id, Training__c, Accounts__c from Training_Account__c where Accounts__c in :accountIds_toRemove and Training__c in :trainingIds order by Accounts__c desc])
		{
		// if this account does not already have this training
			if(AccTrains.Training__c == AccounttoTraining.get(AccTrains.Accounts__c) && AccTrains.Accounts__c == TrainingtoAccount.get(AccTrains.Training__c))
			{
				continue;
			}
			else
			{
			// a collection of account ids to trainings
				accountIds_toRemove.add(AccTrains.Accounts__c);
				AccounttoTraining_toDelete.put(AccTrains.Accounts__c, AccounttoTraining.get(AccTrains.Accounts__c));
				system.debug('Those accounts with their matching Trainings ' + AccounttoTraining_toDelete);
			}
		}

 

Please feel free to nit-pick too. This is totally a work in progress.

 

 

I think that testing batchcode is difficult and now I am scheduling it my tests are just not good.

 

I have a batchable class that takes transcripts of new users create the previous day and assigns to them, according to some rules, new learning objectives.

 

The new users are created by integration to back end systems. A trigger on insert  calls a future method which goes out to the vendor webservice to get a license. I cannot add this routine to that process as I need to fire it in batch in case we hire too many people at once. So a schedule it has to be. (assertion)

 

Here is the schedule controller: (basically cribbed from force.com examples)

 

global class Schedulable_RunAssignmentRules implements Schedulable{

	public static String CRON_EXP = '0 0 2 * * ? *';


	global static String scheduleIt() 
	{
		Schedulable_RunAssignmentRules SRAR = new Schedulable_RunAssignmentRules();
		return System.schedule('New User On-boarding', CRON_EXP, SRAR);
	}

	global void execute(SchedulableContext sc)
    {
		set<id> setTrainees = new set<id>();
		for (lmscons__Transcript__c lT : [select lmscons__Trainee__c from lmscons__Transcript__c where CreatedDate >= :system.today()-1])
		{	
	        setTrainees.add(lT.lmscons__Trainee__c);
	    }

//	    system.debug('setTrainees ' + setTrainees);
		if( setTrainees.size() > 0)
		{
        	RunAssignmentRules(setTrainees);
		}
    }

	public static void RunAssignmentRules(set<id> setTrainees)
	{
		database.executeBatch(new RunAssignmentRulesBatch(setTrainees), 30 );
	}
}

 

An excerpt of the head of the batchable class:

global class RunAssignmentRulesBatch implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts {

global final string strQuery; global final set<id> Trainees; public RunAssignmentRulesBatch(set<id> Trainees) { system.debug('Trainees '+Trainees); this.Trainees = Trainees; if (system.Test.isRunningTest()) { this.strQuery = 'SELECT Id FROM User WHERE Id = \'' + UserInfo.getUserId() + '\' LIMIT 1'; } else { this.strQuery = 'SELECT u.Id, u.Department, u.Division from User u where u.ID in :Trainees and u.ContractorY_N__c = FALSE and u.IsActive=TRUE'; system.debug('strQuery constructor'+strQuery); } } global Database.QueryLocator start(Database.BatchableContext BC) { system.debug('strQuery start'+strQuery); return Database.getQueryLocator(strQuery); } global void finish(Database.BatchableContext BC) { } global void execute(Database.BatchableContext BC, list<User> Trainees) {         system.debug('Trainees in addAssignmentBatch '+Trainees);

 

And the test class

 

@isTest
private class RunAssignmentRulesTest {

	static testMethod void myUnitTest() {

		Profile profile = [select id, Name from profile where name='System Administrator'];

		list<lmscons__Curriculum__c> currList = new list<lmscons__Curriculum__c>();
		lmscons__Curriculum__c curr1 = new lmscons__Curriculum__c(Name = 'Test On-boarding Program First', Type__c = 'Curriculum');
		lmscons__Curriculum__c curr2 = new lmscons__Curriculum__c(Name = 'Test On-boarding Program Second', Type__c = 'Curriculum');
		currList.add(curr1);
		currList.add(curr2);
		insert currList;

		List<Assignment_Rule__c> obcsList = new List<Assignment_Rule__c>();
		Assignment_Rule__c obcs = new Assignment_Rule__c(All_Unit_Departments__c = TRUE, User_Departments__c = '', User_Business_Unit__c='Test Div', Curriculum__c=curr2.ID);
		Assignment_Rule__c obcsb = new Assignment_Rule__c(All_Unit_Departments__c = FALSE, User_Departments__c = 'Test DeptB', User_Business_Unit__c='Test DivB', Curriculum__c=curr2.ID);
		Assignment_Rule__c obcsc = new Assignment_Rule__c(New_Staff__c = TRUE, All_Unit_Departments__c = FALSE, Curriculum__c=curr2.ID );
		obcsList.add(obcs);
		obcsList.add(obcsb);
		obcsList.add(obcsc);
		insert obcslist;

		Test.startTest();
			List<User> UserList = new List<User>();
			User u1 = new User(alias = 'ts01', email='testtest01@test.com', emailencodingkey='UTF-8', lastname='testtest01', languagelocalekey='en_US', Department='Test Dept', Division='Test Div',
				localesidkey='en_US', profileid = profile.Id, timezonesidkey='America/Los_Angeles', username='testtest11@test343SF111112d.com', lmscons__Cornerstone_ID__c='newtest test12'
			);
			User u2 = new User(alias = 'ts02', email='testtest01@test.com', emailencodingkey='UTF-8', lastname='testtest01', languagelocalekey='en_US', Department='Test DeptB', Division='Test DivB',
				localesidkey='en_US', profileid = profile.Id, timezonesidkey='America/Los_Angeles', username='testtest12@test343SF111112d.com', lmscons__Cornerstone_ID__c='newtest test11'
			);
			UserList.add(u1);
			UserList.add(u2);
			insert UserList;
	
			// Schedule the test job
			String jobId = System.schedule('Prepare learning for new Users',
			Schedulable_RunAssignmentRules.CRON_EXP, 
	        new Schedulable_RunAssignmentRules());
	
	   // Get the information from the CronTrigger API object
			CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered,  NextFireTime FROM CronTrigger WHERE id = :jobId];
	
	   // Verify the expressions are the same
	      	System.assertEquals(Schedulable_RunAssignmentRules.CRON_EXP, 
			ct.CronExpression);
	
       // Verify the job has not run
            System.assertEquals(0, ct.TimesTriggered);

            String runDate =  string.Valueof(system.today()+1);

            list<lmscons__Transcript_Line__c> Lines = ([Select id, lmscons__Trainee__c, lmscons__Curriculum_Assignment__c from lmscons__Transcript_Line__c where lmscons__Trainee__c = :curr2.id]);
            if(lines.size() > 0)
            {
                list<lmscons__Curriculum_Assignment__c> assigns = ([Select id, lmscons__Curriculum__c from lmscons__Curriculum_Assignment__c where id = :Lines[0].id]);
            }
       // Verify the next time the job will run Lines
            System.assertEquals(runDate.abbreviate(11) + ' 02:00:00'  , String.valueOf(ct.NextFireTime));
            System.assertNotEquals('Test On-boarding Program Second', [select id, name from lmscons__Curriculum__c where id = :assigns[0].id].name);
    
        Test.stopTest(); System.assertEquals('testScheduledApexFromTestMethodUpdated', [SELECT id, name from lmscons__Curriculum__c WHERE id = :curr2.id].Name); } }

 

My issue is that I need to assert that new users have been created, that the transcript was created and that nothing was assigned... but doing that should make a failure as there will be nothing and the index into the array doesn't exist.

 

How can I clean up the test class so that I can assert something that makes sense?

 

Hi,

 

My first attempt at batching and I am coming up with an error. I have referenced other similar issues but I'm not getting anywhere.

 

Calling from a trigger I have a set of IDs that translate directly to User.Id.

 

 

Trigger:

trigger AddCurrtoTrans on lmscons__Transcript__c (after insert, after update) {
	    /*
	    	adds a curriculum to a transcript when transcript is created
	        need to call a future class to enter a new curriculum assignment record 
	        for each new user added in a given trigger context.
       */

	set<id> setTrainees = new set<id>();
	//string strQuery = '';

	if (trigger.isInsert || trigger.isupdate)
	{
		// filter thoruugh the transcripts to find IDs (future classes cannot take cObjects)
		for (lmscons__Transcript__c lT : trigger.new)
		{
	        setTrainees.add(lT.lmscons__Trainee__c);
	    }
	    system.debug('setTrainees ' + setTrainees);
		//CreateOnBoarding.addCurrtoTrans(setTrainees);
	    //list<User> listTrainees = new list<User>([Select id from User where id in :setTrainees]);

		//RunAssignmentRulesBatch Create = new RunAssignmentRulesBatch(strQuery);
		database.executeBatch(new RunAssignmentRulesBatch(setTrainees), 100 );
	}
}

 

 

Class

global class RunAssignmentRulesBatch implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts {

	global final string strQuery;
	global final set<id> Trainees;

	public RunAssignmentRulesBatch(set<id> Trainees)
	{
		system.debug('Trainees '+Trainees);
		if (system.Test.isRunningTest()) {
			this.strQuery = 'SELECT Id FROM User WHERE Id = \'' + UserInfo.getUserId() + '\' LIMIT 1';
		}
		else
		{
			strQuery = 'SELECT u.Id, u.Department, u.Division from User u where u.ID in :Trainees and u.ContractorY_N__c = FALSE and u.IsActive=TRUE';
			system.debug('strQuery constructor'+strQuery);
		}
	}

	global Database.QueryLocator start(Database.BatchableContext BC) {
		system.debug('strQuery start'+strQuery);
		return  Database.getQueryLocator(strQuery);
	}

	global void finish(Database.BatchableContext BC) {
	}

	global void execute(Database.BatchableContext BC, list<User> Trainees) {
		system.debug('Trainees in execute '+Trainees);
		addAssignmentBatch(BC, Trainees);
	}
    global void addAssignmentBatch(Database.BatchableContext BC, list<User> Trainees)
    {
        /*

            curr.ass requires:
                curriculum | this will be determined by the lmscons__Transcript__c.lmscons__Trainee__c
                transcript | this is passed in by the trigger
                trainess | this is passed in by the trigger
                Trainees to transcript relationship | this is passed in by the trigger

            Analytic Development On-boarding Program
            Pre-Sales On-boarding Program (retired)
            Product Development On-boarding Program
            Professional Services (PS) On-boarding Program
            PTO On-boarding Program
            PTO On-boarding Program - General
            Quality Assurance On-boarding Program
            Sales On-boarding Program
            Scores Delivery On-boarding Program

        */

        system.debug('Trainees in addAssignmentBatch '+Trainees);

        for (User trainee: Trainees)

 

logfile

14:16:47.047 (47406000)|METHOD_EXIT|[1]|RunAssignmentRulesBatch
14:16:47.047 (47640000)|SYSTEM_METHOD_ENTRY|[21]|System.debug(ANY)
14:16:47.047 (47698000)|USER_DEBUG|[21]|DEBUG|strQuery startSELECT u.Id, u.Department, u.Division from User u where u.ID in :Trainees and u.IsActive=TRUE
14:16:47.047 (47712000)|SYSTEM_METHOD_EXIT|[21]|System.debug(ANY)
14:16:47.047 (47739000)|SYSTEM_METHOD_ENTRY|[22]|Database.getQueryLocator(String)
14:16:47.049 (49583000)|SOQL_EXECUTE_BEGIN|[22]|Aggregations:0|SELECT u.Id, u.Department, u.Division from User u 
14:16:47.051 (51344000)|EXCEPTION_THROWN|[22]|System.NullPointerException: Attempt to de-reference a null object
14:16:47.051 (51562000)|SYSTEM_METHOD_EXIT|[22]|Database.getQueryLocator(String)
14:16:47.051 (51628000)|FATAL_ERROR|System.NullPointerException: Attempt to de-reference a null object

Hi,

 

I have read a few posts on this but I have found that it isn't working:

 

I have a custom object with a field called Video_or_Image_link__c. The contents of this are posted onto a VF page on a Spotlights area. The Spotlights are built inside a component.

 

Page:

<body>
<div class="h-base">
    <div class="b-content">
        <div class="b-columns">
	     <c:Spotlights />

 

Component:

<apex:component controller="Spotlight_Controller" access="global">
            <div class="b-spotlight">
                <div class="b-spotlight-title">Learning Spotlights <div class="m-toggler"><span>Hide</span><span class="m-last">Show</span></div></div>
                <div class="b-spotlight-body">
                    <div class="b-spotlight-content">
                        <div class="b-spotlight-tabs">
                            <apex:repeat value="{!Spotlinks}" var="link">
                                <div class="b-spotlight-tab"> {!link.Link_Text__c} <span class="m-arrow"></span></div>
                            </apex:repeat>
                            <p> </p>
                            <p> </p>
                        </div>
                        <div class="b-spotlight-tab-bodies">
                            <apex:repeat value="{!Spotlights}" var="spot">
                                <div class="b-spotlight-tab-body">
                                    <p class="m-title">{!spot.Title__c}</p>

<!-- COMMENTED OUT VIDEO VALUE
<apex:iframe id="vids" width="640" height="360" src="//{!spot.Video_or_Image_link__c}"></apex:iframe> -->

                                    <apex:outputText value="{!spot.Message_Content__c}" escape="false"/>

                                </div>
                            </apex:repeat>
                        </div>
                    </div>
                </div>
            </div>

</apex:component>

 

The problem have is that, when uncommented, the space is taken up by pane that says URL NO LONGER EXISTS "You have attempted to reach a URL that no longer exists on salesforce.com.". The same happens in Firefox, Chrome and IE.

 

The link on the object is www.youtube.com/embed/9D8X82sbewQ .

 

What do I need to do? What have I missed?

 

 

The Controller just for holistic purposes - I know that the data is there...

public with sharing class Spotlight_Controller {
	
	public list<Spotlight__c> Spotlights;
	public list<Spotlight__c> Spotlinks;
	public date dtToday;

	public Spotlight_Controller() {
        dtToday = date.today();
        system.debug('\n ----------------> opening controller');
	}

    public List<Spotlight__c> getSpotlights()
    {
		Spotlights = [select Title__c, Message_Content__c, Video_or_Image_link__c from Spotlight__c where Active__c = TRUE and Publish_Date__c <= :dtToday and End_by__c >= :dtToday order by order__c asc Limit 6];
        system.debug('\n ----------------> opening Spotlights = ' + Spotlights);
        return Spotlights;
    }

 

THis is a repeat post but I cannot find any way of getting this done:

 

I have a VF email template.

 

<messaging:emailTemplate subject="Account Training Review Required" recipientType="User" relatedToType="Case">
<messaging:HTMLEmailBody >
<html>

----

{!if(relatedTo.Education_checkbox__c = true, " as identified by the Product Support case owner.", " as indicated by a relatively high percentage of support calls having been resolved as 'how to' questions.")}

 The above is what I want... But try that and you get this error:

	Error: EL Expression Unbalanced: ... #{if(relatedTo.Education_checkbox__c = true, " as identified by the Product Support case owner.", " as indicated by a relatively high percentage of support calls having been resolved as 'how to' questions.")} This client’s particular profile#{if(relatedTo.Account.Business_Size__c = "BB", ", an account classified as Big Business,", if(relatedTo.Account.Business_Size__c = "SMB", ", an account classified as Small Business,", if(relatedTo.Account.Business_Size__c = "MB", ", an account classified as Mid-Size Business, ", "")))} has submitted #{if(text(floor(relatedTo.Account.AccountCases__c)) != "", text(FLOOR(relatedTo.Account.AccountCases__c)) & " how to cases in the last 90 days ", "no other cases categorised as how-to")} #{if(text(relatedTo.Account.Account_Cases_last_90_days__c) != "", " out of a total of " & TEXT(relatedTo.Account.Account_Cases_last_90_days__c) & " Product Support calls", "")}, which puts it in the #{relatedTo.AccountTrainingStatusCode__c} zone according to calculated metrics #{if(relatedTo.Account.MinCaseThreshold__c="Red", if(relatedTo.AccountTrainingStatusCode__c = "Red", " and " & relatedTo.Account.MinCaseThreshold__c & " when measured against the number of how to cases that we allow.", " but " & relatedTo.Account.MinCaseThreshold__c & " when measured against the number of how to cases that we allow."),".")}

 

If you try this: \'how to\' then you can save but the same thing is displayed in the email:

\'how to\'

 

Surround the text in the condition with htmlencode() and you see this in the email:

\&#39;how to\&#39;

 

Use jsencode() and you see this:

\\\'how to\\\'

 

Clearly the system wants me to escape the character but it then doesn't do anything about it.

 

Please can someone help?

We have a trigger that, when a user is updated from Inactive to Active resets that persons password.

 

When I test in full sandbox it seems fine.

 

When I release it in a changeset it causes the below issue:

 

Failure Message: "System.DmlException: Update failed. First exception on row 0 with id 005800000059ETvAAM; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UserPasswordReset: execution of AfterUpdate caused by: System.UnexpectedException: UNKNOWN_EXCEPTION: An unexpected error occurred. Please include this ErrorId if you .

Trigger:

trigger UserPasswordReset on User (after update) {
   for (User u : Trigger.new){
      // Compares the new value of isActive flag on User table to the old value  
      if (u.isActive && !Trigger.oldMap.get(u.Id).isActive) {
         // If new value isActive is true and old value is false the user's 
         // password will be reset and an email notification will
         // be sent to them.
         System.resetPasswordResult rpr = System.resetPassword(u.Id, true);
      }
   } 
}

 

Test Class

@isTest(SeeAllData=TRUE) 
private class UserUpdateTriggerTest {

    static testMethod void UserTriggerTest() {

        Profile profile = [select id, Name from profile where name='Consumer Standard User'];
        User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
        List<User> uList = new List<User>();
        for (Integer i=0; i<10; i++){
            uList.add(new User(alias             = 'testu'+i
                    ,email             ='test_user_update'+i+'@test.com'
                    ,emailencodingkey  ='UTF-8'
                    ,lastname          ='test_user_update'+i
                    ,languagelocalekey ='en_US'
                    ,localesidkey      ='en_US'
                    ,profileid         = profile.Id
                    ,timezonesidkey    ='America/Los_Angeles'
                    ,username          ='test_user_update'+i+'@test.com'
                    ,Party_Id__c       = 'XX123'+i
                    ,isActive          = false
            ));
        }

        insert uList;

        system.runas(thisUser)
        {
            for (Integer i=0; i<10; i++) {
                uList[i].isActive = true;
            }
            update uList;
        }

    }

}

 

I have a very customised email in Visualforce.

 

I want to write quite complex sentences in it using IF statements but I have found that I get errors in the email template if I have a comma in the comment:

 

{!if(var=true, "AA", "A,A")} breaks when I try to save the template.

{!if(var=true, "AA", "A A")} works fine.

Hi guys

 

My client's instance has been upgraded to Winter 14 and today I noticed the "Code Coverage (%)" column is no longer showing on Classes and Triggers page.

 

Does anyone else have the same experience?

Now you have to click on the name of the class in order to see its code coverage.  Information is still there, but getting to it is now not convenient.....

 

Is it a Winter 14 "feature"?

 

Thanks

King

Hi,

 

My first attempt at batching and I am coming up with an error. I have referenced other similar issues but I'm not getting anywhere.

 

Calling from a trigger I have a set of IDs that translate directly to User.Id.

 

 

Trigger:

trigger AddCurrtoTrans on lmscons__Transcript__c (after insert, after update) {
	    /*
	    	adds a curriculum to a transcript when transcript is created
	        need to call a future class to enter a new curriculum assignment record 
	        for each new user added in a given trigger context.
       */

	set<id> setTrainees = new set<id>();
	//string strQuery = '';

	if (trigger.isInsert || trigger.isupdate)
	{
		// filter thoruugh the transcripts to find IDs (future classes cannot take cObjects)
		for (lmscons__Transcript__c lT : trigger.new)
		{
	        setTrainees.add(lT.lmscons__Trainee__c);
	    }
	    system.debug('setTrainees ' + setTrainees);
		//CreateOnBoarding.addCurrtoTrans(setTrainees);
	    //list<User> listTrainees = new list<User>([Select id from User where id in :setTrainees]);

		//RunAssignmentRulesBatch Create = new RunAssignmentRulesBatch(strQuery);
		database.executeBatch(new RunAssignmentRulesBatch(setTrainees), 100 );
	}
}

 

 

Class

global class RunAssignmentRulesBatch implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts {

	global final string strQuery;
	global final set<id> Trainees;

	public RunAssignmentRulesBatch(set<id> Trainees)
	{
		system.debug('Trainees '+Trainees);
		if (system.Test.isRunningTest()) {
			this.strQuery = 'SELECT Id FROM User WHERE Id = \'' + UserInfo.getUserId() + '\' LIMIT 1';
		}
		else
		{
			strQuery = 'SELECT u.Id, u.Department, u.Division from User u where u.ID in :Trainees and u.ContractorY_N__c = FALSE and u.IsActive=TRUE';
			system.debug('strQuery constructor'+strQuery);
		}
	}

	global Database.QueryLocator start(Database.BatchableContext BC) {
		system.debug('strQuery start'+strQuery);
		return  Database.getQueryLocator(strQuery);
	}

	global void finish(Database.BatchableContext BC) {
	}

	global void execute(Database.BatchableContext BC, list<User> Trainees) {
		system.debug('Trainees in execute '+Trainees);
		addAssignmentBatch(BC, Trainees);
	}
    global void addAssignmentBatch(Database.BatchableContext BC, list<User> Trainees)
    {
        /*

            curr.ass requires:
                curriculum | this will be determined by the lmscons__Transcript__c.lmscons__Trainee__c
                transcript | this is passed in by the trigger
                trainess | this is passed in by the trigger
                Trainees to transcript relationship | this is passed in by the trigger

            Analytic Development On-boarding Program
            Pre-Sales On-boarding Program (retired)
            Product Development On-boarding Program
            Professional Services (PS) On-boarding Program
            PTO On-boarding Program
            PTO On-boarding Program - General
            Quality Assurance On-boarding Program
            Sales On-boarding Program
            Scores Delivery On-boarding Program

        */

        system.debug('Trainees in addAssignmentBatch '+Trainees);

        for (User trainee: Trainees)

 

logfile

14:16:47.047 (47406000)|METHOD_EXIT|[1]|RunAssignmentRulesBatch
14:16:47.047 (47640000)|SYSTEM_METHOD_ENTRY|[21]|System.debug(ANY)
14:16:47.047 (47698000)|USER_DEBUG|[21]|DEBUG|strQuery startSELECT u.Id, u.Department, u.Division from User u where u.ID in :Trainees and u.IsActive=TRUE
14:16:47.047 (47712000)|SYSTEM_METHOD_EXIT|[21]|System.debug(ANY)
14:16:47.047 (47739000)|SYSTEM_METHOD_ENTRY|[22]|Database.getQueryLocator(String)
14:16:47.049 (49583000)|SOQL_EXECUTE_BEGIN|[22]|Aggregations:0|SELECT u.Id, u.Department, u.Division from User u 
14:16:47.051 (51344000)|EXCEPTION_THROWN|[22]|System.NullPointerException: Attempt to de-reference a null object
14:16:47.051 (51562000)|SYSTEM_METHOD_EXIT|[22]|Database.getQueryLocator(String)
14:16:47.051 (51628000)|FATAL_ERROR|System.NullPointerException: Attempt to de-reference a null object