Forum Replies Created

Page 1 of 8
  • component.set('v.acc.Name', 'Name from 3!');
    To:

    var acc = component.get('v.acc');
    acc.Name = 'Name from 3!';
    component.set('v.acc', acc);
    And everything will work.

    Here is why you are seeing this behavior, and why the workaround is working:

    The rule to remember: all changes are propagated down, but only propagated up when they affect the root of the attribute.
    About the workaround: because component.get('v.acc') is returning a pointer to the object (this is JavaScript after all), we are not not copying the data, and it is not less efficient than calling component.get('v.acc.Name'). Sure it is more verbose, but not less efficient!

  • Deepak

    Member
    December 12, 2019 at 5:12 pm in reply to: What is the case of system change event in Salesforce lightning?

    understanding System Events In Lightning Components – Part 1
    In this blog we'll explore how System events in Lightning Components work to help write better code and solve potential performance issues due to race condition and rerendering of components.
    Lightning Components Framework comes with a set of “system” events to notify components when the framework does something important. For example: “init” event is sent to every component when they are initially loaded. Similarly “rerender” event is sent when the framework thinks a component needs to be rerendered due to a button click or change in some attribute value.

    But when there are multiple components, multiple events are triggered within each component and in various order. Understanding when these events are triggered and in what order can help us write better code and also identify potential performance issues due to things like “race condition”, “re-rendering” and more.

    An Example App:

    To understand it better, let’s build an app whose structure looks like the following:

    A standalone app “Main App” that contains a single component “Parent Component”. Parent Component contains two Child components (Child1 and Child2). Further Child1 Component has two child components of it own(SubChild1 and SubChild2).

     

    Below picture shows the actual app itself. It simply prints logs when a system event is triggered.

    To Play With It:

    1. Click here to install the “LiftCycleApp”.

    2. Open the app in Chrome.

    3. Open Chrome JS Debugger to see logs.

     

    Test 1: Initial Load:
    Let’s look at what happens when the app is first loaded. “init” (in JS controller), “render” (in renderer) and “afterRender” (in renderer) are called and in the following manner:

     

    Test 2: Passing Data Via Attribute:
    It is common to pass data from one component to another as an attribute. Let’s see how system events are triggered when that happens. In this case, when “Plus1” button in any of the 3 components is clicked, the value of “num” is incremented and is passed to the other components via attribute.

    <ui:button aura:id="button" label="Plus1" press="{!c.update}"/> totalClicks={!v.num}
    <c:Parent num="{!v.num}"/> //pass it to parent (and then to Child1 and SubChild1)
    Scenario 1: Click on Plus1 button  in “Main” App

    Scenario 2: Click on Plus1 button  in “Parent” component

    Scenario 3: Click on Plus1 button in “SubChild1” component
     

  • You nearly made me forget the syntax there !! I've corrected the trigger above, try that to see if it works.

     

    You need to have a for loop to iterate over all the records that have invoked the trigger.

    Also a before trigger makes more sense, since you're manipulating values on the triggering records.

     

    trigger Peachtree_items_process on Peachtree_items__c (before update, before insert) {

     

    for( PeachTree_Items__c peachTreeItem : trigger.new) //iterate over all items
    if (peachTreeItem.Stock_Minimum__c != null  && peachTreeItem.Qty_On_Hand__c != null &&
    peachTreeItem.Qty_On_PO__c != null) {
    peachTreeItem.Stock_Reorder_Qty__c =
    peachTreeItem.Stock_Minimum__c -
    (peachTreeItem.Qty_On_Hand__c + peachTreeItem.Qty_On_PO__c);
    }
    }

  • JSON Deserialization Techniques in Salesforce
    Brenda FinnIf you have ever been given a JSON object and needed to parse it in Apex, then you may have run into some of the same issues I did so read on. JSON, which stands for JavaScript Object Notation, is widely used due to its ability to define the structure of an object and its values at the same time. For Apex purposes, it is used for many different purposes such as Web Service requests and responses as well as exchanging data with a Visualforce page so its pretty important to know how to handle it properly. While there is built-in Apex support, the documentation unfortunately leaves a little to be desired, leaving you in the dark. Read on if you want to learn more. To read more about the JSON specification, see here.

    1. Understanding JSON Structure
    2. Untyped Parsing of JSON Structure
    3. Parsing JSON Structures in a Type-Safe Manner

    1. Understanding JSON Structure
    First it is important to understand at a very high level the structure of JSON.

    {} delimits the JSON object. Additionally, they are used within a JSON object to indicate key-value pairs.

    [] denotes an array (or list) of records, each of which can be either a single value such as a Name or Sales Price, another array or a list of unlimited name-value pairs (such as properties about a Person – Name, Address, Phone, Email).

    Lets use the following JSON object as an example throughout this article – this is a response from a web service that handles requests for Customer details. The JSON object contains 2 elements, one is an array of Customers and the other is a simple number, Count, containing the value of records processed successfully. For each Customer in the request, there is an array containing that Customer’s properties.

    In this example, there are three records in our JSON object, two of which were a success and one that contains an error.

    To help identify the elements of a JSON object,  blue boxes surround name-value pairs (properties) and red boxes surround the JSON object and its child objects.

    Take note of the syntax.

    The entire JSON object is surrounded by curly braces {}.
    The JSON object has two properties: Customers and Count.
    The value of the Customers property is an array, which is denoted by square brackets [].
    The value of the Count property is a number.
    The array contains three child JSON objects.
    The first and second child JSON objects have a similar structure, each containing properties that have string values.
    Each property is represented as a name:value pair. Quotes around the property name are optional unless the name contains spaces in which case they are required.
    Quotes around the property value are required if it is a string value. For instance, Count’s value is not in quotes as it is an Integer value.
    Properties are separated by commas. There is no comma after the last property in a JSON object.
    So it is a Map (key-value pairs) with two keys:

    Customers
    Count
    For the Customers key, there is an array of key-value pairs, one for each Customer requested, namely: John Smith, Jane Doe, and Michael Johnson.

    So for above example, we have:

    Key = Customers
    Value = Array of 3 elements:

    {“Status”:”Success”,”FirstName”:”John”,”LastName”:”Smith”,”Email”:”[email protected]”,”Phone”:”703.555.1212″}
    {“Status”:”Success”, “FirstName”:”Jane”,”LastName”:”Doe”,”Email”:”[email protected]”,”Phone”:”540.555.1212″}
    {“Status”:”Error”,”Message”:”No Michael Johnson found.”}
    For the Count key, there is a single value, the number of Customer records processed

    Key = Count
    Value = 2 // number of successful Customers found

    2. Untyped Parsing of JSON Objects
    Now that we understand the JSON structure, lets look at the untyped parsing provided by Salesforce. The top-level object corresponds to a Map<String, Object> in Apex. Any data contained within a [] maps to a List or Array of Objects.

    For our example, our top-level object is a Map with two keys, the key is a String but the values are of different types (Array and Integer), so Object is used to achieve this. First, we represent the JSON object as a String for testing purposes.

    String jsonResponse =
    '{"Customers":[' +
    '{' +
    '"Status":"Success",' +
    '"FirstName":"John",' +
    '"LastName":"Smith",' +
    '"Email":"[email protected]",' +
    '"Phone":"703.555.1212"' +
    '},' +
    '{' +
    '"Status":"Success",' +
    '"FirstName":"Jane",' +
    '"LastName":"Doe",' +
    '"Email":"[email protected]",' +
    '"Phone":"540.555.1212"' +
    '},' +
    '{' +
    '"Status":"Error",' +
    '"Message":"No Michael Johnson found."' +
    '}' +
    '],' +
    '"Count":2' +
    '}';
    Map<String, Object> results =
    (Map<String, Object>)JSON.deserializeUntyped(jsonResponse);
    Then the first key in our map is for Customers. Salesforce uses an Array or List of Objects to represent an array. So either one of these statements would work

    List<Object> lstCustomers = (List<Object>)results.get('Customers');
    Object[] aryCustomers = (Object[]) results.get('Customers');
    Now for each array/list, there is a group of name-value pairs, which as we saw above, is represented by a Map in Salesforce as follows. This is a little awkward as our List is actually a List of Map objects.

    for (Object customer : lstCustomers) {
    // now get attributes for this customer.
    Map<String, Object> customerAttributes = (Map<String, Object>)customer;
    // now loop through our customer attributes.
    for (String attributeName : customerAttributes.keyset()) {
    // handle response
    System.debug('========> ' + attributeName + ' = ' +
    customerAttributes.get(attributeName));
    }
    }
    And finally we get our count of successfully processed records.

    Integer count = (Integer)(unTypedResults.get('Count'));
    System.debug('==========> There were ' + count +
    ' Customers processed successfully.');
    This approach is error-prone and frankly just plain ugly. Thankfully, there is a better way to handle this map that is type-safe and much more readable.

    3. Parsing JSON Objects in a Type-Safe Manner
    Now that we have seen how to do it the hard way, lets do it the easy way! Once you know the structure of your JSON object, you can build Apex classes to hold the data in a object-oriented structural fashion and its quite simple. So for our JSON object example, we start with our top-level class: Customers.

    A few tips for creating your classes.

    Data member names must exactly match (case-insensitive) the name of the attribute or element in the JSON object.
    All data members that are being mapped must have public access.
    All data members must be typed correctly to match the element type in the JSON object, otherwise a TypeException is thrown. So in our example, if Count is defined to be a String, an Exception is  thrown as it should be defined as an Integer.
    NOTE: Interestingly enough, you do not have to define a default no-arg constructor. In fact, if you define a private no-arg Constructor , it still parses your object successfully.
    If you do not define a data member for one of the JSON object properties, then it will not be mapped. It will be silently ignored.
    As we saw in Understanding JSON Structure, our top-level object has two keys, one for Customers (a List of Customer properties) and one for Count (a single Integer property). So we create a class with two variables named and typed appropriately.

    public with sharing class CustomersResponse {
    public List<Customer> Customers;
    public Integer Count;
    public CustomersResponse() {
    }

    For each entry in the Customers List, we have a set of properties that may or may not be defined. In the success case, all the Customer details will be populated except Message. In the case of an error, only Status and Message are populated. So we add all possible fields to our Customer object as below.

    public with sharing class Customer {
    public String Status;
    public String Message;
    public String FirstName;
    public String LastName;
    public String Email;
    public String Phone;
    public Customer() {
    }
    }

    Now that we have successfully defined our classes to represent our JSON structure, lets do the mapping. There are two ways to achieve this mapping with the standard Salesforce API. Both approaches are equally acceptable although the first approach is slightly cleaner as it involves one less API call.

    Approach 1
    Type resultType = Type.forName('CustomersResponse');
    CustomersResponse deserializeResults =       (CustomersResponse)JSON.deserialize(response, resultType);
    System.debug('==========> deserialize() results = ' + deserializeResults);

    NOTE: With the above code, in theory, it is possible to use JSON.deserialize(response,CustomersResponse.class), however this does not always work. Sometimes Salesforce is unable to determine the type correctly and you receive a “variable does not exist : CustomerDetails.type” compile error message). So instead, you must first use a Type.forName() call to take care of this problem. Alternatively, you could compile all classes in your Salesforce Org together or define your class as an inner class of the class doing the deserialization work.

    Approach 2
    Type resultType = Type.forName('CustomersResponse');
    CustomersResponse readValueAsResults = (CustomersResponse)JSON.createParser(response).readValueAs(resultType);
    System.debug('==========> createParser().readValueAs() results = ' +      readValueAsResults);

    Tip: Testing JSON Objects
    The best way to discover how to map your JSON object into a set of Apex classes is to take the web service (or mechanism that generates the JSON object) call entirely out of the equation. Create a String with your JSON object and then call JSON.deserializeUntyped() and see what gets return through the use of System.debug. This is easily done in a Unit Test or in an Execute Anonymous script.

    Then once you have all the plumbing in place and want to perform end-to-end testing (crucial as web service calls are not invoked during unit tests), use your dear friend, the Execute Anonymous script, to call the method directly that invokes the web service. If your invocation of the web service is in a future method, place the logic inside a separate method with public access that is called directly from the Execute Anonymous script and have your future method call it directly.

  • Deepak

    Member
    December 12, 2019 at 7:10 am in reply to: How to create the below Appointment table in Salesforce?

    VF page:

    <apex:page controller="Account_Filter" docType="html-5.0">
    <apex:form >
    <apex:pageBlock >

    <!--Search and filter button-->
    <apex:pageBlockButtons location="top">
    <apex:commandButton value="Search" action="{!searchaccounts}" />
    <apex:commandButton value="Show Selected Accounts" action="{!processSelected}" />
    </apex:pageBlockButtons>

    <!--Input Account's fields to query records-->
    <apex:pageBlockSection id="Account-table" columns="2">
    <apex:pageBlockSectionItem >
    <apex:outputLabel value="Name" />
    <apex:inputText value="{!name}" />
    </apex:pageBlockSectionItem>

    <apex:pageBlockSectionItem >
    <apex:outputLabel value="phone" />
    <apex:inputText value="{!phone}" />
    </apex:pageBlockSectionItem>

    <apex:pageBlockSectionItem >
    <apex:outputLabel value="Check_Active" />
    <apex:inputCheckbox value="{!Active}" />
    </apex:pageBlockSectionItem>

    <apex:pageBlockSectionItem >
    <apex:outputLabel value="SLAExpirationDate__c" />
    <apex:input value="{!SLAExpirationDate}" type="date"/>
    </apex:pageBlockSectionItem>

    <apex:pageBlockSectionItem >
    <apex:outputLabel value="BillingPostalCode" />
    <apex:inputText value="{!BillingPostalCode}" />
    </apex:pageBlockSectionItem>

    <apex:pageBlockSectionItem >
    <apex:outputLabel value="End_date" />
    <apex:input value="{!End_Date}" type="date"/>
    </apex:pageBlockSectionItem>

    </apex:pageBlockSection>
    </apex:pageBlock>
    <!--Display all related Account records-->

    <apex:pageBlock >
    <apex:pageBlockTable value="{!wrapClassList}" var="accWrap" id="table" title="All Accounts" >
    <apex:column >
    <apex:inputCheckbox value="{!accWrap.flag}" />
    </apex:column>
    <apex:column value="{!accWrap.conWrap.Name}" />
    <apex:column value="{!accWrap.conWrap.SLAExpirationDate__c}" />
    <apex:column value="{!accWrap.conWrap.check_active__c}" />
    <apex:column value="{!accWrap.conWrap.BillingPostalCode}" />
    <apex:column value="{!accWrap.conWrap.phone}" />
    </apex:pageBlockTable>
    <!--Display selected Account records-->
    <apex:pageBlockTable value="{!selected_accounts}" var="accWrapab" title="All Accounts">
    <apex:column value="{!accWrapab.Name}" />
    <apex:column value="{!accWrapab.SLAExpirationDate__c}" />
    <apex:column value="{!accWrapab.check_active__c}" />
    <apex:column value="{!accWrapab.phone}" />
    <apex:column value="{!accWrapab.BillingPostalCode}" />
    </apex:pageBlockTable>

    </apex:pageBlock>

    </apex:form>
    </apex:page>

     

    Controller:

     

    public with sharing class Account_Filter
    {
    public List<wrapperClass> wrapClassList{get;set;}
    public List<Account> Accounts { get; set; }
    public String name { get; set; }
    public Date SLAExpirationDate { get; set; }
    public String BillingPostalCode { get; set; }
    public Date End_Date { get; set; }
    public string phone { get; set; }
    public wrapperClass wc{get;set;}
    public boolean Active{get;set;}
    public List<Account> selected_accounts{get;set;}
    public Account_Filter()
    {
    Accounts = new List<Account>();
    }

    public void searchaccounts()
    {
    selected_accounts = new List<Account>();

    integer i=0;

    If(!Accounts.isEmpty()){
    Accounts.clear();
    i=0;
    }
    If(!selected_accounts.isEmpty()){
    selected_accounts.clear();

    }
    wrapClassList = new List<wrapperClass>();

    string st='%'+name+'%';
    string queryy='select name,phone,check_active__c,CreatedDate,BillingPostalCode,SLAExpirationDate__c from Account where';

    if(!String.isBlank(name)){
    i=1;
    queryy=queryy+' Name LIKE : st AND';
    }
    if(Active==true){
    i=1;
    queryy=queryy+' check_active__c =: Active AND';
    }
    if(!String.isBlank(phone)){
    i=1;
    queryy=queryy+' Phone =: phone AND';
    }
    if(!String.isBlank(BillingPostalCode)){
    i=1;
    queryy=queryy+' BillingPostalCode =: BillingPostalCode AND';
    }

    if(SLAExpirationDate != NULL && End_Date == NULL){
    queryy=queryy+' SLAExpirationDate__c >=: SLAExpirationDate AND';
    i=1;
    }
    if(SLAExpirationDate == NULL && End_Date != NULL){
    queryy=queryy+' SLAExpirationDate__c <: End_Date AND';
    i=1;
    }
    if(SLAExpirationDate != NULL && End_Date != NULL){
    queryy=queryy+' SLAExpirationDate__c <: End_Date AND SLAExpirationDate__c >=: SLAExpirationDate AND';
    i=1;
    }
    string queryya=queryy.removeEndIgnoreCase('AND');
    if(i==1){
    Accounts=Database.query(queryya);
    }

    For(Account co : Accounts){
    wc = new wrapperClass();
    wc.flag = false;
    wc.conWrap = co;
    wrapClassList.add(wc);
    }
    }
    public class wrapperClass{
    public boolean flag{get;set;}
    public Account conWrap{get;set;}

    }
    public void processSelected() {
    selected_accounts = new List<Account>();
    If(!selected_accounts.isEmpty()){
    selected_accounts.clear();

    }

    for(wrapperClass wrapAccountObj : this.wrapClassList) {
    if(wrapAccountObj.flag == true) {
    selected_accounts.add(wrapAccountObj.conWrap);
    }
    }
    }

    }

  • <apex:outputPanel id=”repeating”>
    <apex:repeat value=”{!change}” var=”c”>
    <apex:selectRadio value=”{!save}”  action=”{!saveInformation}”>
    <apex:selectOption itemValue=”{!c}” itemLabel=”{!c}”  />
    </apex:selectRadio>
    </apex:repeat>
    <apex:actionSupport event=”onchange” reRender=”repeating” action=”{!saveInformation}”>
    </outputPanel>

  • Deepak

    Member
    December 11, 2019 at 4:27 pm in reply to: How to identify a User from 3-rd party in salesforce?

    Use Third-Party Data to Update and Add Records to Salesforce
    A rule set up by your Salesforce admin compares your accounts, contacts, and leads to data from a third-party source—Lightning Data or Data.com. Depending on how your admin sets up the rule, your records are updated as information changes. Or your admin can give you purchase credits to import Lightning Data records to add to Salesforce as accounts.

    REQUIRED EDITIONS AND USER PERMISSIONS
    Available in: Professional, Enterprise, Performance, and Unlimited Editions

    USER PERMISSIONS NEEDED
    To update records:
    Edit on accounts, contacts, leads, and Read on the custom and external objects included in a data package
    Check for New Data Matched to a Record
    Look at the data status to see whether a data service has new data matched to an account, contact, or lead.
    Discover Companies to Import as Accounts in Lightning Experience
    Fill your pipeline with ideal prospects. When your Salesforce admin sets up a Lightning Data package, you can find companies to target and import them into Salesforce as business account

  • Fulfill Orders Faster
    Seamlessly generate orders from quotes to quickly get products and services delivered to your customers.
    Flexible for Evolving Customer Needs
    Split quotes into multiple orders, manage future dated orders, and modify with point- and-click.
    360-Degree View of the Customer
    Quickly generate contracts with all contract term, pricing, asset, and subscription details.
    Connect to Back Office
    Sync order details to ERP for order fulfillment

  • for (Messaging.Inboundemail.BinaryAttachment bAttachment : email.binaryAttachments) {

    Attachment attachment = new Attachment();
    // attach to the newly created contact record
    attachment.ParentId = contact.Id;
    attachment.Name = bAttachment.filename;
    attachment.Body = bAttachment.body;
    insert attachment;
    }

  • Deepak

    Member
    December 11, 2019 at 2:57 pm in reply to: How to fix lookup filter issue which turns into picklist in Salesforce?

    Considerations for Lookup Filters
    REQUIRED EDITIONS AND USER PERMISSIONS
    Available in: both Salesforce Classic (not available in all orgs) and Lightning Experience
    Available in: All Editions except for Database.com.

    USER PERMISSIONS NEEDED
    To manage lookup filters:
    Customize Application
    On the Fields page, the   icon indicates all fields with active lookup filters. The   icon indicates that the lookup filter is required.
    The lookup filters you create in Salesforce also appear in the partner portal and Customer Portal.
    Lookup filters are case-sensitive.
    If you convert a required lookup filter with a custom error message to be optional, Salesforce deletes the message.
    If you create a lookup filter that invalidates an existing value for that field, the value persists. However, when a user edits the record, Salesforce displays an error message and requires the user to change the invalid value before saving.
    You can’t save changes that cause required lookup filters on related records to contain invalid values.
    Versions 16.0 and higher of the Salesforce API support lookup filters. Lookup filters are enforced when you load data through the API.
    If you configure a lookup filter to show inactive users only, the relationship field has no valid options. Inactive users are never valid for relationship fields that point to the User object.
    If you create a filtered lookup on a field that looks up to another object, both objects must be deployed into the organization at the same time.
    Lookup field filters don’t work if the field criteria include a master-detail relationship field.
    Salesforce doesn’t display an error message if the value of a controlling field invalidates the value of a dependent master-detail relationship field.
    Dependent lookups are supported in Visualforce pages.
    In Lightning Experience, a lookup filter doesn’t work if a field referenced in the filtered lookup isn't added to the page layout.
    Spanning Relationships in Lookup Filters
    Filter criteria can include fields directly related to the target object (one level only). For example, on a lookup field pointing to contacts, a lookup filter can reference fields on the account related to the contact via the Account Name relationship field. The lookup field can also reference fields on the contact related to the contact via the Reports To relationship field.

    For required lookup filters, each field referenced on a related lookup object counts against the number of unique relationships allowed for the referenced object, not the source object. For example, the two unique relationships described above count against the number allowed for the Contact object. Optional lookup filters don't count against the limit on the number of unique relationships allowed per object.

    To see which lookup filters affect the limit for a particular target object, from the management settings for the object, go to Related Lookup Filters.
    Lookup Filters vs. Validation Rules
    Validation rules and lookup filters achieve similar ends, but offer different advantages. Use a lookup filter if:

    You want to improve user efficiency by limiting the number of available options in a lookup search dialog.
    You want to improve user efficiency by automating filters on lookup search dialogs that your users manually set.
    Use a validation rule if:

    You're close to the maximum number of lookup filters allowed.
    You must implement a complex business rule that requires you to use a formula. Formulas can reference fields that basic filter criteria can't reference, such as fields on the parent of the source object. Formulas can also use functions. For example, use ISNEW if the rule should only apply on record creation, or ISCHANGED if the rule should apply when a field changes.

  • Create, Preview, and Activate Quote Templates
    Define the look of your company’s quote PDFs by creating templates that your sales reps can choose when they create quote PDFs.

    REQUIRED EDITIONS AND USER PERMISSIONS
    Available in: Salesforce Classic (not available in all orgs) and Lightning Experience
    Available in: Performance and Developer Editions
    In Sales Cloud, also available in: Professional, Enterprise, and Unlimited Editions

    USER PERMISSIONS NEEDED
    To create quote templates:
    Customize Application
    To view quote templates:
    View Setup and Configuration
    Watch a Demo:   Creating Quote Templates (Salesforce Classic) (English only)

    From Setup, enter Templates in the Quick Find box, then select Quote Templates (Lightning Experience) or Templates under Quotes (Salesforce Classic).
    Click New, and then select a template, such as Standard Template, on which to base your new template.
    Give your new template a name, and then click Save.
    In the template editor, drag the elements that you want to the template, and then complete the details. To add:One or more Quote fields or fields from related objects, use a section and add fields to it.
    Text that you can edit and format, such as terms and conditions, use Text/Image Field.
    An image, such as your company logo, use Text/Image Field.
    A table of Quote fields or fields from a different object, such as Quote Line Item, use a list.
    Click Quick Save to save your changes and continue working on the template.
    Click Save and Preview to make sure that the quote PDFs that users create look the way you want them to.Preview shows templates in system administrator profile view. The preview and the template show the rich text and images that you’ve added. Other data is simulated.

    IMPORTANT Save and Preview saves changes to your template, so after you preview, you can’t undo them.
    Click Save when you’re finished.
    Return to the Quote Templates page, and then click Activate.

  • We generally avoid applying for loop in apex code as it will break governer rule so do the query for your program.

  • Presuming that you're dynamically creating components (e.g. c1 and c2), you have total control over the aura:id. A component cannot define its own aura:id, only the aura:id for children within itself. From here, it follows that you're trying to figure out what type of component you're dealing with. For that, we use Component#getType. This tells you exactly what type of component you're dealing with.

    For example:

    var c2 = component.find("child2");
    if(c2.getType() === "c:someComponent") { ...
    Alternatively, if you're exposing actual aura:method references, you can also check for the presence of the function before calling it:

    var c2 = component.find("child2");
    if(c2.someMethod) { ...
    Finally, if you are using interfaces, you can also check if a component is a type of interface:

    if(c2.isInstanceOf("c:interfaceName")) { ...

  • Messages can be displayed in notices and toasts. Notices alert users to system-related issues and updates. Toasts enable you to provide feedback and serve as a confirmation mechanism after the user takes an action.

    Include one <lightning:notificationsLibrary aura:id="notifLib"/> tag in the component that triggers the notifications, where aura:id is a unique local ID. Only one tag is needed for multiple notifications.

    Notices
    Notices interrupt the user's workflow and block everything else on the page. Notices must be acknowledged before a user regains control over the app again. As such, use notices sparingly. They are not suitable for confirming a user’s action, such as before deleting a record. To dismiss the notice, only the OK button is currently supported.

    Notices inherit styling from prompts in the Lightning Design System.

    To create and display a notice, pass in the notice attributes using component.find('notifLib').showNotice(), where notifLib matches the aura:id on the lightning:notificationsLibrary instance.

    Here’s an example that contains a button. When clicked, the button displays a notice with the error variant.

    <aura:component>
    <lightning:notificationsLibrary aura:id="notifLib"/>
    <lightning:button name="notice" label="Show Notice" onclick="{!c.handleShowNotice}"/>
    </aura:component>
    This client-side controller displays the notice.

    ({
    handleShowNotice : function(component, event, helper) {
    component.find('notifLib').showNotice({
    "variant": "error",
    "header": "Something has gone wrong!",
    "message": "Unfortunately, there was a problem updating the record.",
    closeCallback: function() {
    alert('You closed the alert!');
    }
    });
    }
    })
    To create and display a notice, pass in the notice attributes using component.find('notifLib').showNotice(), where notifLib matches the aura:id on the lightning:notificationsLibrary instance.

    Parameters
    PARAMETER
    TYPE
    DESCRIPTION
    header
    String
    The heading that’s displayed at the top of the notice.
    title
    String
    The title of the notice, displayed in bold.
    message
    String
    The message within the notice body. New lines are replaced by <br/> and text links by anchors.
    variant
    String
    Changes the appearance of the notice. Accepted variants are info, warning, and error. This value defaults to info.
    closeCallback
    Function
    A callback that’s called when the notice is closed.
    Toasts
    Toasts are less intrusive than notices and are suitable for providing feedback to a user following an action, such as after a record is created. A toast can be dismissed or can remain visible until a predefined duration has elapsed.

    Toasts inherit styling from toasts in the Lightning Design System.

    To create and display a toast, pass in the toast attributes using component.find('notifLib').showToast(), where notifLib matches the aura:id on the lightning:notificationsLibrary instance.

    Here’s an example that contains a button. When clicked, the button displays a toast with the info variant and remains visible until you click the close button, denoted by the X in the top right corner.

    <aura:component>
    <lightning:notificationsLibrary aura:id="notifLib"/>
    <lightning:button name="toast" label="Show Toast" onclick="{!c.handleShowToast}"/>
    </aura:component>
    This client-side controller displays the toast.

    ({
    handleShowToast : function(component, event, helper) {
    component.find('notifLib').showToast({
    "title": "Success!",
    "message": "The record has been updated successfully."
    });
    }
    })
    Displaying Links in Toasts and Notices
    To display a link in the message, use the messageData attribute to pass in url and label values for the message string.

    ({
    handleShowToast : function(component, event, helper) {
    component.find('notifLib').showToast({
    "title": "Success!",
    "message": "Record {0} created! See it {1}!",
    "messageData": [
    'Salesforce',
    {
    url: 'http://www.salesforce.com/',
    label: 'here',
    }
    ]
    });
    })

  • I believe you are trying to associate a single contact to multiple accounts. This functionality was released in Spring 16' and is implemented through a Salesforce Junction object - AccountContactRelation.

    I assume you have already enabled this functionality through the UI and a parent Account is declared for this Contact.

    I have modified your code to associate the contact to all 20 account.

    global class UpdateProjectNameBatch implements Database.Batchable
    <sObject>
    { ID conId = '0037F00000IfCCKQA3'; //Add the contact Id here
    List<AccountContactRelation> ListInsertion = new List<AccountContactRelation>();
    String query = 'Select Id,Name FROM Account WHERE Name = 'SampleAccountOne'';

    global Database.QueryLocator start(Database.BatchableContext bc)
    {
    return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext bc,List<Account> batch){

    for (Account a : batch)
    {
    AccountContactRelation c = new AccountContactRelation();

    c.AccountId = a.id;
    c.contactId = conId;
    ListInsertion.add(c);
    }

    Insert ListInsertion;

    }

    global void finish(Database.BatchableContext bc)
    {
    //DoNothing.
    }
    }

  • Deepak

    Member
    December 10, 2019 at 2:41 pm in reply to: How to share downloadable link of file to external system in Salesforce?

    Share Files Via Link
    Available in: Salesforce Classic
    Available in: Essentials, Group, Enterprise, Professional, Performance, Unlimited, Contact Manager, and Developer Editions
    You can share a file with anyone by creating a file link and sending it through email or IM. Creating a link generates an encrypted URL that you can send to any recipient, such as leads, customers, partners, and coworkers. Recipients can be inside or outside of your company. The recipient opens a web-based version of the file that they can easily preview and download. File link recipients can only view and download files. They can't be collaborators.

    When you create a public link to a file, anyone who has the link can view and download the file. You can delete the link at any time, and anyone with the link can no longer access the file. If you create a link, only people with the new link can access the file.

    Sharing via link is available in Salesforce Classic and Lightning Experience, and is on by default for most orgs.

    Create and Share a File Link in Lightning Experience
    From Files home or a files related list on a record, right-click a file and choose Public Link.
    From Chatter, right-click the file thumbnail in the feed and choose Public Link.
    You can also right-click a file and click Share to open the Sharing dialog. From here, create a link in the Who Can Access section under Public Link Sharing, or use a link that’s already been created.
    Copy the link and share it with people inside or outside your company.

    Create and Share a File Link in Salesforce Classic
    Start by sharing the file from one of these locations:On Files home, click Upload files, select a file, then click Sharing Settingsand choose Anyone with Link. Copy the link and share it with people inside or outside your company.
    On the Home page, click Create New | File, click Choose File, select a file, and then select Share via link from the dropdown menu.
    On a file detail page, click   File Sharing Settings | Via link.
    In the Sharing Settings dialog box, click Anyone with link from the Share with list.
    Next to the file on the Files page, the Files Owned by list, or the Group Files list, click   | Share via link.
    Next to the file in a feed or on a file hover, click More Actions | File Sharing Settings, then click Anyone with link from the Share with list.
    Click Copy if available (or copy the link manually), and paste the link into an email or IM. File link recipients can only view and download files. They can't be collaborators.
    Unless the file’s already shared with your company, it's privately shared and displays the privately shared icon ( ). It's not posted anywhere, and only the people who you specifically shared it with can find and view it. If it’s already shared with your company, it retains the “your company” icon ( ) and anyone in your company can find and view it.

    To stop sharing a file by link, in the Sharing Settings dialog box, click   next to the link. Anyone with the link can no longer access the file.

    NOTEDocuments from the Documents tab and attachments from the Notes and Attachments related list aren't listed on Files home. And they can't be shared as Salesforce Files.
    A file can be shared a maximum of 2000 times. This count includes shares with records, people, and groups. If a file is approaching the maximum number of shares, consider creating a public link or making the file public by posting it to your feed.
    Enable Link Sharing
    Administrators can enable sharing via link by enabling these permissions:

    From Setup, enter Content Deliveries and Public Links in the Quick Find box, and select Content Deliveries and Public Links. Select Content Deliveries feature can be enabled for users and Public Links can be enabled for users (Requires Content Deliveries).
    From Setup, enter Permission Sets in the Quick Find box, and select Permission Sets. Select a permission set, click System Permissions, and select Create Public Links.
    From Setup, enter Profiles in the Quick Find box, and select Profiles. Select a profile, and click Edit. In General User Permissions, select Create Public Links. You don't need this permission for files in a shared Salesforce CRM Content library. Instead, complete steps 1 and 2 and then ensure that the user is a library member and that Deliver Content is checked in the library permission definition.
    From Setup, enter Content Permissions in the Quick Find box, and select Content Permissions. Next to Library Administrator in the list of library permissions, click Edit, enable Deliver Content, and save your changes.

  • Deepak

    Member
    December 10, 2019 at 2:40 pm in reply to: How to get standard date picker custom Visualforce in Salesforce?

    Please find the below examples to display the date field with date pickers.

    Ex 1 :
    Visual Force Page :
    <apex:page docType="html-5.0" controller="Sample">
    <apex:form >
    <apex:pageBlock >
    <apex:pageBlockSection>
    <apex:pageBlockSectionItem>
    Date: <apex:input type="date" value="{!dat}"/>
    </apex:pageBlockSectionItem>
    </apex:pageBlockSection>
    </apex:pageBlock>
    </apex:form>
    </apex:page>

    Apex Controller :
    public class Sample {
    public Date dat {get;set;}
    public Sample() {

    }
    }

    Ex 2 :
    Visual Force Page :
    <apex:page controller="datePicker" id="mypage">
    <apex:form>
    Date: <apex:inputText value="{!datename}" size="10" id="demo" onfocus="DatePicker.pickDate(false, this , false);" />
    </apex:form>
    </apex:page>

    Apex Controller :
    public class DatePicker
    {
    public String datename {get; set;}
    }

  • Managing Account Assignment Rules
    Create account assignment rules that automatically move accounts and their associated opportunities and cases into territories based on any standard or custom account field, such as zip code, state, industry, revenue, or number of employees. Each rule consists of multiple rows of criteria that specify exactly how the accounts are assigned.

    Account assignment rules are governed by the following:

    A territory can have inherited account assignment rules, meaning that the rules were created somewhere higher in the territory hierarchy and consequently also impact the given territory.
    A territory can have locally defined account assignment rules, meaning that the rule was created at the given territory.
    If a territory doesn't have any inherited or locally-defined account assignment rules, then it only contains accounts that were manually added.
    If an account matches all inherited and locally-defined account assignment rules for multiple territories on the same branch of the hierarchy, then the account is assigned to the lowest matching territory.
    If an account matches a territory's inherited account assignment rules but not all of the territory's locally-defined rules, then the account isn't assigned to the territory, but is evaluated for child territories.
    If a territory has multiple locally-defined account assignment rules, an account is assigned to the territory only if it matches all locally-defined account assignment rules on the territory.
    For example, you have three territories:

    Territory A has four rules marked “Apply to child territories“, and is a parent of territory B.Territory B has three rules not marked “Apply to child territories”, and is a parent of territory C.Territory C has two rules.
    If you assign an account that matches all of territory A’s and territory C’s rules but only one of territory B’s rules, then the account is assigned to territory C. However, if territory B's rules are marked “Apply to child territories,” then the account is assigned only to territory A.
    Working with Account Assignment Rules
    Click Run Rules on the territory detail page to evaluate the active inherited, locally defined rules shown on the page against all existing accounts in your organization. The rules for all subordinate territories are also evaluated—that is, when you run rules on the top-level territory, all rules in the entire hierarchy are evaluated. When you click Run Rules, an icon ( ) displays next to the button for all affected territories to indicate that rules are being processed. An email confirmation is sent when processing is complete.

    NOTE To protect data quality, you can't modify a territory while the processing icon displays.
    Click Manage Rules on the territory detail page to access the Manage Account Assignment Rules page, where you can create, edit, preview, and run account assignment rules:

    Click New to create a new rule, or Edit to edit an existing rule. See Create and Edit Account Assignment Rules.
    Use the Active checkbox to set a locally-defined rule as active or inactive.Active account assignment rules automatically evaluate accounts and assign them to territories when:

    An account is created using the Salesforce user interface, the Lightning Platform API version 20.0 or earlier, or a client such as Connect Offline.
    An account is imported using an import wizard.
    An account is created by the conversion of a lead.
    An account is edited and saved if the Select by default checkbox is selected for the “Evaluate this account against territory rules on save” checkbox option under Layout Properties. If the account assignment rule initiates an opportunity ownership change, you must have transfer access on the opportunity.
    An account is edited and saved via the Lightning Platform API.
    Run Rules is clicked on a territory detail page, provided the Exclude from territory assignment rules checkbox on the account is deselected.
    Save & Run Rules is clicked on the manage account assignment rules page for a territory, provided the Exclude from territory assignment rules checkbox on the account is deselected.
    Duplicate accounts are merged.
    Click a rule name to see the details of that rule, including its active status and criteria. From a rule detail page you can edit, delete, or clone a rule.
    Click Preview to see the accounts that would be assigned to this territory and its child territories if the rules currently marked active were run. See Preview Account Assignments.
    Click Save to save the current active status of locally-defined rules.
    Click Save & Run Rules to save the current active status of locally-defined rules and evaluate the inherited and locally-defined rules shown on the page against all existing accounts in your organization. Running account assignment rules affects accounts in the Recycle Bin.
    Click Edit on the territory detail page to toggle the Confine Opportunity Assignment checkbox. When it is selected, the territory's opportunities remain in the territory or its child territories when you run account assignment rules. The following exceptions apply:

    If an opportunity's account moves to only one of the territory's children, then the opportunity follows the account and is reassigned to the account's new territory. This includes when an account moves to multiple territories and only one of the new territories is a child of the original territory.
    If an opportunity's account moves to more than one of the territory's children, then the opportunity's territory field is set to blank.
    If an opportunity's account moves completely out of the territory and its children, then the opportunity's territory field is set to blank.

    TIP You can also manage account assignment rules using the Data Loader or the Web services API.
    Account Assignment Rules and Opportunities
    Several factors determine how account assignment rules assign opportunities to territories, including:

    Whether the account associated with the opportunity is assigned to one or more territories
    Whether the opportunity owner is a member of the same territory as the account
    The number of users assigned to the territory
    Whether a forecast manager is assigned to the territory

  • trigger rollupopp on Opportunity (after delete,after update,after insert,after undelete) {

    set<ID>AccIds = new set<ID>();

    if(trigger.isinsert || trigger.isundelete){
    for(opportunity opp : trigger.new){
    AccIds.add(opp.AccountId);
    }
    }
    if(trigger.isdelete){
    for(opportunity opp : trigger.old){
    AccIds.add(opp.AccountId);
    }
    }

    if(trigger.isupdate){
    for(opportunity opp:trigger.new){
    AccIds.add(opp.AccountId);
    if(trigger.oldmap.get(opp.id).AccountId != opp.AccountId && trigger.oldmap.get(opp.id).AccountId != null ){
    AccIds.add(trigger.oldmap.get(opp.id).AccountId);
    }
    }
    }
    map<id,double> amtmap = new map<id,double>();
    for(aggregateresult ag : [select AccountId ,SUM(Opty_Amount_C) SOA,count(id) cc from opportunity where AccountId in:AccIds AND RecordType.Name = 'Revenue Type' group by AccountId]){
    amtmap.put((ID)ag.get('AccountId'), double.valueof(ag.get('SOA')));
    // amtmap.put((ID)ag.get('AccountId'), double.valueof(ag.get('cc')));
    }
    list<account>acclist = new list<account>();

    for(id iid : AccIds){
    account acnt = new account(id=iid);
    if(amtmap.containskey(iid)){
    acnt.Total_Opty_Amount_C = amtmap.get(iid);
    }else{
    acnt.Total_Opty_Amount_C = 0;
    }
    acclist.add(acnt);
    }

    if(acclist.size()>0){
    update acclist;
    }

    }

  • Chatbot Terminology
    Sita Nagappan-Alvarez, the CEO of Ursa Major Solar, is curious to learn more about what Maria Jimenez, her Salesforce admin, has discovered about chatbots. After Maria mentions that bots are a smart customer channel that requires a lot of content, Sita’s confused. Bot content? She thought you simply click a button or write some code to deploy bots.

    Maria reassures Sita that bot deployment is easy. It’s creating a useful, helpful, and relevant bot for customers that’s the challenge. Figuring out the purpose of the bot—and the content it should display—is critical. Planning what the bot does and doesn’t do, and says and doesn’t say, can prevent bad customer experiences.

    To understand the types of bot experiences to craft content for, Maria reviews this Einstein bot terminology with the service team.

    Dialog
    Dialogs are conversation snippets that control what a bot can do. Each dialog includes a dialog intent, which is optionally available for NLU training to understand different kinds of customer responses.
    During a conversation with a customer, a bot moves between several different dialogs. Each dialog handles a portion of the conversation. For example, Welcome, Main Menu, Order Status, Location and Hours, and Transfer to Agent are individual dialogs that a customer might experience as part of a single conversation with a bot.
    A dialog for “Chat with an agent”...might look like this:
    Customer: Transfer me to an agent. [Or any variations on this phrase.]
    Bot: No problem. Hang on: I’ll connect you with an agent.
    Dialog Intent
    Dialog intents are the customer's reasons for interacting with your bot. For example, buying a solar panel, returning a solar panel, getting store hours. Dialog intents are actions and generally start with verbs, such as buy, return, find, look up, cancel, edit, etc.
    Optionally, add dialog intents to your dialogs. Then train the bot to create a learning model that the bot can use to understand dialog intents.
    If your customers interact with your bot by typing a message in the chat window, use intents to help your bot understand what they want.

    Entity
    Entities are a type of data that you want to collect from a customer. Salesforce provides the following system entities: Text, DateTime, Date, Money, Number, Person, Location, Organization, Percent, Boolean, and Object (standard Salesforce or custom). You can create custom entities as needed.
    Here are some examples of entities:Order number
    Email address
    Variable
    A variable is a container that stores a specific piece of data collected from a customer. You must associate each variable with an entity. Since variables are containers of information, you can use them within dialog actions as both inputs and outputs and insert them as text in messages.
    Plan Chatbot Content
    With an understanding of chatbot terms, Maria and the Ursa Major Solar service team are in a better position to plan what kinds of bot content to create. After all, what good is a bot if it’s not clear what it’s going to say to customers? Not knowing what a bot should say is as bad as the bot saying the wrong thing: Each makes for a poor customer experience.

    In her previous planning meeting with the service team, Maria agreed to write the bot’s greeting and compile a list of ways customers ask for help.

    Maria explains to Sita and the service team that from everything she’s learned, the best people to research or suggest bot content are the support agents who work with customers every day. Agents know customers. Agents are on the front lines, so they know customers’ questions, concerns, and common issues. But the best people to actually craft bot content are writers. Writers know the importance of words. Writers know how to use words to reflect a company’s brand and tone. Most important, writers know how to create a customer experience with words. Words in, words out… Knowing the impact of words is the best way to write content that helps customers.

    Nevertheless, Maria leads the content planning with these topics and questions.

    Chatbot Content Considerations
    Along with planning content for chatbot conversations, Maria and the service team also discuss these content considerations. As they all know by now, the best way to avoid bad customer experiences with bots is to plan ahead.

    Openings
    Opening a chat with a question—like “How can I help you?”—gets down to business right away.
    Closings
    “Thank you” can end a chat. Customers may indicate they are ready to leave the conversation with words like “OK,” “Well,” and “All right.”
    Response Delays
    Super-short pauses—say, less than one second—between conversation snippets can seem artificial. The average human pause time in text chats is approximately two to four seconds.
    Emojis and Emoticons
    Emojis are warm and enthusiastic: ???? ????. Emoticons are lukewarm and mildly enthusiastic (e.g, 🙂 ^_^ >_>). You can use emojis in place of whole words (???? = “OK,” “good”).
    Text Style
    Machine-like fonts, such as Roboto Mono and Orbitron, clarify to customers that they are interacting with a bot. ALL CAPS equals yelling, all lowercase is informal, and utterance-final period (e.g., “I’m fine.”) can equal seriousness, formality, distance, irritation, or sarcasm.
    Note
    Looking for sample content or apps to extend your bot? Then check out the Salesforce AppExchange! Salesforce has an ecosystem of partners who use the flexibility of the Salesforce Platform to build amazing solutions to extend Salesforce easily.
    With a better understanding of what makes helpful bot content, Maria and the service team are ready to take the next step of learning about Einstein bots.

  • Deepak

    Member
    December 10, 2019 at 2:08 pm in reply to: How to schedule batch class based on country in Salesforce?

    ust saving the class does not schedule it. You still need to tell the DB to schedule it. I generally write a schedule function within my class so that I can easily call it in one line, that uses my static chron string within the class. Something like this should work

    global class Scheduler_class implements Schedulable{

    public static String sched = '0 00 00 * * ?'; //Every Day at Midnight

    global static String scheduleMe() {
    Scheduler_class SC = new Scheduler_class();
    return System.schedule('My batch Job', sched, SC);
    }

    global void execute(SchedulableContext sc) {

    batchAUpdate_based_on_stage b1 = new batchAUpdate_based_on_stage();
    ID batchprocessid = Database.executeBatch(b1,50);
    }
    }
    The you just need to run Scheduler_class.scheduleMe(); from execute anonymous and it will be scheduled to run at your interval. This is important as this tells the DB to actually schedule it.

  • Deepak

    Member
    December 10, 2019 at 2:07 pm in reply to: How to set default value in <lightning:select> in Salesforce?

    <aura:application extends="force:slds" controller="LightningAccountController">
    <aura:attribute name="accounts" type="Account[]" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <lightning:select label="Choose 1" name="a_opt" aura:id="a_opt" onchange="{!c.change}">
    <aura:iteration items="{!v.accounts}" var="account">
    <option value="{!account.Id}">{!account.Name}</option>
    </aura:iteration>
    </lightning:select>
    </aura:application>

  • The correct method would be to use the lightning:overlayLibrary (or create your own modal dialog). How it works is given in the documentation. First, you include overlay library:

    <lightning:overlayLibrary aura:id="overlayLib"/>
    And then you call it when you need it:

    var modalBody;
    $A.createComponent("c:modalContent", {},
    function(content, status) {
    if (status === "SUCCESS") {
    modalBody = content;
    component.find('overlayLib').showCustomModal({
    header: "Application Confirmation",
    body: modalBody,
    showCloseButton: true,
    cssClass: "mymodal",
    closeCallback: function() {
    alert('You closed the alert!');
    }
    })
    }
    });
    Where c:modalContent is the thing you want to show in the modal dialog. I suggest you read the documentation for more information.

  • Deepak

    Member
    December 10, 2019 at 2:04 pm in reply to: How to write Apex trigger for the given requirement in Salesforce?

    Write a trigger on lead for after insert and after update. Write your condition for update the lead status in if block and write the code for lead status updation.

  • You can use the Salesforce Metadata API(http://www.salesforce.com/us/developer/docs/api_meta/) to create a Connected App(https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_connectedapp.htm), it provides the ConnectedApp metadata type for this purpose. You can either use the File Based method(https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_file_based_calls_intro.htm) or the CRUD method(https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_crud_based_calls_intro.htm) (preferable for programmatic creation).

    Represents a Connected App application. A connected app is an application that integrates with salesforce.com using APIs. Connected apps use standard SAML and OAuth protocols to authenticate, provide Single Sign-On, and provide tokens for use with Salesforce APIs. In addition to standard OAuth capabilities, connected apps allow administrators to set various security policies and have explicit control over who may use the applications. It extends the Metadata metadata type and inherits its fullName field.

    ConnectedApp components have the suffix .connectedapp and are stored in the connected apps folder.

    This API is available in any language supporting HTTP callouts using Web Services (Salesforce provides a WSDL to consume in your client app). If you're using a Java, there is a prebuilt client library available here(https://developer.salesforce.com/page/Introduction_to_the_Force.com_Web_Services_Connector). There is also an Apex wrapper(https://github.com/financialforcedev/apex-mdapi) around the API if you're interested in doing this natively.

    Hope this helps.

Page 1 of 8