diff --git a/command/login.go b/command/login.go
index 4a96090a..a2b58010 100644
--- a/command/login.go
+++ b/command/login.go
@@ -17,6 +17,7 @@ type ScratchFeature enumflag.Flag
const (
PersonAccounts ScratchFeature = iota
+ B2BCommerce
ContactsToMultipleAccounts
FinancialServicesUser
StateAndCountryPicklist
@@ -35,6 +36,7 @@ const (
var ScratchFeatureIds = map[ScratchFeature][]string{
PersonAccounts: {"PersonAccounts"},
+ B2BCommerce: {"B2BCommerce"},
ContactsToMultipleAccounts: {"ContactsToMultipleAccounts"},
FinancialServicesUser: {"FinancialServicesUser"},
StateAndCountryPicklist: {"StateAndCountryPicklist"},
@@ -58,6 +60,7 @@ const (
CommunitiesProduct
HealthCloudProduct
CRMAnalyticsProduct
+ B2BCommerceProduct
)
var ScratchProductIds = map[ScratchProduct][]string{
@@ -65,6 +68,7 @@ var ScratchProductIds = map[ScratchProduct][]string{
CommunitiesProduct: {"communities"},
HealthCloudProduct: {"healthcloud"},
CRMAnalyticsProduct: {"crmanalytics"},
+ B2BCommerceProduct: {"b2bcommerce"},
}
type ScratchEdition enumflag.Flag
@@ -97,6 +101,7 @@ const (
EnableEnhancedNotes ScratchSetting = iota
EnableQuote
NetworksEnabled
+ CommerceEnabled
EnableApexApprovalLockUnlock
PermsetsInFieldCreation
EnableLightningPreviewPref
@@ -106,6 +111,7 @@ var ScratchSettingIds = map[ScratchSetting][]string{
EnableEnhancedNotes: {"enableEnhancedNotes"},
EnableQuote: {"enableQuote"},
NetworksEnabled: {"networksEnabled"},
+ CommerceEnabled: {"commerceEnabled"},
EnableApexApprovalLockUnlock: {"enableApexApprovalLockUnlock"},
PermsetsInFieldCreation: {"permsetsInFieldCreation"},
EnableLightningPreviewPref: {"enableLightningPreviewPref"},
@@ -190,6 +196,7 @@ var scratchCmd = &cobra.Command{
Available Features:
AnalyticsAdminPerms - Enables CRM Analytics admin permissions
+ B2BCommerce - Enables B2B Commerce
Communities - Enables Experience Cloud (Communities)
ContactsToMultipleAccounts - Allows a single Contact to be associated with multiple Accounts
DevelopmentWave - Enables CRM Analytics development features
@@ -206,6 +213,7 @@ Available Features:
WavePlatform - Enables Wave Platform (CRM Analytics)
Available Products:
+ b2bcommerce - B2B Commerce (enables B2BCommerce feature and commerceEnabled setting)
communities - Experience Cloud (enables Communities feature and networksEnabled setting)
crmanalytics - CRM Analytics (enables AnalyticsAdminPerms, WavePlatform, InsightsPlatform, EinsteinAnalyticsPlus, EinsteinBuilderFree, DevelopmentWave)
fsc - Financial Services Cloud (enables PersonAccounts, ContactsToMultipleAccounts, FinancialServicesUser)
@@ -225,6 +233,7 @@ Available Settings (deployed after org creation):
enableEnhancedNotes - Enable Enhanced Notes
enableQuote - Enable Quotes
networksEnabled - Enable Experience Cloud (Communities)
+ commerceEnabled - Enable Commerce
enableApexApprovalLockUnlock - Allow Apex to lock/unlock approval processes
permsetsInFieldCreation - Allow assigning permission sets during field creation
enableLightningPreviewPref - Enable Lightning Experience preview pref
@@ -241,6 +250,7 @@ Examples:
force login scratch --edition Enterprise --product fsc
force login scratch --setting enableEnhancedNotes
force login scratch --setting enableQuote
+ force login scratch --product b2bcommerce
force login scratch --product communities
force login scratch --product crmanalytics
force login scratch --product healthcloud
@@ -317,6 +327,7 @@ func expandProductsToFeatures(products []ScratchProduct, features []ScratchFeatu
CommunitiesProduct: {Communities},
HealthCloudProduct: {HealthCloudAddOn, HealthCloudUser},
CRMAnalyticsProduct: {AnalyticsAdminPerms, WavePlatform, InsightsPlatform, EinsteinAnalyticsPlus, EinsteinBuilderFree, DevelopmentWave},
+ B2BCommerceProduct: {B2BCommerce},
}
featureSet := make(map[ScratchFeature]bool)
@@ -360,6 +371,7 @@ func convertSettingsToStrings(settings []ScratchSetting) []string {
func expandProductsToSettings(products []ScratchProduct, settings []ScratchSetting) []string {
productSettings := map[ScratchProduct][]ScratchSetting{
CommunitiesProduct: {NetworksEnabled},
+ B2BCommerceProduct: {CommerceEnabled},
}
settingSet := make(map[ScratchSetting]bool)
diff --git a/command/login_test.go b/command/login_test.go
index d6d713ec..d68c747e 100644
--- a/command/login_test.go
+++ b/command/login_test.go
@@ -22,6 +22,16 @@ func TestExpandProductsToFeatures_SingleFeature(t *testing.T) {
}
}
+func TestExpandProductsToFeatures_B2BCommerce(t *testing.T) {
+ result := expandProductsToFeatures([]ScratchProduct{}, []ScratchFeature{B2BCommerce}, map[string]string{})
+ if len(result) != 1 {
+ t.Fatalf("Expected 1 feature, got %d", len(result))
+ }
+ if result[0] != "B2BCommerce" {
+ t.Errorf("Expected B2BCommerce, got %s", result[0])
+ }
+}
+
func TestExpandProductsToFeatures_MultipleFeatures(t *testing.T) {
result := expandProductsToFeatures([]ScratchProduct{}, []ScratchFeature{PersonAccounts, ContactsToMultipleAccounts}, map[string]string{})
if len(result) != 2 {
@@ -162,6 +172,16 @@ func TestExpandProductsToFeatures_CommunitiesProduct(t *testing.T) {
}
}
+func TestExpandProductsToFeatures_B2BCommerceProduct(t *testing.T) {
+ result := expandProductsToFeatures([]ScratchProduct{B2BCommerceProduct}, []ScratchFeature{}, map[string]string{})
+ if len(result) != 1 {
+ t.Errorf("Expected 1 feature from b2bcommerce product, got %d", len(result))
+ }
+ if result[0] != "B2BCommerce" {
+ t.Errorf("Expected B2BCommerce, got %s", result[0])
+ }
+}
+
func TestExpandProductsToFeatures_HealthCloudProduct(t *testing.T) {
result := expandProductsToFeatures([]ScratchProduct{HealthCloudProduct}, []ScratchFeature{}, map[string]string{})
if len(result) != 2 {
@@ -226,6 +246,16 @@ func TestExpandProductsToSettings_CommunitiesProduct(t *testing.T) {
}
}
+func TestExpandProductsToSettings_B2BCommerceProduct(t *testing.T) {
+ result := expandProductsToSettings([]ScratchProduct{B2BCommerceProduct}, []ScratchSetting{})
+ if len(result) != 1 {
+ t.Errorf("Expected 1 setting from b2bcommerce product, got %d", len(result))
+ }
+ if result[0] != "commerceEnabled" {
+ t.Errorf("Expected commerceEnabled, got %s", result[0])
+ }
+}
+
func TestExpandProductsToSettings_CommunitiesProductWithAdditionalSetting(t *testing.T) {
result := expandProductsToSettings([]ScratchProduct{CommunitiesProduct}, []ScratchSetting{EnableEnhancedNotes})
if len(result) != 2 {
@@ -281,6 +311,42 @@ func TestScratchEditionIds_AllEditionsDefined(t *testing.T) {
}
}
+func TestScratchFeatureIds_AllFeaturesDefined(t *testing.T) {
+ expectedFeatures := map[string]bool{
+ "AnalyticsAdminPerms": true,
+ "B2BCommerce": true,
+ "Communities": true,
+ "ContactsToMultipleAccounts": true,
+ "DevelopmentWave": true,
+ "EinsteinAnalyticsPlus": true,
+ "EinsteinBuilderFree": true,
+ "EventLogFile": true,
+ "FinancialServicesUser": true,
+ "HealthCloudAddOn": true,
+ "HealthCloudUser": true,
+ "ApexUserModeWithPermset": true,
+ "InsightsPlatform": true,
+ "PersonAccounts": true,
+ "StateAndCountryPicklist": true,
+ "WavePlatform": true,
+ }
+
+ if len(ScratchFeatureIds) != len(expectedFeatures) {
+ t.Errorf("Expected %d features, got %d", len(expectedFeatures), len(ScratchFeatureIds))
+ }
+
+ for _, ids := range ScratchFeatureIds {
+ if len(ids) != 1 {
+ t.Errorf("Expected 1 ID per feature, got %d", len(ids))
+ continue
+ }
+ featureName := ids[0]
+ if !expectedFeatures[featureName] {
+ t.Errorf("Unexpected feature: %s", featureName)
+ }
+ }
+}
+
func TestConvertSettingsToStrings_NoSettings(t *testing.T) {
result := convertSettingsToStrings([]ScratchSetting{})
if len(result) != 0 {
@@ -318,6 +384,16 @@ func TestConvertSettingsToStrings_NetworksEnabled(t *testing.T) {
}
}
+func TestConvertSettingsToStrings_CommerceEnabled(t *testing.T) {
+ result := convertSettingsToStrings([]ScratchSetting{CommerceEnabled})
+ if len(result) != 1 {
+ t.Errorf("Expected 1 setting, got %d", len(result))
+ }
+ if result[0] != "commerceEnabled" {
+ t.Errorf("Expected commerceEnabled, got %s", result[0])
+ }
+}
+
func TestConvertSettingsToStrings_EnableApexApprovalLockUnlock(t *testing.T) {
result := convertSettingsToStrings([]ScratchSetting{EnableApexApprovalLockUnlock})
if len(result) != 1 {
@@ -353,6 +429,7 @@ func TestScratchSettingIds_AllSettingsDefined(t *testing.T) {
"enableEnhancedNotes": true,
"enableQuote": true,
"networksEnabled": true,
+ "commerceEnabled": true,
"enableApexApprovalLockUnlock": true,
"permsetsInFieldCreation": true,
"enableLightningPreviewPref": true,
diff --git a/docs/force_login_scratch.md b/docs/force_login_scratch.md
index 3fa08d85..f16d4b5d 100644
--- a/docs/force_login_scratch.md
+++ b/docs/force_login_scratch.md
@@ -8,6 +8,7 @@ Create scratch org and log in
Available Features:
AnalyticsAdminPerms - Enables CRM Analytics admin permissions
+ B2BCommerce - Enables B2B Commerce
Communities - Enables Experience Cloud (Communities)
ContactsToMultipleAccounts - Allows a single Contact to be associated with multiple Accounts
DevelopmentWave - Enables CRM Analytics development features
@@ -24,6 +25,7 @@ Available Features:
WavePlatform - Enables Wave Platform (CRM Analytics)
Available Products:
+ b2bcommerce - B2B Commerce (enables B2BCommerce feature and commerceEnabled setting)
communities - Experience Cloud (enables Communities feature and networksEnabled setting)
crmanalytics - CRM Analytics (enables AnalyticsAdminPerms, WavePlatform, InsightsPlatform, EinsteinAnalyticsPlus, EinsteinBuilderFree, DevelopmentWave)
fsc - Financial Services Cloud (enables PersonAccounts, ContactsToMultipleAccounts, FinancialServicesUser)
@@ -43,6 +45,7 @@ Available Settings (deployed after org creation):
enableEnhancedNotes - Enable Enhanced Notes
enableQuote - Enable Quotes
networksEnabled - Enable Experience Cloud (Communities)
+ commerceEnabled - Enable Commerce
enableApexApprovalLockUnlock - Allow Apex to lock/unlock approval processes
permsetsInFieldCreation - Allow assigning permission sets during field creation
enableLightningPreviewPref - Enable Lightning Experience preview pref
@@ -59,6 +62,7 @@ Examples:
force login scratch --edition Enterprise --product fsc
force login scratch --setting enableEnhancedNotes
force login scratch --setting enableQuote
+ force login scratch --product b2bcommerce
force login scratch --product communities
force login scratch --product crmanalytics
force login scratch --product healthcloud
@@ -96,4 +100,3 @@ force login scratch [flags]
### SEE ALSO
* [force login](force_login.md) - Log into Salesforce and store a session token
-
diff --git a/lib/scratch.go b/lib/scratch.go
index 7f1e5783..8b235a5e 100644
--- a/lib/scratch.go
+++ b/lib/scratch.go
@@ -206,6 +206,7 @@ func buildSettingsMetadata(settings []string) ForceMetadataFiles {
apexSettings := false
userManagementSettings := false
lightningExperienceSettings := false
+ commerceSettings := false
for _, setting := range settings {
switch setting {
@@ -228,6 +229,8 @@ func buildSettingsMetadata(settings []string) ForceMetadataFiles {
true
`
files["unpackaged/settings/Communities.settings"] = []byte(communitiesSettings)
+ case "commerceEnabled":
+ commerceSettings = true
case "enableApexApprovalLockUnlock":
apexSettings = true
case "permsetsInFieldCreation":
@@ -264,6 +267,15 @@ func buildSettingsMetadata(settings []string) ForceMetadataFiles {
files["unpackaged/settings/LightningExperience.settings"] = lexBuffer.Bytes()
}
+ if commerceSettings {
+ var commerceBuffer bytes.Buffer
+ commerceBuffer.WriteString(`
+
+ true
+`)
+ files["unpackaged/settings/Commerce.settings"] = commerceBuffer.Bytes()
+ }
+
return files
}
diff --git a/lib/scratch_test.go b/lib/scratch_test.go
index 9bf65d6a..24281433 100644
--- a/lib/scratch_test.go
+++ b/lib/scratch_test.go
@@ -69,6 +69,29 @@ func TestBuildSettingsMetadata_ExcludesLightningExperienceSettingsWhenUnused(t *
}
}
+func TestBuildSettingsMetadata_AddsCommerceSettings(t *testing.T) {
+ files := buildSettingsMetadata([]string{"commerceEnabled"})
+
+ content, ok := files["unpackaged/settings/Commerce.settings"]
+ if !ok {
+ t.Fatalf("Commerce.settings not generated")
+ }
+ if !strings.Contains(string(content), "true") {
+ t.Errorf("Commerce.settings missing commerceEnabled preference:\n%s", content)
+ }
+ if !strings.Contains(string(content), "