Dynamic package.xml generation

An awesome blog for delta deployment

Apex and Beyond

Some weeks after implementing Continuous Integration as described in my previous post (Continuous integration for Salesforce), we started to see that the build was taking longer and longer. We compared different deployment logs and we saw that even do we were adding some new stuff, we were also deploying all the existing components as well including those that were not changed. So we started thinking and researching how to make our package.xml based on what we changed, and we came across this post: Dynamically Building Package.xml

Using this as a base we came with the following bash script:

Let’s start analyzing what this script is doing.

The following lines take the arguments from the command line and assigns to variables. -l is for the last commit and -p is the base commit to compare against.

Then we check if the folder where we are going to move what…

View original post 517 more words

Salesforce Sharing & Visibility Designer Certification

Salesforce Sharing & Visibility Designer Certification

I Code Cloud

Salesforce Sharing & Visibility Designer Certification

Recently I’ve cleared the Salesforce Sharing & Visibility Designer Certification, my first step towards becoming a Salesforce Technical Architect and so I thought of sharing some insights about the exam. After platform developer II certification, this is undeniably one of the challenging and fantabulous Salesforce exam. Now I have experienced the difference between knowing the path and walking the path, what an amazing experience!!

Sharinhg and visibility cert - Capture[Update] :  If you preparing for Platform Developer II Certification , please click here.

Salesforce Architect Journey

Salesforce-certified architect credentials comprise three tiers of certification that recognize specialized knowledge and skills, as well as your growing expertise in the Salesforce platform:

  • The Salesforce Certified Architecture Designer credentials validate knowledge and expertise in particular specializations.
  • The Salesforce Certified Application Architect and System Architect certifications recognize professionals who possess expertise in a domain area.
  • The Salesforce Certified Technical Architect (CTA) credential is the pinnacle certification…

View original post 940 more words

Introduction to Lightning Web Components – #LWC

As we all know that Salesforce has introduced the new concept to develop the Lightning Components which is LWC and is beta mode. In this post, we are going to learn how we can start working with LWC and all about LWC

I have recorded the videos regarding the same how we can set up the VS Code to start the coding with Salesforce DX. As, LWC is in beta mode and not available either in Sandbox or Developer environment we need to work with Salesforce Spring 19 Pre-Release Org. Here is the video which will take you to step by step how you can set up the tools and start development.

  • What is LWC?
  • Existing System
  • New LWC Structure
  • Comparison of Aura Framework and LWC
  • Setup Visual Code studio
  • Setup Salesforce CLI
  • Create Hello World LWC
  • Walkthrough with the key concept of LWC

Next Step – What the next video

  • LWC Folder Structure.
  • Supported Salesforce Experiences and Tools
  • Unsupported Experiences and Tools
  • Reactive Properties in JavaScript.
    • Public
    • Private
  • How to use attributes in LWC.
  • How to call the JavaScript method from LWC.

Sharing is Caring 🙂 If you have any doubt or query please comment them below in the comment box or you can reach me @ sfdcpanther@gmail.com OR you can tweet me @cloudyamit

Salesforce: Sharing Cheat Sheet

Awesome writeup.

The Silver Lining

Sharing is caring.

Sharing is complex, but necessarily so. It gives you incredibly fine-grained control over data access through it’s flexibility but requires quite a deep understanding to do it properly.

There are great articles out there that describe sharing in detail e.g.

Force.com object and record level security

An Overview of Force.com Security

I don’t want to recreate what’s in those articles, instead I’m providing a short, sharp cheat sheet of the major topics you need to understand. So without further ado…

Sharing Cheat Sheet

Sharing Metadata Records

  • “Object[Share]” for standard objects
  • “Object[__Share]” for custom objects
  • Fields: access level, record ID, user or group ID
  • Share records are not created for for OWDs, role hierchies or the “View All” or “Modify All” permissions

Implicit Sharing

  • For Accounts, Contacts, Cases and Opportunities only.
  • A platform feature, cannot be disabled.
  • Access to a parent account—If you have access to a child…

View original post 681 more words

Things to keep in mind while developing the Salesforce App-exchange Application

In this post, I will discuss what are the important parameters that need to be taken care while developing the App-Exchange Application using Salesforce. Before we dive into the concepts I would like to tell you that after developing the application, every application goes with the below security checks

  1. Checkmarx: – It is a free tool available to scan the Complete Code that is in your org where development has been done.
  2. Security Review: – The second step after submitting the code to the checkmarx and resolving all the issues is to Submit the package for the security review where salesforce representatives check the Quality of the code and functionality as well.

So, In order to develop the application which is secure and minimize the risk of data compromise or any other confidential information a developer must need to keep the following points into the mind while developing the application

1Cross-Site Scripting 
2S(O)QL Injection 
3Cross Site Request Forgery 
4Secure Communications and Cookies 
5Storing Secrets 
6Arbitrary Redirects 
7Access Control 
8Lightning Security Best Practices 
9Marketing Cloud App Security
10Secure PostMessage
11Secure WebSockets

Here is a Link to Trailhead module which explains everything about secure coding guidelines with the practical example

https://trailhead.salesforce.com/en/modules/secdev_injection_vulnerabilities/units/secdev_inject_get_started_wappsec

Resources: – 

  1. Salesforce Document
  2. Salesforce Security Guide
  3. An Overview of Force.com Security

Implement Omni Channel from Scratch – Salesforce

In this post, we will learn how to implement Omni Channel and in my previous post, we have implemented the Live Agent if you have not read yet then Read Here.

Prerequisite: Live agent must be enabled in order to use Omni Channel.

Problems

Problem while using Live Agent: – The company XYZ has now successfully enabled the live agent at their company site and it was working fine however as business growing company  the Global Support VP is getting complaints

  1. Some agents are getting many cases and some are not getting any cases at all.
  2. Agents need to Case manually from the Queues if the case is created manually or any other resource like Email-to-Case. And assigning the cases manually leads the wastage of time.
  3. Also, it is hard to manage what is the capacity of the particular agent and what is the traffic. 

Salesforce Admin has come up with an idea to implement the Omni Channel which will resolve all above problem and will increase the efficiency of the Support Agent.

Solution.gif

Introduction to Omni Channel:- Omni-Channel is a flexible, customizable feature, and you can configure it declaratively—that is, without writing code. Use Omni-Channel to manage the priority of work items, which makes it a cinch to route important work items to agents quickly. Manage your agents’ capacity to take on work items so that they’re given only the number of assignments that they can handle.

Best of all, Omni-Channel routes all these assignments to the correct agents automatically. Agents no longer have to pick and choose work assignments manually from a queue, which saves everyone in your call center time, effort, and brainpower.

Permission to set up the Omni Channel is Customize Application at profile level.

Omni Channel.png

Step1 – Enable Omni Channel:- Setup -> Build -> Customize -> Omni-Channel -> Omni-Channel Settings -> Select Enable Omni-Channel Checkbox -> Save

Enable Omni Channel.png

Setp2 – Create Service Channel:- Service Channels let you turn any Salesforce object―such as a case, lead, SOS session, or even a custom object―into a work record. Omni-Channel then plucks these work items from their queues―like flowers from the garden of agent productivity―and routes them to your agents in real time.

omnichannel_service_channels.png

Setup -> Build -> Customize -> Omni-Channel ->  Service Channels -> New -> 

Service Channel.png

Step3 – Create Routing Configurations: – Routing Configurations determine how work items are routed to agents. They let you prioritize the relative importance and size of work items across your Omni-Channel Queues. That way, the most important work items are handled accordingly, and work is evenly distributed to your agents. After all, we want to make sure every agent gets to have an equal amount of fun, right?

Setup -> Build -> Customize -> Omni-Channel -> Routing Configurations -> New -> 

Routing Configurations.png

Explanation of above Screenshot

  1. Overflow Assignee:- Sets the user or queue that Omni-Channel routes items to when your org reaches Omni-Channel limits.
  2. Routing Priority: – The order in which work items from the queue that are associated with this routing configuration are routed to agents.
  3. Routing Model: Specify how incoming work items are directed to agents using Omni-Channel.
    1. Least Active: – Incoming work items are routed to the agent with the least amount of open work. 
    2. Most Available: – Incoming work items are routed to the agent with the greatest difference between work item capacity and open work items. 

Step4 – Create Queue and Associated with Routing Configurations: – 

Setup -> Administrator -> Manage Users -> Queues -> New ->

Create Queue.png

Step5 – Add Omni Channel to the Console Application: – 

Setup -> Create -> Apps -> Edit Next to Sample Console App(OR You may Select your) -> Scroos Down to “Choose Console Components” Section -> Add Omni Channel From “Available Items” to “Selected Items”

Add Omni Channel.png

Now, as we have done almost part of implementing the Omni Channel. Let’s have a look how our console application looks like

Click on App Launcher and Select Sample Application

Console.png

Step6 – Add Presence Status to Omni Channel: – 

To see the list of available status like Online, Offline, Away, Available For Cases, Available For Chat and etc. We need to create the Presence Status.

Setup -> Build -> Customize -> Omni-Channel -> Presence Status -> New -> 

Presence Status

Repeat the above process to add more presence status.

Step7 – Add Presence Status to Correct Users Profile: – 

Adding the presence status to the Omni Channel that does not mean it will be available in Omni Channel Utility. To make visible these statuses we need to add to the appropriate user’s profile or permission set.

Setup -> Manage Users -> Profiles -> Select the profile on which you want to enable the status (in this demo we will add in System Administrator Profile)->  Scroll down to “Enabled Service Presence Status Access”  section and Click Edit -> 

Presence Status to profile.png

Add presence status from “Available Service Presence Statuses” to “Enabled Service Presence Statuses” Section and save.

Add Presence Status to profile

Step8 – See if presence status is available in Omni Channel utility or Not: – 

Click on App Launcher and Select Sample App

Omni Channel Sttus.png

Now, in Final let us test the App. Copy and paste the code if Live Chat Deployment and Chat Button that we did create in our previous post and save as .html file. if you have not implemented the Live Agent refer this link to implement the same.

From Omni channel Select any online statue and run the HTML file of Live Agent that we did save earlier.

OutPut.png

OutPut 1.png

If you are facing any issues please come up in the comments section with.

Sharing is Caring 🙂

Resources:- 

  1. Live Agent
  2. Omni Channel
  3. Trailhead

 

 

 

Create Lightning Charts With Chart.Js

Create Dynamic Chart using Chart.Js

ABSYZ

Everyone loves a smooth and slick UI. And what if, if you have an awesome UI for which you have to design once and will work across the devices, which is nothing but responsive. One such library which was great but not supported in Lightning experience was Chart.js. As some of its external libraries had older versions, Chart.js wasn’t supported in Lightning Locker Service. Oh, wait a min, what is a Locker Service? That itself is a story to tell about for another day. Anyways you can check out the documentation here (Lightning locker service).

But that is not the situation now. Due to the latest version updates of Chart.js, it is finally compatible with Lightning Locker Service. You may be wondering how can I implement Chart.js in my org? Well, through this blog post am going to explain how to build a Generic Chart.js Lightning component and by…

View original post 197 more words

Dynamic Binding Salesforce Lightning Component(Generic)

Welcome back All, here we will learn about the dynamic field of Lightning Component. As Most of you must be aware of that In Lightning, Component Dynamic component is not available. Recently I was working on one of my projects and implemented the Dynamic binding using the lightning component so I am going to share how I implemented the same so that it may help others.

As we all know that we can use the Dynamic Binding in the VisualForce page but in Lightning Component it is not Possible. 

In this example, We will show the list of Objects in a picklist and when user will select any object it will dynamically show the TOP 15 records in a table.

Output 

OutPut.png

Step1 – Create Apex Class

DynamicBindingDemoController.class

/*
* @Author : Amit Singh
* @Date : 22nd Feb 2018
* @Description : Class is responsible for getting the dynamic data and sending back to
* : Lightning Component
*/
public class DynamicBindingDemoController {
/*
* @Author : Amit Singh
* @Date : 22nd Feb 2018
* @Description : Method to return all available Object to Lightning Component
* @Return Type : List<String>
* @Params : none
*/
@AuraEnabled
public static List<String> listAllObject(){
List<String> objectList = new List<String>();
For(Schema.sObjectType sobj: schema.getGlobalDescribe().values()){
if(sobj.getDescribe().isQueryable())
objectList.add(sobj.getDescribe().getName()+'####'+sobj.getDescribe().getLabel());
}
return objectList;
}
/*
* @Author : Amit Singh
* @Date : 22nd Feb 2018
* @Description : Method to return the dynamic data based on the Selected Object Lightning Component
* @Return Type : DynamicBindingWrapper wrapper class
* @Params : Strig ObjectName
*/
@AuraEnabled
public static DynamicBindingWrapper listAllFields(String objectName){
DynamicBindingWrapper dynamicData = new DynamicBindingWrapper();
List<fieldDataWrapper> wrapperList = new List<fieldDataWrapper>();
// Create Dynamic Query Start ..
String theQuery = 'SELECT ';
SObjectType sObjectName = Schema.getGlobalDescribe().get(objectName);
Map<String,Schema.SObjectField> mfields = sObjectName.getDescribe().fields.getMap();
For(Schema.SObjectField field : mfields.values()){
If(field.getDescribe().isAccessible() && !field.getDescribe().getName().EndsWith('Id')
&& field.getDescribe().getName()!='CreatedDate' && field.getDescribe().getName()!='LastModifiedDate'
&& field.getDescribe().getName()!='LastReferencedDate' && field.getDescribe().getName()!='LastReferencedDate'
&& field.getDescribe().getName()!='LastActivityDate' && field.getDescribe().getName()!='LastViewedDate'
&& field.getDescribe().getName()!='IsDeleted'){
fieldDataWrapper wrapper = new fieldDataWrapper();
theQuery += field.getDescribe().getName() + ',' ;
wrapper.label = field.getDescribe().getLabel();
wrapper.apiName = field.getDescribe().getName();
wrapperList.add(wrapper);
}
}
// Trim last comma
theQuery = theQuery.subString(0, theQuery.length() - 1);
// Finalize query string
theQuery += ' FROM '+objectName+' LIMIT 15';
// Query End ..
System.debug('#### theQuery = '+theQuery);
List<sObject> objectData = Database.Query(theQuery);
if(objectData!=null && objectData.size()>0)
dynamicData.sObjectData = objectData;
else
dynamicData.sObjectData = new List<sObject>{};
dynamicData.fieldList = wrapperList;
System.debug('#### dynamicData '+dynamicData);
return dynamicData;
}
/* Class to store the dynamic data
* and list of related fields
*/
public class DynamicBindingWrapper{
@AuraEnabled
public List<sObject> sObjectData { get; set; }
@AuraEnabled
public List<fieldDataWrapper> fieldList { get; set; }
}
/*
* Class to store the field information
*/
public class fieldDataWrapper{
@AuraEnabled
public String label { get; set; }
@AuraEnabled
public String apiName { get; set; }
}
}

https://gist.github.com/amitastreait/bbdffd3849af765ecacab071e3edfb36.js

Step2 – Create the Lightning Component

DynamicBindingDemo.cmp

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction,force:hasSObjectName"
controller='DynamicBindingDemoController'
access="global" >
<!-- call the doInit method to load the list of All the Available Objects into the Org -->
<aura:handler name='init' value='{!this}' action='{!c.doInit}' />
<aura:attribute name='objectList' type='List' />
<aura:attribute name="isSending" type="boolean" />
<c:Spinner />
<div class="slds-m-around_small">
<div class="slds-page-header">
<div class="slds-media">
<div class="slds-media__body">
<h1 class="slds-page-header__title slds-truncate slds-align-middle" title="Dynamic Binding in Ligtning Component">
Dynamic Field Binding in Ligtning Component</h1>
<p class="slds-text-body_small slds-line-height_reset">
By SFDC Panther • 24/02/2018</p>
</div>
</div><br/>
</div><br/>
<div class="slds-grid slds-wrap">
<div class="slds-size_1-of-2">
<div class="slds-box_x-small">
<!-- show the list of All the Object -->
<lightning:select name="selectObject" label="Select an Object"
onchange="{!c.doHandleChange}" aura:id='selectObject'>
<option value="" text="- None -" />
<aura:iteration items='{!v.objectList}' var='obj'>
<option value="{!obj.key}" text="{!obj.value}" />
</aura:iteration>
</lightning:select>
</div>
</div>
<br/>
<ui:scrollerWrapper class="scrollerSize">
<div class="slds-size_2-of-2">
<div id='sfdctable' aura:id='sfdcDiv'>
<!-- devision that will show the dynamic content -->
</div>
</div>
</ui:scrollerWrapper>
</div>
</div>
</aura:component>
({
doInit : function(component, event, helper) {
helper.onInit(component, event, helper);
},
doHandleChange : function(component, event, helper) {
helper.onHandleChange(component, event, helper);
},
})
({
onInit : function(component, event, helper) {
/* Call the Apex class method to fetch the List of all object */
var action = component.get('c.listAllObject');
action.setCallback(this, function(response){
var state = response.getState();
if(state === 'SUCCESS' && component.isValid()){
/* set the value to the attribute of the component */
var responseValue = response.getReturnValue();
var lstOptions = [];
for(var i=0; i < responseValue.length; i++){
lstOptions.push({
value : responseValue[i].split('####')[1],
key : responseValue[i].split('####')[0]
});
}
lstOptions.sort();
component.set('v.objectList', lstOptions);
}else{
var errors = response.getError();
$A.log(errors);
if(errors || errors[0].message){
console(errors[0].message);
}
}
});
$A.enqueueAction(action);
},
onHandleChange : function(component, event, helper){
/* Call this method whenever user will select the Obejct
* and show the Dynamic Content */
var selObject = component.find('selectObject').get('v.value');
var action = component.get('c.listAllFields');
if(selObject!=null && selObject!='' && selObject!=undefined){
action.setParams({
"objectName" : selObject
});
action.setCallback(this, function(response){
var state = response.getState();
if( state === 'SUCCESS' && component.isValid()){
//component.find("dynamicBody").set("v.body",[]);
component.find('sfdcDiv').set("v.body",[]);
var responseValue = response.getReturnValue();
var objectValue = responseValue.sObjectData;
var fieldList = responseValue.fieldList;
/* Create Dynamic Table */
var sObjectDataTableHeader = [];
// Create table Header
for (var i=0; i < fieldList.length; i++) {
sObjectDataTableHeader.push(fieldList[i].label);
}
console.log(sObjectDataTableHeader);
//Get the count of columns.
var columnCount = sObjectDataTableHeader.length;
//Create a HTML Table element.
var table = document.createElement("TABLE");
//table.border = "1";
//Add the header row.
var row = table.insertRow(-1);
for (var i = 0; i < columnCount; i++) {
var headerCell = document.createElement("TH");
headerCell.innerHTML = sObjectDataTableHeader[i];
headerCell.className='hearderClass';
row.appendChild(headerCell);
}
var dvTable = document.getElementById("sfdctable");
dvTable.innerHTML = "";
dvTable.appendChild(table);
/* Create Dynamic Table End */
if(objectValue.length){
for(var j=0; j < objectValue.length; j++){
// Dynamic table Row
row = table.insertRow(-1);
// Dynamic Table Row End
for (var i=0; i < fieldList.length; i++) {
// Dynamic table Row
var cell = row.insertCell(-1);
cell.innerHTML = objectValue[j][fieldList[i].apiName];
component.set('v.isSending' , false);
}
}
}else{
}
}else{
var errors = response.getError();
$A.log('Error Details '+errors);
if( errors || errors[0].message){
console.log('Error Details '+errors[0].message);
}
}
});
$A.enqueueAction(action);
}else{
component.set('v.isSending' , false);
}
},
})

See the comments into the component.

Step3: – Click on Controller from the right and paste the below code for Controller Javascript

DynamicBindingDemoController.js


({
doInit : function(component, event, helper) {
helper.onInit(component, event, helper);
},
doHandleChange : function(component, event, helper) {
helper.onHandleChange(component, event, helper);
},
})

Step4: – Click on Helper from the right and paste the below code for Helper Javascript

DynamicBindingDemoHelper.js


({
onInit : function(component, event, helper) {
/* Call the Apex class method to fetch the List of all object */
var action = component.get('c.listAllObject');
action.setCallback(this, function(response){
var state = response.getState();
if(state === 'SUCCESS' && component.isValid()){
/* set the value to the attribute of the component */
var responseValue = response.getReturnValue();
var lstOptions = [];
for(var i=0; i < responseValue.length; i++){
lstOptions.push({
value : responseValue[i].split('####')[1],
key : responseValue[i].split('####')[0]
});
}
lstOptions.sort();
component.set('v.objectList', lstOptions);

}else{
var errors = response.getError();
$A.log(errors);
if(errors || errors[0].message){
console(errors[0].message);
}
}
});
$A.enqueueAction(action);
},
onHandleChange : function(component, event, helper){
/* Call this method whenever user will select the Obejct
* and show the Dynamic Content */
var selObject = component.find('selectObject').get('v.value');
var action = component.get('c.listAllFields');
if(selObject!=null && selObject!='' && selObject!=undefined){
action.setParams({
"objectName" : selObject
});
action.setCallback(this, function(response){
var state = response.getState();
if( state === 'SUCCESS' && component.isValid()){
//component.find("dynamicBody").set("v.body",[]);
component.find('sfdcDiv').set("v.body",[]);
var responseValue = response.getReturnValue();
var objectValue = responseValue.sObjectData;
var fieldList = responseValue.fieldList;

/* Create Dynamic Table */
var sObjectDataTableHeader = [];
// Create table Header
for (var i=0; i < fieldList.length; i++) {
sObjectDataTableHeader.push(fieldList[i].label);
}
console.log(sObjectDataTableHeader);
//Get the count of columns.
var columnCount = sObjectDataTableHeader.length;
//Create a HTML Table element.
var table = document.createElement("TABLE");
//table.border = "1";
//Add the header row.
var row = table.insertRow(-1);
for (var i = 0; i < columnCount; i++) {
var headerCell = document.createElement("TH");
headerCell.innerHTML = sObjectDataTableHeader[i];
headerCell.className='hearderClass';
row.appendChild(headerCell);
}
var dvTable = document.getElementById("sfdctable");
dvTable.innerHTML = "";
dvTable.appendChild(table);
/* Create Dynamic Table End */

if(objectValue.length){
for(var j=0; j < objectValue.length; j++){
// Dynamic table Row
row = table.insertRow(-1);
// Dynamic Table Row End
for (var i=0; i < fieldList.length; i++) {
// Dynamic table Row
var cell = row.insertCell(-1);
cell.innerHTML = objectValue[j][fieldList[i].apiName];
component.set('v.isSending' , false);

}
}
}else{

}
}else{
var errors = response.getError();
$A.log('Error Details '+errors);
if( errors || errors[0].message){
console.log('Error Details '+errors[0].message);
}
}
});
$A.enqueueAction(action);
}else{
component.set('v.isSending' , false);
}
},
})

See the comments.

Step5: – Create Lightning Application

DynamicBindingDemoApplication.app

<aura:application access=”Global” extends=”force:slds” >
<c:DynamicBindingDemo />
</aura:application>

Click on Preview to see the output of the component.

Happy learning 🙂

Sharing is caring 🙂 😉

Resource:- 

OPFOCOUS Blog

Complete Code