Friday, 27 June 2025

Salesforce Platform Cache

 

What is Platform Cache?

Platform Cache is temporary memory storage provided by Salesforce for your org. It allows developers to cache frequently accessed data (e.g., record data, session-specific data, or calculations) and access it much faster than querying the database every time.

Types of Platform Cache

Salesforce provides two types of cache:

TypeDescription
Org CacheShared across all users in the org; used for commonly accessed data
Session CacheUnique per user session (browser or API session); used for session-specific data

Benefits of Platform Cache

 .  Reduces Apex processing time
 .  Minimizes redundant database calls (SOQL/SOSL)
 .  Improves performance of Lightning Components and APIs
 .  Helps in managing resource-heavy calculations

Apex Class

public  class ProductCacheService {
    public class ProductWrapper {
        @AuraEnabled public String Id;
        @AuraEnabled public String Name;
        @AuraEnabled public Decimal BasePrice;
    }

    @AuraEnabled
public static ProductWrapper getProductDetailsByName(String productName) {
    if (String.isBlank(productName)) {
        throw new AuraHandledException('Product Name cannot be blank.');
    }

    // Safe alphanumeric cache key
    String sanitizedName = productName != null ? productName.replaceAll('[^a-zA-Z0-9]', '') : '';
    if (String.isBlank(sanitizedName)) {
        throw new AuraHandledException('Product Name must contain at least one alphanumeric character.');
    }

    String key = 'ProductName' + sanitizedName.toLowerCase(); // no special characters allowed

    // Get cache partition
    Cache.OrgPartition part = Cache.Org.getPartition('ProductCachePartition');

    // Try cache first
    ProductWrapper cached = (ProductWrapper) part.get(key);
    if (cached != null) {
        System.debug('Retrieved from cache: ' + cached);
        return cached;
    }

    // Partial match (LIKE)
    List<Product2> products = [
        SELECT Id, Name, Base_Price__c
       FROM Product2
        WHERE Name LIKE :('%' + productName + '%')
        LIMIT 1
    ];

    if (products.isEmpty()) {
        throw new AuraHandledException('No product found with the given name.');

444333333    }


    Product2 product = products[0];

    ProductWrapper wrapper = new ProductWrapper();
    wrapper.Id = product.Id;
    wrapper.Name = product.Name;
    wrapper.BasePrice = product.Base_Price__c;

    part.put(key, wrapper, 600); // store in cache
    System.debug('Stored in cache: ' + wrapper);
    return wrapper;
}

}

ProductSearch.js

public with sharing class ProductCacheService {
    @AuraEnabled
    public static Decimal getProductPrice(String productId) {
        if (String.isBlank(productId)) {
            throw new AuraHandledException('Product ID cannot be blank.');
        }

        //  Create a cache-safe key
        String key = 'Product' + productId.replaceAll('[^a-zA-Z0-9]', '');

        //  Get Platform Cache partition
        Cache.OrgPartition part = Cache.Org.getPartition('ProductCachePartition');

        //  Try from cache
        Decimal cachedPrice = (Decimal) part.get(key);
        if (cachedPrice != null) {
            System.debug('Retrieved from cache: ' + cachedPrice);
            return cachedPrice;
        }

        //  Fetch from DB
        Product2 product = [SELECT Base_Price__c FROM Product2 WHERE Id = :productId LIMIT 1];
        cachedPrice = product.Base_Price__c;

        //  Store in cache for 10 minutes (600 seconds)
        part.put(key, cachedPrice, 600);
        System.debug('Stored in cache: ' + cachedPrice);
        return cachedPrice;
    }
}

import { LightningElement, track } from 'lwc';
import getProductPrice from '@salesforce/apex/ProductCacheService.getProductPrice';

export default class ProductPrice extends LightningElement {
    @track productId = '';
    @track price;
    @track error;

    handleInputChange(event) {
        this.productId = event.target.value;
        this.price = null;
        this.error = null;
    }

    handleGetPrice() {
        if (!this.productId) {
            this.error = 'Please enter a Product ID.';
            return;
        }

        getProductPrice({ productId: this.productId })
            .then(result => {
                this.price = result;
                this.error = null;
            })
            .catch(error => {
                this.error = 'Error retrieving price. Check the Product ID.';
                this.price = null;
                console.error(error);
            });
    }
}

<template>
    <lightning-card title="Product Price Checker" icon-name="utility:money">
        <div class="slds-p-around_medium">
            <lightning-input
                label="Enter Product ID"
                value={productId}
                onchange={handleInputChange}
                placeholder="e.g. 01t5g000009kXyzAAE">
            </lightning-input>

            <lightning-button
                label="Get Price"
                variant="brand"
                onclick={handleGetPrice}
                class="slds-m-top_medium">
            </lightning-button>

            <template if:true={price}>
                <p class="slds-m-top_medium">
                    <strong>Price:</strong> ₹ {price}
                </p>
            </template>

            <template if:true={error}>
                <p class="slds-text-color_error slds-m-top_medium">
                    {error}
                </p>
            </template>
        </div>
    </lightning-card>
</template>

Tuesday, 22 April 2025

Salesforce Integration Target Vs Source

 

Salesforce Integration Target Vs Source

Target Screen1: Manage Connected Apps 

   Go to the App Manager

  • Click the down arrow next to your app
  • Click View
  • Copy the Consumer Key and Consumer Secret for OAuth flows

Step:1


Step:2



Endpoint Details

  • URL Mapping: /receiveAccount/*
  • HTTP Method: POST
  • Class Name: OrgB_AccountReceiver
  • Method Name: receiveAccount()

@RestResource(urlMapping='/receiveAccount/*')

global class OrgB_AccountReceiver {

    @HttpPost

    global static String receiveAccount() {

        RestRequest req = RestContext.request;

        String requestBody = req.requestBody.toString();

        System.debug('Received body: ' + requestBody);

        try {

            Account acc = (Account) JSON.deserialize(requestBody, Account.class);

            // Clear ID if present to avoid insert error

            acc.Id = null;

           insert acc;

            return 'Account inserted: ' + acc.Id;

        } catch (Exception e) {

            return JSON.serialize(new Map<String, Object>{

                'errorCode' => 'APEX_ERROR',

                'message' => e.getMessage()

            });

        }

    }

}

Step 1: Navigate to Auth. Providers

  1. Go to Setup in your Salesforce org.
  2. In the Quick Find box, search for and click "Auth. Providers".
  3. Click the "New" button.

Step 2: Configure Auth. Provider Details

In the New Auth. Provider screen, set the following fields:

Field

Value

Provider Type

Salesforce

Name

SSO From Partner Org (or any name you choose)

URL Suffix

Auto-filled (can be customized, e.g., SalesforceSSO)

Consumer Key

(Copy from the Connected App in the other org — explained below)

Consumer Secret

(From the same Connected App as above)

Authorize Endpoint URL

https://login.salesforce.com/services/oauth2/authorize
(Use
test.salesforce.com for sandboxes)

Token Endpoint URL

https://login.salesforce.com/services/oauth2/token

User Info Endpoint URL

https://login.salesforce.com/services/oauth2/userinfo

Default Scopes

openid profile email or leave blank

Registration Handler

Create or select a registration handler Apex class (explained below)

Execute Registration As

Select an admin user

Icon URL

(Optional)

Custom Logout URL

(Optional)

Click Save.

Step 3: Copy Callback URL

After saving, Salesforce generates a Callback URL (e.g.,
https://yourDomain.my.salesforce.com/services/authcallback/SalesforceSSO).

 

Create Named Credential (Target Org)

Step 1: Navigate to Named Credentials

  • In Setup, search and click “Named Credentials”
  • Click “New Named Credential”   



Step:2



Step:3


Step:4



 

Sync Account Data from Org A to Org B via Named Credential and Apex

To send Account record data from Salesforce Org A to Salesforce Org B using:

  • @future(callout=true) method for async execution
  • Named Credential (OrgB_API) for secure endpoint access
  • REST API call to a custom Apex REST service in Org B

Step 2: Create Apex Class in Org A

public class AccountSync {

    @future(callout=true)

    public static void sendToOrgB(Id accId) {

        Account acc = [SELECT Id, Name, Phone, Website, Email__c FROM Account WHERE Id = :accId LIMIT 1];

        HttpRequest req = new HttpRequest();

        req.setEndpoint('callout:OrgB_API/services/apexrest/receiveAccount/');

        req.setMethod('POST');

        req.setHeader('Content-Type', 'application/json');

        req.setHeader('Accept', 'application/json');

        req.setBody(JSON.serialize(acc));

        req.setTimeout(120000);

        Http http = new Http();

        try {

            HttpResponse res = http.send(req);

            System.debug('Org B Response: ' + res.getBody());

        } catch(Exception e) {

            System.debug('Error sending Account to Org B: ' + e.getMessage());

        }

    }

}

Source Org :-



 

Target :-



 

 

Friday, 21 February 2025

Two-Way Account Data Integration

 Account data submitted in Salesforce → Sent to External API → Account created in the external system → External System ID stored in Salesforce.

Two-Way Integration: Synchronizing Accounts Between Salesforce and an External System
1. User Submits Account Form
The user enters Name, Email, and Phone in a Lightning Web Component (LWC).
Clicking Submit triggers a call to an Apex method (sendAccountData).
2. Data Sent to External API
The Apex method sends account details to an external system via an API request.
The external system creates a new account and returns a unique External System ID.
3. Account Created in Salesforce
A new Account record is inserted in Salesforce.
The response from the external system is processed:
If an id is received, it is stored in the External_Id__c field on the Salesforce Account.
If no ID is returned, an appropriate message is stored.
4. Two-Way Synchronization Achieved
Salesforce and the external system are now linked via the External System ID.
Future updates can be synchronized based on this ID for real-time integration.

Monday, 3 February 2025

How to Debug: Console, HRA, and Apex Debug Logs Salesforce

 Explanation of Log Content:

Console.log:

Used for frontend debugging in JavaScript or Lightning Web Components (LWC).

Logs messages, variables, and errors to the browser console.


HRA.log:

A custom log file for a Human Resources Application.

Tracks application events, warnings, and errors for auditing and debugging purposes.


Apexdebug.log:

Generated by Salesforce for debugging Apex code.

Captures execution details, SOQL queries, debug statements, and exceptions.

These logs are essential for troubleshooting, monitoring, and improving applications. The content and structure will vary depending on the specific use case and the system being debugged.

Understanding Logs: Console.log, HRA.log, and Apex Debug.log