From 26423a7f339bd023391dc5bd1a9ea0f9de3dec26 Mon Sep 17 00:00:00 2001 From: Christopher Gary Date: Wed, 14 Apr 2021 21:46:10 -0400 Subject: [PATCH] Modification to Services to process Datetime and add error toast --- .forceignore | 11 ++++- README.md | 48 ++++++++++++++----- .../classes/OpportunityCloneService.cls | 4 +- .../opportunityCustomClone.html | 15 +++--- .../opportunityCustomClone.js | 27 +++++++++-- 5 files changed, 77 insertions(+), 28 deletions(-) diff --git a/.forceignore b/.forceignore index e81d1f8..2e8ef3e 100644 --- a/.forceignore +++ b/.forceignore @@ -27,4 +27,13 @@ package.xml *.setting # Exclude FieldSets -*.fieldSet \ No newline at end of file +*.fieldSet + +# Exclude Profiles +*.profile + +# Exclude Custom Fields +*.field + +# Exclude the Opportnity CustomObject +Opportunity.object \ No newline at end of file diff --git a/README.md b/README.md index afcda4a..d8326bc 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,44 @@ -# Salesforce DX Project: Next Steps +# Smart Clone - Opportunity Cloner -Now that you’ve created a Salesforce DX project, what’s next? Here are some documentation resources to get you started. +The purpose of the Smart Clone is to provide the user with the functionality to clone an opportunity, but with added +benefits. -## How Do You Plan to Deploy Your Changes? +- The ability to select only fields that need to be edited during the cloning +- The ability to select fields that must be cleared of their original value +- The ability to clone other child objects than just Opportunity Products -Do you want to deploy a set of changes, or create a self-contained application? Choose a [development model](https://developer.salesforce.com/tools/vscode/en/user-guide/development-models). +The Project consists of the following components: +| Item | Description | +| ---- | ----------- | +| OpportunityCloneService | Apex class that contains the Apex functionality | +| OpporutnityCloneserviceTest | Code coverage and unit test class | +| TestCloneUtility | Utilities used in the Code coverage and unit test class | +| SmartCloneChildList custom label | Custom Label used as a setting to store semi-colon separated list of child objects to select from | +| opportunityCustomClone | Lightning web component that is the visual interface | +| OppCustomCloneAura | Aura Lightning Component that is used to wire to a QuickAction | +| Opportunity.SmartClone QuickAction | The QuickAction button to use on the Opportunity Detail Layout | +| Opportunity.ClonedFields fieldset | the fieldet used to configure displayable and cleared fields for input | -## Configure Your Salesforce DX Project +### Additional Notes -The `sfdx-project.json` file contains useful configuration information for your project. See [Salesforce DX Project Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm) in the _Salesforce DX Developer Guide_ for details about this file. + - This application currently will not support the cloning of a hierarchy of children. This means it is only designed to support + the cloning of direct children to the Opportunity, and the Opportunity itself -## Read All About It +## Setup -- [Salesforce Extensions Documentation](https://developer.salesforce.com/tools/vscode/) -- [Salesforce CLI Setup Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm) -- [Salesforce DX Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm) -- [Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference.htm) +### Prerequisites + +- You need to have the Salesforce CLI installed on your system to follow the install directions. + +### Installed Steps + +1. Clone this repository to your local filesystem. +2. Navigate to the directory created from the clone. +3. Create a 'build' folder in the directory of this cloned repository +4. Convert the project into deployable Metadata API format using the following command `sfdx force:source:convert -r ./force-app/main/default -d ./build/unpackaged/` +5. Zip the 'unpackaged' directory located in the 'build' folder. +6. Deploy the zip file into your instance using the following command `sfdx force:mdapi:deploy -u -f ./build/unpackaged.zip -w 30 --verbose` + 1. Optionally, you can use the `-l RunLocalTests` option if installing into a production instance separately. +7. Once the deployment completes successfully, the components will be installed in your instance. + +### Setup Steps diff --git a/force-app/main/default/classes/OpportunityCloneService.cls b/force-app/main/default/classes/OpportunityCloneService.cls index 73c4201..b59591c 100644 --- a/force-app/main/default/classes/OpportunityCloneService.cls +++ b/force-app/main/default/classes/OpportunityCloneService.cls @@ -32,7 +32,7 @@ public with sharing class OpportunityCloneService { for(Schema.ChildRelationship childRel:childRelationshipList) { if(String.isNotBlank(childRel.getRelationshipName())){ Schema.DescribeSObjectResult childObjRes = childRel.getChildSObject().getDescribe(); - if(!restrictedRelationshipList.isEmpty()){ + if(!restrictedRelationshipList.isEmpty() && restrictedRelationshipList[0] != 'N/A'){ if(restrictedRelationshipList.contains(childObjRes.getName())){ opportunityChildrenMap.put(childRel.getRelationshipName(),childObjRes); } @@ -207,7 +207,7 @@ public with sharing class OpportunityCloneService { returnObj = Date.valueOf(fieldValue); } when DATETIME { - returnObj = Datetime.parse(fieldValue); + returnObj = Datetime.valueOf(fieldValue); } when ID { returnObj = Id.valueOf(fieldValue); diff --git a/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html index 741982d..b4c2c5f 100644 --- a/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html +++ b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html @@ -6,17 +6,14 @@ -
-

Child Records to Clone

-
-
- -
-
+

Child Records to Clone

+ +
List of children records to clone:
+
+
-
diff --git a/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js index 90d1462..9fc6299 100644 --- a/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js +++ b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js @@ -2,6 +2,7 @@ import { LightningElement, api, wire, track } from 'lwc'; import { getObjectInfo } from 'lightning/uiObjectInfoApi'; import { getRecord } from 'lightning/uiRecordApi'; import { NavigationMixin} from 'lightning/navigation'; +import { ShowToastEvent } from 'lightning/platformShowToastEvent'; import OPPORTUNITY_OBJECT from '@salesforce/schema/Opportunity'; import ObtainCloneOpportunityFields from '@salesforce/apex/OpportunityCloneService.ObtainCloneOpportunityFields'; import ObtainChildRelationships from '@salesforce/apex/OpportunityCloneService.ObtainOpporunityChildRelationships'; @@ -17,6 +18,21 @@ export default class OpportunityCustomClone extends NavigationMixin(LightningEle childRelationshipList; recordInfo; childRelationshipDisplayList = []; + toastAttributes = { + "success": { + "title":"Success!", + "message":"Your action was successful", + "variant":"success", + "mode":"dismissable" + }, + "error": { + "title":"Error", + "message":"There was an error attempting to execute your request. {0}", + "messageData":[], + "variant":"error", + "mode":"pester" + } + }; @track childRelationshipSelectionList = []; @wire(getRecord,{recordId:'$recordId',layoutTypes:['Full'],modes:['Edit']}) @@ -27,7 +43,6 @@ export default class OpportunityCustomClone extends NavigationMixin(LightningEle } if(data) { - //window.console.log('Original Data: %s',JSON.stringify(data,null,"\t")); this.recordInfo = data.fields; } } @@ -85,7 +100,6 @@ export default class OpportunityCustomClone extends NavigationMixin(LightningEle fullSelectedList.push(chosenObj); } this.childRelationshipSelectionList = fullSelectedList; - window.console.log('Full Selected List: %s',JSON.stringify(this.childRelationshipSelectionList,null,"\t")); } handleChildSelectionRemoval(evt){ @@ -108,11 +122,15 @@ export default class OpportunityCustomClone extends NavigationMixin(LightningEle window.console.log('Child Relationships Selected: %s',JSON.stringify(childRelList,null,"\t")); CloneOpportunityWithChildren({'oppId':this.recordId,'newValues':fields,'childRelationshipsToClone':childRelList}) .then((results)=>{ - window.console.log('Successful callout. %s',JSON.stringify(results,null,"\t")); this.sendToOpp(results); }) .catch((err)=>{ - window.console.log('There was an error attempting to clone records.'); + let toastInstanceMessage = this.toastAttributes.error; + toastInstanceMessage.messageData.push(err.body.message); + const event = new ShowToastEvent(toastInstanceMessage); + this.dispatchEvent(event); + //window.console.log('There was an error attempting to clone records.'); + //window.console.dir(err.body.message); }); } sendToOpp(oppId){ @@ -131,7 +149,6 @@ export default class OpportunityCustomClone extends NavigationMixin(LightningEle var formFieldsToReturn = []; var fieldRequirementMap = this.requiredFieldMap; if(this.opportunityFields && this.displayedFields && this.recordInfo) { - window.console.log('fieldInfo %s: ', JSON.stringify(this.recordInfo,null,"\t")); this.displayedFields.forEach(fieldName => { let fieldItem = fieldRequirementMap[fieldName]; let fieldDisplay = JSON.parse(JSON.stringify(this.opportunityFields[fieldName]));