Skip to content

Instantly share code, notes, and snippets.

@jagmohansingh
Last active April 11, 2021 06:11
Show Gist options
  • Save jagmohansingh/1a947da18b0eb81ba546c49253f88bb1 to your computer and use it in GitHub Desktop.
Save jagmohansingh/1a947da18b0eb81ba546c49253f88bb1 to your computer and use it in GitHub Desktop.
Create Quote using Opportunity Lightning Action
<aura:component controller="CreateQuoteController" implements="force:hasRecordId,force:hasSObjectName,flexipage:availableForRecordHome,force:lightningQuickActionWithoutHeader" access="global" >
<aura:attribute name="recordId" type="String" />
<aura:attribute name="defaults" type="Object" />
<aura:attribute name="editSection" type="List" />
<aura:attribute name="readSection" type="List" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<lightning:notificationsLibrary aura:id="notificationsLibrary" />
<lightning:spinner aura:id="quote_spinner" variant="brand" size="medium" />
<lightning:card iconName="standard:quotes" title="Create Quote">
<lightning:recordEditForm
aura:id="quoteRecordForm"
onsubmit="{!c.handleOnSubmit}"
onsuccess="{!c.handleOnSuccess}"
onerror="{!c.handleOnError}"
objectApiName="Quote"
class="slds-card__body_inner">
<lightning:messages aura:id="messages" />
<!-- editable fields section -->
<div class="slds-section slds-is-open">
<h3 class="slds-section__title slds-theme_shade slds-m-top_small">
<span class="slds-truncate slds-p-horizontal_small">Quote Information</span>
</h3>
<div class="slds-section__content">
<aura:iteration items="{!v.editSection}" var="editField">
<c:DynamicInputField fieldName="{!editField.fieldName}" data="{!v.defaults}" isDisabled="false" isRequired="{!editField.required}" />
</aura:iteration>
</div>
</div>
<!-- read-only fields section -->
<div class="slds-section slds-is-open">
<h3 class="slds-section__title slds-theme_shade slds-m-top_small">
<span class="slds-truncate slds-p-horizontal_small">Additional Information</span>
</h3>
<div class="slds-section__content">
<aura:iteration items="{!v.readSection}" var="readField">
<c:DynamicInputField fieldName="{!readField.fieldName}" data="{!v.defaults}" isDisabled="true" />
</aura:iteration>
</div>
</div>
<div class="slds-m-top_medium">
<lightning:button variant="brand" label="Create" type="submit" />
</div>
</lightning:recordEditForm>
</lightning:card>
</aura:component>
public with sharing class CreateQuoteController {
@AuraEnabled
public static Map<String, Object> getQuoteDefaultValue(String oppId){
Opportunity opp = [
select Id, Name, AccountId
from Opportunity
where Id = :oppId
];
Map<String, Object> defaultValues = new Map<String, Object>();
defaultValues.put('OpportunityId', (Id) oppId);
defaultValues.put('Name', opp.Name);
Set<Id> oppIds = new Set<Id>();
oppIds.add((Id) oppId);
Map<Id, List<OpportunityContactRole>> oppContactRolesMap = getOpportunityContactRoles(oppIds);
List<OpportunityContactRole> oppContactRoles = oppContactRolesMap.get((Id) oppId);
if(oppContactRoles != null && oppContactRoles.size() > 0) {
defaultValues.put('ContactId', oppContactRoles.get(0).ContactId);
}
Map<String, Object> data = new Map<String, Object>();
data.put('defaults', defaultValues);
// get edit and read sections
List<DescribeHelper.SObjectFieldWrapper> editFields = DescribeHelper.getSortedFieldSetFields('Quote', 'Create_Quote_Edit');
List<DescribeHelper.SObjectFieldWrapper> readFields = DescribeHelper.getSortedFieldSetFields('Quote', 'Create_Quote_Read');
data.put('editFields', editFields);
data.put('readFields', readFields);
return data;
}
private static Map<Id, List<OpportunityContactRole>> getOpportunityContactRoles(Set<Id> oppIds) {
Map<Id, List<OpportunityContactRole>> oppContactRolesMap = new Map<Id, List<OpportunityContactRole>>();
List<OpportunityContactRole> contactRoles = [
select Id, ContactId, OpportunityId
from OpportunityContactRole
where OpportunityId IN :oppIds
];
// map opportunity contact roles to opportunity
for(OpportunityContactRole ocr : contactRoles) {
if(!oppContactRolesMap.containsKey(ocr.OpportunityId)) {
oppContactRolesMap.put(ocr.OpportunityId, new List<OpportunityContactRole>());
}
oppContactRolesMap.get(ocr.OpportunityId).add(ocr);
}
return oppContactRolesMap;
}
}
({
doInit: function(component, event, helper) {
var recordId = component.get('v.recordId');
var action = component.get('c.getQuoteDefaultValue');
action.setParams({
'oppId': recordId
});
helper.showSpinner(component);
action.setCallback(this, function(response){
var state = response.getState();
helper.hideSpinner(component);
if(state === 'SUCCESS'){
var data = response.getReturnValue();
component.set('v.defaults', data.defaults);
component.set('v.editSection', data.editFields);
component.set('v.readSection', data.readFields);
} else if(state === 'ERROR'){
var errors = response.getError();
if(errors){
if(errors[0] && errors[0].message){
console.log("Error: " + errors[0].message);
} else if (errors.message) {
console.log("Error: " + errors.message);
}
} else {
console.log("Something went wrong.");
}
}
});
$A.enqueueAction(action);
},
handleOnSubmit: function(component, event, helper) {
helper.showSpinner(component);
// you can set some default fields here as well
// let's you have some fields which you don't want to
// show on the form but still want to set default values
},
handleOnSuccess: function(component, event, helper) {
helper.hideSpinner(component);
var record = event.getParam("response");
component.find("notificationsLibrary").showToast({
"title": "Success",
"variant": "success",
"message": "Quote {0} created.",
"messageData": [
{
url: '/' + record.id,
label: record.fields.Name.value
}
]
});
var navEvent = $A.get("e.force:navigateToSObject");
navEvent.setParams({
"recordId": record.id,
"slideDevName": "related"
});
navEvent.fire();
},
handleOnError: function(component, event, helper) {
helper.hideSpinner(component);
var err = event.getParam('error');
component.find("notificationsLibrary").showToast({
"title": "Error",
"variant": "error",
"message": err.body ? err.body.message : (err.data ? err.data.message : 'Something went wrong.')
});
}
})
({
showSpinner: function(component){
var spinner = component.find('quote_spinner');
$A.util.removeClass(spinner, 'slds-hide');
},
hideSpinner: function(component){
var spinner = component.find('quote_spinner');
$A.util.addClass(spinner, 'slds-hide');
}
})
public with sharing class DescribeHelper {
/**
* This method returns all the fields for FieldSet on an Object sorted by Field Label.
*/
public static List<SObjectFieldWrapper> getSortedFieldSetFields(String sObjectName, String fieldSetName) {
List<SObjectFieldWrapper> objFields = new List<SObjectFieldWrapper>();
//describe the provided sObject
Schema.DescribeSObjectResult res = Schema.getGlobalDescribe().get(sObjectName).getDescribe();
Map<String, Schema.FieldSet> fieldSetMap = res.fieldSets.getMap();
Schema.FieldSet fs = fieldSetMap.get(fieldSetName);
for(Schema.FieldSetMember fsm : fs.getFields()) {
SObjectFieldWrapper sfw = new SObjectFieldWrapper();
sfw.fieldName = fsm.getFieldPath();
sfw.fieldType = fsm.getType().name();
sfw.fieldLabel = fsm.getLabel();
sfw.required = fsm.getRequired() || fsm.getDbRequired();
objFields.add(sfw);
}
objFields.sort();
return objFields;
}
public class SObjectFieldWrapper implements Comparable {
@AuraEnabled
public String fieldName {get; public set;}
@AuraEnabled
public String fieldLabel {get; public set;}
@AuraEnabled
public String fieldType {get; public set;}
@AuraEnabled
public Boolean required {get; public set;}
public Integer compareTo(Object withObj) {
SObjectFieldWrapper compareTo = (SObjectFieldWrapper) withObj;
return fieldLabel.compareTo(compareTo.fieldLabel);
}
}
}
<aura:component access="global">
<aura:attribute name="fieldName" type="String" access="global" />
<aura:attribute name="isRequired" type="Boolean" access="global" />
<aura:attribute name="data" type="List" access="global" />
<aura:attribute name="isDisabled" type="Boolean" access="global" />
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>
<div class="slds-grid slds-gutters_x-small">
<div class="slds-col slds-size_1-of-1 slds-p-top_x-small">
<lightning:inputField aura:id="myInputField" fieldName="{!v.fieldName}" disabled="{!v.isDisabled}" required="{!v.isRequired}" />
</div>
</div>
</aura:component>
({
onRender: function(component, event, helper) {
var defaults = component.get('v.data');
var fieldName = component.get('v.fieldName');
var inputField = component.find('myInputField');
if(defaults && fieldName && inputField) {
inputField.set('v.value', defaults[fieldName]);
}
},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment