Study Notes for PDII Certification

I was tasked with taking the PDII Salesforce certification in 24hrs, and making it a top priority. The following are notes taken while cram studying and taking practice exams.

Localization & Multi Currency

General Guidelines

Multi Currency Support

SELECT Name, format(convertCurrency(Purchase_Cost__c)) FROM Bike_Part__c
SELECT Name, format(Purchase_Cost__c) FROM Bike_Part__c

Multi Language Support

LWCs & Multi Currency / Locales

import LOCALE from '@salesforce/i18n/locale'
import CURRENCY from `@salesforce/i18n/currency`

...
const date = new Date(2025, 1, 2)
this.localDate = new Intl.DateTimeFormat(LOCALE).format(date)
const setting = Intl.NumberFormat(LOCALE, { style: 'currency', currency: CURRENCY })

Platform Event-based Trigger maintenance

SOQL Query Selectiveness & Query Performance

Salesforce Big Objects

How are they different?

Salesforce Connect & External Objects

Lightning Usage App for Lightning Perf Testing

Advanced SOQL Usage

SELECT MailingCountry, COUNT(Id)
FROM Contact
GROUP BY MailingCountry
HAVING COUNT(Id) >= 100
SELECT Id, Status, Subject, ActivityDate, OwnerId, Owner.Name,
    TYPEOF What
        WHEN Account THEN Id, Name, AnnualRevenue
        WHEN Custom_Object__c THEN Id, Custom_Field_1__c, Custom_Field_2__c
        ELSE Id, Name
    END
FROM Task
WHERE Owner.Name = 'John Turner'
LIMIT 50
SELECT Owner.Name, FORMAT(SUM(Amount))
FROM Opportunity
WHERE IsWon = true
GROUP BY ROLLUP (Owner.Name)
ORDER BY SUM(Amount) DESC

Aura Components

<ltng:require
  scripts="{!join(',', $Resource.d3, $Resource.uikitJs)}"
  styles="{!$Resource.uikitCss}"
  afterScriptsLoaded="{!c.afterScriptsLoaded}"
/>
$T.createComponent("c:TrafficAnalytics", null)
  .then(function (cmp) {
    cmp.displaySettings(); // Example of calling a method directly on the component
    expect(cmp.get("v.isDisplaySettings")).toBe(true); // Retrieve value of <aura:attribute>
  })
  .catch(function (e) {
    done.fail(e);
  });

Emitting Events

Aura Bundle Files

Apex Sharing

Visualforce Concepts

Async VF Using JS

global with sharing class AccountRemoter {
     @RemoteAction // Required for Remoting
    global static String getAccountName(String accId) { // Must be global and static
        Account acc = [SELECT Name FROM Account WHERE Id = :accId];
        return acc.Name;
    }
}
function fetchAccount() {
  var accountId = "001...";

  // Syntax: ControllerName.MethodName(param, callback, options)
  AccountRemoter.getAccountName(
    accountId,
    function (result, event) {
      if (event.status) {
        console.log("Account Name: " + result);
      } else {
        console.log("Error: " + event.message);
      }
    },
    { escape: true }, // Security setting to prevent XSS
  );
}
<apex:remoteObjects>
  <apex:remoteObjectModel name="Account" jsId="RemoteAcc" fields="Name,Phone,Industry">
    <apex:remoteObjectField name="BillingCity" jsAlias="City" />
  </apex:remoteObjectModel>
</apex:remoteObjects>
// Create a new Account using the jsId defined above
var acc = new SObjectModel.RemoteAcc();

// Set some values
acc.set("Name", "New Tech Corp");
acc.set("City", "San Francisco");

// Save to the database
acc.create(function (error, result, event) {
  if (error) {
    alert(error.message);
  } else {
    console.log("New Account ID: " + result[0]);
  }
});

AJAX-Like Refreshing of Content using VF Tags

<apex:page controller="MyController">
  <apex:form>
    <apex:selectList value="{!selectedPriority}" size="1">
      <apex:selectOption itemValue="Low" itemLabel="Low" />
      <apex:selectOption itemValue="High" itemLabel="High" />

      <apex:actionSupport event="onchange" action="{!checkPriority}" reRender="msgPanel" status="loadingStatus" />
    </apex:selectList>

    <apex:outputPanel id="msgPanel">
      <apex:outputText value="Warning: High Priority Selected!" rendered="{!isHighPriority}" />
    </apex:outputPanel>

    <apex:actionStatus id="loadingStatus" startText=" (processing...)" stopText="" />
  </apex:form>
</apex:page>

Custom Metadata vs. Custom Settings

Apex Concepts Review

global class DiscountCalculatorPlugin implements Process.Plugin {

    // 1. The Invoke method: This is where the logic happens
    global Process.PluginResult invoke(Process.PluginRequest request) {
        // Pull the input parameter 'Amount' from the Flow
        Decimal amount = (Decimal)request.inputParameters.get('Amount');

        // Simple Logic: 10% discount
        Decimal discountedAmount = amount * 0.90;

        // Map the result back to the 'FinalPrice' output parameter
        Map<String, Object> result = new Map<String, Object>();
        result.put('FinalPrice', discountedAmount);

        return new Process.PluginResult(result);
    }

    // 2. The Describe method: This tells Flow Builder what to show the Admin
    global Process.PluginDescribe describe() {
        Process.PluginDescribe describe = new Process.PluginDescribe();
        describe.Tag = 'Commerce Tools';
        describe.Name = 'Apply Standard Discount';
        describe.Description = 'Calculates a 10% discount for the provided amount.';

        // Define Input Parameters
        describe.inputParameters = new List<Process.PluginDescribe.InputParameter>{
            new Process.PluginDescribe.InputParameter('Amount',
                Process.PluginDescribe.DataCategory.CURRENCY, true)
        };

        // Define Output Parameters
        describe.outputParameters = new List<Process.PluginDescribe.OutputParameter>{
            new Process.PluginDescribe.OutputParameter('FinalPrice',
                Process.PluginDescribe.DataCategory.CURRENCY)
        };

        return describe;
    }
}

Other Misc. Notes from Practice Exam

const event = new CustomEvent('nameofevent', { detail: data })`
afterEach(() => {
  while (document.body.firstChild) {
    document.body.removeChild(document.body.firstChild);
  }
});
<targetConfigs>
    <targetConfig targets="lightning__RecordPage">
        <property name="prop1" type"String" />
        <supportedFormFactors>
            <supportedFormFactor type="Small" /> <!-- Can also be "Large" -->
        </supportedFormFactors>
    </targetConfig>
</targetConfigs>

Other Related Topics