Monday, September 2, 2024

Get Records from Report and Assign equally to available users

 global class CreateDailyDialListTasksForAgents implements Schedulable {

    global void execute(SchedulableContext SC) {

        String reportName = 'DQ_Account_Buckets';

        List<Report> reportList = [SELECT Id, DeveloperName FROM Report WHERE DeveloperName = :reportName];

        if (!reportList.isEmpty()) {

            fetchReportData(reportList[0].Id);

        }

    }

    global void fetchReportData(Id reportId){

        Reports.ReportResults results = Reports.ReportManager.runReport(reportId, true);

        if(results != null && results.getFactMap() != null){

            List<String> headers = new List<String>();            

            for(String colName : results.getReportMetadata().getDetailColumns()) {

                String label = results.getReportExtendedMetadata().getDetailColumnInfo().get(colName).getLabel();

                headers.add(label);

            }

            Reports.ReportFactWithDetails factDetails = (Reports.ReportFactWithDetails)results.getFactMap().get('0!0_0');  

            Map<String,String> accPhoneMap = new Map<String,String>();

            for (Reports.ReportDetailRow row : factDetails.getRows()) {

                Integer cellIndex = 0;

                String Name;

                String Phone;

                for (Reports.ReportDataCell cell : row.getDataCells()){ 

                    String column = headers.get(cellIndex);                    

                    if(Column == 'Property Owner: Account Name'){

                        Name = cell.getLabel();

                    }

                    if(Column == 'Property Owner: Phone'){

                        Phone = cell.getLabel();

                    }

                    cellIndex++;

                }      

                accPhoneMap.put(Name,Phone);

            }

            system.debug(accPhoneMap);

            if(accPhoneMap != null && !accPhoneMap.isEmpty()){

                createTasksForAgents(accPhoneMap);

            }

        }        

    }

    global void createTasksForAgents(Map<String,String> accPhoneMap){

        List<Id> usersIds = new List<Id>();

        List<Id> availableUsersIds = new List<Id>();

      /*  for(GroupMember gm :[Select UserOrGroupId From GroupMember where Group.Name ='Collection Queue']){

            String uId = gm.UserOrGroupId;

            if(uId.startsWith('005')){

                usersIds.add(uId);

            }            

        }*/

        for(User u :[Select Id From User where Profile.Name ='HOA Account Loyalty' OR Profile.Name ='HOA Account Loyalty Mgr']){

            usersIds.add(u.Id);          

        }

        if(!usersIds.isEmpty()){

            for(UserServicePresence usp :[Select UserId From UserServicePresence Where IsCurrentState = true and UserId IN:usersIds]){

                availableUsersIds.add(usp.UserId);

            }

            if(availableUsersIds.isEmpty()){

                return;

            }

            List<Task> tasksList = new List<Task>();

            for(String acc : accPhoneMap.keySet()){

                Task t = new Task();

                t.Subject = 'Call '+acc+' @ '+accPhoneMap.get(acc);

                t.IsReminderSet = true;

                t.ReminderDateTime = System.now();

                t.ActivityDate = Date.today();

                tasksList.add(t);

            }  

            Integer noOfUsers = availableUsersIds.size();

            Integer noOfTasks = tasksList.size();

            Integer recordsPerUser = (noOfTasks + noOfUsers - 1) / noOfUsers;

            Map<Id, List<Task>> userTaskMap = new Map<Id, List<Task>>();

            for(Id uId : availableUsersIds){

                userTaskMap.put(uId, new List<Task>());

            }            

            Integer currentIndex = 0;

            for(Task t : tasksList){

                String uId = availableUsersIds[Math.mod(currentIndex, noOfUsers)];

                userTaskMap.get(uId).add(t);

                currentIndex++;

            }

            List<Task> tasksToInsert = new List<Task>();

            for(Id uId : userTaskMap.keySet()){

                List<Task> tasks = userTaskMap.get(uId);

                for (Task t : tasks) {

                    t.OwnerId = uId;

                    tasksToInsert.add(t);

                }

            }

            Database.insert(tasksToInsert,false);

        }

    }

}

Wednesday, September 28, 2022

LWC Datatable with Pagination and keep selected rows persistent

 Here is the code to display data in LWC Datatable with pagination and keep selected rows persistent between each page.


accountsTable.html :

<template>
  <lightning-card
    variant="Narrow"
    title="Partner Lookup"
    icon-name="standard:contact"
    class="slds-var-m-around_small"
  >
    <lightning-button
      variant="brand"
      icon-name="utility:email"
      label="Send Email"
      title="Brand action"
      slot="actions"
      onclick={openEmailPopup}
      disabled={disableEmail}
    >
    </lightning-button>
    <div class="slds-card__body slds-card__body_inner">
      <template if:true={showLoading}>
        <lightning-spinner
          alternative-text="Loading"
          size="medium"
          class="spinnerClass"
          variant="brand"
        >
        </lightning-spinner>
      </template>
      <lightning-input
        type="search"
        class="slds-size_4-of-12 slds-var-p-bottom_small"
        label="Company"
        value={searchKey}
        onchange={handleSearchChange}
      >
      </lightning-input>
      <template if:false={noData}>
        <lightning-datatable
          data-id="table"
          key-field="Id"
          data={data}
          columns={columns}
          onrowselection={onRowSelection}
          selected-rows={allSelectedRows}
          class="slds-table_bordered"
        >
        </lightning-datatable>
        <div slot="footer">
          <lightning-layout class="slds-var-p-around_small">
            <lightning-layout-item class="slds-size_2-of-12">
              <lightning-button
                label="Previous"
                icon-name="utility:chevronleft"
                onclick={previousHandler}
                disabled={disbalePrevious}
              >
              </lightning-button>
            </lightning-layout-item>
            <lightning-layout-item class="slds-size_2-of-12">
              Page {page} of {totalPage}
            </lightning-layout-item>
            <lightning-layout-item class="slds-size_2-of-12">
              <lightning-button
                label="Next"
                icon-name="utility:chevronright"
                icon-position="right"
                onclick={nextHandler}
                disabled={disbaleNext}
              >
              </lightning-button>
            </lightning-layout-item>
          </lightning-layout>
        </div>
      </template>
      <template if:true={noData}>
        <p class="slds-text-heading_small slds-var-p-top_small">
          No matching Accounts to display.
        </p>
      </template>
    </div>
  </lightning-card>
  <template if:true={showModal}>
    <section aria-modal="true" class="slds-modal slds-fade-in-open">
      <div class="slds-modal__container">
        <header class="slds-modal__header">
          <h2 class="slds-text-heading_small">Send Email</h2>
          <lightning-button-icon
            class="slds-modal__close"
            icon-name="utility:close"
            variant="bare-inverse"
            onclick={closeModal}
            alternative-text="Close"
            title="Close"
          >
          </lightning-button-icon>
        </header>
        <div
          class="slds-var-p-around_small slds-modal__content modalBody slds-is-relative"
        >
          <template if:true={showModelLoading}>
            <lightning-spinner
              alternative-text="Loading"
              size="medium"
              class="spinnerClass"
              variant="brand"
            >
            </lightning-spinner>
          </template>
          <lightning-layout multiple-rows="true" horizontal-align="space">
            <lightning-layout-item size="12">
              <lightning-input
                name="recipients"
                required="true"
                value={recipients}
                label="Recipients"
                onchange={onChangeRecipient}
              >
              </lightning-input>
            </lightning-layout-item>
            <lightning-layout-item size="12">
              <lightning-combobox
                name="template"
                label="Template"
                value={selectedTemplate}
                placeholder="Select Template"
                options={templateOptions}
                onchange={handleTemplateChange}
              >
              </lightning-combobox>
            </lightning-layout-item>
            <lightning-layout-item size="12">
              <lightning-input
                name="subject"
                required="true"
                value={subject}
                label="Subject"
                onchange={onChangeSubject}
              >
              </lightning-input>
            </lightning-layout-item>
            <lightning-layout-item size="12">
              <lightning-input-rich-text
                value={htmlBody}
                label="Content"
                label-visible="true"
                share-with-entity-id={recordId}
                required="true"
                onchange={onChangeContent}
              >
              </lightning-input-rich-text>
            </lightning-layout-item>
          </lightning-layout>
        </div>
        <footer class="slds-modal__footer">
          <lightning-button
            variant="neutral"
            label="Cancel"
            title="Cancel"
            onclick={closeModal}
            class="slds-var-p-right_small"
          >
          </lightning-button>
          <lightning-button
            variant="brand"
            icon-name="utility:send"
            label="Send"
            title="Send"
            onclick={onClickSendEmail}
          >
          </lightning-button>
        </footer>
      </div>
    </section>
    <div class="slds-backdrop slds-backdrop_open"></div>
  </template>
</template>


AccountsTable.js:


import { LightningElement, wire, api, track } from "lwc";
import getPartners from "@salesforce/apex/AccountController.getPartners";
import getRecipients from "@salesforce/apex/AccountController.getRecipients";
import getEmailBody from "@salesforce/apex/AccountController.getEmailBody";
import sendEmail from "@salesforce/apex/AccountController.sendEmail";
import emailTemplateLabel from "@salesforce/label/c.AccountTemplates";
import { ShowToastEvent } from "lightning/platformShowToastEvent";

const columns = [
  { label: "First Name", fieldName: "FirstName", type: "text" },
  { label: "Last Name", fieldName: "LastName", type: "text" },
  { label: "Email", fieldName: "Email", type: "text" },
  { label: "Phone", fieldName: "Phone", type: "Text" },
  { label: "Country", fieldName: "MailingCountry", type: "Text" }
];
const DELAY = 300;
export default class AccountsTable extends LightningElement {
  @api recordId = null;
  @track showLoading = true;
  @track showModelLoading = true;
  @track searchKey = "";
  @track page = 1;
  @track items = [];
  @track data = [];
  @track columns;
  @track startingRecord = 1;
  @track endingRecord = 0;
  @track pageSize = 10;
  @track totalRecountCount = 0;
  @track totalPage = 0;
  @track disableEmail = true;
  @track allSelectedRows = [];
  @track error;
  @track showModal = false;
  @track recipients;
  @track selectedrecipients;
  @track selectedTemplate;
  @track subject;
  @track htmlBody;
  isPageChanged = false;
  initialLoad = true;

  @wire(getPartners, {
    recId: "$recordId",
    searchKey: "$searchKey"
  })
  wiredPartners({ error, data }) {
    if (data) {
      this.processRecords(data);
      this.error = undefined;
      this.showLoading = false;
    } else if (error) {
      this.error = error;
      this.data = undefined;
      this.showLoading = false;
    }
  }
  processRecords(data) {
    this.items = data;
    this.totalRecountCount = data.length;
    this.totalPage = Math.ceil(this.totalRecountCount / this.pageSize);
    const arr = this.items.slice(0, this.pageSize);
    const newArr = arr.map((object) => {
      return { ...object, Id: object.Id + "-1" };
    });
    this.data = newArr;
    this.endingRecord = this.pageSize;
    this.columns = columns;
  }
  get disbalePrevious() {
    return this.page == 1;
  }
  get disbaleNext() {
    return this.page == this.totalPage;
  }
  previousHandler() {
    this.showLoading = true;
    this.isPageChanged = true;
    if (this.page > 1) {
      this.page = this.page - 1;
      this.displayRecordPerPage(this.page);
    }
    this.showLoading = false;
  }
  nextHandler() {
    this.showLoading = true;
    this.isPageChanged = true;
    if (this.page < this.totalPage && this.page !== this.totalPage) {
      this.page = this.page + 1;
      this.displayRecordPerPage(this.page);
    }
    this.showLoading = false;
  }
  displayRecordPerPage(page) {
    this.startingRecord = (page - 1) * this.pageSize;
    this.endingRecord = this.pageSize * page;
    this.endingRecord =
      this.endingRecord > this.totalRecountCount
        ? this.totalRecountCount
        : this.endingRecord;
    const arr = this.items.slice(this.startingRecord, this.endingRecord);
    const newArr = arr.map((object) => {
      return { ...object, Id: object.Id + "-" + page };
    });
    this.data = newArr;
    this.startingRecord = this.startingRecord + 1;
    this.template.querySelector(
      '[data-id="table"]'
    ).selectedRows = this.allSelectedRows;
  }
  onRowSelection(event) {
    if (!this.isPageChanged || this.initialLoad) {
      this.initialLoad = false;
      var selectedRows = event.target.selectedRows;
      var allSelectedRows = this.allSelectedRows;
      var currentPageNumber = this.page;
      //Process the rows now
      //Condition 1 -> If any new row selected, add to our allSelectedRows attribute
      //Condition 2 -> If any row is deselected, remove from allSelectedRows attribute
      //Solution - Remove all rows from current page from allSelectedRows attribute and then add again
      //Removing all rows coming from curent page from allSelectedRows
      var i = allSelectedRows.length;
      if (i > 0) {
        while (i--) {
          var pageNumber = allSelectedRows[i].split("-")[1];
          if (pageNumber && pageNumber == currentPageNumber) {
            allSelectedRows.splice(i, 1);
          }
        }
      }
      selectedRows.forEach(function (row) {
        allSelectedRows.push(row);
      });
      if (allSelectedRows.length > 0) {
        this.disableEmail = false;
      } else {
        this.disableEmail = true;
      }
      this.allSelectedRows = allSelectedRows;
    } else {
      this.isPageChanged = false;
    }
  }
  handleSearchChange(event) {
    this.showLoading = true;
    window.clearTimeout(this.delayTimeout);
    const searchKey = event.target.value;
    this.delayTimeout = setTimeout(() => {
      this.searchKey = searchKey;
      var data = [];
      for (var i = 0; i < this.items.length; i++) {
        if (
          this.items[i] != undefined &&
          this.items[i].FirstName.includes(this.searchKey)
        ) {
          data.push(this.items[i]);
        }
      }
      this.processRecords(data);
      this.page = 1;
      this.showLoading = false;
    }, DELAY);
  }
  openEmailPopup() {
    this.showModal = true;
    this.showModelLoading = true;
    var recs = [];
    for (var i = 0; i < this.allSelectedRows.length; i++) {
      recs.push(this.allSelectedRows[i].split("-")[0]);
    }
    getRecipients({ recIds: recs })
      .then((result) => {
        this.showModelLoading = false;
        this.recipients = result;
        this.selectedrecipients = result;
        this.error = undefined;
      })
      .catch((error) => {
        this.showModelLoading = false;
        this.recipients = undefined;
        this.selectedrecipients = undefined;
        this.error = error;
      });
  }
  get templateOptions() {
    var options = emailTemplateLabel.split(";");
    var resultMap = [];
    for (let i = 0; i < options.length; i++) {
      resultMap.push({
        class: "optionClass",
        label: options[i],
        value: options[i]
      });
    }
    return resultMap;
  }
  onChangeRecipient(event) {
    this.recipients = event.detail.value;
  }
  onChangeSubject(event) {
    this.subject = event.detail.value;
  }
  onChangeContent(event) {
    this.htmlBody = event.detail.value;
  }
  handleTemplateChange(event) {
    this.showModelLoading = true;
    this.selectedTemplate = event.detail.value;
    getEmailBody({ leadId: this.recordId, templateName: this.selectedTemplate })
      .then((result) => {
        this.showModelLoading = false;
        for (var key in result) {
          this.subject = key;
          this.htmlBody = result[key];
        }
        this.error = undefined;
      })
      .catch((error) => {
        this.showModelLoading = false;
        this.error = error;
        this.subject = undefined;
        this.htmlBody = undefined;
      });
  }
  get noData() {
    return this.items.length == 0 ? true : false;
  }
  closeModal() {
    this.closeEmailModel();
  }
  onClickSendEmail() {
    if (
      this.recipients == undefined ||
      this.recipients == null ||
      this.recipients == ""
    ) {
      this.showToast("error", "Error", "Enter the Recipients");
    } else if (
      this.subject == undefined ||
      this.subject == null ||
      this.subject == ""
    ) {
      this.showToast("error", "Error", "Enter the Subject");
    } else if (
      this.htmlBody == undefined ||
      this.htmlBody == null ||
      this.htmlBody == ""
    ) {
      this.showToast("error", "Error", "Enter the Content");
    } else {
      this.showModelLoading = true;
      sendEmail({
        leadId: this.recordId,
        toAddress: this.recipients,
        subject: this.subject,
        body: this.htmlBody
      })
        .then((result) => {
          this.showToast("success", "Success!", "Email sent successfully.");
          this.error = undefined;
          this.closeEmailModel();
        })
        .catch((error) => {
          this.showModelLoading = false;
          this.error = error;
          this.showToast("error", "Email sending failed!", this.error);
        });
    }
  }
  closeEmailModel() {
    this.recipients = this.selectedrecipients;
    this.selectedTemplate = undefined;
    this.subject = undefined;
    this.htmlBody = undefined;
    this.showModelLoading = false;
    this.showModal = false;
  }
  showToast(type, title, msg) {
    const evt = new ShowToastEvent({
      title: title,
      message: msg,
      variant: type,
      mode: "dismissable"
    });
    this.dispatchEvent(evt);
  }
}

AccountController.apxc

public class AccountController { @AuraEnabled(cacheable=true) public static List<partnerData> getPartners(String recId, String searchKey){ String partnerName; if(String.isNotBlank(searchKey)){ partnerName = searchKey+'%'; } List<partnerData> partnerList = new List<partnerData>(); for(Contact con : [SELECT Id,FirstName,LastName,Email,Phone,MailingCountry From Contact where FirstName like:partnerName]){ partnerList.add(new partnerData(con)); } return partnerList; } @AuraEnabled public static String getRecipients(List<String> recIds){ Set<String> recSet = new Set<String>(); for(Contact con :
                [SELECT Id,FirstName,LastName,Email,Phone,MailingCountry From Contact Where Id IN:recIds order by Name]){ recSet.add(con.Email); } return String.join(new List<String>(recSet),';'); } @AuraEnabled public static map<string,string> getEmailBody(String leadId, String templateName){ map<string,string> emailmap = new map<string,string>(); EmailTemplate et = [select id,Name,Subject,Body from EmailTemplate where Name=:templateName]; Messaging.SingleEmailMessage email = Messaging.renderStoredEmailTemplate(et.id, leadId ,null); if(email.getHtmlBody() != null ){ emailmap.put(email.getSubject(),email.getHtmlBody()); }else{ emailmap.put(email.getSubject(),email.getPlainTextBody()); } return emailmap; } @AuraEnabled public static String sendEmail(String leadId,String toAddress,String subject,String body){ List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>(); Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); mail.setToAddresses(toAddress.split(';')); mail.setTargetObjectId(leadId); // mail.setReplyTo('noreply@gmail.com'); // change it with your mail address. // mail.setSenderDisplayName('salesforce User'); mail.setSubject(subject); mail.setHtmlBody(body); mail.setTreatTargetObjectAsRecipient(false); mail.setSaveAsActivity(true); mails.add(mail); try{ Messaging.sendEmail(mails); return 'Success'; }catch(exception e){ return e.getMessage(); } } public class partnerData{ @AuraEnabled public string Id{get;set;} @AuraEnabled public string FirstName{get;set;} @AuraEnabled public string LastName{get;set;} @AuraEnabled public string Email{get;set;} @AuraEnabled public string Phone{get;set;} @AuraEnabled public string MailingCountry{get;set;} public partnerData(Contactpartner){ this.Id = partner.Id; this.FirstName       = partner.FirstName; this.LastName        = partner.LastName; this.Email           = partner.Email; this.Phone          = partner.Phone; this.MailingCountry  = partner.MailingCountry ; } } }

Monday, September 26, 2022

SOQL to view all permissions enabled for a Permisssionset

SELECT Id, Name, Label, LicenseId, ProfileId, IsOwnedByProfile, IsCustom, PermissionsEmailSingle, PermissionsEmailMass, PermissionsEditTask, PermissionsEditEvent, PermissionsExportReport, PermissionsImportPersonal, PermissionsDataExport, PermissionsManageUsers, PermissionsEditPublicFilters, PermissionsEditPublicTemplates, PermissionsModifyAllData, PermissionsManageCases, PermissionsMassInlineEdit, PermissionsEditKnowledge, PermissionsManageKnowledge, PermissionsManageSolutions, PermissionsCustomizeApplication, PermissionsEditReadonlyFields, PermissionsRunReports, PermissionsViewSetup, PermissionsTransferAnyEntity, PermissionsNewReportBuilder, PermissionsActivateContract, PermissionsActivateOrder, PermissionsImportLeads, PermissionsManageLeads, PermissionsTransferAnyLead, PermissionsViewAllData, PermissionsEditPublicDocuments, PermissionsViewEncryptedData, PermissionsEditBrandTemplates, PermissionsEditHtmlTemplates, PermissionsChatterInternalUser, PermissionsManageEncryptionKeys, PermissionsDeleteActivatedContract, PermissionsChatterInviteExternalUsers, PermissionsSendSitRequests, PermissionsOverrideForecasts, PermissionsViewAllForecasts, PermissionsApiUserOnly, PermissionsManageRemoteAccess, PermissionsCanUseNewDashboardBuilder, PermissionsManageCategories, PermissionsConvertLeads, PermissionsPasswordNeverExpires, PermissionsUseTeamReassignWizards, PermissionsEditActivatedOrders, PermissionsInstallPackaging, PermissionsPublishPackaging, PermissionsManagePartners, PermissionsChatterOwnGroups, PermissionsEditOppLineItemUnitPrice, PermissionsCreatePackaging, PermissionsBulkApiHardDelete, PermissionsInboundMigrationToolsUser, PermissionsSolutionImport, PermissionsManageCallCenters, PermissionsManageSynonyms, PermissionsOutboundMigrationToolsUser, PermissionsDelegatedPortalUserAdmin, PermissionsViewContent, PermissionsManageEmailClientConfig, PermissionsEnableNotifications, PermissionsManageDataIntegrations, PermissionsViewDataCategories, PermissionsManageDataCategories, PermissionsAuthorApex, PermissionsManageMobile, PermissionsApiEnabled, PermissionsManageCustomReportTypes, PermissionsManagePartnerNetConn, PermissionsEditCaseComments, PermissionsTransferAnyCase, PermissionsContentAdministrator, PermissionsCreateWorkspaces, PermissionsManageContentPermissions, PermissionsManageContentProperties, PermissionsManageContentTypes, PermissionsScheduleJob, PermissionsManageExchangeConfig, PermissionsManageAnalyticSnapshots, PermissionsScheduleReports, PermissionsManageBusinessHourHolidays, PermissionsManageDynamicDashboards, PermissionsManageInteraction, PermissionsViewMyTeamsDashboards, PermissionsModerateChatter, PermissionsResetPasswords, PermissionsFlowUFLRequired, PermissionsCanInsertFeedSystemFields, PermissionsActivitiesAccess, PermissionsManageKnowledgeImportExport, PermissionsEmailTemplateManagement, PermissionsEmailAdministration, PermissionsManageChatterMessages, PermissionsForceTwoFactor, PermissionsViewEventLogFiles, PermissionsManageNetworks,  PermissionsManageAuthProviders, PermissionsRunFlow, PermissionsViewGlobalHeader, PermissionsManageQuotas, PermissionsCreateCustomizeDashboards, PermissionsCreateDashboardFolders, PermissionsViewPublicDashboards, PermissionsManageDashbdsInPubFolders, PermissionsCreateCustomizeReports, PermissionsCreateReportFolders, PermissionsViewPublicReports, PermissionsManageReportsInPubFolders, PermissionsEditMyDashboards, PermissionsEditMyReports, PermissionsViewAllUsers, PermissionsAllowUniversalSearch, PermissionsConnectOrgToEnvironmentHub, PermissionsCreateCustomizeFilters, PermissionsContentHubUser, PermissionsModerateNetworkFeeds, PermissionsModerateNetworkFiles, PermissionsGovernNetworks, PermissionsSalesConsole, PermissionsTwoFactorApi, PermissionsDeleteTopics, PermissionsEditTopics, PermissionsCreateTopics, PermissionsAssignTopics, PermissionsIdentityEnabled, PermissionsIdentityConnect, PermissionsAllowViewKnowledge, PermissionsContentWorkspaces,  PermissionsManageSearchPromotionRules, PermissionsCustomMobileAppsAccess, PermissionsViewHelpLink, PermissionsManageProfilesPermissionsets, PermissionsAssignPermissionSets, PermissionsManageRoles, PermissionsManageIpAddresses, PermissionsManageSharing, PermissionsManageInternalUsers, PermissionsManagePasswordPolicies, PermissionsManageLoginAccessPolicies, PermissionsManageCustomPermissions, PermissionsCanVerifyComment, PermissionsManageUnlistedGroups, PermissionsStdAutomaticActivityCapture, PermissionsInsightsAppDashboardEditor, PermissionsManageTwoFactor, PermissionsInsightsAppUser, PermissionsInsightsAppAdmin, PermissionsInsightsAppEltEditor, PermissionsInsightsAppUploadUser, PermissionsInsightsCreateApplication, PermissionsDebugApex, PermissionsLightningExperienceUser, PermissionsConfigCustomRecs, PermissionsSubmitMacrosAllowed, PermissionsBulkMacrosAllowed, PermissionsShareInternalArticles, PermissionsModerateNetworkMessages, PermissionsManageSessionPermissionSets, PermissionsManageTemplatedApp, PermissionsUseTemplatedApp, PermissionsSendAnnouncementEmails, PermissionsChatterEditOwnPost, PermissionsChatterEditOwnRecordPost, PermissionsCreateAuditFields, PermissionsUpdateWithInactiveOwner, PermissionsWaveTrendReports, PermissionsWaveTabularDownload, PermissionsManageSandboxes, PermissionsAutomaticActivityCapture, PermissionsImportCustomObjects, PermissionsDelegatedTwoFactor, PermissionsChatterComposeUiCodesnippet, PermissionsSelectFilesFromSalesforce, PermissionsModerateNetworkUsers, PermissionsMergeTopics, PermissionsSubscribeToLightningReports, PermissionsManagePvtRptsAndDashbds, PermissionsAllowLightningLogin, PermissionsCampaignInfluence2, PermissionsViewDataAssessment, PermissionsRemoveDirectMessageMembers, PermissionsCanApproveFeedPost, PermissionsAddDirectMessageMembers, PermissionsAllowViewEditConvertedLeads,  PermissionsShowCompanyNameAsUserBadge, PermissionsAccessCMC,  PermissionsViewHealthCheck, PermissionsManageHealthCheck, PermissionsPackaging2, PermissionsManageCertificates, PermissionsCreateReportInLightning, PermissionsPreventClassicExperience, PermissionsHideReadByList, PermissionsUseSmartDataDiscovery, PermissionsGetSmartDataDiscovery, PermissionsCreateUpdateSDDDataset, PermissionsCreateUpdateSDDStory, PermissionsManageSmartDataDiscovery, PermissionsShareSmartDataDiscoveryStory, PermissionsManageSmartDataDiscoveryModel, PermissionsListEmailSend, PermissionsFeedPinning, PermissionsChangeDashboardColors, PermissionsManageRecommendationStrategies, PermissionsManagePropositions, PermissionsCloseConversations, PermissionsSubscribeReportRolesGrps, PermissionsSubscribeDashboardRolesGrps, PermissionsUseWebLink, PermissionsHasUnlimitedNBAExecutions, PermissionsViewOnlyEmbeddedAppUser, PermissionsAdoptionAnalyticsUser, PermissionsViewAllActivities, PermissionsSubscribeReportToOtherUsers, PermissionsLightningConsoleAllowedForUser, PermissionsSubscribeReportsRunAsUser, PermissionsSubscribeToLightningDashboards, PermissionsSubscribeDashboardToOtherUsers, PermissionsCreateLtngTempInPub, PermissionsTransactionalEmailSend, PermissionsViewPrivateStaticResources, PermissionsViewCustomerSentiment, PermissionsCreateLtngTempFolder, PermissionsApexRestServices, PermissionsEnableCommunityAppLauncher, PermissionsGiveRecognitionBadge, PermissionsCanRunAnalysis,  PermissionsLtngPromoReserved01UserPerm, PermissionsManageSubscriptions, PermissionsWaveManagePrivateAssetsUser, PermissionsCanEditDataPrepRecipe, PermissionsAddAnalyticsRemoteConnections, PermissionsManageSurveys, PermissionsRecordVisibilityAPI, PermissionsViewRoles,  PermissionsSmartDataDiscoveryForCommunity, PermissionsCanManageMaps, PermissionsStoryOnDSWithPredicate, PermissionsModifyDataClassification, PermissionsPrivacyDataAccess, PermissionsQueryAllFiles, PermissionsModifyMetadata,  PermissionsSandboxTestingInCommunityApp, PermissionsCanEditPrompts, PermissionsViewUserPII, Description, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById, SystemModstamp, NamespacePrefix, HasActivationRequired, Type FROM PermissionSet

Tuesday, August 30, 2022

How to login to Salesforce using Session id

Replace host url and session id in url

 https://<endpoint host>/secur/frontdoor.jsp?sid=<session id>

Thursday, February 4, 2021

How to Run Schedule Apex only once or every few mins

Using Scheduled Apex in UI, you cannot set a scheduled class to run only once. It's always recurring. So, you'll need to use System.scheduled via the system log to implement a workaround.

Example code for running a job 10 minutes from now only once


String hour = String.valueOf(Datetime.now().hour());
String min = String.valueOf(Datetime.now().minute() + 10); 
String ss = String.valueOf(Datetime.now().second());

//parse to cron expression
String nextFireTime = ss + ' ' + min + ' ' + hour + ' * * ?';

MyScheduledJob s = new MyScheduledJob(); 
System.schedule('Job Started At ' + String.valueOf(Datetime.now()), nextFireTime, s);


Abort the job by adding a finish method to your class that implements the Schedulable Interface. This stops the job from running more than once.

Example code to abort the job


global void finish(Database.BatchableContext BC)
{
// Get the ID of the AsyncApexJob representing this batch job from Database.BatchableContext.
// Query the AsyncApexJob object to retrieve the current job's information.
AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email ..... FROM AsyncApexJob WHERE Id = 
:BC.getJobId()];

//then use the active job id and abort it
system.abortJob(a.id);
}


Example code for running a job every 2 mins


Integer frequency = 2;
Integer totalIterations = 60/frequency - 1;
for(Integer i = 0; i <= totalIterations; i++){
Integer count = i*frequency;
String minuteString = (count < 10) ? '0' + count : '' + count;
System.schedule('Scheduled Job ' + i, '0 ' + minuteString + ' * * * ?', new MyScheduledJob());
}

Sunday, December 20, 2020

How to start learning Salesforce

Salesforce.com is a company that leverages cloud computing to design Customer Relationship Management (CRM) software for organizations. This CRM software can be used by salespeople to track sales, support people to track the resolution of queries and cases, and the entire workforce of a company to collaborate with each other.

The best of SFDC is its vast documentation and publicly available resources to learn easily.

My goal is to help you learn Salesforce as quickly as possible!

Disclaimer: all the resources provided in this blog post are publicly available I am just guiding you to those resources.

Modules in the salesforce

1.     Admin
2.    Development
3.    Lightning Aura Components
4.    Lightning Web Components
5.    Integration

I would recommend start learning in this flow

Admin >> Development >> Lightning Aura Components (or) Lightning Web Components  >> Integration

Trailhead is the fun way to learn Salesforce, checkout about Trailhead here: 

https://trailhead.salesforce.com/content/learn/modules/trailhead_basics/get-started-with-trailhead

Click on each link to see details 

1.    Admin:

Trailhead:

https://trailhead.salesforce.com/content/learn/trails/force_com_admin_beginner

https://trailhead.salesforce.com/en/content/learn/trails/force_com_admin_intermediate

https://trailhead.salesforce.com/en/content/learn/trails/force_com_admin_advanced

Guide:

https://help.salesforce.com/articleView?id=basics_welcome_salesforce_users.htm&type=5

https://help.salesforce.com/articleView?id=overview.htm&type=5#quicktour_tips

 Blogs:

http://www.apexhours.com/introduction-to-salesforce/

Video Tutorial:

https://www.youtube.com/playlist?list=PLaGX-30v1lh1BaUKgXa05gqrOP0vUg_6i

https://www.youtube.com/c/Salesforce/playlists

https://www.youtube.com/watch?v=bOzlOkPU0cI&list=PLdYQMTciVWO9xjvh1J7SXjhzpnzWvLih4

https://www.youtube.com/watch?v=nUARw_Yci3Y&list=PLy9U5GDpYZVPfD-kJg_hceKPo6JZi5BpT

 

2.    Development:

Trailhead:

https://trailhead.salesforce.com/content/learn/trails/force_com_dev_beginner

https://trailhead.salesforce.com/en/content/learn/trails/force_com_dev_intermediate

https://trailhead.salesforce.com/en/content/learn/trails/force_com_dev_advanced

Guide:

https://resources.docs.salesforce.com/228/latest/en-us/sfdc/pdf/salesforce_apex_language_reference.pdf

https://resources.docs.salesforce.com/228/latest/en-us/sfdc/pdf/salesforce_pages_developers_guide.pdf

Blogs:

https://www.sfdc-lightning.com/p/triggers.html

https://www.sfdc-lightning.com/p/apexvisualforce.html

Video Tutorial:

https://www.youtube.com/playlist?list=PLaGX-30v1lh1e8roeCUumUEel5ukdPubj

https://www.sfdc99.com/video-tutorials/

https://www.sfdc99.com/apex-academy/

https://www.youtube.com/c/SalesforceDevelopers/playlists

https://www.youtube.com/watch?v=iPlfPKBXhAw&list=PLdYQMTciVWO8D1lxAzLdEwmt1k8f8ic0t

 

3.    Lightning Aura Components:

Trailhead:

https://trailhead.salesforce.com/en/content/learn/trails/lex_dev

Guide:

https://resources.docs.salesforce.com/228/latest/en-us/sfdc/pdf/lightning.pdf

Blogs:

https://www.sfdc-lightning.com/p/salesforce-lightning.html

Video tutorial:

https://www.youtube.com/watch?v=FrnmcH0Lrkw&list=PLQXsHnNZgiNe35JsuHAb-PsDmD4kwEIsg

https://www.youtube.com/watch?v=CiqCfsTrlLA&list=PLV3ll8m0ZlppQBGJUItatmL8HU2UtmByd

 

4.    Lightning Web Components:

Trailhead:

https://trailhead.salesforce.com/en/content/learn/trails/build-lightning-web-components

Guide:

https://developer.salesforce.com/docs/component-library/documentation/en/lwc

Blogs:

https://www.sfdc-lightning.com/p/lightning-web-components.html

Video Tutorial:

https://www.youtube.com/playlist?list=PLaGX-30v1lh2R0DmV94hqMtPSpiIT7xmO

https://www.youtube.com/watch?v=dcRM7Mq541Y&list=PLV3ll8m0Zlpog5kPVuyYc1d3CzbsNqPxK

https://www.youtube.com/watch?v=7hhdKS-yChs&list=PLgIMQe2PKPSJ0hK7DInqhLlw7QK5Pt6fD

https://www.youtube.com/watch?v=6p2Ia4XWnNw&list=PL-JzyFWuCbkKcFSOCRlCUk79YbET5QvZC

 

5.    Integration:

Trailhead:

https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services

Guide:

https://resources.docs.salesforce.com/228/latest/en-us/sfdc/pdf/api_rest.pdf

https://resources.docs.salesforce.com/228/latest/en-us/sfdc/pdf/apex_api.pdf

Blogs:

https://www.sfdc-lightning.com/p/integration-topics.html

Video Tutorial:

https://www.youtube.com/playlist?list=PLaGX-30v1lh2Y-TZgeQWSnGQWgWHP9mPH

https://www.youtube.com/watch?v=Jcmw5WqjNwU&list=PLV3ll8m0ZlpqVOJCTFJu8uNJ-f2OppInR

https://www.youtube.com/watch?v=H7k3zlPGlkA&list=PLuL63vr-9xHzI83rrXaXHDcsfVqzrp0iO

 

 Data Loader:

https://resources.docs.salesforce.com/228/latest/en-us/sfdc/pdf/salesforce_data_loader.pdf

https://www.youtube.com/watch?v=fnPXaq5A-2c

 

ANT Migration Tool:

https://resources.docs.salesforce.com/sfdc/pdf/salesforce_migration_guide.pdf

https://www.youtube.com/watch?v=i_FwNDegf_o

 

Marketing Cloud:

https://www.youtube.com/playlist?list=PLaGX-30v1lh34rpIP_g1Daabqq7_xvcmp

 

Community Cloud:

https://www.youtube.com/playlist?list=PLaGX-30v1lh0yjm8UbB-4smaykJzCsH2y

 

Useful Blog URLs

https://jenwlee.com/

https://automationchampion.com/

http://vinaychaturvedi.com/

https://www.simplysfdc.com/

https://www.asagarwal.com/

http://www.miraforce.net/

https://salesforceweek.ly/

https://salesforcediaries.com/

https://www.salesforceblogger.com/

https://www.sfdc-lightning.com/

https://www.apexhours.com/blog/

https://www.sfdc99.com/

https://www.jitendrazaa.com/blog/

https://blog.enree.co/

https://sfdcfanboy.com/

https://hellosnl.blogspot.com/

https://www.brcline.com/blog/category/programming/salesforce

http://www.sfdcpanda.com/

http://santanuboral.blogspot.com/?m=0

https://www.auraforce.ca/

https://sfdcmonkey.com/

http://theblogreaders.com/

https://www.sfdcpanther.com/

https://www.sfdcstuff.com/?m=0

https://nitinindora.wordpress.com/

https://www.srinivas4sfdc.com/?m=0

https://bobbuzzard.blogspot.com