• bharath kumar 52
  • NEWBIE
  • 125 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 5
    Likes Received
  • 78
    Likes Given
  • 81
    Questions
  • 39
    Replies
Hi All,

I have a flow on quote object which will get triggered on change of a status from "status a" to "status b" and I have another flow which will count the number of quotes in a particular status and updates the opportunity. But when i try changing the status from "status a" to "status b" the other flow gets triggered and throws me the following error in the update element of the flow which counts and updates the opportunity. 
We can't save this record because the “Submission Stage Update” process failed. Give your Salesforce admin these details. 
This error occurred when the flow tried to update records: FIELD_FILTER_VALIDATION_EXCEPTION: Value does not exist or does not match filter criteria.. 
You can look up ExceptionCode values in the SOAP API Developer Guide. Error ID: 1448297641-117949 (1971948975)k up ExceptionCode values in the SOAP API Developer Guide. Error ID: 1448297641-117949 (1971948975)


I have tried debug mode and the logs too yet im not able to figure out if this is a generic salesforce error to contact support or something that can be fixed by myself.
Any help is greatly appreciated.

Thanks,
Bharath
Hi All,

I am trying to implement a integration with an external system via mulesoft and one of the things i've noticed in my experience previously is that some oauth flows often want you to approve the request once. Although i understand that this is for the sake of security, it isn't practical in the case of ESB where things work from the backend. Can someone tell me what flow once must go with while trying to integrate using an ESB?

Thanks,
Bharath
Hi All,

I am working on a component where i am getting the results from an apex class and displaying it on the screen but i am not able to display and bind information on the screens eventhough i am stringifying the json.
 
Component :

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" controller="SaveDRLines">
	<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="drLines" type="list"/>
    <aura:attribute name="wrapperList" type="Object[]"/>
    <aura:attribute name="recordId" type="String" default="a0tE0000000qtxjIAA"/>

    <table class="slds-table slds-table_bordered slds-table_cell-buffer">
                <thead>
                    <tr class="slds-text-title_caps">
					<!--header checkbox for select all-->
                        
                        <th scope="col">
                            <div class="slds-truncate" title="Name">Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Price">Price</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Quantity">Quantity</div>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <aura:iteration items="{!v.wrapperList}" var="wr" ><!--indexVar="index"-->
                        	<th scope="row">
                                <div class="slds-truncate" title="{!wr.name}">
                                   {!wr.name}
                                </div>
                            </th>
                        	
                        	<th scope="row">
                                <div class="slds-truncate" title="{!wr.price}">
                                   <lightning:input name="price" style="width:250px!important" value="{!wr.price}" />
                                </div>
                            </th>
                        	
                        	<th scope="row">
                                <div class="slds-truncate" title="{!wr.quantity}">
                                   <lightning:input name="quantity" style="width:250px!important" value="{!wr.quantity}" />
                                </div>
                            </th>
                    </aura:iteration>
        		</tbody>
    </table>
</aura:component>


JS Controller :
({
	doInit : function(component, event, helper) {
		var JsonData='[{"Id":"01tE0000008kwYSIAY","Name":"924737217148","AlternateID__c":"924737217148","Family":"Conventional"},{"Id":"01tE0000008kwYTIAY","Name":"924737310100","AlternateID__c":"924737310100","Family":"Automotive Other"}]';
        var array=JSON.parse(JsonData);
        var drId=component.get("v.recordId");
        console.log('drId >>>> '+drId);
        var IdList=[];
        for(let jo in array){
            IdList.push(array[jo].Id);
            console.log(array[jo].Id);
        }
        
        component.set("v.drLines", JsonData);
        var action = component.get("c.returnDRLines");
        action.setParams({productIdList:IdList, recordId: drId});
        action.setCallback(this,function(response){
            var state = response.getState();
            if (state === "SUCCESS"){
                console.log('SUCCESS');
                //console.log('response.getReturnValue() >>>> '+JSON.stringify(response.getReturnValue()));
                var s= JSON.stringify(response.getReturnValue());
                console.log('s value >>>> '+JSON.stringify(s));
                component.set("v.wrapperList", s);
                //REDIRECT TO DR RECORD
            }
            else{
                console.log('Error...');
                //REDIRECT TO DR RECORD
            }
        });
        $A.enqueueAction(action);
	}
})

Apex controller :
public class SaveDRLines {
    
    
    /*Display lines on ltng component*/
    @AuraEnabled
    public static list<DRLineWrapper> returnDRLines( list<Id> productIdList, Id recordId){
        list<Deal_Registration_Line__c> drLineList= new list<Deal_Registration_Line__c>();
        list<PriceBookEntry> pbeList = new list<PriceBookEntry>();
        list<DRLineWrapper> dwList = new list<DRLineWrapper>();
        //ADD THE ROLE NAME FILTER TO GET THE RIGHT PRICEBOOK
        pbeList=[select Pricebook2.Name, Product2.Id, PriceBook2Id, Product2.Name, UnitPrice, Product2.ProductCode,
        Product2.Description, Product2.Family, Product2.Product_Line__c from PriceBookEntry where IsActive = true
         limit 10];//AND Product2.Id IN:productIdList
        for(PriceBookEntry pbe : pbeList){
            DRLineWrapper dw= new DRLineWrapper();
            dw.quantity=0;
            dw.name=pbe.Product2.Name;
            dw.price=pbe.UnitPrice;
            dw.productId=pbe.Product2Id;
            dw.drId=recordId;
            dwList.add(dw);
        }
        system.debug('dwList >>> '+dwList);
        /*for(PriceBookEntry pbe : pbeList){
            Deal_Registration_Line__c drLine= new Deal_Registration_Line__c();
            drLine.Deal_Registration__c=recordId;
            drLine.Quantity__c=wo.quantity;
            drLine.Unit_Price__c=wo.price;
            drLine.Product__c =wo.productId;
            drLineList.add(drLine);
            
        }*/
        //insert drLineList;
        return dwList;
    }
    
    @AuraEnabled
    public static string insertDRLines(list<DRLineWrapper> drWrapList){
        list<Deal_Registration_Line__c> drlineList = new list<Deal_Registration_Line__c>();
        for(DRLineWrapper dw: drWrapList){
            Deal_Registration_Line__c drLine= new Deal_Registration_Line__c();
            drLine.Deal_Registration__c=dw.drId;
            drLine.Quantity__c=dw.quantity;
            drLine.Unit_Price__c=dw.price;
            drLine.Product__c=dw.productId;
            drlineList.add(drLine);
            
        }
        insert drlineList;
    	return 'success';
    }
    
    public class DRLineWrapper{
        @AuraEnabled 
        public String name{get;set;}
        @AuraEnabled
        public Integer quantity{get;set;}
        @AuraEnabled 
        public decimal price{get;set;}
        @AuraEnabled 
        public String productId{get;set;}
        @AuraEnabled 
        public String drId{get;set;}
        
    }

}

Any help would be greatly appreciated.

Thanks,
Bharath​​​​​​​
Hi All,

I am trying to build a search component which takes multiple criteria so i am adding fields, criteria and the search string. When i try to add more than 1 criteria in my lightning component i am getting this error
"This page has an error. You might just need to refresh it. Action failed: c:FilterComponent$controller$searchProducts [Cannot read property 'get' of undefined] Failing descriptor: {c:FilterComponent$controller$searchProducts}"
Please help me fix this. I also tried checking if its an array or not but that doesn't work in my favour.
User-added image


 
Component :

<aura:component controller="SearchFilterController" Implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="prodWrapper" type="list"/>
    <aura:attribute type="Object" name="testAttribute" />
    <aura:attribute name="accountList" type="Account[]"/>
    <aura:attribute name="productFields" type="list"/>
    <aura:attribute name="criteriaType" type="list"/>
    <lightning:card>
        <div class="slds-m-around--xx-large">
            <div class="slds-float_right slds-p-bottom_small">
                <h1 class="slds-page-header__title">Add Row 
                    <lightning:buttonIcon iconName="utility:add"  size="large" variant="bare" alternativeText="Add" onclick="{!c.addRow}"/>
                </h1>
            </div>
            <div class="container-fluid">        
                <table class="slds-table slds-table_bordered slds-table_cell-buffer"> 
                    <thead>
                        <tr class="slds-text-title_caps">
                            <th scope="col">
                                <div class="slds-truncate">Sr. No</div>
                            </th>
                            <th scope="col">
                                <div class="slds-truncate" title="Field Name">Field Name</div>
                            </th>
                            <th scope="col">
                                <div class="slds-truncate" title="Criteria">Criteria</div>
                            </th>
                            <th scope="col">
                                <div class="slds-truncate" title="Value">Value</div>
                            </th>  

                            <th scope="col">
                                <div class="slds-truncate" title="Action">Action</div>
                            </th>
                        </tr>
                    </thead>   
                    <tbody>      
                        <aura:iteration items="{!v.prodWrapper}" var="acc" indexVar="index">
                            <!--{!v.prodWrapper.size} -->
                            <tr>
                                <td> 
                                    {!'index'+index}
                                </td>
                                <td>
                                    <!--<lightning:input name="fieldName" type="text" maxlength="50" value="{!v.testAttribute.fieldNames}" />
                                {!index}
									-->
                                     <lightning:select aura:id="PicklistId" label="Select a field" name="fieldName" onchange="{c.changeHandler}" >
                                                <option value="" text="- None -" /> 
                                                <aura:iteration items="{!v.productFields}" var="field">
                                                    <option value="{!field}" text="{!field}" />  
                                                </aura:iteration>
                                            </lightning:select>
								</td>
                                <td>
                                   <!-- <lightning:input name="criteria" type="string" maxlength="30" value="{!acc.criteriaType}" />
                                -->
                                    <lightning:select aura:id="PicklistId2" label="Select a criteria" name="criteria" >
                                                <option value="" text="- None -" /> 
                                                <aura:iteration items="{!v.criteriaType}" var="per">
                                                    <option value="{!per}" text="{!per}" />  
                                                </aura:iteration>
                                            </lightning:select>
								</td>
                                <td>
                                    <lightning:input name="searchFieldValue" type="text" value="{!acc.searchStr}" />
                                </td>
   
                                <td>
                                    <a onclick="{!c.removeRecord}" data-record="{!index}">
                                        <lightning:icon iconName="utility:delete" size="small" alternativeText="Delete"/>
                                        <span class="slds-assistive-text">Delete</span>
                                    </a>
                                </td> 
                            </tr>
                        </aura:iteration>
                    </tbody>
                </table>
                <div class="slds-align_absolute-center slds-p-top_small">
                    <lightning:button variant="brand" label="Submit" title="Brand action" onclick="{!c.searchProducts}" />
                </div>
            </div>
        </div>
    </lightning:card>
</aura:component>

==================

JS Controller :

({	
    doInit:function(component, event, helper) {
        
        var action = component.get("c.displayFieldsAndCriteria");
            
        action.setCallback(this, function(response) {
                //get response status 
                var state = response.getState();
                if (state === "SUCCESS") {
                    //set empty account list
                   var respValue=JSON.parse(response.getReturnValue());
                    component.set("v.testAttribute",respValue);
                    //var testValue = component.set("v.testAttribute",response.getReturnValue());
                    var respVal =response.getReturnValue();
                    //console.log('respVal >>> '+respVal);
                    console.log('v.testAttribute value >>>>'+respValue);
                    console.log('criteriaType value >>>>'+respValue.criteriaType);
                    console.log('searchStr value >>>>'+respValue.searchStr);
                   // console.log('fieldNames value >>>>'+JSON.stringify(respValue.fieldNames));
                    //console.log('respValue.fieldNames typeof >>>> '+typeof(respValue.fieldNames));
                    var result=respValue.fieldNames;
                    console.log('result stringified >>>>>> '+result.typeof);
                    component.set("v.productFields",respValue.fieldNames);
                    component.set("v.criteriaType",respValue.criteriaType);
                    /*var criteriaTypeVar= component.get("v.criteriaType");
                    console.log('criteriaTypeVar >>>> '+criteriaTypeVar[0]);
                    var productFieldsVar= component.get("v.productFields");
                    console.log('productFields >>>> '+productFieldsVar);*/
                    alert('data received from class');
                }
            }); 
            $A.enqueueAction(action);

    },
  	
    addRow: function(component, event, helper) {
        //get the List from component  
        var pwList = component.get("v.prodWrapper");
        
        //Add New criteria
        pwList.push({
            'fieldNames': '',
            'criteriaType': '',
            'searchStr': ''
        });
        component.set("v.prodWrapper", pwList);
    },
    
    removeRecord: function(component, event, helper) {

        var criteriaList = component.get("v.prodWrapper");

        var selectedItem = event.currentTarget;
        //Get the selected item index
        var index = selectedItem.dataset.record;
        criteriaList.splice(index, 1);
        component.set("v.prodWrapper", criteriaList);
    },
    
    changeHandler:function(component, event, helper){
    var count=event.target.id;
    console.log('input id >>>> '+count);
	},
    	
   searchProducts: function(component, event, helper) {  
       var a= component.get("v.prodWrapper");
       console.log(a);
        var fName=component.find("PicklistId").get("v.value");
        for(var i=0;i<a.length;i++){
            
                console.log('fName >>>>'+ fName.length);
                a[i].fieldNames=fName;
                console.log('a value >>>> '+JSON.stringify(a));
           
        }
         /*var b= component.find("PicklistId2").get("v.value");
            var c= component.find("PicklistId").get("v.value");*/
        // use compo.find.get for picklist fields and while setting parameters create a json string
        // send the created json string to server
          /*console.log('typeof c>> '+typeof(c) +' '+JSON.stringify(c));
        console.log('typeof b >> '+typeof(b) +' '+JSON.stringify(b));
       console.log('typeof a >> '+typeof(a) +' '+JSON.stringify(a));*/
        var action = component.get("c.generateQuery");
            action.setParams({
                "prodWrapList": JSON.stringify(component.get("v.prodWrapper"))
            });
        action.setCallback(this, function(response) {
                //get response status 
                var state = response.getState();
                if (state === "SUCCESS") {
                    //set empty account list
                    component.set("v.prodWrapper", []);
                    alert('data sent to generateQuery');
                }
            }); 
            $A.enqueueAction(action);
       
    }
})





 

Hi All,

I am working on building a search component with filters which are passed by end users. Although i am able to capture the filters and send them to my apex class, I am not able to convert the list<object> to json or a wrapper in order to build my query.I have also given the input data formats that i receive in the code below. Can some one let me know as to how i can convert the list<object> to list<string> or list<wrapper> ?
 

// json sent by lightning component
[{"fieldNames":"test","criteriaType":"91102444","searchStr":"123123"},{"fieldNames":"Pasqua","criteriaType":"911032323","searchStr":"123"}]


//How the json gets converted and looks in debug logs currently
20:50:23:004 USER_DEBUG [11]|DEBUG|prodWrapList >>>> ({criteriaType=91102444, fieldNames=test, searchStr=123123}, {criteriaType=911032323, fieldNames=Pasqua, searchStr=123})

public class SearchFilterController {
	@AuraEnabled
    public static void saveAccountList(List<Account> accList) 
	{        
        Insert accList;
    }
    
    @AuraEnabled
    public static void generateQuery(List<object> prodWrapList) 
	{        
		system.debug('prodWrapList >>>> '+prodWrapList.tostring());
        system.debug('prodWrapList size >>>> '+prodWrapList.size());
        list<String> queryParams=(list<String>)prodWrapList;
        List<productWrapper> lstWrapper = new List<productWrapper>();
        
        //lstWrapper.addAll((List<productWrapper>)prodWrapList);
        //JSON.deserializeUntyped((list<string>)prodWrapList); ---->FATAL_ERROR System.TypeException: Invalid conversion from runtime type List<ANY> to List<String>
        //JSON.deserialize(prodWrapList, lstWrapper); ----> doesn't work
        system.debug('deserialized lst >>>> '+lstWrapper);
    }
    
 
    
    
        public class productWrapper{
            @AuraEnabled
            public String searchStr{get; set;}
            @AuraEnabled
            public Map<String,String> fieldNames{get; set;}
            @AuraEnabled
            public list<String> criteriaType{get; set;}
            
            public productWrapper(){
                criteriaType= new list<String>();
                criteriaType.add('equal to');
                criteriaType.add('greater than or equal to');
                criteriaType.add('lesser than or equal to');
                criteriaType.add('lesser than');
                criteriaType.add('greater than');
                criteriaType.add('contains');
                
                Map<String, Schema.SObjectField> schemaFieldMap = Schema.SObjectType.Product2.fields.getMap();
                //Map<String, Object> queriedFieldValues = new Map<String, Object>();
                for (String fieldName: schemaFieldMap.keySet()) {
                    try { 
                        fieldNames.put(fieldName, fieldName); 
                    } 
                    catch(Exception e){
                        
                    }
            }
        }
    }
}
Hi,

I am trying to build a formula in process builder where i need to check if the country's picklist value is either "United States" or "US" or "United States of America" but the thing is only United States is in the picklist(which is ok). But when i try to use the below formula in process builder i get a error message as shown below . Can someone help me out ?
Formula result is data type (Boolean), incompatible with expected data type (Text)
//my code

ISPICKVAL([Deal_Registration__c].Country__c,"United States")||
ISPICKVAL([Deal_Registration__c].Country__c,"United States of America")||
ISPICKVAL([Deal_Registration__c].Country__c,"US")

User-added image
Hi,

I am trying to build a formula in process builder where i need to check if the country's picklist value is either "United States" or "US" or "United States of America" but the thing is only United States is in the picklist(which is ok). But when i try to use the below formula in process builder i get a error message as shown below . Can someone help me out ?
Formula result is data type (Boolean), incompatible with expected data type (Text)




User-added image
ISPICKVAL([Deal_Registration__c].Country__c,"United States")||
ISPICKVAL([Deal_Registration__c].Country__c,"United States of America")||
ISPICKVAL([Deal_Registration__c].Country__c,"US")

 
Hi All,

Ia m working on a scenario where i need to submit a record for approval through a javascript button. I have tried submitting it for approval as a partner user but i always get an error message when i trigger it from the custom button. I thought of using process builder but that will again affect the order of execution as there are a couple of workflows and triggers running and this might mess it up.
I tried submitting the record through anonymous window and through batch and it got successfully submitted. Based on my understanding i am thinking that it is an issue with the user submitting it and scheduling is the only option. Any workarounds/suggestions will be of much help to me.
Below is the error message and the code i have worked on :
First error: Process failed. First exception on row 0; first error: NO_APPLICABLE_PROCESS, No applicable approval process was found.: []
//below is the code which i have altered so submit approval request from partner portal

webservice static string thresholdMetCheck (Id DemoId, String DemoAmount){         

         String ret ='';
         String totDemoAmount;
         totDemoAmount = DemoAmount.replace('$','').replace(',','').replace('USD','').replace('CNY','').replace('EUR','').replace('GBP','').replace('JPY','');
         Schema.DescribeSObjectResult drDescribe = Schema.SObjectType.Demo_Registration__c; 
         Map<String,Schema.RecordTypeInfo> rtMapByNamedr= drDescribe.getRecordTypeInfosByName();
         String approvalPhaseRT = rtMapByNamedr.get('Approval Phase').getRecordTypeId();
         if(double.valueof(totDemoAmount) >= double.valueof(System.Label.Threshold_Amount )){
             ret = 'true';
             Demo_Registration__c dr = [Select id, CreatedById, Approval_Status__c,Partner_Account__r.OwnerId,Distribution_Manager__c from Demo_Registration__c where id=:DemoId];
            List<QueueSObject> newDRQ=[select id, QueueId, SObjectType from QueueSObject where SObjectType='Demo_Registration__c' and QueueId = :System.Label.New_Design_Reg_QueueId];
            //There should be only one queue for Demo_Registration__c
            if(newDRQ.size()>1){
                ApexPages.Message errmsg=new ApexPages.Message(ApexPages.Severity.ERROR,'Too many queues on Demo Registration found');
                ApexPages.addMessage(errmsg);
            }else if(newDRQ.size()==0){
                ApexPages.Message errmsg=new ApexPages.Message(ApexPages.Severity.ERROR,'No queue on Demo Registration found');
                ApexPages.addMessage(errmsg);
            }else{

                dr.Approval_Status__c = 'Unsubmitted'; 
                dr.OwnerId = newDRQ.get(0).QueueId;
                dr.RecordTypeId = approvalPhaseRT;
                Demo_Registration__Share drShare = new Demo_Registration__Share(AccessLevel = 'Edit', ParentId = dr.Id, UserOrGroupId = dr.CreatedById);
                try{
                    Database.Saveresult res=Database.update(dr);
                    insert drShare;
                   system.debug('Approval_Status__c in submit logic >>>' +dr.Approval_Status__c);
                }catch(DMLException e){
                    ApexPages.Message errmsg=new ApexPages.Message(ApexPages.Severity.ERROR,e.getMessage());
                    ApexPages.addMessage(errmsg);
                }
                
                system.debug('**********OwnerId' + dr.OwnerId);
            }

            dr.Approval_Status__c='Submitted';
            if(dr.Partner_Account__r.OwnerId!=null){
                  
              dr.OwnerId=dr.Partner_Account__r.OwnerId;
                SYSTEM.DEBUG('Account owner isnt null'); 
            }else{
                SYSTEM.DEBUG('Account owner IS null'); 
                return 'No Partner Account associated with this record';
            }
            dr.RecordTypeId=approvalPhaseRT;    //assigning the appropriate page layout    
            
            try{
                Database.Saveresult reslt=Database.update(dr);
                system.debug('dr >>>>> '+dr);
            }catch(DMLException e){
                system.debug(e.getMessage());
                return 'false';
            }
            
         //create the new approval request to submit
         Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
         req.setComments('Submitted for approval. Please review.');
         req.setObjectId(dr.Id);
         req.setNextApproverIds(new List<Id>{dr.Partner_Account__r.OwnerId});
         // submit the approval request for processing
         Approval.ProcessResult result = Approval.process(req);
         
         }else{
             ret = 'false';
         }
         return ret;
     }





 

Hi All,

I am working on a requirement and i am facing an issue where "mapAdjIdToAdj" map is filled by a query in getOpportunitySize function and i can see the values too in that function using debug, but the map doesn't have any values when i use debug to get its values in getAdjustmentList function. I have also declared the map public and static so that it is accessible by all functions of the class .

public static map<id,opportunity_adjustment__c> mapAdjIdToAdj = new map<id,opportunity_adjustment__c> ();
Can someone please tell me what's wrong?

public class OppAdjPocController1 {
public static list<opportunityAdjustment> adjustmentList = new list<opportunityAdjustment>();
public static boolean isWon;
public static map<id,opportunity_adjustment__c> mapAdjIdToAdj = new map<id,opportunity_adjustment__c> ();

    @AuraEnabled
    public static list<opportunity_roc__c> getOpportunitySize(Id OpportunityId){
      
        list<opportunity_roc__c> oppSizeList = new list<opportunity_roc__c>([select id,name,opportunity__c,unit_price__c,Quantities__c from opportunity_roc__c where opportunity__c=:OpportunityId]);
        return oppSizeList;
    }

    
    @AuraEnabled
    public static list<opportunityAdjustment> getAdjustmentList(Id OpportunityId){
        list<opportunity_roc__c> oppSizeList = new list<opportunity_roc__c>([select id,Name,Opportunity__c,Opportunity__r.StageName,Unit_price__c,Quantities__c from opportunity_roc__c where opportunity__c=:OpportunityId]);
		list<opportunity_adjustment__c> oppAdjList = new list<opportunity_adjustment__c>([select id,Opportunity_Size__c,Adjusted_Price__c,Adjusted_Quantity__c,Reason_for_adjustment__c,latest_version__c from opportunity_adjustment__c where opportunity__c=:OpportunityId and latest_version__c=true]);
        map<id,opportunity_adjustment__c> mapOppSizeIdToAdj = new map<id,opportunity_adjustment__c> ();
        
        if(!oppAdjList.isEmpty()){
			for(opportunity_adjustment__c oAdj : oppAdjList){
                mapOppSizeIdToAdj.put(oAdj.Opportunity_Size__c,oAdj);
                //mapOppSizeIdToAdj.put(oAdj.Opportunity_Size__c,new list<opportunity_adjustment__c>{oAdj});
				mapAdjIdToAdj.put(oAdj.Id,oAdj);//this works for 1 to many
			}
		
		}
        	system.debug('mapAdjIdToAdj>>>>>>>'+mapAdjIdToAdj.values());//getting values here
         for(opportunity_roc__c os : oppSizeList){
            string adjReason;
            Decimal adjAmount=0;
            Integer adjQuantity=0;
            
            if(mapOppSizeIdToAdj.get(os.Id)!=null){
                adjAmount=mapOppSizeIdToAdj.get(os.Id).Adjusted_Price__c;
				adjQuantity=Integer.valueof(mapOppSizeIdToAdj.get(os.Id).Adjusted_Quantity__c);
				adjReason=mapOppSizeIdToAdj.get(os.Id).Reason_for_adjustment__c;             
            }
            else{
               adjAmount=0; 
               adjQuantity=0;
               adjReason='';
            }

             adjustmentList.add(new opportunityAdjustment(os.name,os.unit_price__c,os.quantities__c,adjReason,adjAmount,adjQuantity,os.opportunity__c,os.opportunity__r.StageName,os.Id));
           
           
        }

           return adjustmentList;
        
    }
    
    
    
    @AuraEnabled
    public static string createOpportunityAdjustment(list<opportunityAdjustment> oppAdjlist){
       	string message='';
        list<Opportunity_Adjustment__c> adjustmentListToInsert = new list<Opportunity_Adjustment__c>();
        list<Opportunity_Adjustment__c> previousAdjListToUpdate = new list<Opportunity_Adjustment__c>();
        try{
            
            Opportunity_Adjustment__c oppAdj;
            if(oppAdjlist[0].oppStageName!='3 - Won'){
                throw new OppAdjPocControllerException('You cannot update adjustments until the opportunity stage is  3 - Won');
            }else{
                for(opportunityAdjustment oa : oppAdjlist){
                    oppAdj = new Opportunity_Adjustment__c();
                    oppAdj.Adjusted_Price__c = oa.adjustmentAmount;
                    oppAdj.Adjusted_Quantity__c = oa.adjustmentQuantity;
                    oppAdj.Reason_for_adjustment__c = oa.adjustmentReason;
                    oppAdj.Adjustment_amount__c = oa.adjustmentAmount * oa.adjustmentQuantity;
                    oppAdj.Opportunity_Size__c = oa.oppSizeId;
                    oppAdj.Opportunity__c = oa.oppId;
                    oppAdj.Opportunity_Size_ExtId__c = oa.oppSizeId;
                    oppAdj.Latest_version__c = True;
                    if(oppAdj.Adjusted_Price__c>0 || oppAdj.Adjusted_Quantity__c>0){
                       
                    adjustmentListToInsert.add(oppAdj);
                    } 
                }
               
                for(Opportunity_Adjustment__c prevAdj : mapAdjIdToAdj.values()){
                    //getting null in the iterable list mapAdjIdToAdj.values() despite being set 
					
                    Opportunity_Adjustment__c oa = new Opportunity_Adjustment__c();
                    oa.Id=prevAdj.Id;
                    if(prevAdj.Latest_Version__c==true){
                        oa.Latest_Version__c=false;
                    }
                       previousAdjListToUpdate.add(oa); 
                }
                if(previousAdjListToUpdate!=null){
                update previousAdjListToUpdate;
                }
                
            }  //else - Stage check
                if(adjustmentListToInsert!=null){
                    
                   insert adjustmentListToInsert;

                }
                
        }    
        catch(Exception e){
            message=e.getMessage();
            System.debug('Error '+e.getMessage());
            System.debug('Error line'+e.getLineNumber());
        }
        return message;
    }


    class opportunityAdjustment{
 		
        @AuraEnabled
        public string osiName{get;set;}
        @AuraEnabled
        public Decimal unitPrice{get;set;}
        @AuraEnabled
        public Decimal quantity{get;set;} 
        @AuraEnabled
        public string adjustmentReason{get;set;}
        @AuraEnabled
        public Integer adjustmentQuantity{get;set;} 
        @AuraEnabled
        public Decimal adjustmentAmount{get;set;}
        @AuraEnabled
        public string oppId{get;set;}
        @AuraEnabled
        public string oppStageName{get;set;} 
        @AuraEnabled
        public string oppSizeId{get;set;} 
        
        public opportunityAdjustment(){
            
        }
         		
        public opportunityAdjustment(string name,Decimal osUnitPrice, Decimal osQty, String adjReason, Decimal adjAmount,Integer adjQty, Id oppId,String oppStageName, Id oppSizeId){
        osiName=name;
        unitPrice=osUnitPrice;
        quantity=osQty;   
        adjustmentReason=adjReason;
        adjustmentAmount=adjAmount;
        adjustmentQuantity=adjQty;
        this.oppStageName=oppStageName;
        this.oppId=oppId;
        this.oppSizeId=oppSizeId;
    	}
    }


}

Hi All,

I am working on a requirement where i am supposed to display a lightning component embedded in a quick action in a "new tab" instead of a modal popup. The component that i have embedded in the quick action takes the opportunity id as a input and based on a button click i will be saving some child records related to it.
I have tried this link too but it doesn't work https://salesforce.stackexchange.com/questions/158244/how-to-open-lightning-component-tab-from-lightning-quick-action-instead-of-light
Assuming that the code is something like below 

Component :
<aura:component 
    implements="force:appHostable, flexipage:availableForAllPageTypes, flexipage:availableForRecordHome, force:hasRecordId, forceCommunity:availableForAllPageTypes, force:lightningQuickAction">
    <aura:handler name="init" action="{!c.navigateToeDiscoverySearchCmp}" value="{!this}" />
    <aura:attribute name="recordId" type="Id" />
</aura:component>

Controller js :
({
    navigateToeDiscoverySearchCmp : function(component, event, helper) {
        var evt = $A.get("e.force:navigateToComponent");
        evt.setParams({
            componentDef : "c:TestOppAdj",
            recordId: component.get("v.recordId") // this value is not getting set
        });
        evt.fire();
    } 
})
Because the recordId is not getting set i am getting the below issue  else the tables in the below pic would be populated

User-added imageAlso, i am getting something like this in the url /one/one.app#eyJjb21wb25lbnREZWYiOiJjOlRlc3RPcHBBZGoiLCJhdHRyaWJ1dGVzIjp7fSwic3RhdGUiOnt9fQ%3D%3D and not the id .

Can someone tell me where i am going wrong or help me deal with this issue?

Thanks,
Bharath

Hi All,

I am working on a requirement where i am supposed to make the table editable and capture values. The challenge here is that i have to capture values from this table and store it in another object so i think i am supposed to add a new column to lightning datatable using wrapper.
User-added image

The user should enter values in columns amount and reason which i am planning to implement through wrapper but how to set values is something which is confusing me and i am not sure if this approach will work. Please check my code and let me know if you have any suggestions.
Component Code:

<aura:component controller="OpportunityAdjustmentController">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="OppId" type="Id" />
    <aura:attribute name="listOfAdjustments" type="OpportunityLineItem[]" />
	<aura:attribute name="wrapperList" type="object"/>
    
  <div class="slds-p-around--large">
      
     
      <p style="color:red">{!v.wrapperList}</p>
      
  <!--https://www.lightningdesignsystem.com/components/data-tables/-->
    <table class="slds-table slds-table--bordered slds-table--cell-buffer">
      <thead>
        <tr class="slds-text-title--caps">
          <th scope="col">
            <div class="slds-truncate" title="Product Name">Product Name</div>
          </th>
          <th scope="col">
            <div class="slds-truncate" title="Quantity">Quantity</div>
          </th>
          <th scope="col">
            <div class="slds-truncate" title="Adjusted Amount">Adjusted Amount</div>
          </th>
          <th scope="col">
            <div class="slds-truncate" title="Adjusted Quantity">Adjusted Quantity</div>
          </th>
        </tr>
      </thead>
      <!--table body start, 
        Iterate contact list as a <tr>
        -->
      <tbody>
          <aura:iteration items="{!v.wrapperList}" var="wrapObj">
            <!--<aura:iteration items="{!v.wrapperList.lstContact}" var="con"> -->
              <tr>
                <th scope="row">
                  <div class="slds-truncate" title="{!wrapObj.oli.name}">{!wrapObj.oli.name}</div>
                </th>
                <th scope="row">
                  <div class="slds-truncate" title="{!wrapObj.adjustmentReason}">{!wrapObj.adjustmentReason}</div>
                    <!--Planning to use input tag here-->
                </th>
                <th scope="row">
                  <div class="slds-truncate" title="{!wrapObj.adjustmentAmount}">{!wrapObj.adjustmentAmount}</div>
                     <!--Planning to use input tag here-->
                </th>
                <th scope="row">
                   <div class="slds-truncate" title="{!con.LeadSource}">{!con.LeadSource}</div>
                </th>
              </tr>
            <!-- </aura:iteration> -->
         </aura:iteration>
      </tbody>
    </table>
  </div>
</aura:component>
 
Apex controller :
public class OpportunityAdjustmentController {
public static list<opportunityAdjustment> adjustmentList = new list<opportunityAdjustment>();
    @AuraEnabled
    public static list<opportunityAdjustment> getOpportunityAdjustment(Id OpportunityId){
        list<opportunitylineitem> oliList = new list<opportunitylineitem>([select id,name,opportunityid,unitprice,quantity from opportunitylineitem where
                                                                           opportunityid=:OpportunityId]);
        for(opportunitylineitem oli : oliList){
            string reason;
            Decimal adjAmount=0;
            adjustmentList.add(new opportunityAdjustment(oli,'',adjAmount,oli.opportunityid,oli.Id));
        }
        return adjustmentList;
    }
    
    @AuraEnabled
    public static list<opportunityAdjustment> createOpportunityAdjustment(list<opportunityAdjustment> oppAdjlist){
        //list<opportunitylineitem> oliList = new list<opportunitylineitem>([select id,name,opportunityid,unitprice,quantity from opportunitylineitem where opportunityid=:OpportunityId]);
        list<Opportunity_Adjustment__c> adjustmentListToInsert = new list<Opportunity_Adjustment__c>();
        Opportunity_Adjustment__c oppAdj = new Opportunity_Adjustment__c();
        for(opportunityAdjustment oa : oppAdjlist){
            oppAdj.Adjustment_amount__c = oa.adjustmentAmount;
            oppAdj.Reason_for_adjustment__c = oa.adjustmentReason;
            oppAdj.Opportunity__c = oa.oppId;
            adjustmentListToInsert.add(oppAdj);
            //adjustmentListToInsert.add(new opportunityAdjustment(oli,'',adjAmount,oli.opportunityid,oli.Id));
        }
        if(adjustmentListToInsert!=null){
            
           insert adjustmentListToInsert;
        }
        return adjustmentList;
    }


    class opportunityAdjustment{
        @AuraEnabled
        public opportunitylineitem oli{get;set;}
        @AuraEnabled
        public string adjustmentReason{get;set;} // set data on attribute level
        @AuraEnabled
        public Decimal adjustmentAmount{get;set;} // set data on attribute level
        @AuraEnabled
        public string oppId{get;set;}
        @AuraEnabled
        public string oliId{get;set;} 
        
        opportunityAdjustment(OpportunityLineItem o, String s, Decimal d, Id oppId, Id oliId){}
        
        
    
    }


}

Thanks,
Bharath​​​​​​​
 
Hi All,

I am new to forecasting but i have a requirement where i am required to check if the forecasted revenue vs actual revenue from an opportunity and in case the amount is edited and reduced(less than the original opportunity amount) i must be able to maintain the new numbers seperately and the original numbers must not be altered so that we are able to get a complete view of why the sales numbers went down. Please let me know if its possible in standard forecasting or if i have to use a bit of customization with it. If you could detail it in steps that would be of great help to me.

Thanks,
Bharath
Hi All,

I am trying to learn integration using jwt and would like to know the steps or flow involved in outbound integrations(SFDC --> ESB/API Gateway) which uses JWT as a authentication mechanism.
Any answer would be of much help to me.

Thanks,
Bharath
Hi All,

I am working on integrations and in order to make sure that the external system receivess and consumes the json data posted by salesforce we need provide the format so that they can using it as a specification to build code to parse the request.
Can you please confirm if salesforce always provides data in the below format when sending data(single sobject) to an external system ?
//Sample json request for a single sobject record

{
  "totalSize" : 1,
  "done" : true,
  "records" : [ {
    "attributes" : {
      "type" : "Account",
      "url" : "/services/data/v47.0/sobjects/Account/0010K00002IlcJwQAJ"
    },
    "Id" : "0010K00002IlcJwQAJ",
    "Name" : "TeslaSpax123"
  } ]
}

 
Hi All,

I am experimenting on salesforce integrations and i am trying to get data from salesforce to an external system.During that i get a prompt like the one below which prompts me to allow or deny.approval during login
My question is that how do i bypass this screen? i.e provide an auto approval either through config or code whenever an external system needs to access a resource from salesforce once it is authenticated.
This is something which happens when i use Web-Server and Useragent flow. Please advise on which is the best flow when it comes to bidirectional integrations(SFDC --> ERP and ERP ---> to SFDC)

Thanks,
Bharath
Hi All,

I haven't worked much on integrations so i would like to know what's the difference in these 2 syntaxes below in generating json, i personally feel they do the same thing but i would like to know the differences and any other pros and cons of both the approaches and when to use which approach.

Generating json :
Approach 1
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeFieldName('Patient satisfaction');
gen.writeStartArray();
for (Patient_Satisfaction__c  patientSatisfaction : PrRecord) {
gen.writeStartObject();
gen.writeObjectField('First name', patientSatisfaction.Reporter_First_Name__c);
gen.writeObjectField('Last name', patientSatisfaction.Reporter_Last_Name__c);
gen.writeObjectField('Phone', patientSatisfaction.Reporter_Phone__c);
gen.writeObjectField('description', patientSatisfaction.Description_of_Feedback__c);gen.writeEndObject();
     } 
gen.writeEndArray();
gen.writeObjectField('incident_group_id',7387);
gen.writeObjectField('Name', 'TestAPI');
gen.writeEndObject();
//// This code snippet generates a json array

Approach2:
String jsonstr='{"Name":"'+ Accname +'","Phone":"'+ phone +'"}';

 Http h2= new Http();
//setting headers and other stuff required for callouts
//
//
req2.setBody(jsonstr);

            HttpResponse res2=h2.send(req2);
            System.debug(res2+'###1213createresp');
            deserializeResponse deresp2=(deserializeResponse)System.JSON.deserialize(res2.getBody(),deserializeResponse.class);



 

I have a requirement where i need a opportunity related task to appear under related opportunity's account and contact but i am able to see it only under related account and not under related contact.Can someone tell what is going wrong here and is it possible to achieve this using a process builder ?

Hi All,

I am planning to integrate salesforce with a google api. But, the challenge here is that i have a lot of users and  each user has a different set of data.
In order to make sure that the user data flows from google to salesforce i used their api and REST callouts . But, the catch here is that i am currently hardcoding the token which i get from oauthplayground. But in realtime scenario when i click on a button i need the latest dataa to be shown from google to salesforce can someonen please help me on how i can get the token of each user dynamically and notjust hardcoding a single token?

Hi All,

I am trying to save the currently applied "class" which is triggered onclicking s,m or l of the particular record of an sobject which should be saved in a field of user object and i need to do it for more than one record. How can i achieve this requirement? Can someone help me with the approach if not for the code?
Tiles image

Thanks,
Bharath

Hi All,

I am working on a PoC where i need to display sobject records cards. But when i do i have few hyperlinks on each card onclick of which i want my card to be resized. I used addstyle but am not able to do it for more than 1 record.
Also, is there any way to store the card size for that particular user? i.e when i resize the card it should be visible with the same size next time the user visits the page.
<aura:component controller="tileController">
    <aura:attribute name="tiles" type="TileRecord__c[]" />
    <aura:attribute name="tileCount" type="Integer" default="0" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
    <lightning:layout multipleRows="true">
      
        <aura:iteration items="{!v.tiles}" var="tile" indexVar="index">
            <lightning:layoutItem padding="around-small" size="10" smallDeviceSize="12" mediumDeviceSize="6" largeDeviceSize="4" >
               
                <article aura:id="{!tile.Id}" class="slds-card slds-card__narrow slds-size_2-of-3" style="padding-left: 10px;" data-row-index="{!index}">
                    <a href="{! '#tiles/' + tile.Id }">
                        
                        <span class="slds-badge">{!tile.Name}</span>
                    </a>
                    
                    <!--<lightning:button label="Toggle" onclick="{!c.resizeToSmall}"/> -->
                    <p><!--<ui:button aura:id="sml" press="{!c.resizeToSmall}">s</ui:button> -->
                        <a aura:id="md" href="javascript:void(0)" onclick="{!c.resizeToSmall}">s</a>
                        <a aura:id="md" href="javascript:void(0)" onclick="{!c.resizeToMedium}">m</a>
                        <a aura:id ="lg" href="javascript:void(0)" onclick="{!c.resizeToLarge}">l</a>
                    </p>
                    
                    <p>{!tile.Description__c}</p>
                    <p style="color:red; font-weight:bold;">{!index}</p>
                    
                    <a href="javascript:void(0)" onclick="{!c.doSomething}">
                        Click me to do Something </a>
                    
                </article>
                  
            </lightning:layoutItem>
        </aura:iteration>
       
    </lightning:layout>    
    
</aura:component>

Controller :
({
	doInit : function(component, event, helper) {
		var tiles=component.get("c.displayTiles");
        tiles.setCallback(this,function(a){
            component.set("v.tiles",a.getReturnValue());    
        });
        $A.enqueueAction(tiles);//tiles ---> action on server side	
	},
    applyCSS: function(cmp, event) {
        //var href = event.currentTarget;
        //$A.util.addClass(href, 'changeMe');
         var cmpTarget = cmp.find('{!tile.Id}');
        $A.util.addClass(cmpTarget, 'changeMe');
    },
    resizeToSmall:function(component, event, helper){
//OnClick on s,m,l hyperlinks on the component it should be resized.
       	/*var src = event.getSource().getLocalId();
        
        var cmpTarget = component.find('changeIt');
        $A.util.addClass(src, 'changeMe');
        console.log('After');*/
        var cmpTarget = component.find('{!tile.Id}');
        console.log('target'+cmpTarget);
        var arr = [];
        //arr = component.find("main").getElement().childNodes;
        //console.log(event.target);
        
        
    },
    resizeToLarge:function(component, event, helper){
        
        console.log('Large');
    },
    resizeToMedium:function(component, event, helper){
        
        console.log('Medium');
    },
    doSomething : function(component,event, helper) {
       console.log('Hey There .. the anchor was clicked');
       console.log(event);
       var href = event.srcElement.href;
       console.log(href);

    } 
})

 
Hi,

I am trying to build a formula in process builder where i need to check if the country's picklist value is either "United States" or "US" or "United States of America" but the thing is only United States is in the picklist(which is ok). But when i try to use the below formula in process builder i get a error message as shown below . Can someone help me out ?
Formula result is data type (Boolean), incompatible with expected data type (Text)




User-added image
ISPICKVAL([Deal_Registration__c].Country__c,"United States")||
ISPICKVAL([Deal_Registration__c].Country__c,"United States of America")||
ISPICKVAL([Deal_Registration__c].Country__c,"US")

 
Hi All,

I am working on a project and in the data model i can see "Created By and Last modified By" for some objects and "Created By, Last modified By and Owner name" for some objects(all are standard fields). May i ask you that on what basis are the owner fields added?(In general context)

Thanks and Regards,
Bharath Kumar M

Hi All,

Following is my data model :

Event (Custom) ---> Child--->Grandchild

My requirement is to send an email alert to a user in a lookup of grandchild WHEN either a "Parent,Child or Grandchild is updated".
Any help on achieving this with a single trigger/workflow is greatly appreciated.(I believe we need to use more than one trigger /workflow for this)
 

Hi All,

I have a situation where i need to insert 2 fields from account and the few fields from contact(related to account) to a custom object . Is it possible using triggers?
 

Hi All,

I have a scenario where Person A and Person B are 2 helpdesk representatives who login using partner community portal.
Person A should not be able to view "Cases" assigned to Person B and vice versa.
How can i achieve this?
 

Hi All,

I am trying to implement a integration with an external system via mulesoft and one of the things i've noticed in my experience previously is that some oauth flows often want you to approve the request once. Although i understand that this is for the sake of security, it isn't practical in the case of ESB where things work from the backend. Can someone tell me what flow once must go with while trying to integrate using an ESB?

Thanks,
Bharath
Hi All,

I am working on a component where i am getting the results from an apex class and displaying it on the screen but i am not able to display and bind information on the screens eventhough i am stringifying the json.
 
Component :

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" controller="SaveDRLines">
	<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="drLines" type="list"/>
    <aura:attribute name="wrapperList" type="Object[]"/>
    <aura:attribute name="recordId" type="String" default="a0tE0000000qtxjIAA"/>

    <table class="slds-table slds-table_bordered slds-table_cell-buffer">
                <thead>
                    <tr class="slds-text-title_caps">
					<!--header checkbox for select all-->
                        
                        <th scope="col">
                            <div class="slds-truncate" title="Name">Name</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Price">Price</div>
                        </th>
                        <th scope="col">
                            <div class="slds-truncate" title="Quantity">Quantity</div>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <aura:iteration items="{!v.wrapperList}" var="wr" ><!--indexVar="index"-->
                        	<th scope="row">
                                <div class="slds-truncate" title="{!wr.name}">
                                   {!wr.name}
                                </div>
                            </th>
                        	
                        	<th scope="row">
                                <div class="slds-truncate" title="{!wr.price}">
                                   <lightning:input name="price" style="width:250px!important" value="{!wr.price}" />
                                </div>
                            </th>
                        	
                        	<th scope="row">
                                <div class="slds-truncate" title="{!wr.quantity}">
                                   <lightning:input name="quantity" style="width:250px!important" value="{!wr.quantity}" />
                                </div>
                            </th>
                    </aura:iteration>
        		</tbody>
    </table>
</aura:component>


JS Controller :
({
	doInit : function(component, event, helper) {
		var JsonData='[{"Id":"01tE0000008kwYSIAY","Name":"924737217148","AlternateID__c":"924737217148","Family":"Conventional"},{"Id":"01tE0000008kwYTIAY","Name":"924737310100","AlternateID__c":"924737310100","Family":"Automotive Other"}]';
        var array=JSON.parse(JsonData);
        var drId=component.get("v.recordId");
        console.log('drId >>>> '+drId);
        var IdList=[];
        for(let jo in array){
            IdList.push(array[jo].Id);
            console.log(array[jo].Id);
        }
        
        component.set("v.drLines", JsonData);
        var action = component.get("c.returnDRLines");
        action.setParams({productIdList:IdList, recordId: drId});
        action.setCallback(this,function(response){
            var state = response.getState();
            if (state === "SUCCESS"){
                console.log('SUCCESS');
                //console.log('response.getReturnValue() >>>> '+JSON.stringify(response.getReturnValue()));
                var s= JSON.stringify(response.getReturnValue());
                console.log('s value >>>> '+JSON.stringify(s));
                component.set("v.wrapperList", s);
                //REDIRECT TO DR RECORD
            }
            else{
                console.log('Error...');
                //REDIRECT TO DR RECORD
            }
        });
        $A.enqueueAction(action);
	}
})

Apex controller :
public class SaveDRLines {
    
    
    /*Display lines on ltng component*/
    @AuraEnabled
    public static list<DRLineWrapper> returnDRLines( list<Id> productIdList, Id recordId){
        list<Deal_Registration_Line__c> drLineList= new list<Deal_Registration_Line__c>();
        list<PriceBookEntry> pbeList = new list<PriceBookEntry>();
        list<DRLineWrapper> dwList = new list<DRLineWrapper>();
        //ADD THE ROLE NAME FILTER TO GET THE RIGHT PRICEBOOK
        pbeList=[select Pricebook2.Name, Product2.Id, PriceBook2Id, Product2.Name, UnitPrice, Product2.ProductCode,
        Product2.Description, Product2.Family, Product2.Product_Line__c from PriceBookEntry where IsActive = true
         limit 10];//AND Product2.Id IN:productIdList
        for(PriceBookEntry pbe : pbeList){
            DRLineWrapper dw= new DRLineWrapper();
            dw.quantity=0;
            dw.name=pbe.Product2.Name;
            dw.price=pbe.UnitPrice;
            dw.productId=pbe.Product2Id;
            dw.drId=recordId;
            dwList.add(dw);
        }
        system.debug('dwList >>> '+dwList);
        /*for(PriceBookEntry pbe : pbeList){
            Deal_Registration_Line__c drLine= new Deal_Registration_Line__c();
            drLine.Deal_Registration__c=recordId;
            drLine.Quantity__c=wo.quantity;
            drLine.Unit_Price__c=wo.price;
            drLine.Product__c =wo.productId;
            drLineList.add(drLine);
            
        }*/
        //insert drLineList;
        return dwList;
    }
    
    @AuraEnabled
    public static string insertDRLines(list<DRLineWrapper> drWrapList){
        list<Deal_Registration_Line__c> drlineList = new list<Deal_Registration_Line__c>();
        for(DRLineWrapper dw: drWrapList){
            Deal_Registration_Line__c drLine= new Deal_Registration_Line__c();
            drLine.Deal_Registration__c=dw.drId;
            drLine.Quantity__c=dw.quantity;
            drLine.Unit_Price__c=dw.price;
            drLine.Product__c=dw.productId;
            drlineList.add(drLine);
            
        }
        insert drlineList;
    	return 'success';
    }
    
    public class DRLineWrapper{
        @AuraEnabled 
        public String name{get;set;}
        @AuraEnabled
        public Integer quantity{get;set;}
        @AuraEnabled 
        public decimal price{get;set;}
        @AuraEnabled 
        public String productId{get;set;}
        @AuraEnabled 
        public String drId{get;set;}
        
    }

}

Any help would be greatly appreciated.

Thanks,
Bharath​​​​​​​
Hi All,

I am trying to build a search component which takes multiple criteria so i am adding fields, criteria and the search string. When i try to add more than 1 criteria in my lightning component i am getting this error
"This page has an error. You might just need to refresh it. Action failed: c:FilterComponent$controller$searchProducts [Cannot read property 'get' of undefined] Failing descriptor: {c:FilterComponent$controller$searchProducts}"
Please help me fix this. I also tried checking if its an array or not but that doesn't work in my favour.
User-added image


 
Component :

<aura:component controller="SearchFilterController" Implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="prodWrapper" type="list"/>
    <aura:attribute type="Object" name="testAttribute" />
    <aura:attribute name="accountList" type="Account[]"/>
    <aura:attribute name="productFields" type="list"/>
    <aura:attribute name="criteriaType" type="list"/>
    <lightning:card>
        <div class="slds-m-around--xx-large">
            <div class="slds-float_right slds-p-bottom_small">
                <h1 class="slds-page-header__title">Add Row 
                    <lightning:buttonIcon iconName="utility:add"  size="large" variant="bare" alternativeText="Add" onclick="{!c.addRow}"/>
                </h1>
            </div>
            <div class="container-fluid">        
                <table class="slds-table slds-table_bordered slds-table_cell-buffer"> 
                    <thead>
                        <tr class="slds-text-title_caps">
                            <th scope="col">
                                <div class="slds-truncate">Sr. No</div>
                            </th>
                            <th scope="col">
                                <div class="slds-truncate" title="Field Name">Field Name</div>
                            </th>
                            <th scope="col">
                                <div class="slds-truncate" title="Criteria">Criteria</div>
                            </th>
                            <th scope="col">
                                <div class="slds-truncate" title="Value">Value</div>
                            </th>  

                            <th scope="col">
                                <div class="slds-truncate" title="Action">Action</div>
                            </th>
                        </tr>
                    </thead>   
                    <tbody>      
                        <aura:iteration items="{!v.prodWrapper}" var="acc" indexVar="index">
                            <!--{!v.prodWrapper.size} -->
                            <tr>
                                <td> 
                                    {!'index'+index}
                                </td>
                                <td>
                                    <!--<lightning:input name="fieldName" type="text" maxlength="50" value="{!v.testAttribute.fieldNames}" />
                                {!index}
									-->
                                     <lightning:select aura:id="PicklistId" label="Select a field" name="fieldName" onchange="{c.changeHandler}" >
                                                <option value="" text="- None -" /> 
                                                <aura:iteration items="{!v.productFields}" var="field">
                                                    <option value="{!field}" text="{!field}" />  
                                                </aura:iteration>
                                            </lightning:select>
								</td>
                                <td>
                                   <!-- <lightning:input name="criteria" type="string" maxlength="30" value="{!acc.criteriaType}" />
                                -->
                                    <lightning:select aura:id="PicklistId2" label="Select a criteria" name="criteria" >
                                                <option value="" text="- None -" /> 
                                                <aura:iteration items="{!v.criteriaType}" var="per">
                                                    <option value="{!per}" text="{!per}" />  
                                                </aura:iteration>
                                            </lightning:select>
								</td>
                                <td>
                                    <lightning:input name="searchFieldValue" type="text" value="{!acc.searchStr}" />
                                </td>
   
                                <td>
                                    <a onclick="{!c.removeRecord}" data-record="{!index}">
                                        <lightning:icon iconName="utility:delete" size="small" alternativeText="Delete"/>
                                        <span class="slds-assistive-text">Delete</span>
                                    </a>
                                </td> 
                            </tr>
                        </aura:iteration>
                    </tbody>
                </table>
                <div class="slds-align_absolute-center slds-p-top_small">
                    <lightning:button variant="brand" label="Submit" title="Brand action" onclick="{!c.searchProducts}" />
                </div>
            </div>
        </div>
    </lightning:card>
</aura:component>

==================

JS Controller :

({	
    doInit:function(component, event, helper) {
        
        var action = component.get("c.displayFieldsAndCriteria");
            
        action.setCallback(this, function(response) {
                //get response status 
                var state = response.getState();
                if (state === "SUCCESS") {
                    //set empty account list
                   var respValue=JSON.parse(response.getReturnValue());
                    component.set("v.testAttribute",respValue);
                    //var testValue = component.set("v.testAttribute",response.getReturnValue());
                    var respVal =response.getReturnValue();
                    //console.log('respVal >>> '+respVal);
                    console.log('v.testAttribute value >>>>'+respValue);
                    console.log('criteriaType value >>>>'+respValue.criteriaType);
                    console.log('searchStr value >>>>'+respValue.searchStr);
                   // console.log('fieldNames value >>>>'+JSON.stringify(respValue.fieldNames));
                    //console.log('respValue.fieldNames typeof >>>> '+typeof(respValue.fieldNames));
                    var result=respValue.fieldNames;
                    console.log('result stringified >>>>>> '+result.typeof);
                    component.set("v.productFields",respValue.fieldNames);
                    component.set("v.criteriaType",respValue.criteriaType);
                    /*var criteriaTypeVar= component.get("v.criteriaType");
                    console.log('criteriaTypeVar >>>> '+criteriaTypeVar[0]);
                    var productFieldsVar= component.get("v.productFields");
                    console.log('productFields >>>> '+productFieldsVar);*/
                    alert('data received from class');
                }
            }); 
            $A.enqueueAction(action);

    },
  	
    addRow: function(component, event, helper) {
        //get the List from component  
        var pwList = component.get("v.prodWrapper");
        
        //Add New criteria
        pwList.push({
            'fieldNames': '',
            'criteriaType': '',
            'searchStr': ''
        });
        component.set("v.prodWrapper", pwList);
    },
    
    removeRecord: function(component, event, helper) {

        var criteriaList = component.get("v.prodWrapper");

        var selectedItem = event.currentTarget;
        //Get the selected item index
        var index = selectedItem.dataset.record;
        criteriaList.splice(index, 1);
        component.set("v.prodWrapper", criteriaList);
    },
    
    changeHandler:function(component, event, helper){
    var count=event.target.id;
    console.log('input id >>>> '+count);
	},
    	
   searchProducts: function(component, event, helper) {  
       var a= component.get("v.prodWrapper");
       console.log(a);
        var fName=component.find("PicklistId").get("v.value");
        for(var i=0;i<a.length;i++){
            
                console.log('fName >>>>'+ fName.length);
                a[i].fieldNames=fName;
                console.log('a value >>>> '+JSON.stringify(a));
           
        }
         /*var b= component.find("PicklistId2").get("v.value");
            var c= component.find("PicklistId").get("v.value");*/
        // use compo.find.get for picklist fields and while setting parameters create a json string
        // send the created json string to server
          /*console.log('typeof c>> '+typeof(c) +' '+JSON.stringify(c));
        console.log('typeof b >> '+typeof(b) +' '+JSON.stringify(b));
       console.log('typeof a >> '+typeof(a) +' '+JSON.stringify(a));*/
        var action = component.get("c.generateQuery");
            action.setParams({
                "prodWrapList": JSON.stringify(component.get("v.prodWrapper"))
            });
        action.setCallback(this, function(response) {
                //get response status 
                var state = response.getState();
                if (state === "SUCCESS") {
                    //set empty account list
                    component.set("v.prodWrapper", []);
                    alert('data sent to generateQuery');
                }
            }); 
            $A.enqueueAction(action);
       
    }
})





 
Hi All,

Ia m working on a scenario where i need to submit a record for approval through a javascript button. I have tried submitting it for approval as a partner user but i always get an error message when i trigger it from the custom button. I thought of using process builder but that will again affect the order of execution as there are a couple of workflows and triggers running and this might mess it up.
I tried submitting the record through anonymous window and through batch and it got successfully submitted. Based on my understanding i am thinking that it is an issue with the user submitting it and scheduling is the only option. Any workarounds/suggestions will be of much help to me.
Below is the error message and the code i have worked on :
First error: Process failed. First exception on row 0; first error: NO_APPLICABLE_PROCESS, No applicable approval process was found.: []
//below is the code which i have altered so submit approval request from partner portal

webservice static string thresholdMetCheck (Id DemoId, String DemoAmount){         

         String ret ='';
         String totDemoAmount;
         totDemoAmount = DemoAmount.replace('$','').replace(',','').replace('USD','').replace('CNY','').replace('EUR','').replace('GBP','').replace('JPY','');
         Schema.DescribeSObjectResult drDescribe = Schema.SObjectType.Demo_Registration__c; 
         Map<String,Schema.RecordTypeInfo> rtMapByNamedr= drDescribe.getRecordTypeInfosByName();
         String approvalPhaseRT = rtMapByNamedr.get('Approval Phase').getRecordTypeId();
         if(double.valueof(totDemoAmount) >= double.valueof(System.Label.Threshold_Amount )){
             ret = 'true';
             Demo_Registration__c dr = [Select id, CreatedById, Approval_Status__c,Partner_Account__r.OwnerId,Distribution_Manager__c from Demo_Registration__c where id=:DemoId];
            List<QueueSObject> newDRQ=[select id, QueueId, SObjectType from QueueSObject where SObjectType='Demo_Registration__c' and QueueId = :System.Label.New_Design_Reg_QueueId];
            //There should be only one queue for Demo_Registration__c
            if(newDRQ.size()>1){
                ApexPages.Message errmsg=new ApexPages.Message(ApexPages.Severity.ERROR,'Too many queues on Demo Registration found');
                ApexPages.addMessage(errmsg);
            }else if(newDRQ.size()==0){
                ApexPages.Message errmsg=new ApexPages.Message(ApexPages.Severity.ERROR,'No queue on Demo Registration found');
                ApexPages.addMessage(errmsg);
            }else{

                dr.Approval_Status__c = 'Unsubmitted'; 
                dr.OwnerId = newDRQ.get(0).QueueId;
                dr.RecordTypeId = approvalPhaseRT;
                Demo_Registration__Share drShare = new Demo_Registration__Share(AccessLevel = 'Edit', ParentId = dr.Id, UserOrGroupId = dr.CreatedById);
                try{
                    Database.Saveresult res=Database.update(dr);
                    insert drShare;
                   system.debug('Approval_Status__c in submit logic >>>' +dr.Approval_Status__c);
                }catch(DMLException e){
                    ApexPages.Message errmsg=new ApexPages.Message(ApexPages.Severity.ERROR,e.getMessage());
                    ApexPages.addMessage(errmsg);
                }
                
                system.debug('**********OwnerId' + dr.OwnerId);
            }

            dr.Approval_Status__c='Submitted';
            if(dr.Partner_Account__r.OwnerId!=null){
                  
              dr.OwnerId=dr.Partner_Account__r.OwnerId;
                SYSTEM.DEBUG('Account owner isnt null'); 
            }else{
                SYSTEM.DEBUG('Account owner IS null'); 
                return 'No Partner Account associated with this record';
            }
            dr.RecordTypeId=approvalPhaseRT;    //assigning the appropriate page layout    
            
            try{
                Database.Saveresult reslt=Database.update(dr);
                system.debug('dr >>>>> '+dr);
            }catch(DMLException e){
                system.debug(e.getMessage());
                return 'false';
            }
            
         //create the new approval request to submit
         Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
         req.setComments('Submitted for approval. Please review.');
         req.setObjectId(dr.Id);
         req.setNextApproverIds(new List<Id>{dr.Partner_Account__r.OwnerId});
         // submit the approval request for processing
         Approval.ProcessResult result = Approval.process(req);
         
         }else{
             ret = 'false';
         }
         return ret;
     }





 

Hi All,

I am working on a requirement where i am supposed to display a lightning component embedded in a quick action in a "new tab" instead of a modal popup. The component that i have embedded in the quick action takes the opportunity id as a input and based on a button click i will be saving some child records related to it.
I have tried this link too but it doesn't work https://salesforce.stackexchange.com/questions/158244/how-to-open-lightning-component-tab-from-lightning-quick-action-instead-of-light
Assuming that the code is something like below 

Component :
<aura:component 
    implements="force:appHostable, flexipage:availableForAllPageTypes, flexipage:availableForRecordHome, force:hasRecordId, forceCommunity:availableForAllPageTypes, force:lightningQuickAction">
    <aura:handler name="init" action="{!c.navigateToeDiscoverySearchCmp}" value="{!this}" />
    <aura:attribute name="recordId" type="Id" />
</aura:component>

Controller js :
({
    navigateToeDiscoverySearchCmp : function(component, event, helper) {
        var evt = $A.get("e.force:navigateToComponent");
        evt.setParams({
            componentDef : "c:TestOppAdj",
            recordId: component.get("v.recordId") // this value is not getting set
        });
        evt.fire();
    } 
})
Because the recordId is not getting set i am getting the below issue  else the tables in the below pic would be populated

User-added imageAlso, i am getting something like this in the url /one/one.app#eyJjb21wb25lbnREZWYiOiJjOlRlc3RPcHBBZGoiLCJhdHRyaWJ1dGVzIjp7fSwic3RhdGUiOnt9fQ%3D%3D and not the id .

Can someone tell me where i am going wrong or help me deal with this issue?

Thanks,
Bharath

Hi All,

I am experimenting on salesforce integrations and i am trying to get data from salesforce to an external system.During that i get a prompt like the one below which prompts me to allow or deny.approval during login
My question is that how do i bypass this screen? i.e provide an auto approval either through config or code whenever an external system needs to access a resource from salesforce once it is authenticated.
This is something which happens when i use Web-Server and Useragent flow. Please advise on which is the best flow when it comes to bidirectional integrations(SFDC --> ERP and ERP ---> to SFDC)

Thanks,
Bharath

Hey,

I have following problem - I'm using named credentials with auth provider to send offline conversion to Google Ads.

 

My auth provider setup:

Provider Type - Open ID Connect
Name - Google API
URL Suffix - Google_API
Consumer Key - ***.apps.googleusercontent.com
Authorize Endpoint URL - https://accounts.google.com/o/oauth2/auth?access_type=offline&prompt=consent
Token Endpoint URL - https://www.googleapis.com/oauth2/v4/token
Default Scopes - openid 

 

My named credential setup:

Url - https://adwords.google.com/api/adwords/cm/v201809/OfflineConversionFeedService

Scope - openid https://www.googleapis.com/auth/adwords
Generate Authorization Header - checked

 

My app at google contains redirect_uri from salesforce and in "APIs & Services" I have enabled "Google Ads API".

 

When I edit named credential and "Start Authentication Flow on Save" and enter my google credentials, my integration works for 1 hour. I receive 200 and can see that Google Adwords received my data.

After na hour I receive;

"System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: [AuthenticationError.OAUTH_TOKEN_INVALID @ ; trigger:'&lt;null&gt;'] faultcode=soap:Client faultactor="

 

When I reauthenticate in named credentials once again it start to again work for another hour.

Have you got guys any ideas what I'm doing wrong?

Hi All,

I am working on a PoC where i am consuming data from an external servcie and displaying it on a VF page.
Can someone let me know where i am going wrong and what needs to be done to display the data on the VF page.
public class TickerData {
	
	public list<Prices> pricelist{get;set;}
    private static String endpoint='https://koinex.in/api/ticker';
    
    public list<Prices> getmakeTickerData(){
		
		
		pricelist = new list<Prices>();
        Http http= new Http();
        HttpRequest request= new HttpRequest();
        request.setendpoint(endpoint);
        request.setMethod('GET');
        HttpResponse response = http.send(request); //response contains json body
        
        if(response.getStatusCode()==200){
            system.debug('Response'+response.getBody());
            //JSON2Apex js=JSON2Apex.parse(response.getBody());
            JSONParser parser = JSON.createParser (response.getBody()); 
   			while (parser.nextToken()!=null) { 
                if (parser.getCurrentToken()== JSONToken.START_ARRAY) {    
                    while (parser.nextToken()!= null) { 
                        
                        //
			if(response.getstatusCode() == 200 && response.getbody() != null){

				pricelist=(List<Prices>)json.deserialize(response.getbody(),List<Prices>.class);

			}//
                        /*if (parser.getCurrentToken()== JSONToken.START_OBJECT) { 
                            JSON2Apex the = (JSON2Apex) parser.readValueAs (JSON2Apex.class); 
                        }*/
                  }
            }
			
			
            //Map<String,Object> results=(Map<String,Object>)JSON.deserializeUntyped(response.getBody());
            /*List<Object> prices=(List<Object>)results.get('prices');
            
            for(Object o:prices){
                System.debug('Prices :'+o);
                
            }*/
        	}
        
    	}
        return pricelist;
	}


	public class Prices {
		public String BTC{get;set;}
		public String ETH{get;set;}
		public String XRP{get;set;}
		public String BCH{get;set;}
		public String LTC{get;set;}
		public String NEO{get;set;}
		public Double MIOTA{get;set;}
		public String TRX{get;set;}
		public String OMG{get;set;}
		public String AE{get;set;}
		public String ZRX{get;set;}
		public String GAS{get;set;}
		public String BAT{get;set;}
		public String GNT{get;set;}
		public String REQ{get;set;}
		public String AION{get;set;}
		public String NCASH{get;set;}
		public String XLM{get;set;}
	}
	
    public class JSON2Apex {
		public Prices prices;
		public Stats stats;
	}
    
	public Prices prices;
	public Stats stats;

	public class ETH {
		public String currency_full_form;
		public String currency_short_form;
		public String per_change;
		public Double last_traded_price;
		public String lowest_ask;
		public String highest_bid;
		public String min_24hrs;
		public String max_24hrs;
		public Integer vol_24hrs;
	}

	public class Stats {
		public ETH ETH;
		public ETH BTC;
		public ETH LTC;
		public ETH XRP;
		public ETH BCH;
		public ETH OMG;
		public ETH REQ;
		public ETH ZRX;
		public ETH GNT;
		public ETH BAT;
		public ETH AE;
		public ETH TRX;
		public ETH XLM;
		public ETH NEO;
		public ETH GAS;
		public ETH NCASH;
		public ETH AION;
	}

}
 
VF Page :

<apex:page controller="TickerData">
<apex:form>

<apex:pageBlock >

<apex:pageBlockTable value="{!makeTickerData}" var="wrap" width="100%">
<apex:column headerValue="BTC" value="{!wrap.BTC}"/>
<apex:column headerValue="ETH" value="{!wrap.ETH}"/>
</apex:pageBlockTable>

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

 
Hi,

I need to design approval process we need to send approval for 5 users, 
If 1st user accepts then it need to more 2nd approval then 3rd then 4th then 5th
if any one reject that need to move back 
ex: if 3th rejects need to go to 2nd to approval.

How can we acheive these ?
I cannot complete the challenge in my playground because in the previous module where Knowledge was enabled, the Enable Lightning Knowledge  setting was defaulted to checked, and no instructions specifically indicated to make sure it was unchecked. Now, the steps in the next module cannot be completed. What should I do to move forward?
I have a vf page where i want to add rows every time "add  row" button is clicked..but i am facing some error..when a new row is created previous row's values are automatically copied ..
here is my controller class-
public class SayanTest{
public Service_Type__c acc{get;set;}
public Service_Request__c sr{get;set;}
public Service_Line_Item__c slt;
public List<Service_Line_Item__c> cont{get;set;}
//public List<Work_Order__c> wo{get;set;}
public List<Work_Order__c> wod=new List<Work_Order__c>();
public List<Service_Type__c > accl{get;set;}
//public List<Service_Line_Item__c> cont1{get;set;}
public Boolean showBank{get;set;}
public Boolean showCard{get;set;}
public Boolean showOther{get;set;}
public Boolean showTransfer{get;set;}
public boolean displayPopup {get; set;} 
public boolean flag1 {get;set;}
public String selected {get;set;}
public Boolean tenkservice{get;set;}
public Boolean engineoiltype{get;set;}
public Boolean clutchtype{get;set;}
public Boolean tyretype{get;set;}
public Boolean fanbelt{get;set;}
public Boolean coolant{get;set;}
public Boolean newRow{get;set;}
public Boolean estimation{get;set;}
public Decimal engrate{get;set;}
public Decimal clutchrate{get;set;}
public Decimal tyrerate{get;set;}
public Decimal fanrate{get;set;}
public Decimal coolrate{get;set;}
public Decimal englbr{get;set;}
public Decimal clutchlbr{get;set;}
public Decimal tyrelbr{get;set;}
public Decimal fanlbr{get;set;}
public Decimal coollbr{get;set;}
public Decimal allRateSpare{get;set;}
public Decimal allRateLabour{get;set;}
public Decimal sum{get;set;}
public Decimal count{get;set;}
public Decimal total{get;set;}
public Boolean tyrecount;
public Boolean engcount;
public Boolean clutchcount;
public Boolean fanbeltcount;
public Boolean coolantcount;
public Boolean oilfiltertype{get;set;}
public Decimal s;
public decimal engspare;
public Decimal englabour;
public Decimal engqty{get;set;}
public Decimal englbrqty{get;set;}
public Decimal clutchspare;
public Decimal clutchlabour;
public Decimal clutchspareqty{get;set;}
public Decimal clutchlbrqty{get;set;}
public Decimal tyrespare;
public Decimal tyrelabour;
public Decimal tyrespareqty{get;set;}
public Decimal tyrelbrqty{get;set;}
public Decimal fanbeltspare;
public Decimal fanbeltlabour;
public Decimal fanbeltspareqty{get;set;}
public Decimal fanbeltlbrqty{get;set;}
public Decimal coolantspare;
public Decimal coolantlabour;
public Decimal coolantspareqty{get;set;}
public Decimal coolantlbrqty{get;set;}
public Decimal allspare;
public Decimal alllabour;
public Decimal allspareqty{get;set;}
public Decimal alllbrqty{get;set;}
public Decimal oilfilterspareqty{get;set;}
public Decimal oilfiltersparerate{get;set;}
public Decimal oilfilterlabourqty{get;set;}
public Decimal oilfilterlabourrate{get;set;}
public Integer jobcount;
public Integer i=0;
public SayanTest(ApexPages.StandardController controller) { 
 acc= (Service_Type__c)controller.getRecord();
showBank = false;
      showCard = false;
      showTransfer = false;
      tenkservice=false;
      engineoiltype=false;
      clutchtype=false;
      tyretype=false;
      fanbelt=false;
      coolant=false;
      showOther=false;
      newRow=false;
      estimation=false;
      sum=0;
      s=0;
      count=0;
      total=0;
      engcount=false;
      clutchcount=false;
      engrate=0;
      clutchrate=0;
      tyrerate=0;
      fanrate=0;
      coolrate=0;
      allRateSpare=0;
      englbr=0;
      clutchlbr=0;
      tyrelbr=0;
      fanlbr=0;
      coollbr=0;
      allRateLabour=0;
      tyrecount=false;
      fanbeltcount=false;
      coolantcount=false;
      engspare=0;
      englabour=0;
      clutchspare=0;
      clutchlabour=0;
      tyrespare=0;
      tyrelabour=0;
      fanbeltspare=0;
      fanbeltlabour=0;
      engqty=0;
      englbrqty=0;
      clutchspareqty=0;
      clutchlbrqty=0;
      tyrespareqty=0;
      tyrelbrqty=0;
      fanbeltspareqty=0;
      fanbeltlbrqty=0;
      coolantspareqty=0;
      coolantlbrqty=0;
      allspare=0;
      allspareqty=0;
      alllabour=0;
      alllbrqty=0;
      jobcount=0;
           
    acc = new Service_Type__c ();
    cont = new List<Service_Line_Item__c>();
    accl=new List<Service_Type__c >();
   // wo=new List<Work_Order__c>();
   //wod=new Work_Order__c();
    //cont1= new List<Service_Line_Item__c>();
   // slt=new Service_Line_Item__c();
   
    AddRow();
   

}
public PageReference  AddRow(){
//Service_Type__c  s=new Service_Type__c ();
 Service_Line_Item__c sli=new Service_Line_Item__c();
    cont.add(sli);
   
    
    return null;
}


   
   

}
Hi All,

I am working on converting a vf page to lightning component where i need to display error messages from a constructor.
//Following is the code in the constructor
 catch(exception ex){
        ApexPages.addmessage(new ApexPages.Message(ApexPages.Severity.ERROR,String.ValueOf(ex)));// This is for vf
        
    }

The above code works in VF. But, how do i display the message in a lightning component?

Thanks and Regards,
Bharath Kumar M

Hi All,

I am working on a requirement where the metadata type of the field is datetime and is used in several places. However, in one of the vf pages i need to show only the "date" which needs to be extracted from datetime.

Here's what i tried :
1.) Assign the value from datetime field to a string variable to get the substring.(NOT possible to assign datetime to string)
2.)Assign the value from datetime to date. In this case i get a totally different date value i.e with a difference of almost a month.
Below is the snippet for the same.
 

datetime finishDatetime;// datetime
date finishDate; // date only


finishDatetime= sr.CKSW_BASE__Finish__c;
finishDate=finishDatetime.date();   //This gives me the value of Feb 28th when converted to date along with a string of 0's and GMT where as the original value in the backend is around March 15th.

Any suggestions would be greatly helpful.


Thanks and Regards,
Bharath Kumar M
Hi All,

I tried adding the below piece of code to   the communitieslogin  and sitelogin vf page . Tried several ways and went to help and solutions articles too but that doesn't help. Can someone please help me with adding html / vf tags to the vf page?
<apex:page id="loginPage" controller="CommunitiesLoginController" action="{!forwardToAuthPage}" title="{!$Label.site.site_login}">

 <!--Start - Added by bharath
Below are the lines of code i tried to add
-->
 <apex:outputPanel >
    <apex:outputtext value="For best experience use Google chrome"/>
    <a href="https://www.google.com/chrome/browser/desktop/index.html">Download Chrome</a>
    
    
    </apex:outputPanel> -->
          <!--End - Added by bharath-->

</apex:page>


================================
//Doesn't work in this either


<apex:page id="loginPage" showHeader="false" controller="SiteLoginController" title="{!$Label.site.site_login}">
  <apex:composition template="{!$Site.Template}">
    <apex:define name="body">  
      <center>
        <apex:panelGrid bgcolor="white" columns="1"> 
          <br/>
          <br/>
          <apex:panelGrid width="758" cellpadding="0" cellspacing="0" bgcolor="white" columns="1" styleClass="topPanelContainer"> 
            <br/>
            <apex:outputPanel layout="block" styleClass="topPanel">
              <apex:panelGrid width="758" cellpadding="0" cellspacing="0" bgcolor="white" columns="2"> 
                <apex:image url="{!URLFOR($Resource.SiteSamples, 'img/clock.png')}"/>
                <apex:panelGroup >
                  <br/>
                  <apex:outputText styleClass="title" value="{!$Label.site.login}"/>
                  <br/>
                  <c:SiteLogin id="siteLogin"/>
                  <br/>
                </apex:panelGroup>
              </apex:panelGrid> 
             </apex:outputPanel>
            <c:SitePoweredBy />
          </apex:panelGrid> 
          
          <!--Start - Added by bharath-->
   <!-- <apex:outputPanel rendered="{! IF(userAgent !='Chrome', true,false ) }">
    <apex:outputtext value="For best experience use Google chrome"/>
    <a href="https://www.google.com/chrome/browser/desktop/index.html">Download Chrome</a>
    
    
    </apex:outputPanel> -->
          <!--End - Added by bharath-->
          
       </apex:panelGrid>
      </center>
      <br/>
    </apex:define>
  </apex:composition>
</apex:page>

Thanks,
Bharath
Hi All,

Following is the debug log that i am getting 
(
//list item 1
AppointmentBookingSlot:[BestSlotGrades=(GradeSlotResult:[Grade=100.00000000000000000000000000000000000, HeaderText=ASAP, IconName=clock-o, IsYesOrNoObjective=false, NumberOfAppointmentsWithGrade100=1, Objective=null, ObjectiveRecordTypeName=Objective_Asap, RankInAppointments=1, Text=1486735200000], 
GradeSlotResult:[Grade=100, HeaderText=Minimize Travel, IconName=car, IsYesOrNoObjective=false, NumberOfAppointmentsWithGrade100=24, Objective=null, ObjectiveRecordTypeName=Objective_Minimize_Travel, RankInAppointments=1, Text=null], 
GradeSlotResult:[Grade=100, HeaderText=Preferred Resource, IconName=users, IsYesOrNoObjective=true, NumberOfAppointmentsWithGrade100=24, Objective=null, ObjectiveRecordTypeName=Objective_PreferredEngineer, RankInAppointments=1, Text=null]), Grade=100.000000000000000000000000000000, 
Interval=TimeInterval:[2017-02-10 09:00:00,2017-02-10 11:00:00], SORT_BY_DATE=SORT_BY_DATE, SORT_BY_GRADE=SORT_BY_GRADE, SORT_BY_NO_SORT=SORT_BY_NO_SORT, SortByObjective=null, m_sortBy=SORT_BY_DATE],


// list item 2
AppointmentBookingSlot:[BestSlotGrades=(GradeSlotResult:[Grade=98.85057471264367816091954022988505800, HeaderText=ASAP, IconName=clock-o, IsYesOrNoObjective=false, NumberOfAppointmentsWithGrade100=1, Objective=null, ObjectiveRecordTypeName=Objective_Asap, RankInAppointments=2, Text=1486742400000], 
GradeSlotResult:[Grade=100, HeaderText=Minimize Travel, IconName=car, IsYesOrNoObjective=false, NumberOfAppointmentsWithGrade100=24, Objective=null, ObjectiveRecordTypeName=Objective_Minimize_Travel, RankInAppointments=2, Text=null], GradeSlotResult:[Grade=100, HeaderText=Preferred Resource, IconName=users, IsYesOrNoObjective=true, NumberOfAppointmentsWithGrade100=24, Objective=null, ObjectiveRecordTypeName=Objective_PreferredEngineer, RankInAppointments=2, Text=null]), Grade=99.0804597701149425287356321839080, Interval=TimeInterval:[2017-02-10 11:00:00,2017-02-10 13:00:00], SORT_BY_DATE=SORT_BY_DATE, SORT_BY_GRADE=SORT_BY_GRADE, SORT_BY_NO_SORT=SORT_BY_NO_SORT, SortByObjective=null, m_sortBy=SORT_BY_DATE])

I need to obtain Interval=TimeInterval:[2017-02-10 11:00:00,2017-02-10 13:00:00] and display it on a vf page.
This is a list of object----> i.e a managed package class called "​AppointmentBookingSlot". How can i parse this? 
Can someone provide me the pseudocode (like which data structure should be used to segregate) on how to proceed?

Any inputs would be very much helpful to me.


Thanks and Regards,

Bharath Kumar M

 

Hi All,

I am working on a requirement where a method returns value and that value is used by some other method. But the method is returning object from which i am not able to get any values. How can i convert the object to string? Tried type casting but i am not able to do it.
public static object getCandidates(string serviceId )
   {
        
                CKSW_SRVC.GradeSlotsService candidatesService =         new CKSW_SRVC.GradeSlotsService(getCandidatesSchedulePolicyId(), serviceId)  ;
                system.debug('elad'+candidatesService);
                CKSW_SRVC.AdvancedGapMatrix candidates = candidatesService.GetGradedMatrix(false);
                System.debug('candidates  :: '+candidates );
             
                return candidates;
   }


Debug log received :

//As you can observe the debug log i get is returning values with flower braces in between and not in the beginning so i am not able to extract values from it.

15:40:15:745 USER_DEBUG [1056]|DEBUG|candidates  :: AdvancedGapMatrix:[CPUTimeTook=301, CurrentTime=2017-01-20 10:10:00, ResourceIDToScheduleData={a0Z6C000000ClQuUAK=ResourceScheduleData:[AdditionalObjects=null, CurrentSlotsIndexInAB=0, Resource=CKSW_BASE__Resource__c:{Id=a0Z6C000000ClQnUAK, Name=Test_FT1, CKSW_BASE__Location__c=a0F6C0000008kO2UAI, CKSW_BASE__Contractor__c=false, CKSW_BASE__Active__c=true}, SchedulingOptions=()], a0Z6C000000ClRHUA0=ResourceScheduleData:[AdditionalObjects=null, CurrentSlotsIndexInAB=0, Resource=CKSW_BASE__Resource__c:{Id=a0Z6C000000ClRHUA0, Name=Field Tech 1, CKSW_BASE__Location__c=a0F6C0000008kO2UAI, CKSW_BASE__Contractor__c=false, CKSW_BASE__Active__c=true}, SchedulingOptions=()], a0Z6C000000ClRMUA0=ResourceScheduleData:[AdditionalObjects=null, CurrentSlotsIndexInAB=0, Resource=CKSW_BASE__Resource__c:{Id=a0Z6C000000ClRMUA0, Name=Field Tech 2, CKSW_BASE__Location__c=a0F6C0000008kO2UAI, CKSW_BASE__Contractor__c=false, CKSW_BASE__Active__c=true}, SchedulingOptions=()], a0Z6C000000DykdUAC=ResourceScheduleData:[AdditionalObjects=null, CurrentSlotsIndexInAB=0, Resource=CKSW_BASE__Resource__c:{Id=a0Z6C000000DykdUAC, Name=Field Tech 3, CKSW_BASE__Location__c=a0F6C0000008kO2UAI, CKSW_BASE__Contractor__c=false, CKSW_BASE__Active__c=true}, SchedulingOptions=()], a0Z6C000000E2DpUAK=ResourceScheduleData:[AdditionalObjects=null, CurrentSlotsIndexInAB=0, Resource=CKSW_BASE__Resource__c:{Id=a0Z6C000000E2DpUAK, Name=Field Tech 4, CKSW_BASE__Location__c=a0F6C0000008kO2UAI, CKSW_BASE__Contractor__c=false, CKSW_BASE__Active__c=true}, SchedulingOptions=()]}, Service=CKSW_BASE__Service__c:{Id=a0n6C0000009sURQAY, Name=S-0709, CKSW_BASE__Resource__c=a0Z6C000000DykdUAC, CKSW_BASE__Location__c=a0F6C0000008kO2UAI, CKSW_BASE__Early_Start__c=2017-01-12 12:15:00, CKSW_BASE__Due_Date__c=2017-01-13 21:35:00, CKSW_BASE__Start__c=2017-01-12 16:00:00, CKSW_BASE__Finish__c=2017-01-12 17:30:00, CKSW_BASE__Duration__c=1.50, CKSW_BASE__Duration_Type__c=Hours, CKSW_BASE__Geolocation__Latitude__s=37.806308, CKSW_BASE__Geolocation__Longitude__s=-77.852860, CKSW_BASE__Appointment_Start__c=2017-01-12 16:00:00, CKSW_BASE__Appointment_Finish__c=2017-01-12 18:00:00, CKSW_BASE__Same_Resource__c=false, CKSW_BASE__Same_Day__c=false}]


//I expect the ABOVE debug log to appear in the below format i.e which generally displays list values when debugged. 
15:40:15:750 USER_DEBUG [10]|DEBUG|List of acc(Account:{Id=0016C000003xBCDQA2, Name=Mintus, RecordTypeId=01236000000nZNeAAM}, Account:{Id=0016C000002ZtrgQAC, Name=test, RecordTypeId=01236000000nZNeAAM}, Account:{Id=0016C000002ZyIaQAK, Name=ACME, RecordTypeId=01236000000nZNeAAM}, Account:{Id=0016C000002t9mQQAQ, Name=Reliance, RecordTypeId=0126C00000005xXQAQ}, Account:{Id=0016C000002XuCxQAK, Name=First Services Provider Account, RecordTypeId=01236000000nZNeAAM})

Any suggestions/ solutions on this would be of great help.

Thanks and Regards,
Bharath
I never came across this scenario and I need your input. 

You have a class with sharing, you have another class without sharing, without sharing class is callig a method in with sharing class, how does the sharing context work?


 
Hi Team,

I am new to integration. I need to send PDF files from Salesforce to Netsuite when a checkbox is selected in Salesforce. I just know the approach that I need to convert the pdf to xml format in a restlet. But how to do this. 

Thanks in Advance 
Hi
I need to perform an action on a LWC component when the flow navigates to Next/Finish. Since this component is part of a screen, I cant add my own navigation buttons on this component.
So, Is there any way to listen to the flow's native Navigation events?
Or, the only solution is to override the footer and add my own navigation buttons and use c-pubsub to perform an action on the mentioned component?
Thanks in advanced!
 
How to send multiple files from REST API POST method in a single callout? Please let me know is this possible or not using apex...Or there is a way to achive this.
Hello,

I am working with a developer on a button that pushes several demographic fields from the account object in Salesforce to an external system through API. The form where users will be filling out field values and pressing update is built within a lightning component. It was tested in a sandbox org. and was working, but since it has been pushed into production, the button is no longer worker for any user other than the developer who created the component and pushed it into SF. 

When any user but the developer tries to update the fields and push it into the external system, the push (from the backend where the developer is checking) shows no values (i.e. it is reading the fields as null even though users are putting in updated values) and therefore, nothing is being updated in the external system. I tried to see if there were any differences in permissions between the developer's user account and the other accounts we have been testing with, but have not found any. If anything, the other user accounts we are testing with have more permissions/access within the produciton SF org. than the developer's user account. Additionally, the developer has confirmed that nothing on the component's code has changed since the testing done in the sandbox.

I am wondering if any of you have any suggestions or insight on where I may look to try and troubleshoot this error? Is there any obvious reason why the push is only working for the developer and no other user? Why would the fields being pushed be showing null even when users are filling them in with updated values?

Thanks in advance for any and all help/insight.

Ricki
I want to create a validation rule in case object.
User-added image

Kindly help.
Thanks in advance.
Regards, Prince Sharma
I'm new in apex I tried my best. Here is my requirement We are sending a Post request to External system and we want salesforce fields to go to external system along with external system required fields(Name and Incident_group_id). I'm not able to conctenate Salesforce fields along with external system required field in Json format. Not sure what is wrong in the code. I'm calling this code in trigger. sorry for messy code, still trying to figure out apex. It doesn't send Json object (Patient satisfaction) it just sends incident_group_id and Name(both external system fields)

public class RadarUpdate {
@future (callout=true)
public static void postcallout(string id) { 
List<Patient_Satisfaction__c> PrIds = new list<Patient_Satisfaction__c>();
List<Patient_Satisfaction__c> PrRecord  = [select id, Name, Reporter_First_Name__c, Reporter_Last_Name__c, 
Reporter_Phone__c, Description_of_Feedback__c from Patient_Satisfaction__c where id IN :PrIds ] ;
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeFieldName('Patient satisfaction');
gen.writeStartArray();
for (Patient_Satisfaction__c  patientSatisfaction : PrRecord) {
gen.writeStartObject();
gen.writeObjectField('First name', patientSatisfaction.Reporter_First_Name__c);
gen.writeObjectField('Last name', patientSatisfaction.Reporter_Last_Name__c);
gen.writeObjectField('Phone', patientSatisfaction.Reporter_Phone__c);
gen.writeObjectField('description', patientSatisfaction.Description_of_Feedback__c);gen.writeEndObject();
     } 
gen.writeEndArray();
gen.writeObjectField('incident_group_id',7387);
gen.writeObjectField('Name', 'TestAPI');
gen.writeEndObject();
String jsonS = gen.getAsString();
System.debug('jsonMaterials'+jsonS);
  
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://api.radarfirst.com/incidents');
request.setMethod('POST');
request.setHeader('Content-Type','application/json;charset=UTF-8');
request.setHeader('User-agent', 'Salesforce-integration-client');
request.setHeader('Authorization','Bearer abc');
request.setBody(jsonS);
// Set the body as a JSON object
HttpResponse response = http.send(request);
if (response.getStatusCode() != 422) {
System.debug('The status code returned was not expected: ' +
response.getStatusCode() + ' ' + response.getStatus());
} else {
System.debug(response.getBody());
}
}
}
 

Hey,

I have following problem - I'm using named credentials with auth provider to send offline conversion to Google Ads.

 

My auth provider setup:

Provider Type - Open ID Connect
Name - Google API
URL Suffix - Google_API
Consumer Key - ***.apps.googleusercontent.com
Authorize Endpoint URL - https://accounts.google.com/o/oauth2/auth?access_type=offline&prompt=consent
Token Endpoint URL - https://www.googleapis.com/oauth2/v4/token
Default Scopes - openid 

 

My named credential setup:

Url - https://adwords.google.com/api/adwords/cm/v201809/OfflineConversionFeedService

Scope - openid https://www.googleapis.com/auth/adwords
Generate Authorization Header - checked

 

My app at google contains redirect_uri from salesforce and in "APIs & Services" I have enabled "Google Ads API".

 

When I edit named credential and "Start Authentication Flow on Save" and enter my google credentials, my integration works for 1 hour. I receive 200 and can see that Google Adwords received my data.

After na hour I receive;

"System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: [AuthenticationError.OAUTH_TOKEN_INVALID @ ; trigger:'&lt;null&gt;'] faultcode=soap:Client faultactor="

 

When I reauthenticate in named credentials once again it start to again work for another hour.

Have you got guys any ideas what I'm doing wrong?

Having a problem getting a salesforce access token. Getting the access token works fine in postman, but what I'm trying to do it in C# i'm getting an error.
I've tried to doing the equivlent to what I was doing in postman but I'm not sure if getting this right.
 
var client = new HttpClient();
        string baseAddress = @"https://test.salesforce.com/services/oauth2/token";

        string grant_type = "authorization_code";
        string client_id = "client_id here";
        string client_secret = "client_secret here";
        string auth_url = "https://test.salesforce.com/services/oauth2/authorize";
        string callback_url = "https://app.getpostman.com/oauth2/callback";
        string redirect_uri = "https://app.getpostman.com/oauth2/callback";

        var form = new Dictionary<string, string>
            {
                {"grant_type", grant_type},
                {"client_id", client_id},
                {"client_secret", client_secret},
                {"auth_url", auth_url},
                {"callback_url", callback_url},
                {"redirect_uri", redirect_uri}
            };

        HttpResponseMessage tokenResponse =  client.PostAsync(baseAddress, new FormUrlEncodedContent(form)).GetAwaiter().GetResult();
        var jsonContent =  tokenResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();



This is the error I'm getting:
{ 
"error": "invalid_grant", 
"error_description":"invalid authorization code" 
}

 
HI Everyonce,

Can anyone let me know how to integrate medical devices with salesforce using any middleware tools.
Hi All,

I have created login form with username and passsword.I have created new custom fields in the contact object.
On click of submit button.It will validates the contact is existing or not and returns contact's FirstName,LastName,Email,Phone.

For this I created a RESTAPI which will take the username and password as a parameters and validates against the credentials and  returns the contact details for that valid user.Login form i have created in my org. using lightning.

Now my challenge is  when the user clicks on submit button it should get the contact details from the RESTAPI and maps with the contact object fields and   reload or refresh the page with contact details and displays the field values FirstName,LastName,Email and Phone.
I am trying to pass the variables or map the variables which are returned from REST API to APEX.

How can I acheive this scenario.Do I need to create another lightning component to refresh the parent component to child component and returns the login contact details.

If anyone can provide a sample code that would be a great help.

Any help would be greatly appreciated.

Thanks,
Sirisha
Looking for best REST API to upload a file to a record with at least file size 100MB?
 
I have created custom REST API handles POST call, inserts both ContentVersion, ContentDocumentLink records (Base 64 content in request body) manually. But using custom API not able to upload(not able to test) file size more than 23 MB.
 
other way using with standard salesforce REST API, (/services/data/v35.0/chatter/feed-elements)issue is, It's not supporting Base 64 binary data conversion to normal format..

But in salesforce developer guide docs, mentioned that file size limit to upload REST API is 2 GB.
(Copied same lines, links from the articles).
 
  • maximum file size for uploads is 2 GB for ContentVersion objects”,
  • To upload a binary file up to 2 GB (including headers) ”,
  • “Salesforce CRM Content
  • Content and Libraries tabs in Salesforce Classic
  • 2 GB
  • 2 GB (including headers) when uploaded via Chatter REST API
  • 2 GB (including headers) when uploaded via REST API

 
 
 
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_insert_update_blob.htm
 
https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/intro_input.htm
 
https://help.salesforce.com/articleView?id=collab_files_size_limits.htm&type=5
 
 
Let us know if you worked on the requirement “Upload file to record using REST API (file size should support atleast 100 MB)”
 
I'm trying to install the Einstein Discovery Writeback package so we can show recommendations from discovery on custom objects.  But installation keeps failing with this error.  I've tried recompiling with no success.  Is there some other feature or package missing that we need?

Dependent class is invalid and needs recompilation: Class analytics_ed.PredictionUtil : Type is not visible: ConnectApi.SmartDataDiscoveryPredictionIntegration: Dependent class is invalid and needs recompilation: Class analytics_ed.PredictionUtil : Type is not visible: ConnectApi.SmartDataDiscovery
Hi there, I am trying to emulate the "convert lead" action on a custom object of mine which I've made a path for (see below)User-added image

When I click on the final stage in my Path, I would like it to generate a pop-up that will then let me create new records in related objects.  Is this possible?  Here is a picture of what im talking about.

User-added image

If anyone could should me how to do this I would really appreciate it!
How can we write test class for  JWTBearerTokenExchange Class?

Main class is avilble here
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_Auth_JWTBearerTokenExchange.htm
Hi,

I am trying to configure SSO between Salesforce and Ringcentral. When I login to Ringcentral using the SSO option, it redirects me to the Salesforce error screen. On checking the SAML trace, I can see below error:

GET https://domain-name.my.salesforce.com/_nc_external/identity/saml/SamlError?idpError=1605 HTTP/1.1

Any pointers on how to resolve this?

 

I have been trying to connect Salesforce and Google API using server to server application.

 

Intent :- To communicate data between Salesforce and Google Spreadsheet which is hosted in Google Sites and using some Google Forms, Google scripts and triggers to update data.

 

So, for doing this I need a server to server application model from Google as it wouldnt require a consent from user while its communicating data. for doing this I need to create a JWT and pass it to Google to get the token and proceed with the next steps.

 

JWT for Google requires a RSA with SHA256 signing of the msg using the private key that google has provided in the certificate when I created the server to server application in Google.

I havent found this info anywhere till now :(

In salesforce, we have a crypto class in which can sign with RSA SHA1 (or) generate digest with SHA256, I tried generating a digest using SHA256 and signing that digest usng RSA and the private key given by google. Even thats not working.

 

Google isnt accepting my assertion values (JWT) and its returning an invalid Grant message.

 

I have seen that Jeff douglas has posted some information about this here :-http://blog.jeffdouglas.com/2010/07/06/using-rsa-sha1-with-salesforce-crypto-class/

But unfortunately he has mentioned about domain model and asking us to upload a certificate to google, which i dont want to do or which is not my scenario.

 

Also Google requires a UT8 base64 URL encoded value at all places as mentioned in this link :-https://developers.google.com/accounts/docs/OAuth2ServiceAccount#libraries But salesforce has a separate URL encoding and a separate base64encoding method available in the EncodingUtil class.

 

I have a C# dotnet application which is generating the same value and its able to hit Google and get the value properly. But uses the certificate file and gets the privatekey directly. I used openssl to retrieve the privatekey from the .p12 certificate file provided by Google and have pasted it in my code. I am sure there is some problem in the signing part, because when I compare the values generated by my .NET application and Salesforce Apex code, its returning correct values, but when it comes to the signature part, the length is also same for the returned data (signature) from both .NET and SF but Google returns an invalid grant while calling from SF but returns a bearer token when I call it from my .NET application.

 

public class TestRestAPICall
{
    public class JWTClaimSet
    {
       public string iss {get;set;}
       public string scope {get;set;}
       public string aud {get;set;}
       public Long exp {get;set;}
       public Long iat {get;set;}
       //public string prn {get;set;}
    }

//@future (callout=true)
public static void LoginToGoogle()
{
    //Set your username and password here        
    String clientId = '851234545868.apps.googleusercontent.com';

    //Construct HTTP request and response
    Http http = new Http();
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();


    String JWTHeader =  '{"typ":"JWT","alg":"RS256"}';
    //String Base64EncodedJWTHeader = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9'; //To encode later using code

    //Taken from .net application
// Since the information is going to be same, I have encoded it already in .NET and using it here
    String Base64EncodedJWTHeader = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9';
// Salesforce returns time in milliseconds, so we are dividing it by 1000 to set the seconds value instead of milliseconds value
    Long expires_at = math.roundToLong(DateTime.now().addMinutes(40).getTime() / 1000);
    Long issued_at = math.roundToLong(DateTime.now().addSeconds(-2).getTime() / 1000);
    //Long issued_at = 1372276504;
    //Long Expires_at = 1372279804;

    JWTClaimSet JWT = new JWTClaimSet();
    //JWT.prn = username;
    JWT.iss = '851234545868@developer.gserviceaccount.com';
    JWT.scope = 'https://www.googleapis.com/auth/drive.file';
    JWT.aud = 'https://accounts.google.com/o/oauth2/token';
    JWT.iat = issued_at;
    JWT.exp = expires_at;

    String strJWTJSON = JSON.Serialize(JWT);
    system.debug('Unencoded claimset::'+strJWTJSON);


    Blob ClaimsetBlob = Blob.valueOf(strJWTJSON);
    String Base64EncodedClaimset = EncodingUtil.base64Encode(ClaimsetBlob);
    //Base64EncodedClaimset = PerformPostBase64Encode(Base64EncodedClaimset);
    system.debug('Base64 Encoded Claimset::'+Base64EncodedClaimset);

    // constructing the base64 encoded string to sign it
    string Base64EncodedString = Base64EncodedJWTHeader + '.' + Base64EncodedClaimset;


    // Steps to sign the base64Encoded string
    String algorithmName = 'RSA';
    String key = 'MIICXAIBAAKBgQCi16h+5TeQU5Fo0DlR6+YmrzYXZ7DLxz+dBEnB8Hj0gznqlz8p7nQ7I4AV/SfiJQ6JbU16sKS5IW7Hob5ieW1DfwxYZeCSBPbEkt7eASrI8xqGU5RVewaQivY3vO+avgSSUT+ZU243XsDvZJQlkE3e46FhBvFedDQvuk2iEfgdxQIDAQABAoGAFaO882f4c0h3qUsKYvWLNxbPhFq2Js5KiM4aEximqi+KEb+ZmDPk5Dr6eXGTzDyKav7IbgZtTWDA/OxkhWeHelsMB9LqBq50L6hLHTK4hHecPrT3oN4GviUXh5y5Vt479A1TopjLKdt7V4AnAs0HEWJzar/euUa+T9eODPWPFP0CQQDWQeK2cqzWSVHUpkufp7a0Sc2RvfcIpOf8kRFBLnKiFGr7BscLz6qsaG1M8TyUNMrCquwLSNSDMvPjl6sCjgRPAkEAwpFx8+lspjN0yV5M5XHPmnoddTHwV/8QHoccMBBq0ZMFs2m1E/rFhwMHRBiFN6flbze8src7YnOmmtYqsGizqwJAfqoEtYel1ikST3zgSEqGIJ9hAEAlwt56pz27zaT/8AHSHQUstzbV14cE1u/muFddZyhU03cC62078djAKIp80QJAKMMT3ofOrVsmYnGRJpibZ7+hoEXgFm9nTx37N86YsmNc1GOW/iKRc2GdChUhA7H3DT/eForwtAWKp/Gqa97jlQJBAKjKOIKvdYS9fTpCzs1nUHg9rvVartRR5xxwLH57bBincuSJSBGjwd1FInAh2tgiUGPWGPsplShP87wao9+n9VQ=';
    Blob privateKey = EncodingUtil.base64Decode(key);

    Blob input = Blob.valueOf(Base64EncodedString);
    //Blob SHA256InputBlob = Crypto.generateDigest('SHA-256',input);

    Blob Blobsign = Crypto.sign(algorithmName, input , privateKey);


    // The following line is just for debugging and viewing the blob data in signature as string and its not used anywhere
    String signature = EncodingUtil.urlEncode(EncodingUtil.convertToHex(Blobsign),'UTF-8');

    system.debug('Unencoded signature ::'+signature);
    String base64EncodedSignature = EncodingUtil.base64Encode(Blobsign); 
    //base64EncodedSignature = PerformPostBase64Encode(base64EncodedSignature);
    system.debug('Base 64 encoded signature ::'+base64EncodedSignature );

    system.debug('Encoded assertion : ' + Base64EncodedString+'.'+base64EncodedSignature);

    string URLEncodedUTF8GrantType = encodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer','UTF-8');
    string URLEncodedUTF8Assertion = encodingUtil.urlEncode(Base64EncodedString+'.'+base64EncodedSignature,'UTF-8');        

    system.debug('URLEncodedUTF8GrantType : ' + URLEncodedUTF8GrantType);
    system.debug('URLEncodedUTF8Assertion : ' + URLEncodedUTF8Assertion);

    //Making the call out
    req.setEndpoint('https://accounts.google.com/o/oauth2/token');
    req.setMethod('POST');
    //req.setHeader('Content-Length', '-1');
    req.setHeader('Content-Type','application/x-www-form-urlencoded');
    //req.setHeader('grant_type',URLEncodedUTF8GrantType);
    //req.setHeader('assertion',URLEncodedUTF8Assertion);
    req.setBody('grant_type='+URLEncodedUTF8GrantType+'&assertion='+URLEncodedUTF8Assertion);
    res = http.send(req);
    system.debug('Response : '+res.getBody());
}

 public static String PerformPostBase64Encode(String s)
 {
    s = s.Replace('+', '-');
    s = s.Replace('/', '_');
    s = s.Split('=')[0]; // Remove any trailing '='s
    return s;
 }
}

 

 

I have also posted my problem at stackexchange, it would be great if anyone could help me out :-

 

http://salesforce.stackexchange.com/questions/13301/connect-apex-and-google-api-using-jwt-to-retrieve-oauth-2-0-token

Hi 

 

we have a validation rule on Lead object ,we need to make  this validation rule as inactive like do not fire in the trigger which is on task object .the trigger is copying some field values from task  to the lead object.

 

Thanka in advance

  • April 10, 2013
  • Like
  • 2