From 2622f1438519930e9f0f8cd0db51822ed8b2b423 Mon Sep 17 00:00:00 2001 From: Christopher Gary Date: Fri, 2 Apr 2021 22:25:09 -0400 Subject: [PATCH] Initialize Repository --- .eslintignore | 15 +++ .forceignore | 18 +++ .gitignore | 42 +++++++ .prettierignore | 10 ++ .prettierrc | 13 ++ .vscode/extensions.json | 9 ++ .vscode/launch.json | 16 +++ .vscode/settings.json | 7 ++ README.md | 18 +++ config/project-scratch-def.json | 116 ++++++++++++++++++ force-app/main/default/aura/.eslintrc.json | 9 ++ .../classes/OpportunityCloneService.cls | 65 ++++++++++ .../OpportunityCloneService.cls-meta.xml | 5 + force-app/main/default/lwc/.eslintrc.json | 11 ++ .../opportunityCustomClone.html | 3 + .../opportunityCustomClone.js | 3 + .../opportunityCustomClone.js-meta.xml | 5 + manifest/package.xml | 36 ++++++ package.json | 43 +++++++ sfdx-project.json | 11 ++ 20 files changed, 455 insertions(+) create mode 100644 .eslintignore create mode 100644 .forceignore create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 config/project-scratch-def.json create mode 100644 force-app/main/default/aura/.eslintrc.json create mode 100644 force-app/main/default/classes/OpportunityCloneService.cls create mode 100644 force-app/main/default/classes/OpportunityCloneService.cls-meta.xml create mode 100644 force-app/main/default/lwc/.eslintrc.json create mode 100644 force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html create mode 100644 force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js create mode 100644 force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js-meta.xml create mode 100644 manifest/package.xml create mode 100644 package.json create mode 100644 sfdx-project.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..4b69683 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,15 @@ +**/lwc/**/*.css +**/lwc/**/*.html +**/lwc/**/*.json +**/lwc/**/*.svg +**/lwc/**/*.xml +**/aura/**/*.auradoc +**/aura/**/*.cmp +**/aura/**/*.css +**/aura/**/*.design +**/aura/**/*.evt +**/aura/**/*.json +**/aura/**/*.svg +**/aura/**/*.tokens +**/aura/**/*.xml +.sfdx \ No newline at end of file diff --git a/.forceignore b/.forceignore new file mode 100644 index 0000000..7a7923f --- /dev/null +++ b/.forceignore @@ -0,0 +1,18 @@ +# List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status +# More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm +# + +package.xml + +# LWC configuration files +**/jsconfig.json +**/.eslintrc.json + +# LWC Jest +**/__tests__/** + +# Exclude applications +*.appMenu + +# Exclude FlexiPage +*.flexipage \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b336084 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# This file is used for Git repositories to specify intentionally untracked files that Git should ignore. +# If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore +# For useful gitignore templates see: https://github.com/github/gitignore + +# Salesforce cache +.sfdx/ +.localdevserver/ + +# LWC VSCode autocomplete +**/lwc/jsconfig.json + +# LWC Jest coverage reports +coverage/ + +# SOQL Query Results +**/scripts/soql/query-results + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Dependency directories +node_modules/ + +# build and scripts directories +build/ +scripts/ + +# Eslint cache +.eslintcache + +# MacOS system files +.DS_Store + +# Windows system files +Thumbs.db +ehthumbs.db +[Dd]esktop.ini +$RECYCLE.BIN/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..f3720b2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,10 @@ +# List files or directories below to ignore them when running prettier +# More information: https://prettier.io/docs/en/ignore.html +# + +**/staticresources/** +.localdevserver +.sfdx +.vscode + +coverage/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..15683b6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,13 @@ +{ + "trailingComma": "none", + "overrides": [ + { + "files": "**/lwc/**/*.html", + "options": { "parser": "lwc" } + }, + { + "files": "*.{cmp,page,component}", + "options": { "parser": "html" } + } + ] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..7e6cb10 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "salesforce.salesforcedx-vscode", + "redhat.vscode-xml", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "financialforce.lana" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e07e391 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Apex Replay Debugger", + "type": "apex-replay", + "request": "launch", + "logFile": "${command:AskForLogFileName}", + "stopOnEntry": true, + "trace": true + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..76decfb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/.sfdx": true + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..afcda4a --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Salesforce DX Project: Next Steps + +Now that you’ve created a Salesforce DX project, what’s next? Here are some documentation resources to get you started. + +## How Do You Plan to Deploy Your Changes? + +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). + +## Configure Your Salesforce DX Project + +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. + +## Read All About It + +- [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) diff --git a/config/project-scratch-def.json b/config/project-scratch-def.json new file mode 100644 index 0000000..e0f0c52 --- /dev/null +++ b/config/project-scratch-def.json @@ -0,0 +1,116 @@ +{ + "orgName":"Opportunity Clone Dev Org", + "country":"US", + "adminEmail":"cgary@cloudperformer.com", + "edition": "Developer", + "description": "Developer Edition Scratch Org with all features installed.", + "hasSampleData": false, + "features":["API","AuthorApex","BigObjectsBulkAPI","CascadeDelete","CaseClassification", + "ChangeDataCapture","Communities","ConnectedAppToolingAPI","ContactsToMultipleAccounts", + "ContractApprovals","Communities","CustomNotificationType","IoT","DebugApex", + "EnablePRM","Entitlements","EventLogFile","FlowSites","ForceComPlatform", + "GenericStreaming","IdentityProvisioningFeatures","Interaction","LiveMessage", + "Knowledge","LightningSalesConsole","LightningServiceConsole","LiveAgent", + "MarketingUser","OutboundMessageHTTPSession","ProcessBuilder","RecordTypes", + "SalesforceContentUser","SalesforceIdentityForCommunities","SalesUser", + "SAML20SingleLogout","SessionIdInLogEnabled","SingleSignOn","Sites", + "StreamingAPI","ServiceCloud","ServiceUser","Workflow","WorkflowFlowActionFeature", + "WorkThanksPref"], + "settings": { + "accountSettings":{ + "enableAccountHistoryTracking":true, + "enableAccountTeams":true, + "enableContactHistoryTracking":true, + "enableRelateContactToMultipleAccounts":true, + "showViewHierarchyLink":true + }, + "activitiesSettings":{ + "autoRelateEventAttendees":true, + "enableActivityReminders":true, + "enableClickCreateEvents":true, + "enableDragAndDropScheduling":true, + "enableEmailTracking":true, + "enableGroupTasks":true, + "enableListViewScheduling":true, + "enableMultidayEvents":true, + "enableRecurringEvents":true, + "enableRecurringTasks":true, + "enableSidebarCalendarShortcut":true, + "enableSimpleTaskCreateUI":true, + "enableUNSTaskDelegatedToNotifications":true, + "showHomePageHoverLinksForEvents":true, + "showMyTasksHoverLinks":true + }, + "apexSettings":{ + "enableApexApprovalLockUnlock":true, + "enableApexCtrlImplicitWithSharingPref":true, + "enableApexPropertyGetterPref":true, + "enableAuraApexCtrlAuthUserAccessCheckPref":true, + "enableAuraApexCtrlGuestUserAccessCheckPref":true, + "enableMngdCtrlActionAccessPref":true, + "enableNonCertifiedApexMdCrud":true + }, + "communitiesSettings":{ + "enableNetworksEnabled":true + }, + "contractSettings":{ + "autoCalculateEndDate":true, + "notifyOwnersOnContractExpiration":true + }, + "entitlementSettings":{ + "assetLookupLimitedToActiveEntitlementsOnAccount":true, + "assetLookupLimitedToActiveEntitlementsOnContact":true, + "assetLookupLimitedToSameAccount":true, + "assetLookupLimitedToSameContact":true, + "enableEntitlements":true, + "enableEntitlementVersioning":true, + "entitlementLookupLimitedToActiveStatus":true, + "entitlementLookupLimitedToSameAccount":true, + "entitlementLookupLimitedToSameAsset":true, + "entitlementLookupLimitedToSameContact":true + }, + "ioTSettings":{ + "enableIoT":true + }, + "knowledgeSettings":{ + "defaultLanguage":"en_US", + "enableChatterQuestionKBDeflection":true, + "enableCreateEditOnArticlesTab":true, + "enableExternalMediaContent":true, + "enableKnowledge":true, + "enableLightningKnowledge":true, + "showArticleSummariesInternalApp":true, + "showValidationStatusField":true + }, + "liveAgentSettings":{ + "enableLiveAgent":true + }, + "macroSettings":{ + "enableAdvancedSearch":true, + "macrosInFolders":true + }, + "nameSettings":{ + "enableMiddleName":true, + "enableNameSuffix":true + }, + "omniChannelSettings":{ + "enableOmniChannel":true, + "enableOmniSkillsRouting":true + }, + "opportunitySettings":{ + "enableUpdateReminders":true, + "autoActivateNewReminders":true, + "enableOpportunityTeam":true, + "promptToAddProducts":true + }, + "orderSettings": { + "enableOrders":true, + "enableNegativeQuantity":true, + "enableReductionOrders":true, + "enableZeroQuantity":true + }, + "quoteSettings": { + "enableQuote":true + } + } +} \ No newline at end of file diff --git a/force-app/main/default/aura/.eslintrc.json b/force-app/main/default/aura/.eslintrc.json new file mode 100644 index 0000000..b637383 --- /dev/null +++ b/force-app/main/default/aura/.eslintrc.json @@ -0,0 +1,9 @@ +{ + "plugins": ["@salesforce/eslint-plugin-aura"], + "extends": ["plugin:@salesforce/eslint-plugin-aura/recommended", "prettier"], + "rules": { + "func-names": "off", + "vars-on-top": "off", + "no-unused-expressions": "off" + } +} diff --git a/force-app/main/default/classes/OpportunityCloneService.cls b/force-app/main/default/classes/OpportunityCloneService.cls new file mode 100644 index 0000000..da7f4ca --- /dev/null +++ b/force-app/main/default/classes/OpportunityCloneService.cls @@ -0,0 +1,65 @@ +/** + * @description This service exposes methods that contain logic to make cloning an opportunity + * much easier and more functional. + * @author Cloud Performer Inc. + * @version 1.0 + * @group Opportunity Cloning + * @history 2021-04-02 - CJG - Created + */ +public with sharing class OpportunityCloneService { + /** + * @description exception class that is thrown when something happens in the opportunity + * clonde process. + */ + public class CloneException extends System.Exception {} + public static Map opportunityChildrenMap; + static { + List childRelationshipList = + Schema.Opportunity.getSObjectType().getDescribe().getChildRelationships(); + opportunityChildrenMap = new Map(); + for(Schema.ChildRelationship childRel:childRelationshipList) { + Schema.DescribeSObjectResult childObjRes = childRel.getChildSObject().getDescribe(); + opportunityChildrenMap.put(childObjRes.getName(),childObjRes); + } + } + + @AuraEnabled(cacheable=true) + public static List ObtainOpporunityChildRelationships(){ + return new List(opportunityChildrenMap.keySet()); + } + + public static String ObtainQueryStringForOppAndChildren(Id oppRecordId, List relationships) { + String queryString = 'SELECT '; + queryString += String.join(ObtainFieldsForObject('Opportunity'),','); + List subqueryList = new List(); + for(String relationship:relationships){ + Schema.DescribeSObjectResult childObject = opportunityChildrenMap.get(relationship); + String childQueryString = '(SELECT ' + String.join(ObtainFieldsForObject(childObject.getName()),',') + ' FROM '; + childQueryString += relationship + ')'; + subqueryList.add(childQueryString); + } + queryString += ', ' + String.join(subqueryList,',') + 'FROM Opportunity WHERE Id =\'' + oppRecordId + '\''; + + return queryString; + } + /** + * @description this method is responsible for getting the list of fields for a particular object + */ + private static List ObtainFieldsForObject(String objectName) { + List fieldNameList; + List objectListToDescribe = new List{objectName}; + List describeItem = System.Schema.describeSObjects(objectListToDescribe); + if(describeItem.isEmpty()) { + throw new OpportunityCloneService.CloneException('Could not find info for ' + objectName + '.'); + } + Map fieldSObjectMapping = describeItem[0].fields.getMap(); + fieldNameList = new List(); + for(Schema.SObjectField fieldToken:fieldSObjectMapping.values()) { + Schema.DescribeFieldResult fieldTokenDescribe = fieldToken.getDescribe(); + if(fieldTokenDescribe.isCreateable() && fieldTokenDescribe.isUpdateable()) { + fieldNameList.add(fieldTokenDescribe.getName()); + } + } + return fieldNameList; + } +} diff --git a/force-app/main/default/classes/OpportunityCloneService.cls-meta.xml b/force-app/main/default/classes/OpportunityCloneService.cls-meta.xml new file mode 100644 index 0000000..d75b058 --- /dev/null +++ b/force-app/main/default/classes/OpportunityCloneService.cls-meta.xml @@ -0,0 +1,5 @@ + + + 51.0 + Active + diff --git a/force-app/main/default/lwc/.eslintrc.json b/force-app/main/default/lwc/.eslintrc.json new file mode 100644 index 0000000..d679b1d --- /dev/null +++ b/force-app/main/default/lwc/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "extends": ["@salesforce/eslint-config-lwc/recommended", "prettier"], + "overrides": [ + { + "files": ["*.test.js"], + "rules": { + "@lwc/lwc/no-unexpected-wire-adapter-usages": "off" + } + } + ] +} diff --git a/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html new file mode 100644 index 0000000..27e0f69 --- /dev/null +++ b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js new file mode 100644 index 0000000..b08bbe7 --- /dev/null +++ b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js @@ -0,0 +1,3 @@ +import { LightningElement } from 'lwc'; + +export default class OpportunityCustomClone extends LightningElement {} \ No newline at end of file diff --git a/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js-meta.xml b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js-meta.xml new file mode 100644 index 0000000..0416469 --- /dev/null +++ b/force-app/main/default/lwc/opportunityCustomClone/opportunityCustomClone.js-meta.xml @@ -0,0 +1,5 @@ + + + 51.0 + false + \ No newline at end of file diff --git a/manifest/package.xml b/manifest/package.xml new file mode 100644 index 0000000..cb2f64a --- /dev/null +++ b/manifest/package.xml @@ -0,0 +1,36 @@ + + + + * + ApexClass + + + * + ApexComponent + + + * + ApexPage + + + * + ApexTestSuite + + + * + ApexTrigger + + + * + AuraDefinitionBundle + + + * + LightningComponentBundle + + + * + StaticResource + + 51.0 + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..6036983 --- /dev/null +++ b/package.json @@ -0,0 +1,43 @@ +{ + "name": "salesforce-app", + "private": true, + "version": "1.0.0", + "description": "Salesforce App", + "scripts": { + "lint": "npm run lint:lwc && npm run lint:aura", + "lint:aura": "eslint **/aura/**", + "lint:lwc": "eslint **/lwc/**", + "test": "npm run test:unit", + "test:unit": "sfdx-lwc-jest", + "test:unit:watch": "sfdx-lwc-jest --watch", + "test:unit:debug": "sfdx-lwc-jest --debug", + "test:unit:coverage": "sfdx-lwc-jest --coverage", + "prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"", + "prettier:verify": "prettier --list-different \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"" + }, + "devDependencies": { + "@prettier/plugin-xml": "^0.12.0", + "@salesforce/eslint-config-lwc": "^0.7.0", + "@salesforce/eslint-plugin-aura": "^1.4.0", + "@salesforce/sfdx-lwc-jest": "^0.9.2", + "eslint": "^7.6.0", + "eslint-config-prettier": "^6.11.0", + "husky": "^4.2.1", + "lint-staged": "^10.0.7", + "prettier": "^2.0.5", + "prettier-plugin-apex": "^1.6.0" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}": [ + "prettier --write" + ], + "**/{aura|lwc}/**": [ + "eslint" + ] + } +} diff --git a/sfdx-project.json b/sfdx-project.json new file mode 100644 index 0000000..1ac36e6 --- /dev/null +++ b/sfdx-project.json @@ -0,0 +1,11 @@ +{ + "packageDirectories": [ + { + "path": "force-app", + "default": true + } + ], + "namespace": "", + "sfdcLoginUrl": "https://login.salesforce.com", + "sourceApiVersion": "51.0" +}