Friday, 22 December 2017

vlocity - omniscript formula to get firstday of current month


Add the below in the formula box to get first day of current month

DATE(
IF(
OR(%Month%==null,%Year%==null),
 MONTH(TODAY())+'/02/'+YEAR(TODAY()),
(%Month%+'/'+'02'+'/'+%Year%)
)
)


Tuesday, 5 December 2017

salesforce - trigger before update



Trigger Code:
==========

trigger UpdateClosedCaseTrigger on Case (before update) {
//before update 
    if(Trigger.isUpdate && Trigger.isBefore){
        UpdateClosedCase_Helper.updateCase(Trigger.new,Trigger.oldMap,Trigger.newMap);
    }
}


Helper Code:
==========

public class UpdateClosedCaseHelper {
    public static boolean skipSuperUserFilter = false;
    public static void updateCase(List<Case> newcaselist,Map<Id,Case> oldMap,Map<Id,Case> newMap){
        if(!skipSuperUserFilter){
            //get current user info
            User u=[SELECT Id,Support_Super_User__c From User WHERE Id=:UserInfo.getUserId()];
            Set<Id> caseIdset=new Set<Id>();
            Map<Id,case> junctionMap=new Map<Id,case>();
            //get all case id's
            for(Case cd:newcaselist){
                caseIdset.add(cd.Id);
                junctionMap.put(cd.Id,cd);
            }
            //query all child cases          
            for(Case c:[SELECT Id, status,(select Id,status from cases) FROM Case WHERE Id IN:caseIdset]){
                //check for value change
                if(oldMap.get(c.Id)!=newMap.get(c.Id)){
                    //case is not going to close
                    if(!newMap.get(c.Id).status.equals('Closed') &&
                      !newMap.get(c.Id).status.equals('Resolved')){
                        if(u.Support_Super_User__c){
                            //update case
                        }
                        else{
                            if(oldMap.get(c.Id).status.equals('Closed'))
                                c.addError('Please contact your Almac Super User to re-open closed cases');
                            else{
                                //update case
                            }
                        }                     
                    }else{
                        //closing or resolving case
                        if((newMap.get(c.Id).status.equals('Closed') || newMap.get(c.Id).status.equals('Resolved')) &&
                           !isAllchildsClosed(c.cases)){                     
                               if(u.Support_Super_User__c){
                                   //update case
                               }
                               else{
                                   if(oldMap.get(c.Id).status.equals('Closed'))
                                       c.addError('Please contact your Almac Super User to re-open closed cases');
                                   else{
                                       //update case
                                   }
                               }
                           }
                        else{
                            junctionMap.get(c.Id).addError('Please close all child cases before Closing/Resolving it');
                        }
                    }
                }
            } 
        }
    }
    public static boolean isAllchildsClosed(List<Case> childs){
        boolean flag=false;
        for(Case c:childs){
            if(!'Closed'.equals(c.Status)){
                flag=true;
                break;
            }
        }
        return flag;
    }
}



Notes:
=====
1.Records will be updated only if Trigger.new list is iterated in helper class. in below case the helper class must contain the below statements, no explicity update statement needed.

for(Case c:newcaselist){
      c.status='Closed';
}


2.Related fields like owner.name, account.name are not available in newcaselist, we need to query them in helper class and all other object fields are available to update in helper class.


 

slds - ui:inputPhone validation



Component.cmp
============

<ui:inputPhone aura:id="phonenumber" class="slds-input" value="{!v.groupAccount.phoneNumber}" placeholder=" " change="{!c.onEnterPhone}" />




Controller.js
=========
 onEnterPhone : function(component, event, helper) {
        try{
        console.log('PortalGroupNew Controller onEnterPhone');
         var inputCmp = component.find("phonenumber");
        var value = inputCmp.get("v.value");
        while(value.includes('+'))
value=value.replace('+','');
        while(value.includes('-'))
        value=value.replace('-','');
        while(value.includes('('))
        value=value.replace('(','');
        while(value.includes(')'))
        value=value.replace(')','');
        // is input numeric?
        if (isNaN(value)) {
            inputCmp.set("v.errors", [{message:"Input not a number: " + value}]);
        } else {
            inputCmp.set("v.errors", null);
        }
        }catch(err){
            console.log('phone validation:'+err.stack);
        }
    }

 

Monday, 4 December 2017

vlocity - onclick javascript button on omniscript dataraptor post action

HTML template Id:  sendEmail.html
element Id: OppUpdateEmailConga

give HTML template Id to the dataraptor post action html template section.


place the below code in omniscript configuration


CUSTOM HTML TEMPLATES:

<style>
.inputpremium{
display:none;
}
.via-slds ng-form.ng-valid span.vlc-asterix.icon-v-asterix:before{
color: #50e3c2
}
    .vlc-slds--tertiary-container{
    visibility:hidden;
    }
    div[comma-value]{
      position:relative;
      font-weight: 600;
    }
    div[comma-value]:before{
      content: attr(comma-value);
      position:absolute;
      left:0;
    }
    div[comma-value] input{
      color:#fff;
    }
    </style>
    <script>
        baseCtrl.prototype.$scope.$root.updatepremium = function() {
            updatecommify();
        }

        baseCtrl.prototype.$scope.$root.sendEmail= function() {
            sendEmail();
        }

</script>
<script type="text/ng-template" id="downloadstepoverride.html">
        <div class="slds-grid vlc-slds-step--container" vlc-slds-window-scroll="test">
 
 
            <section id='{{::child.name}}'
                    ng-show='child.bAccordionActive && child.bAccordionOpen'
                    class="step-step slds-size--1-of-1">
 
                <!-- banner template -->
                <vlc-slds-banner></vlc-slds-banner>
 
                <!-- article when embedded in omniscript -->
                <vlc-slds-embedded-article></vlc-slds-embedded-article>
 
                <form novalidate
                    role='form'
                    stepForm
                    name='{{::bpTree.sOmniScriptId}}-{{$index}}'
                    id='{{::bpTree.sOmniScriptId}}-{{$index}}'
                    vlc-slds-disable-auto-complete="testing"
                    class='slds-grid slds-wrap'>
 
                    <!-- child controls in the step new comment-->
                    <div class='slds-col--padded slds-size--1-of-1'>
                        <div  class="slds-grid slds-wrap slds-grid--pull-padded">
                            <child vlc-slds-change-inline-templates="::child.eleArray[0].propSetMap.showInputWidth"
                                class="slds-size--1-of-1 slds-medium--1-of-1 slds-large-size--{{child.eleArray[0].propSetMap.controlWidth}}-of-12"
                                ng-repeat='child in ::children = child.children'
                                ng-show='::!child.eleArray[0].propSetMap.hide'
                                ng-if='(child.eleArray[0].propSetMap.hide && child.eleArray[0].type!=="Formula")||(!child.eleArray[0].propSetMap.show || evaluateShow(child.eleArray[0], this))'>
                            </child>
                        </div>
                    </div>
 
                    <div class='slds-col--padded slds-size--1-of-1 slds-m-top--medium slds-m-bottom--medium'>
 
                        <div class='slds-grid slds-wrap vlc-slds-button--footer'>
 
                            <div class='vlc-slds--tertiary-container'>
 
                                <div class='vlc-slds-button--tertiary'
                                    ng-if='child.bAccordionActive'
                                    confirmed-click='cancel()'
                                    ng-confirm-click='{{::child.propSetMap.cancelMessage}}'>
                                    {{::child.propSetMap.cancelLabel}}
                                </div>
 
                                <!-- test -->
                                <div ng-show='!child.bHasNext'
                                    class='vlc-slds-button--tertiary'
                                    ng-if='bpTree.scriptState == "saveAndResume" && child.bAccordionActive'
                                    vlc-animation-slider="test"
                                    confirmed-click='completeScript(true)'
                                    ng-confirm-click='{{::child.propSetMap.completeMessage}}'>
                                    {{::child.propSetMap.completeLabel}}
                                </div>
 
 
                                <div class='vlc-slds-button--tertiary'
                                    ng-if='bpTree.propSetMap.allowSaveForLater && bpTree.scriptState !== "review" && child.bAccordionActive'
                                    confirmed-click='saveForLater(child)'
                                    ng-confirm-click='{{::child.propSetMap.saveMessage}}' >
                                    {{::child.propSetMap.saveLabel}}
                                </div>
 
                            </div>
 
                            <div class='slds-size--1-of-1 slds-medium-size--6-of-12'>
 
                                <div class='slds-grid slds-wrap slds-grid--pull-padded vlc-slds-small--size-column' style="justify-content:flex-end">
                     
                        <!-- OMNI:2008 -->
                        <div ng-if='child.bHasPrevious'
                        class='slds-size--1-of-1 slds-medium-size--{{::child.propSetMap.previousWidth}}-of-12 vlc-slds-remote-action--button'>
 
                        <div class="slds-form-element__control">
 
                            <div class="vlc-control-wrapper">
                         
                            <div
                                id="{{::child.name + '_prevBtn'}}"
                                class="slds-box vlc-slds-box--neutral"
                                ng-click='sidebarNav(bpTree.children[bpTree.response.lastStepNo])'
                                aria-hiddens="true"
                                vlc-animation-slider="test"
                                reverse="true">
 
                                <p>
                                {{::child.propSetMap.previousLabel}}
                                </p>
 
                            </div>
 
                            </div>
 
                        </div>
 
                        </div>
 
                                    <div ng-if='child.bHasNext'
                        class='slds-size--1-of-1 slds-medium-size--{{::child.propSetMap.nextWidth}}-of-12 vlc-slds-remote-action--button'>
 
                                        <div class="slds-form-element__control">
 
                                            <div class="vlc-control-wrapper">
 
                                                <div
                                id="{{::child.name + '_nextBtn'}}"
                                ng-click='nextRepeater(child.nextIndex, child.indexInParent)'
                                                    ng-disabled='checkValidity(this, child.index, child.indexInParent, "Step", null, true)'
                                                    vlc-animation-slider='test'
                                                    class='slds-box'>
                                                    <p>{{::child.propSetMap.nextLabel}}</p>
                                                </div>
 
                                            </div>
                                        </div>
 
                                    </div>
 
                                </div>
 
                            </div>
 
                        </div>
 
                    </div>
 
                </form>
            </section>
        </div>
</script>
<script type="text/ng-template" id="dandopremiumoverride.html">
        <div class="slds-col--padded slds-size--1-of-1">
            <ng-form name='loopform'
                     class='slds-form-element vlc-flex vlc-slds-text-block vlc-slds-rte'
                     id='{{::child.eleArray[0].name}}'>
     
                <label class='slds-form-element__label'>
                </label>
     
                <div class="slds-form-element__control">
                    <p>
                        <h5>
                            <strong>&nbsp;</strong>Premium:&nbsp; <strong>&nbsp; &nbsp;{{bpTree.response.QuickQuote.Block1|n.DNOPremium | currency:"USD$"}}&nbsp;</strong>
                        </h5>
                    </p>
                </div>
            </ng-form>
        </div>
</script>
<script type="text/ng-template" id="premiumcalculationoverride.html">
    <div class='slds-col--padded slds-size--1-of-1'>
 
        <ng-form name='loopform'
                 class='slds-form-element vlc-flex vlc-form-group vlc-slds-remote-action--button'
                 ng-repeat='control in child.eleArray'>
 
            <div class="slds-form-element__control">
 
                <div class="vlc-control-wrapper">
 
                    <div id='{{::control.name}}'
                         class='slds-box'
                         title='{{::control.propSetMap.label}}'
                         ng-click='buttonClick(this.bpTree.response, control, this);$root.updatepremium();'>
                        <p>{{::control.propSetMap.label}}</p>
                    </div>
 
                </div>
 
                <div class='vlc-sub-block'></div>
 
            </div>
 
        </ng-form>
 
    </div>
 
</script>
<script type="text/ng-template" id="quickquoteblockoverride.html">
    <div class="slds-col--padded slds-size--1-of-1">
     
            <ng-form name='loopform'
                     class='slds-form-element vlc-flex slds-clearfix vlc-slds-block'
                     id ='{{::control.name}}'
                     ng-repeat='control in child.eleArray' >
     
                <div class="slds-form-element__control">
     
                    <!-- add block label -->
                    <label vlc-slds-toggle="toggle"
                           class="slds-form-element__label slds-clearfix" ng-if="::control.propSetMap.label">
     
                        <slds-svg-icon aria-hidden="true"
                                       sprite="'utility'"
                                       icon="'chevrondown'"
                                       size="'small'"
                                       extra-classes="'vlc-slds-collapse slds-button__icon slds-button__icon--large'">
                        </slds-svg-icon>
     
                        <slds-svg-icon aria-hidden="true"
                                       sprite="'utility'"
                                       icon="'chevronup'"
                                       size="'small'"
                                       extra-classes="'vlc-slds-expand slds-button__icon slds-button__icon--large'">
                        </slds-svg-icon>
     
     
                        <div class="slds-form-element__label--toggleText">
                            {{::control.propSetMap.label}}
                            <span ng-if='!( $first && $last )'>{{control.index+1}}</span>
                        </div>
                     
                        <div class="vlc-slds-control-action__container" vlc-bubble-canceller="testing">
     
                            <span ng-if='::control.propSetMap.repeat'
                                  ng-click='baseCtrl.addItem(this, child, $index)'
                                  aria-hidden="true">
                                {{::customLabels.OmniAdd}}
                            </span>
     
                            <span ng-if='child.eleArray.length > 1'
                                  ng-click='removeDomElement(this, child, $index)'
                                  vlc-slds-remove-item="ng-form.vlc-slds-block"
                                  aria-hidden="true">
                                {{::customLabels.OmniDelete}}
                            </span>
     
                        </div>
     
                    </label>
     
                 
                    <!-- block withing the main grid  ng-hide hides hthe block by default-->
                    <div class='slds-size--1-of-1 ng-hide'
                         vlc-slds-toggle-elem='visible'>
     
                        <div class="vlc-slds-control-action__container" vlc-bubble-canceller="test" ng-if="::!control.propSetMap.label">
     
                            <span ng-if='::control.propSetMap.repeat'
                                  ng-click='baseCtrl.addItem(this, child, $index)'
                                  aria-hidden="true">
                                  Add Alternative
                            </span>
     
                            <span ng-if='child.eleArray.length > 1'
                                  ng-click='removeDomElement(this, child, $index)'
                                  vlc-slds-remove-item="ng-form.vlc-slds-block"
                                  aria-hidden="true">
                                {{::customLabels.OmniDelete}}
                            </span>
     
                        </div>
     
                        <div  class="slds-grid slds-wrap slds-grid--pull-padded">
                            <child vlc-slds-change-inline-templates="::child.eleArray[0].propSetMap.showInputWidth"
                                   class="slds-size--1-of-1 slds-medium--1-of-1 slds-large-size--{{child.eleArray[0].propSetMap.controlWidth}}-of-12"
                                   ng-repeat='child in ::children = control.children'
                                   ng-show='::!child.eleArray[0].propSetMap.hide'
                                   ng-if='(child.eleArray[0].propSetMap.hide && child.eleArray[0].type!=="Formula")||(!child.eleArray[0].propSetMap.show || evaluateShow(child.eleArray[0], this))'>
                            </child>
                        </div>
                    </div>
     
                </div>
     
            </ng-form>
     
        </div>     
</script>
<script type="text/ng-template" id="sendEmail.html">
<div class='slds-col--padded slds-size--1-of-1'>

    <ng-form name='loopform'
             class='slds-form-element vlc-flex vlc-form-group vlc-slds-remote-action--button'
             ng-repeat='control in child.eleArray'>

        <div class="slds-form-element__control">

            <div class="vlc-control-wrapper">

                <div id='OppUpdateEmailConga'
                     class='slds-box'
                     title='{{::control.propSetMap.label}}'
                     ng-click='buttonClick(this.bpTree.response, control, this);$root.sendEmail();'>
                    <p>{{::control.propSetMap.label}}</p>
                </div>

            </div>

            <div class='vlc-sub-block'></div>

        </div>

    </ng-form>


</div>  </script>





CUSTOM JAVASCRIPT:

function updatecommify(){
        setTimeout(updatecommifydelay, 1000);
    }
function updatecommifydelay(){
        var slides = document.getElementsByClassName("inputpremium");
        for (var i = 0; i < slides.length; i++) {
            commify(slides.item(i));
        }
    }
    function commify(target) {
        var value = target.value;
        var chars = value.split("").reverse();
        var withCommas = [];
        for (var i = 1; i <= chars.length; i++) {
            withCommas.push(chars[i - 1]);
            if (i % 3 == 0 && i != chars.length) {
                withCommas.push(",");
            }
        }
        var val = withCommas.reverse().join("");
        val = '$' + val;
        target.parentNode.setAttribute("comma-value", val)
    }
function sendEmail() {
//Custom logic here  //Access to Data JSON with baseCtrl.prototype.$scope.bpTree.response
alert('Quote has been sent');
 }
 

Wednesday, 29 November 2017

Salesforce - Schedulable test class

Add below statements in your test class to verify the test results


@isTest
static void test(){
// Schedule the test job
//Class runs every day at 1 PM.
      String jobId = System.schedule('testBasicScheduledApex','0 0 13 * * ?',     
         new TestScheduledApexFromTestMethod());

      // Get the information from the CronTrigger API object
      CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, 
         NextFireTime
         FROM CronTrigger WHERE id = :jobId];

      // Verify the expressions are the same
      System.assertEquals('0 0 13 * * ?', 
         ct.CronExpression);

      // Verify the job has not run 
      System.assertEquals(0, ct.TimesTriggered);
}

 

Friday, 17 November 2017

salesforce - create record in related list with a detail page button

Create a detail page button associated to execute javascript function selected on Account object and place it in account layout.

place the below code on javascript code to create an opportunity record Account related list

{!REQUIRESCRIPT("/soap/ajax/22.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/22.0/apex.js" )} 
var connection = sforce.connection; 
var newopportunity= new sforce.SObject("Opportunity"); 
newopportunity.Name = "{!Account.Name}"; 
newopportunity.AccountId="{!Account.Id}"; 
newopportunity.StageName="Active"; 
newopportunity.CloseDate=new Date(); 
result = sforce.connection.create([newopportunity]); 
alert(result );



That's it, oncliking the button a record Id will be appeared, refresh the page and you will see a record in the opportunity related list.

vlocity - Launch omniscript from visualforce page

vf page:
=====

<apex:page standardStylesheets="false" showHeader="false" sidebar="false" docType="html-5.0" standardController="vlocity_ins__Household__c"
           extensions="Vlocity_RelationshipGroup" action="{!returnScriptPage}">
    <apex:pageMessages />
</apex:page>
           

controller
=======

public without sharing class Vlocity_RelationshipGroup {
   
    @TestVisible private final string recId{get;set;} 
    public String accessLevel;
   
    public Vlocity_RelationshipGroup(ApexPages.StandardController stdController) {
        //get current record Id       
        recId = stdController.getId();
    }
    public Set<id> retrieveAllAgentIds(String profileName){
        Set<Id> agentId = new Set<id>();
        List<CASE_GroupMembership__c> groupList = [SELECT SFDC_GroupID__c FROM CASE_GroupMembership__c WHERE CASE_Group_Member__c =: UserInfo.getUserId()];
        Set<String> groupMembSet = new Set<String>();
        for(CASE_GroupMembership__c csGrupMem : groupList){
            groupMembSet.add(csGrupMem.SFDC_GroupID__c);
        }
       
        if(!groupList.isEmpty()){ 
            List<CASE_GroupMembership__c> groupOwner = [SELECT SFDC_GroupID__c, CASE_Group_Member__c, CASE_IsGroupOwner__c FROM CASE_GroupMembership__c WHERE SFDC_GroupID__c IN :groupMembSet AND CASE_IsGroupOwner__c = true];
            for(CASE_GroupMembership__c csGrupRec : groupOwner){
                agentId.add(csGrupRec.CASE_Group_Member__c);
            }
        }
        system.debug('agentId'+agentId);
        return agentId;
    }
   
    public pagereference returnScriptPage() {
        PageReference pageRef;
        String profileName = [Select Id,Name from Profile where Id=:userinfo.getProfileId()].Name;
       
        if(profileName == 'Agent' || profileName == 'District Agent'){
            List<CASE_Household_Sharing__c> hhShare = [SELECT CASE_Access_Level__c,CASE_Record_ID__c,CASE_User_ID__c,Id FROM CASE_Household_Sharing__c WHERE CASE_Record_ID__c =: recId AND CASE_User_ID__c =: Userinfo.getUserId()];
            if(!hhShare.isEmpty()){
                accessLevel = hhShare[0].CASE_Access_Level__c;
            }
        }
        else if(profileName == 'Agent Staff' || profileName == 'District Agent Staff'){
            Set<id> agentIdSet = retrieveAllAgentIds(profileName);
            List<CASE_Household_Sharing__c> hhShare = [SELECT CASE_Access_Level__c,CASE_Record_ID__c,CASE_User_ID__c,Id FROM CASE_Household_Sharing__c WHERE CASE_Record_ID__c =: recId AND CASE_User_ID__c IN :agentIdSet];
            for(CASE_Household_Sharing__c hhShareRecord: hhShare){
                if(accessLevel == null || accessLevel == 'Read Only'){
                    accessLevel = hhShareRecord.CASE_Access_Level__c;
                }
            }           
        }
        if(accessLevel == 'Read/Write'){
            pageRef = new PageReference('/apex/vlocity_ins__OmniScriptUniversalPage?id='+recId+'&OmniScriptType=OmniScripts&OmniScriptSubType=Edit%20RelationshipGroup&OmniScriptLang=English&PrefillDataRaptorBundle=&scriptMode=vertical&layout=lightning&ContextId='+recId+'#/');
            pageRef.setRedirect(true);
            return pageRef;
        }
        else{
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Insufficient Privileges to Edit this Group'));
            return null;
        }
    }
    public pagereference returnScriptPage1() {
       
        PageReference pageRef = new PageReference('/apex/vlocity_ins__OmniScriptUniversalPage?id='+recId+'&OmniScriptType=OmniScripts&OmniScriptSubType=Create%20RelationshipGroup&OmniScriptLang=English&PrefillDataRaptorBundle=&scriptMode=vertical&layout=lightning&ContextId='+recId+'#/');
        pageRef.setRedirect(true);
       
        return pageRef;
    }
   
}

Thursday, 5 October 2017

slds - Typeahead block with lightning components

use the component from Basecomponent like this

<aura:component controller="PortalGroupController" >
<aura:handler name="oSelectedRecordEvent" event="c:selectedsObjectRecordEvent" action="{!c.handleComponentEvent}"/>   

<c:PortalTypeAhead searchfield="Name" sObjectAPI="Standard_Industry_Code__c" returnfields="Name,SIC_Description__c" />
</aura:component >

basecontroller.js will be like

 handleComponentEvent : function(component, event, helper) {
        console.log('handleComponentEvent success');
        var selectedAccountGetFromEvent='';
    // get the selected Account record from the COMPONETN event 
        try{
        selectedAccountGetFromEvent = event.getParam("recordByEvent"); 
        }catch(err){
            console.log(err.stack);
        }
       // alert('portagroupNew data: '+selectedAccountGetFromEvent);
        var gpacc = component.get("v.groupAccount");
         gpacc.sic=selectedAccountGetFromEvent;
        component.set('v.groupAccount',gpacc);
       // alert('gp sic: '+gpacc.sic); 
 }

c:PortalTypeAhead.cmp

<aura:component >
    <aura:attribute name="searchfield" type="string" />
    <aura:attribute name="sObjectAPI" type="string" />
    <aura:attribute name="returnfields" type="string" />

   
   <aura:handler name="oSelectedRecordEvent" event="c:selectedsObjectRecordEvent" action="{!c.handleComponentEvent}"/>   
    <div class="slds-grid slds-wrap">
        <div class="slds-size_1-of-1">
            <div class="slds-form-element">
                <div class="slds-form-element__control slds-input-has-icon slds-input-has-icon_right">
                    <lightning:icon class="slds-icon slds-input__icon slds-input__icon_right slds-icon-text-default" iconName="utility:search" size="x-small"/>
                    <input type="text" id="sictxt" class="slds-input searchbar form-control" style="font-size:22px;" placeholder=" Search by SIC code"  onkeyup="{!c.searchKeyChange}"/>
                </div>
            </div>
        </div>
        <div class="slds-size_1-of-1">
            <c:PortalTypeAheadList searchfield="{!v.searchfield}" sObjectAPI="{!v.sObjectAPI}" returnfields="{!v.returnfields}" />
        </div>
    </div>
</aura:component>



PortalTypeAheadcontroller.js

({
    searchKeyChange: function(component, event, helper) {
        var myEvent = $A.get("e.c:PortalTypeAheadEvent");
        myEvent.setParams({"searchKey": event.target.value});
        myEvent.fire();
    }, 
    handleComponentEvent : function(component, event, helper) {
        console.log('handleComponentEvent success');
    // get the selected Account record from the COMPONETN event 
       var selectedAccountGetFromEvent = event.getParam("recordByEvent"); 
        console.log('data: '+selectedAccountGetFromEvent);
        document.getElementById('sictxt').value=selectedAccountGetFromEvent;
       //component.find("sictxt").set("v.selectedRecord" , selectedAccountGetFromEvent);   
 }
})


PortalTypeAheadList.cmp

<aura:component Controller="PortalGroupController">   
    <aura:attribute name="searchfield" type="string" />
    <aura:attribute name="sObjectAPI" type="string" />
    <aura:attribute name="returnfields" type="string" /> 
    <aura:attribute name="hosturl" type="String" />
<aura:handler event="c:PortalTypeAheadEvent" action="{!c.searchKeyChange}" />
    <aura:attribute name="Groups" type="PortalGroupController.CheckCensusWrapper[]" />
    <aura:attribute name="Results" type="Object[]"/>
    <aura:attribute name="oRecord" type="sObject" />
      <aura:registerEvent name="oSelectedRecordEvent" type="c:selectedsObjectRecordEvent"/>
    <Style>
    .search:hover{
        box-shadow: 0 0 11px rgba(33,33,33,.2);
        color:black
    }
    </Style>
    <div aura:id="resultDiv" class="slds-show">
    <aura:iteration items="{!v.Results}" var="result">
             <ui:outputText click="{!c.selectRecord}" class="slds-input slds-box search" value="{!result}"/>
            <!--
            <li data-index="{!ind}" role="presentation" class="slds-box search recordstyle" onclick="{!c.selectRecord}">
                 <span>{!result}</span>
            </li>
-->
            <br />
    </aura:iteration>
    </div>

</aura:component>


PortalTypeAheadListController.js


({
    searchKeyChange: function(component, event) {
        var pillTarget = component.find("resultDiv");
      $A.util.removeClass(pillTarget, 'slds-hide');
      $A.util.addClass(pillTarget, 'slds-show');
       
        var hosturl=decodeURIComponent(window.location.host);
        console.log('hosturl: '+hosturl);
        component.set('v.hosturl',hosturl);
       
        var searchKey = event.getParam("searchKey");
        var action = component.get("c.getTypeAheadData");
        var sobAPI=component.get("v.sObjectAPI");       
        var returnfields=component.get("v.returnfields");
        var searchfield=component.get("v.searchfield");
        console.log('searchKey: '+searchKey);
        action.setParams({
            "searchKey": searchKey,
            "sObjectAPI": sobAPI,
            "returnfields": returnfields,
            "searhfield":searchfield
        });
        action.setCallback(this, function(a) {
           // console.log(JSON.stringify(a.getReturnValue()));
            component.set("v.Results", a.getReturnValue());
        });
        $A.enqueueAction(action);
    },
    selectRecord : function(component, event, helper){
        console.log('selectRecord success');
        try{
      var target = event.getSource(); 
            var txtVal = target.get("v.value") ;
            console.log('Selected Value is '+txtVal); 
    // call the event 
      var compEvent = component.getEvent("oSelectedRecordEvent");
    // set the Selected sObject Record to the event attribute.
         compEvent.setParams({"recordByEvent" : txtVal });
    // fire the event
         compEvent.fire();
             }catch(err){
            console.log(err.stack);
        }
     //hide record
     var pillTarget = component.find("resultDiv");
      $A.util.addClass(pillTarget, 'slds-hide');
      $A.util.removeClass(pillTarget, 'slds-show');
     
    }

})

selectedsObjectRecordEvent.event

<aura:event type="COMPONENT" description="by this event we are pass the selected sObject(lookup list record) in the parent component">
    <aura:attribute name="recordByEvent" type="String"/>
</aura:event>


Apex method will be like


@AuraEnabled
    public static List<String> getTypeAheadData(String searchKey,String sObjectAPI,String returnfields,String searhfield){
        List<String> data=new List<String>();
        String filter1=searchKey.trim();
        String filter=filter1+'%';
        //System.debug('filter :'+filter);
        String qry='SELECT '+returnfields+' FROM '+sObjectAPI+' WHERE '+searhfield+' LIKE :filter';
        System.debug('TypeAheadQuery: '+qry);
        List<String> retfieldslist=new List<String>();
        try{
            if(returnfields.contains(','))
            retfieldslist=returnfields.split(',');
        List<sObject> soblist=Database.query(qry);
            String str='';
            for(sObject s:soblist){
                for(String t:retfieldslist){
                    str+=String.valueOf(s.get(t))+'-';
                }
                str=str.trim();
                str=str.removeEnd('-');
            data.add(str);
                str='';
            }
        }catch(Exception e){
            System.debug('Exception: '+e+'\n'+e.getStackTraceString());
        }
        System.debug('data: '+data);
        return data;       
    }





Wednesday, 4 October 2017

vlocity - Typeahead block construction example

/*
 author: Balayesu
 description:   This class sets select element values dynamically in Dental questions omniscript
*/
global with sharing class DentalQuestionsOmniscriptController implements vlocity_ins.VlocityOpenInterface {
    public String groupId;
    public Boolean invokeMethod(String methodName, Map<String, Object> input, Map<String, Object> outMap, Map<String, Object> options){
        boolean flag=false;
        System.debug('Setting inputSelect options');
        if(methodName.equals('getSICcodes')){
            flag=getSICcodes(input,outMap,options);
        }
        if(methodName.equals('getSICcodesTypeAhead')){
            flag=getSICcodesTypeAhead(input,outMap,options);
        }
        return flag;
    }
 
//get options for select element
    public boolean getSICcodes(Map<String, Object> input, Map<String, Object> outMap, Map<String, Object> options){
        Map<String,String> dupmap=new Map<String,String>();
         List<Map<String,String>> selectoptions=new List<Map<String,String>>();
        String contacttypes='';
        for(Standard_Industry_Code__c c:[SELECT Name FROM Standard_Industry_Code__c where Name!=null]){
         
            contacttypes+=c.Name+';';
         
        }
     
        List<String> ctlist=new List<String>();
        if(contacttypes.contains(';')){
            for(String s:contacttypes.split(';')){
                if(s!='' && s!=null){
                    if(!dupmap.containsKey(s)){
                        ctlist.add(s);
                        dupmap.put(s,s);
                    }
                }
            }
        }
        System.debug('ctlist :'+ctlist);
        for(String s:ctlist){
            selectoptions.add(new Map<String,String>{'name'=>s,'value'=>s});
        }
        System.debug('selectoptions: '+selectoptions);
        outMap.put('options',selectoptions);
        boolean flag=true;
        return flag;
    }
    public boolean getSICcodesTypeAhead(Map<String, Object> input, Map<String, Object> outMap, Map<String, Object> options){
        Map<String,String> dupmap=new Map<String,String>();
         List<Map<String,String>> selectoptions=new List<Map<String,String>>();
        String contacttypes='';     
        try{
            System.debug('input :'+JSON.serialize(input));
            List<Map<String,String>> lookupoptions=new List<Map<String,String>>();
            String filter1;
            //Fetch individual consumer data
            if(input.containsKey('QuestionsStep')){
                Map<String,Object> stepPA=(Map<String,Object>)input.get('QuestionsStep');
                Map<String,Object> memblock=(Map<String,Object>)stepPA.get('SICTypeAhead-Block');
                filter1=(string)memblock.get('SICTypeAhead');
            }
            filter1=filter1.trim();
            string filter=filter1+'%';
            System.debug('filter :'+filter);
         
            for(Standard_Industry_Code__c c:[SELECT Id,Name,SIC_Description__c  FROM Standard_Industry_Code__c where Name LIKE :filter]){
            lookupoptions.add(new Map<String,String>{'SICId'=>String.valueOf(c.id),'SIC'=>String.valueOf(c.Name + ' - ' +c.SIC_Description__c)});
        }     
            system.debug('suggestions: '+lookupoptions);
            outMap.put('suggestions',lookupoptions);
        }catch(exception ex){
            System.debug('The following exception has occurred: ' + ex.getMessage());
            System.debug('Stacktrace -- The following exception has occurred: ' + ex.getStackTraceString());
        }
        return true;
        //====================end of new code ======================
    }
}



Below is the configuration for the typeahead element









Thursday, 28 September 2017

Salesforce - Get All Field API names of a sObject



public String showFields(String sobjectname) {
        //fields.clear();
        String fields='';
        system.debug('name' + sobjectname);
        Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        Map <String, Schema.SObjectField> fieldMap =  schemaMap.get(sobjectname).getDescribe().fields.getMap();
        for(Schema.SObjectField sfield : fieldMap.Values())
        {
            schema.describefieldresult dfield = sfield.getDescribe();
           // system.debug(dfield.getname()+'=>'+dfield.getLabel());
           fields+=dfield.getName()+',';
        }
        fields=fields.removeEnd(',');
        System.debug('fields: '+fields);
        return fields;
    }

Thursday, 21 September 2017

SLDS - ui:inputselect example to display values from salesforce

define  component like this,

<aura:component controller="NewCampaignController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >

 <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="CampSearchDataListWrp" type="NewCampaignController.CampSearchDataListWrapper" />


<ui:inputSelect class="multiple uiInputSelect"  multiple="true" aura:id="ContactType" value="{!v.CampSearchDataListWrp.ContactType}" required="true"/>


<ui:inputSelect aura:id="sic" label="SIC" change="{!c.onSicChange}">
                        <aura:iteration items="{!v.groupAccount.sicCodes}" var="level">
                            <ui:inputSelectOption text="{!level}" label="{!level}"/>
                        </aura:iteration>
                    </ui:inputSelect>


</aura:component>


controller class will be like,

 //get data from apex
          var inputsel = component.find("ContactType");
      var opts=[];
         var action2 = component.get("c.getContactType");
       /* action2.setCallback(this, function(a) {         
        for(var i=0;i< a.getReturnValue().length;i++){
            console.log('value: '+a.getReturnValue()[i]);
            opts.push({"class": "optionClass", label: a.getReturnValue()[i], value: a.getReturnValue()[i]});
        }
        inputsel.set("v.options", opts);
console.log('response data: '+JSON.stringify(response.getReturnValue()));
    });*/
        action2.setCallback(this, function(response) {
            if(component.isValid() && response.getState() === "SUCCESS" ) {
                try{
                console.log('response data: '+JSON.stringify(response.getReturnValue()));
                component.set("v.CampSearchDataListWrp",response.getReturnValue());
                var data=component.get("v.CampSearchDataListWrp");
                    var dt=data.ContactType;
                    for(var x in dt){
                console.log('data: '+dt[x]);
                        opts.push({"class": "optionClass", label: dt[x], value: dt[x]});
                    }
                     inputsel.set("v.options", opts);   
                }catch(err){
                    console.log('Exception:'+err.stack);
                }
            }
        });
        $A.enqueueAction(action2);       



apex controller is like,

global with sharing class NewCampaignController {

  global class CampSearchDataListWrapper{
                                                                     @AuraEnabled
                                                                     public String EmailType{get;set;}
                                                                     @AuraEnabled
                                                                     public String CustomerClass{get;set;}
                                                                     @AuraEnabled
                                                                     public String MemberStatus{get;set;}
                                                                     @AuraEnabled
                                                                     public List<String> ContactType{get;set;}
                                                                   
                                                                 }
                                                               
                                                                 @AuraEnabled
                                                                 public static CampSearchDataListWrapper getContactType(){
                                                                     Map<String,String> dupmap=new Map<String,String>();
                                                                   
                                                                     //get all contact types
                                                                     String contacttypes='';
                                                                     for(Contact c:[SELECT Contact_Types__c FROM Contact where Contact_Types__c!=null]){
                                                                       
                                                                          contacttypes+=c.Contact_Types__c+';';
                                                                           
                                                                          }
                                                                 
                                                                     List<String> ctlist=new List<String>();
                                                                 if(contacttypes.contains(';')){
                                                                         for(String s:contacttypes.split(';')){
                                                                             if(s!='' && s!=null){
                                                                                  if(!dupmap.containsKey(s)){
                                                                                  ctlist.add(s);
                                                                                       dupmap.put(s,s);
                                                                                  }
                                                                             }
                                                                         }
                                                                 }
                                                                 System.debug('ctlist :'+ctlist);
                                                                    CampSearchDataListWrapper csw=new CampSearchDataListWrapper();
                                                                     csw.ContactType=ctlist;
                                                                     return csw;
                                                                 }
}




Thursday, 14 September 2017

SLDS - Tooltip Example

 <div class="slds-grid slds-wrap slds-grid--pull-padded" >
                            <div class="slds-col--padded slds-size--1-of-3 slds-medium-size--1-of-3 slds-large-size--1-of-3">
                                <div class="slds-form-element" onmouseover="{!c.showempinfo}" onmouseout="{!c.hideempinfo}">
                                    <div class="slds-form-element__control slds-input-has-icon slds-input-has-icon_right">                                  
                                        <lightning:icon class="icn slds-icon slds-input__icon slds-input__icon_right slds-icon-text-default" iconName="utility:info" size="small"  />
                                        <ui:inputNumber aura:id="contribution" class="slds-input" value="{!v.groupAccount.employeeContribution}" placeholder="Employee Contribution" />
                                    </div>
                                </div>
                                <div class="slds-popover slds-popover_tooltip slds-nubbin_bottom-left slds-fall-into-ground" role="tooltip" aura:id="empinfo" style="position: absolute; top: -32px; left: 275px;">
                                    <div class="slds-popover__body">
                                       This text will show as a tooltip on placing the mouse over the component. on removing the mouse the tooltip hides itseflf.
                                    </div>
                                </div>
                            </div>
</div>




controller.js

    showempinfo : function(component, event, helper){
        console.log('showempinfo success');
        var cmpTarget=component.find('empinfo');
         $A.util.removeClass(cmpTarget, 'slds-fall-into-ground');
        $A.util.addClass(cmpTarget, 'slds-rise-from-ground');
    },
    hideempinfo : function(component, event, helper){
        console.log('hideempinfo success');
        var cmpTarget=component.find('empinfo');
         $A.util.removeClass(cmpTarget, 'slds-rise-from-ground');
        $A.util.addClass(cmpTarget, 'slds-fall-into-ground');
    }

Tuesday, 12 September 2017

Salesforce - User Trigger

trigger UserTrigger on User (after insert) {  
    Map<Id,Id> userAccMap=new Map<Id,Id>();
    Id novatechprofileId;
    if(trigger.isInsert && trigger.isafter){
        try{
            novatechprofileId=[SELECT Id FROM Profile WHERE NAME='Novatech Customer Community Plus Login User' limit 1].Id;
        }catch(QueryException qe){
            system.debug('unable to get profile for novatech due to '+qe);
        }
        //query new user details
        for(User u:[SELECT Id, ProfileId, IsActive,ContactId,AccountId FROM User WHERE Id IN:Trigger.newMap.keyset()]){              
            //get user profile
            if(novatechprofileId!=null && novatechprofileId==u.ProfileId){
                if(u.AccountId!=null)
                    userAccMap.put(u.Id,u.AccountId);
            }
        }
    }
   //change the user
   UserTriggerHelper.shareRecords(userAccMap);
}



here is the helper class



public class UserTriggerHelper {
    @future
    public static void shareRecords(Map<Id,Id> userAccMap){
        System.debug('userAccMap:'+userAccMap);
        //get accounts from contacts  
        List<Account> parentaccs=[SELECT Id,parentId from Account WHERE Id IN:userAccMap.values()];
        List<Account> childaccs=[SELECT Id,parentId FROM Account WHERE ParentId IN:userAccMap.values()];
        childaccs.addAll(parentaccs);
        System.debug('child acclist: '+childaccs);
        List<AccountShare> outacclist=new List<AccountShare>();
        //Share Account access to it's children
        for(Id userId:userAccMap.keySet()){
            //get all children
            for(Account child:childaccs){
                //check if accid is belongs to useraccmap
                if(child.parentid!=null && (userAccMap.get(userId)==child.parentid)
                   || (userAccMap.get(userId)==child.Id)) {
                       outacclist.add(new AccountShare(AccountId=child.Id,
                                                       UserOrGroupId=userId,
                                                       AccountAccessLevel='Edit',
                                                      OpportunityAccessLevel='None',
                                                      CaseAccessLevel='Edit',
                                                      ContactAccessLevel='Read'));
                   }
            }
        }
        System.debug('sharedlist: '+outacclist);
        try{
            insert outacclist;
        }catch(Exception e){
            System.debug('Unable to share records due to '+e+'\n'+e.getStackTraceString());
        }
    }
}