This plan uses the Pomodoro Technique (25-minute focused study blocks) and Ebbinghaus Forgetting Curve principles (spaced review) to help you master the PDI content. It provides clear goals, tasks, and detailed activities for every study day.
Goal: Build a strong foundation in Salesforce data modeling, Apex programming, and SOQL.
Objectives:
Tasks:
Account relates to Contact.Account and Opportunity.Student__c).Student__c (Custom Object).Objectives:
Tasks:
Text, Number, and Date in a custom object.Student__c:TODAY() - Enrollment Date.Master-Detail relationship between Student__c and a custom object Class__c.Lookup relationship between Class__c and Teacher__c.Objectives:
Tasks:
Learn Syntax:
String, Integer, Boolean).for, while) and conditionals (if-else).Practice in Developer Console:
Write a simple Apex snippet to calculate a discount:
Integer price = 100;
Integer discount = 20;
Integer finalPrice = price - discount;
System.debug('Final Price: ' + finalPrice);
Write an Apex Class:
DiscountCalculator:calculateDiscount(price, discountPercentage).Summarize key Apex concepts in notes.
Objectives:
Tasks:
Basic SOQL Queries:
Query Account records:
SELECT Id, Name FROM Account WHERE Industry = 'Technology'
Test in Developer Console.
Filters and Sorting:
Query Contact records sorted by LastName:
SELECT Id, FirstName, LastName FROM Contact ORDER BY LastName ASC
Nested Queries:
Query parent-child relationships:
SELECT Name, (SELECT LastName FROM Contacts) FROM Account
Hands-on:
Objectives:
Tasks:
Learn Trigger Syntax:
Trigger.new and Trigger.old.Write a Trigger:
Automate Student__c updates:
Grade field based on the Age field.Example:
trigger StudentTrigger on Student__c (before insert) {
for (Student__c student : Trigger.new) {
if (student.Age < 10) {
student.Grade = 'Elementary';
}
}
}
Test the Trigger by inserting records in Salesforce.
Objectives:
Tasks:
Objectives:
Tasks:
Trigger.new?).Here’s the detailed week-by-week learning plan for Salesforce PDI. Each week will follow the format used for Week 1, with clear objectives, tasks, and activities.
Goal: Understand declarative automation tools like Process Builder and Flows, and master programmatic automation with triggers and asynchronous Apex.
Objective:
Tasks:
Introduction to Process Builder:
Hands-on Task:
Status field:Status field to "Active."Test the Process:
Write notes summarizing:
Objective:
Tasks:
Introduction to Flow Builder:
Hands-on Task:
Customer Feedback).Test the Flow:
Write notes summarizing:
Objective:
Tasks:
Introduction to Approval Processes:
Hands-on Task:
Discount Request__c):Test the Approval Process:
Write notes summarizing:
Objective:
Tasks:
Review Trigger Basics:
Before and After events).Trigger.new and Trigger.oldMap.Hands-on Task:
Write a Trigger on Contact:
Example:
trigger ContactTrigger on Contact (after insert) {
for (Contact con : Trigger.new) {
Task t = new Task();
t.Subject = 'Follow up with ' + con.FirstName;
t.WhatId = con.Id;
t.Status = 'Not Started';
insert t;
}
}
Future Methods:
Learn the purpose of Future methods (asynchronous operations).
Write a Future method to send emails:
@future
public static void sendEmail(String email) {
// Logic to send email
System.debug('Email sent to ' + email);
}
Test the Trigger and Future Method:
Objective:
Tasks:
Learn Batch Apex Basics:
start, execute, finish.Hands-on Task:
Write a Batch Apex class to clean up inactive Accounts:
Status to "Archived."Example:
global class BatchAccountArchiver implements Database.Batchable<sObject> {
global Database.QueryLocator start(Database.BatchableContext context) {
return Database.getQueryLocator('SELECT Id, Status FROM Account WHERE Status = \'Inactive\'');
}
global void execute(Database.BatchableContext context, List<Account> scope) {
for (Account acc : scope) {
acc.Status = 'Archived';
}
update scope;
}
global void finish(Database.BatchableContext context) {
System.debug('Batch job completed.');
}
}
Test the Batch Job:
Database.executeBatch(new BatchAccountArchiver());.Write notes on:
Objective:
Tasks:
Queueable Apex:
Study how Queueable Apex allows for chaining operations.
Hands-on: Write a Queueable class to calculate discounts for multiple records.
Example:
public class DiscountProcessor implements Queueable {
public void execute(QueueableContext context) {
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Industry = 'Retail'];
for (Account acc : accounts) {
acc.Discount__c = 10;
}
update accounts;
}
}
Execute with:
System.enqueueJob(new DiscountProcessor());
Scheduled Jobs:
Learn how to schedule recurring tasks.
Write a job to send weekly reminders for overdue tasks:
global class TaskReminderJob implements Schedulable {
global void execute(SchedulableContext sc) {
List<Task> overdueTasks = [SELECT Id, Subject FROM Task WHERE Status = 'Not Started' AND DueDate < TODAY];
for (Task t : overdueTasks) {
System.debug('Reminder: ' + t.Subject);
}
}
}
Schedule it:
String cron = '0 0 12 * * ?'; // Noon daily
System.schedule('Weekly Task Reminder', cron, new TaskReminderJob());
Test both Queueable Apex and Scheduled Jobs.
Objective:
Tasks:
Goal: Master the creation of user interfaces using Visualforce and Lightning Web Components (LWC). Learn to optimize UI for user experience and performance.
Objective:
<apex> components.Tasks:
Learn Visualforce Basics:
<apex:page>, <apex:form>, <apex:inputText>.Hands-on Task:
Create a Visualforce page:
Contact’s First Name and Last Name.Example:
<apex:page>
<apex:form>
<apex:inputText label="First Name" value="{!firstName}" />
<apex:inputText label="Last Name" value="{!lastName}" />
<apex:commandButton value="Submit" action="{!submit}" />
</apex:form>
</apex:page>
Test:
Summarize:
<apex> components work.Objective:
Tasks:
Understand Custom Controllers:
Hands-on Task:
Create a custom controller to fetch Account data dynamically:
Example: Visualforce Page:
<apex:page controller="AccountController">
<apex:form>
<apex:inputText value="{!searchTerm}" label="Search Account" />
<apex:commandButton value="Search" action="{!searchAccounts}" />
</apex:form>
<apex:pageBlock>
<apex:pageBlockTable value="{!accounts}" var="acc">
<apex:column value="{!acc.Name}" />
<apex:column value="{!acc.Industry}" />
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>
Custom Controller:
public class AccountController {
public String searchTerm { get; set; }
public List<Account> accounts { get; set; }
public void searchAccounts() {
accounts = [SELECT Name, Industry FROM Account WHERE Name LIKE :('%' + searchTerm + '%')];
}
}
Test:
Summarize:
Objective:
Tasks:
Learn LWC Basics:
Hands-on Task:
Create a simple LWC that displays a greeting message:
Example: HTML:
<template>
<lightning-card>
<lightning-input label="Enter your name" onchange={handleNameChange}></lightning-input>
<p>Hello, {name}!</p>
</lightning-card>
</template>
JavaScript:
import { LightningElement } from 'lwc';
export default class GreetingComponent extends LightningElement {
name = '';
handleNameChange(event) {
this.name = event.target.value;
}
}
Test:
Summarize:
Objective:
Tasks:
Learn Event Handling:
Hands-on Task:
Build a parent-child LWC:
Example: Child Component JavaScript:
import { LightningElement, api } from 'lwc';
export default class ChildComponent extends LightningElement {
@api message;
handleClick() {
this.dispatchEvent(new CustomEvent('customclick', { detail: 'Child Clicked!' }));
}
}
Parent Component JavaScript:
import { LightningElement } from 'lwc';
export default class ParentComponent extends LightningElement {
messageFromChild = '';
handleCustomClick(event) {
this.messageFromChild = event.detail;
}
}
Test:
Summarize:
Objective:
Tasks:
Dynamic Forms:
Case objects.Performance Optimization:
@wire for data fetching.Summarize:
Objective:
Tasks:
Objective:
Tasks:
Goal: Master Salesforce testing requirements, debugging tools, and deployment strategies while preparing for the final exam with mock tests.
Objective:
Tasks:
Study Unit Testing Basics:
System.assert.Write a Test Class:
Test a trigger that updates Account.Description when a new Contact is created.
Example Test Class:
@isTest
public class AccountTriggerTest {
@isTest
static void testContactTrigger() {
Account acc = new Account(Name = 'Test Account');
insert acc;
Contact con = new Contact(FirstName = 'Test', LastName = 'Contact', AccountId = acc.Id);
insert con;
Account updatedAcc = [SELECT Description FROM Account WHERE Id = :acc.Id];
System.assertEquals('Contact Added', updatedAcc.Description);
}
}
Validate:
Summarize:
Objective:
Tasks:
Study Debugging Basics:
Debug, Error, Info).Hands-on Task:
Create an Apex class with a bug (e.g., incorrect SOQL query).
Use System.debug() to log variable values and identify the issue.
public class DebugExample {
public static void debugAccounts() {
List<Account> accounts = [SELECT Id FROM Account WHERE Industry = null]; // Intentional bug
System.debug('Accounts: ' + accounts);
}
}
Fix the Bug:
Summarize:
System.debug() statements.Objective:
Tasks:
Understand Change Sets:
Hands-on Task:
Validate and Deploy:
Summarize:
Objective:
Tasks:
Study Salesforce DX Basics:
sfdx force:source:push, sfdx force:source:pull).Hands-on Task:
Create a Scratch Org using CLI:
sfdx force:org:create -s -f config/project-scratch-def.json -a MyScratchOrg
Deploy metadata:
sfdx force:source:deploy -p force-app/main/default
Retrieve metadata:
sfdx force:source:retrieve -m ApexClass:MyClass
Test Deployment:
Summarize:
Objective:
Tasks:
Take a Full-Length Mock Exam:
Review Results:
Revisit Weak Areas:
Objective:
Tasks:
Flashcard Review:
Practice Coding:
Revise Notes:
Objective:
Tasks:
Light Review:
Relax:
Prepare for Exam:
This plan ensures a comprehensive preparation for the PDI exam. It incorporates efficient learning techniques and hands-on practice to build both theoretical and practical Salesforce skills.