PicoZ

Salesforce-Configure-Price-Quote.md

Salesforce-Configure-Price-Quote.md

Introduction

With the Salesforce Configure Price Quote app template you can load raw input data from Salesforce CPQ for the Lead-to-Order process, extracted to either Snowflake or SQl Server using CData Sync. The raw input data is transformed through a series of transformations that take place via dbt (data build tool) and produce the required input data used in Process Mining process apps.

Lead-to-Order process

The Lead-to-Order process is an end to end process which starts with a potential customer's intent to buy a product, up to the fulfillment of this sale. See the illustration below.

Lead Qualification

Once a lead is generated, the lead will go through a qualification process. The objective of this process is to determine whether the lead is most likely to make an actual purchase. Once the lead is qualified this will turn into an actual opportunity for a sale. In Salesforce, this is tracked via the Lead object.

Opportunity Management

As a lead qualifies into an opportunity, the sales team will work on the opportunity together with the potential customer, in order to identify the need and suggest an appropriate product or service which will meet this need. In case the opportunity is won, this will generate one or more orders in order to fulfill the won opportunity. In Salesforce, this is tracked via the Opportunity object, and the Quote object.

Quote Management Once an opportunity moves forward with a customer, products and services will be offered through quotes. In Salesforce CPQ the Quote object contains information about the products and services a customer wants to buy. You can create as many quotes as you want on a given opportunity. However many quotes your opportunity contains, only one can be designated as primary.

Order Management

Within Order management, the order lifecycle is maintained, including order capture, and fulfillment. In Salesforce, the Order object is used to maintain this process. One quote may have multiple orders if the configuration is set in CPQ package.

Contract Management

Contracts are used when orders included at least one subscription product under a contract-based renewal model. Salesforce CPQ creates a contract record for them.

Optionally, this may then extend and generate an invoice and receivables, in what is called the Lead-to-Cash process.

Entity relationship diagram

The following shows all objects that were used for the process. However not all of them would be converted as entities as they were merely used for connecting the entities that actually had activities tracked in the process.

Tags

TagDescription
Amended opportunityOnce a contract is amended a new opportunity is created to keep track of that new piece in the contract. These opportunities are automatically created.
Approval process started multiple timesMultiple approvals may exist for one entity, however if the same approval process is triggered multiple times, there might be inefficiencies to review. Applies for all entities (Lead, Opportunity, Quote, Order, Contract).
Multiple Owner ChangesApplies for all entities (Lead, Opportunity, Quote, Order, Contract), reflects that the owner of that entity has been changed multiple times and that may be justified (vacations, escalations) or may require attention.
Opportunity amount reducedOpportunity Amount was changed to a value less than the original value. Represents an opportunity which is losing value.
Opportunity close date postponedAn opportunity is getting delayed according to its original close date, which means the opportunity might require attention.
Primary quote changed multiple timesThe primary quote in an opportunity is the one that can turn into an order. There might be inefficiencies to review if these changes happen constantly.

Due Dates

Due dateDescription
Original Opportunity Close DateIdentifies original expected close date for the opportunity and verifies against the actual close date.

Salesforce Sales Cloud configuration

Source system

Salesforce Sales Cloud with Salesforce CPQ package. The CPQ package must be installed in the Salesforce Org.

Depending on which fields have field history tracked, different change events will be recorded. Field history tracking can be configured from each object within Salesforce setup. Recommended minimal setup is having the following object and fields tracked:

  • Lead: Status
  • Opportunity: Stagename
  • Quote: Status
  • Order: Status

By default, Field History is disabled per object. In order to setup Field History Tracking for an object, the following Salesforce manual contains a step by step instruction: Salesforce - Track Field History for Standard Objects. Note: if a field is activated for tracking, the values will be tracked from that moment onwards. Any changes before that point in time will not be saved. As of February 2022, Salesforce retains field history data for up to 18 months through the org and up to 24 months via the API, and Field history tracking data doesn't count towards Salesforce org's data storage limits.

In case the history needs to be stored for a longer period of time, Field Audit Trail must be activated. This allows copying of history data into a separate big data object and allows storage for up to 10 years.

Environmental settings

  • To connect via CData Sync, the user establishing the connection must be API Enabled, and must have appropriate read permissions on each of the objects which are being extracted. All fields included in the input tables must be visible for the user extracting the data.
  • The user must be marked as "Marketing User" in the user settings in order to extract Campaign information.
  • To allow users to create multiple orders from a quote, "Allow Multiple Orders" in CPQ Order Package Settings must be selected.
  • In order to calculate amounts using historical exchange rates, Effective dated currency should be enabled in the Salesforce org, and historical exchange rates should be loaded into the system.

System specific settings

The Salesforce Configure Price Quote app template works on the process starting on the marketing campaign generation, up to the generation of customer orders, if the order includes subscription products the process adds contract to track the subscriptions.

This includes processing of the following Salesforce transactional objects:

  • Campaign
  • CampaignMember
  • Lead
  • LeadHistory
  • Opportunity
  • OpportunityFieldHistory
  • Quote (SBQQ__Quote__c)
  • QuoteHistory (SBQQ_Quote_History)
  • Order
  • OrderItem
  • OrderHistory
  • Contract
  • ContractHistory
  • ProcessInstance
  • ProcessInstanceStep

The following additional objects which are used to add additional attribute information into the model:

  • Account
  • RecordType
  • User
  • ProcessDefinition

In case they are used, the following tables add Currency conversion to the model:

  • CurrencyType*
  • DatedConversionRate*

*CurrencyType, DatedExchangeRate objects are by default disabled in Salesforce orgs.

Configuring CData Sync for Salesforce Sales Cloud CPQ

Below is a description on how to use CData Sync to set up a source connection and load data into a Process Mining Salesforce CPQ Lead-to-Order process app.

In general, you should follow the steps as described in Loading data using CData Sync (Snowflake) or Loading data using CData Sync (SQL Server) to set up data loading using CData Sync. Since specific settings are required when using Salesforce CPQ, pay attention to the steps described below.

Setting up the source connection

  • Select Salesforce as the source system to which you want to create a connection from the list.
  • Select Basic as the Auth Scheme.
  • Enter the correct User, Password, Security Token, and Login URL to set up the connection to Salesforce.
  • Set API Version to 52.0 or higher.

Define the following settings in the Replicate Options section in the Advanced tab in the Job Settings panel.

  • Under Destination Schema, setup the target data schema in the SQL Server or Snowflake database.
  • Select the Alter Schema option.
  • Select the Drop Table option.

Important: Make sure you edit the Pre-job Event.

CData Sync allows the use of environment variables in order to drive specific extraction logic in each query.

VariableDescriptionComment
start_extraction_dateDefines first date for which data will be extracted.Mandatory
end_extraction_dateLast date for which data will be extracted.

In order to setup the environment variables:

StepAction
1Access the job created in the previous step.
2Click on the Events tab.
3Add the following lines to the Pre-Job Event script.

<!-- Modify environment variables here. --> <!-- Variable start_extraction_date must be populated.--> <api:set attr="out.env:start_extraction_date" value="2022-01-01" /> <!-- In case a specific end date is needed, replace the value string with the required date in yyyy-MM-dd format. --> <!-- i.e api:set attr="out.env:end_extraction_date" value="2022-02-01" --> <api:set attr="out.env:end_extraction_date" value="[null | now() | todate('yyyy-MM-dd')]" /> <api:push item="out" />

Important: Do not modify the api:info details that are shown by default.

In order to modify the environment variables, modify the values within the Events tab. By default, end_extraction_date will default to today's date. start_extraction_date must always be populated.

Table Replication

Once the job is correctly setup, click on Add Custom Query under the Tables tab and paste the following queries (each query needs to maintain the semicolon at the end). Make sure you save all changes.

Default Extraction

The following script is prepared for scenarios where Currency Conversions and Person Accounts are not used and are disabled. In case any of these are used, please add the scripts in the Alternative Scenarios section.

REPLICATE [Account_raw] SELECT [Id], [AccountSource], [BillingCountry], [BillingState], [CreatedById], [CreatedDate], [Industry], [Name], [OwnerId], [Ownership], [ParentId], [Rating], [Type] FROM [Account]; REPLICATE [Campaign_raw] SELECT [Id], [CreatedById], [CreatedDate], [Name], [OwnerId], [ParentId], [Status], [Type] FROM [Campaign] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [CampaignMember_raw] SELECT [Id], [CampaignId], [CreatedById], [CreatedDate], [LeadId], [Status] FROM [CampaignMember] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [Lead_raw] SELECT [Id], [ConvertedOpportunityId], [CreatedById], [CreatedDate], [Name], [OwnerId] FROM [Lead] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [Opportunity_raw] SELECT [Id], [AccountId], [Amount], [CloseDate], [CreatedById], [CreatedDate], [ForecastCategory], [IsClosed], [IsWon], [LastStageChangeDate], [LeadSource], [Name], [OwnerId], [Probability], [StageName], [Type], [SBQQ__AmendedContract__c] FROM [Opportunity] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [RecordType_raw] SELECT [Id], [Name] FROM [RecordType]; REPLICATE [User_raw] SELECT [Id], [Department], [Name], [UserType] FROM [User]; REPLICATE [ProcessDefinition_raw] SELECT [Id], [Name], [TableEnumOrId], [Type] FROM [ProcessDefinition] WHERE [Type] = 'Approval'; REPLICATE [ProcessInstance_raw] SELECT [Id], [TargetObjectId], [CreatedById], [CreatedDate], [ProcessDefinitionId], [Status] FROM [ProcessInstance] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [ProcessInstanceStep_raw] SELECT [Id], [Comments], [CreatedById], [CreatedDate], [ProcessInstanceId], [StepStatus] FROM [ProcessInstanceStep] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [SBQQ__Quote__c_raw] SELECT [Id], [CreatedById], [CreatedDate], [Name], [SBQQ__Opportunity2__c] FROM [SBQQ__Quote__c] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [Order_raw] SELECT [Id], [CreatedById], [CreatedDate], [Name], [OpportunityId], [SBQQ__Quote__c] FROM [Order] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [OrderItem_raw] SELECT [OrderId], [SBQQ__Contract__c] FROM [OrderItem] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}'); REPLICATE [Contract_raw] SELECT [Id], [CreatedDate], [ContractNumber], [CreatedById], [OwnerId] FROM [Contract]; REPLICATE [LeadHistory_raw] WITH ReplicateStartDate = '{env:start_extraction_date}', replicateenddate = '{env:end_extraction_date}' SELECT * FROM [LeadHistory] WHERE ((((([Field] = 'Status') OR ([Field] = 'Rating')) OR ([Field] = 'Owner')) AND ([DataType] != 'EntityId'))); REPLICATE [OpportunityFieldHistory_raw] WITH ReplicateStartDate = '{env:start_extraction_date}', replicateenddate = '{env:end_extraction_date}' SELECT * FROM [OpportunityFieldHistory] WHERE (((((([Field] = 'Amount') OR ([Field] = 'StageName')) OR ([Field] = 'Owner')) OR ([Field] = 'CloseDate')) AND ([DataType] != 'EntityId'))); REPLICATE [SBQQ__Quote__History_raw] WITH ReplicateStartDate = '{env:start_extraction_date}', replicateenddate = '{env:end_extraction_date}' SELECT * FROM [SBQQ__Quote__History] WHERE ((((([Field] = 'SBQQ__Status__c') OR ([Field] = 'SBQQ__ExpirationDate__c')) OR ([Field] = 'SBQQ__Primary__c')) OR ([Field] = 'SBQQ__SubscriptionTerm__c')) OR ([Field] = 'SBQQ__SalesRep__c')) AND ([DataType] != 'EntityId'); REPLICATE [OrderHistory_raw] WITH ReplicateStartDate = '{env:start_extraction_date}', ReplicateEndDate = '{env:end_extraction_date}' SELECT * FROM [OrderHistory] WHERE ((([Field] = 'Status') OR ([Field] = 'Owner')) OR ([Field] = 'TotalAmount')) AND ([DataType] != 'EntityId'); REPLICATE [ContractHistory_raw] WITH ReplicateStartDate = '{env:start_extraction_date}', replicateenddate = '{env:end_extraction_date}' SELECT * FROM [ContractHistory] WHERE ((([Field] = 'Status') OR ([Field] = 'Owner')) OR ([Field] = 'ContractTerm')) AND ([DataType] != 'EntityId');

Note regarding CData Salesforce Provider Version 21.0.8097.0 When a table has an _Incremental Check Column_ field predefined in CData Sync, the SQL query cannot use the same date field in both statements (WITH and WHERE) at the same time. If version 21.0.8097.0 (or an older version) of CData is used, the date filtering should be done in the WHERE clause and should be removed from the WITH statement.

Alternative Scenarios

The following scenarios can be used in combination of each other:

Multi Currency and Dated Conversion Rates are enabled in Salesforce Org

In case multi currency is used in the Salesforce org, add the following queries:

REPLICATE [CurrencyType_raw] SELECT [Id], [IsCorporate], [IsoCode] FROM [CurrencyType] WHERE [IsCorporate] = 1; REPLICATE [DatedConversionRate_raw] SELECT [Id], [IsoCode], [NextStartDate], [StartDate], [ConversionRate] FROM [DatedConversionRate];

Additionally, the Opportunity query must be changed to the following to add the CurrencyIsoCode field in the query.

REPLICATE [Opportunity_raw] SELECT [Id], [AccountId], [Amount], [CloseDate], [CreatedById], [CreatedDate], [CurrencyIsoCode], [ForecastCategory], [IsClosed], [IsWon], [LastStageChangeDate], [LeadSource], [Name], [OwnerId], [Probability], [StageName], [Type], [SBQQ__AmendedContract__c] FROM [Opportunity] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}');

Person Accounts enabled in Salesforce Org

In Case Person Accounts (field IsPersonAccount) are used - replace the Accounts query with the following query. This query will add the field IsPersonAccount in the Accounts extraction.

REPLICATE [Account_raw] SELECT [Id], [AccountSource], [BillingCountry], [BillingState], [CreatedById], [CreatedDate], [Industry], [IsPersonAccount], [Name], [OwnerId], [Ownership], [ParentId], [Rating], [Type] FROM [Account];

Record Types are enabled in Salesforce Org

In case Record Types are used the Opportunity query must be amended to add the RecordTypeId field in the query. The following replicate shows Opportunity with RecordTypeId and CurrencyIsoCode values added.

REPLICATE [Opportunity_raw] SELECT [Id], [AccountId], [Amount], [CloseDate], [CreatedById], [CreatedDate], [CurrencyIsoCode], [ForecastCategory], [IsClosed], [IsWon], [LastStageChangeDate], [LeadSource], [Name], [OwnerId], [Probability], [RecordTypeId], [StageName], [Type], [SBQQ__AmendedContract__c] FROM [Opportunity] WHERE ([CreatedDate] >= '{env:start_extraction_date}') AND ([CreatedDate] <= '{env:end_extraction_date}');

Input fields

The following tables include the list of fields per input table, their description, data type to be used when formatting the input and the filter flag to identify those that are being used to filter data.

Input types

Below is an overview of the different field types and their default format settings.

Field typeDescription
booleantrue, false, 1, 0
dateyyyy-mm-dd
datetimeyyyy-mm-dd hh:mm:ss[.ms], where [.ms] is optional.
doubleDecimal separator: . (dot); thousand separator: none
integerThousand separator: none
textN/A

Account

Represents an individual account, which is an organization or person involved with your business (such as customers, competitors, and partners).

FieldDescriptionData TypeFiltering
IdAccount Identifier (Primary Key).text
AccountSourceThe source of the account record. For example, Advertisement, Data.com, or Trade Show. The source is selected from a pick list of available values, which are set by an administrator.text
BillingCountryDetails for the billing address of this account.text
BillingStateDetails for the billing address of this account.text
CreatedByIdUser ID who created the account.text
CreatedDateDate in which the account was created.datetime
IndustryAn industry associated with this account.text
IsPersonAccount*Indicates whether this account has a record type of Person Account (true) or not (false). This field is not available by default in Salesforce, but is setup by Salesforce when requested for B2C environments. This attribute can be enabled / disabled using the use_is_person_account DBT variable.boolean
NameName of the account. If the account has a record type of Person Account: This value is the concatenation of the FirstName, MiddleName, LastName, and Suffix of the associated person contact.text
OwnerIdThe ID of the user who currently owns this account.text
OwnershipOwnership type for the account, for example Private, Public, or Subsidiary.text
ParentIdID of the parent object, if any.text
RatingThe account's prospect rating, for example Hot, Warm, or Cold.text
TypeType of account, for example, Customer, Competitor, or Partner.text

Campaign

Represents and tracks a marketing campaign, such as a direct mail promotion, webinar, or trade show.

FieldDescriptionData TypeFiltering
IdCampaign Identifier (Primary Key).text
CreatedByIdUser ID who created the campaign.text
CreatedDateDate in which the campaign was created.datetimetime based filter
NameName of the campaign.text
OwnerIdID of the user who owns this campaign.text
ParentIdID of the parent Campaign record, if any.text
StatusStatus of the campaign, for example, Planned, In Progress.text
TypeType of campaign, for example, Direct Mail or Referral Program.text

CampaignMember

Represents the association between a campaign and either a lead or a contact.

FieldDescriptionData TypeFiltering
IdCampaign Member Identifier (Primary Key).text
CampaignIdRequired. ID of the Campaign to which this Lead or Contact is associated.text
CreatedByIdUser ID who created the campaign member record.text
CreatedDateDate in which the campaign member record was created.datetimetime based filter
LeadIdRequired. ID of the Lead who is associated with a Campaign.text
StatusControls the HasResponded flag on this object. In the Salesforce user interface, Marketing users can define valid status values for the Status picklist.text

Contract

Represents the subscription products that customers have purchased. The Contract store information on the subscriptions that sales reps have quoted or ordered.

FieldDescriptionData TypeFiltering
IdContract Identifier (Primary Key).text
CreatedByIdUser ID who created the contract record.text
CreatedDateDate in which the contract record was created.datetimetime based filter
ContractNumberAuto Number assigned to the Contract once is created.text
OwnerIdID of the user who owns this contract.text

ContractHistory

History for tracked fields of Contract.

FieldDescriptionData TypeFiltering
IdContract History Identifier (Primary Key).text
ContractIdRelated Contract Record Id.text
CreatedByIdUser ID who created the history record.text
CreatedDateDate in which the history record was created.datetimetime based filter
DataTypeData Type for the field which was modified.text<> EntityId
FieldField which was modified on the contract record.textin (Status, Owner, ContractTerm)
NewValueValue after change.text
OldValueValue before change.text

CurrencyType

Represents the currencies used by an organization for which the Multi-currency feature is enabled.

FieldDescriptionData TypeFiltering
IdCurrency Type record identifier (Primary Key).text
IsCorporateIndicates whether this currency type is the corporate currency (true) or not (false). Label is Corporate Currency. All other currency conversion rates are applied against this corporate currency.boolean= 1
IsoCodeISO code of the currency. Must be one of the valid alphabetic, three-letter currency ISO codes defined by the ISO 4217 standard, such as USD, GBP, or JPY.text

DatedConversionRate

Represents the dated exchange rates used by an organization for which the Multi-currency and the effective dated currency features are enabled.

FieldDescriptionData TypeFiltering
IdDated Conversion Rate record identifier (Primary Key).text
ConversionRateConversion rate of this currency type against the corporate currency.double
IsoCodeISO code of the currency. Must be one of the valid alphabetic, three-letter currency ISO codes defined by the ISO 4217 standard, such as USD, GBP, or JPY.text
NextStartDateThe date on which the next effective dated exchange rate will start. Effectively the day after the end date for this exchange rate.date
StartDateThe date on which the effective dated exchange rate starts.date

Lead

Represents a prospect or lead.

FieldDescriptionData TypeFiltering
IdLead Identifier (Primary Key).text
ConvertedOpportunityIdObject reference ID that points to the opportunity into which the lead has been converted.text
CreatedByIdUser ID who created the campaign member record.text
CreatedDateDate in which the campaign member record was created.datetimetime based filter
NameConcatenation of FirstName, MiddleName, LastName, and Suffix up to 203 characters, including white spaces.text
OwnerIdID of the lead's owner.text

LeadHistory

History for tracked fields of Lead.

FieldDescriptionData TypeFiltering
IdLead History Identifier (Primary Key).text
LeadIdRelated Lead Record Id.text
CreatedByIdUser ID who created the history record.text
CreatedDateDate in which the history record was created.datetimetime based filter
DataTypeData Type for the field which was modified.text<> EntityId
FieldField which was modified on the lead record.textin (Status, Rating, Owner)
NewValueValue after change.text
OldValueValue before change.text

Opportunity (Main Object)

Represents an opportunity, which is a sale or pending deal. This will be the main Case Identifier for the Process Mining model.

FieldDescriptionData TypeFiltering
IdOpportunity Identifier (Primary Key).text
AccountIdID of the account associated with this opportunity.text
AmountEstimated total sale amount. For opportunities with products, the amount is the sum of the related products.double
CloseDateDate when the opportunity is expected to close.date
CreatedByIdUser ID who created the opportunity record.text
CreatedDateDate in which the opportunity record was created.datetimetime based filter
CurrencyIsoCodeAvailable only for organizations with the Multi-currency feature enabled. Contains the ISO code for any currency allowed by the organization.text
ForecastCategoryUsed to group opportunities for forecasting. It is implied, but not directly controlled, by the StageName field.text
IsClosedBoolean value which states whether the opportunity is closed.boolean
IsWonBoolean value which states whether the opportunity is won.boolean
LastStageChangeDateShows timestamp in which the stage was changed last. Present starting from Salesforce REST API version 52.0.datetime
LeadSourceSource of this opportunity, such as Advertisement or Trade Show.text
NameA name for this opportunity.text
OwnerIdID of the User who has been assigned to work this opportunity.text
ProbabilityPercentage of estimated confidence in closing the opportunity. It is implied, but not directly controlled, by the StageName field.double
RecordTypeId*ID of the record type assigned to this object. In order for this field to appear on the opportunity object, there needs to be at least one record type for opportunities.text
SBQQ__AmendedContract__cID of the related contract that was amended. The origin for the amendment opportunity.text
StageNameCurrent stage of this record. The StageName field controls several other fields on an opportunity.text
TypeType of opportunity. For example, Existing Business or New Business.text

OpportunityFieldHistory

Represents the history of changes to the values in the fields of an opportunity.

FieldDescriptionData TypeFiltering
IdOpportunity History Identifier (Primary Key).text
OpportunityIdRelated Opportunity Record Id.text
CreatedByIdUser ID who created the history record.text
CreatedDateDate in which the history record was created.datetimetime based filter
DataTypeData Type for the field which was modified.text<> EntityId
FieldField which was modified on the opportunity record.textin (StageName, Amount, Owner, CloseDate)
NewValueValue after change.text
OldValueValue before change.text

Order

Represents an order associated with a quote, an order record track the products from customers purchases.

FieldDescriptionData TypeFiltering
IdOrder Identifier (Primary Key).text
CreatedByIdUser ID who created the order.text
CreatedDateDate in which the quote was order.datetimetime based filter
NameName for the order.text
OpportunityIdRelated Opportunity Record Id.text
SBQQ__Quote__cID for the quote associated with the order.text

OrderItem

Represents an order product which is a product or service that is provided to a customer according to an associated order for each of the quote lines.

FieldDescriptionData TypeFiltering
OrderIdID for the order associated with the order product.text
SBQQ__Contract__cThe contract of the subscription that is created from this order product.text

Note: Filter in OrderItem is done by CreatedDate field which is not being extracted

OrderHistory

Represents historical information about changes that have been made to the standard fields of the associated order, or to any custom fields with history tracking enabled.

FieldDescriptionData TypeFiltering
IdOrder History Identifier (Primary Key).text
OrderIdRelated order Record Id.text
CreatedByIdUser ID who created the history record.text
CreatedDateDate in which the history record was created.datetimetime based filter
DataTypeData Type for the field which was modified.text<> EntityId
FieldField which was modified on the order record.textin (Status, Owner, TotalAmount)
NewValueValue after change.text
OldValueValue before change.text

Quote

Represents the Quote object that stores all the details of the products and prices quoted for an opportunity. Quotes are created from and synced with opportunities, and emailed as PDFs to customers.

FieldDescriptionData TypeFiltering
IdQuote Identifier (Primary Key).text
CreatedByIdUser ID who created the quote.text
CreatedDateDate in which the quote was created.datetimetime based filter
NameSystem-generated number for referencing the quote.text
SBQQ__Opportunity2__cID for the opportunity associated with the quote.text

QuoteHistory

Represents historical information about changes that have been made to the standard fields of the associated quote, or to any custom fields with history tracking enabled.

FieldDescriptionData TypeFiltering
IdQuote History Identifier (Primary Key).text
ParentIdRelated quote Record Id.text
CreatedByIdUser ID who created the history record.text
CreatedDateDate in which the history record was created.datetimetime based filter
DataTypeData Type for the field which was modified.text<> EntityId
FieldField which was modified on the quote record.textin (SBQQ__Primary__c, SBQQ__Status__c, SBQQ__SubscriptionTerm__c) or in (SBQQ__SalesRep__c, SBQQ__ExpirationDate__c) and OldValue not null
NewValueValue after change.text
OldValueValue before change.textWhen "Field" takes the following values, OldValue cannot be null:'SBQQ__SalesRep__c', 'SBQQ__ExpirationDate__c'

ProcessDefinition

Represents the definition of a single approval process.

FieldDescriptionData TypeFiltering
IdProcess Definition Identifier (Primary Key).text
NameThe unique process name, used internally.text
TableEnumOrIdSpecifies the object associated with the approval process, such as Account or Contact.text
TypeThis field shows the type of process. In this case the only type that is of interest for the logic are the Approval types.text= Approval

ProcessInstance

Represents an instance of a single, end-to-end approval process.

FieldDescriptionData TypeFiltering
IdProcess Instance Identifier (Primary Key).text
CreatedByIdUser ID who created the process instance.text
CreatedDateDate in which the process instance was created.datetimetime based filter
ProcessDefinitionIdThe ID of this approval process instance. This is a relationship field.text
StatusThe status of this approval process instance, for example Started, Pending, or Approved.text
TargetObjectIdID of the object affected by this approval process instance. This is a polymorphic relationship field.text

ProcessInstanceStep

Represents one work item in an approval process (ProcessInstance).

FieldDescriptionData TypeFiltering
IdProcess Instance Step Identifier (Primary Key).text
CommentsLimit: 4,000 bytes.text
CreatedByIdUser ID who created the process instance step.text
CreatedDateDate in which the process instance step was created.datetimetime based filter
ProcessInstanceIdID of the ProcessInstance that this approval step belongs to. This is a relationship field.text
StepStatusThe current status of this approval step. Examples are Approved, Fault, Held, NoResponse, Pending, Reassigned, Rejected, Removed, Started.text

RecordType

Represents a record type, which might define a different sales process for opportunities.

FieldDescriptionData TypeFiltering
IdRecord Type Identifier (Primary Key).text
NameLabel of the record type in the user interface.text

User

Represents each user in the Salesforce organization.

FieldDescriptionData TypeFiltering
IdUser Identifier (Primary Key).text
DepartmentThe company department associated with the user.text
NameConcatenation of FirstName and LastName.text
UserTypeThe category of user license.text

Design specifications

Entities

Salesforce already treats each object as an individual entity, however the objects are joined to additional master data in order to provide additional information.

EntityInput Data
LeadLead, User
OpportunityOpportunity, Accounts, User, RecordType
QuoteQuote, User
OrderOrder, User
ContractContract, User

Activities

EntityActivityDescription
LeadCreationLead is generated in the system. Identified based on the CreateDate field on the Lead object.
LeadAdd to CampaignLead is added to a marketing campaign for tracking. Identified based on the CreateDate field on the CampaignMember object for each LeadId.
LeadStatus Change*Lead moves from different status. Standard status in Salesforce are: Open, Contacted, Qualified, Unqualified. Identified based on the Old and New values for field = Status on the LeadHistory object.
LeadApprovals*Any approval process which was submitted. This may be generated by any custom configuration the customer has.
LeadAdditional Field Changes*Depending on fields tracked on the object, the event will be record as a change activity. In the standard connector, Owner and Rating are tracked, but may be expanded depending on customer configuration. Identified based on records on the LeadHistory object.
OpportunityCreationOpportunity is generated in the system. Identified based on the CreateDate field on the Opportunity object.
OpportunityStage Change*Opportunity moves from different status. Standard status in Salesforce are: Prospecting, Qualification, Needs Analysis, Value Proposition, ID Decision Makers, Perception Analysis, Proposal / Price Quote, Negotiation / Review, Closed Won, Closed Lost. Identified based on the Old and New values for field = StageName on the OpportunityFieldHistory object.
OpportunityAdditional Changes*Depending on fields tracked on the object, the event will be record as a change activity. In the standard connector, Owner, Close Date and Amount are tracked, but may be expanded depending on customer configuration. Identified based on values on the OpportunityFieldHistory object.
OpportunityApprovals*Any approval process which was submitted. This may be generated by any custom configuration the customer has.
QuoteCreationQuote is generated in the system. Identified based on the CreateDate field on the Quote.
QuoteApprovals*Any approval process which was submitted. This may be generated by any custom configuration the customer has.
QuoteStatus Change*Quote moves from different status. Standard status in Salesforce are: Draft, In Review, Approved, Denied, Presented, Accepted, Rejected. Identified based on the Old and New values for field = Status on the QuoteHistory object.
QuoteAdditional Changes*Depending on fields tracked on the object, the event will be record as a change activity. In the standard connector, Primary quote, subscription terms, Sales Rep and Expiration date are tracked, but may be expanded depending on customer configuration. Identified based on the values on the QuoteHistory object.
OrderCreationOrder is generated in the system. Identified based on the CreateDate field on the Order.
OrderStatus Change*Order moves from different status. Standard status in Salesforce are: Draft, Activated. Identified based on the Old and New values for field = Status on the OrderHistory object.
OrderAdditional Changes*Depending on fields tracked on the object, the event will be record as a change activity. In the standard connector, Owner, and TotalAmount are tracked, but may be expanded depending on customer configuration. Identified based on the values on the OrderHistory object.
OrderApprovals*Any approval process which was submitted. This may be generated by any custom configuration the customer has.
ContractCreationContract is generated in the system. Identified based on the CreateDate field on the Contract.
ContractStatus Change*Contract moves from different status. Standard status in Salesforce are: Draft, In Approval Process, Activated. Identified based on the Old and New values for field = Status on the ContractHistory object.
ContractAdditional Changes*Depending on fields tracked on the object, the event will be record as a change activity. In the standard connector, Owner, and Contract term are tracked, but may be expanded depending on customer configuration. Identified based on the values on the ContractHistory object.
ContractApprovals*Any approval process which was submitted. This may be generated by any custom configuration the customer has.

*The actual activity names will depend on the values defined on the customer Salesforce organization.

Fields

Cases_base

FieldData TypeDescription
Case_IDTextThe unique identifier of the case. Mandatory field.
CaseTextA user-friendly name to identify the case.
Account*TextAccount related to the opportunity.
Account_billing_state*TextBilling State for Account.
Account_billing_country*TextBilling Country for Account.
Account_industry*TextIndustry for Account.
Account_owner*TextAccount Owner.
Account_ownership*TextAccount Ownership (Public, Private, Subsidiary).
Account_rating*TextRating for Account (Hot, Warm, Cold).
Account_source*TextSource for Account, such as email campaign or advertising.
Account_type*TextAccount Type (mid-size, small).
Case_ownerTextOpportunity Owner.
Case_statusTextThe status of the case in the process. For example, 'open', 'closed', 'pending', 'approved', etc.
Case_typeTextThe categorization of the cases.
Case_valueDoubleA monetary value related to the case. Shown in corporate currency.
Corporate_currency*TextCurrency code used to report values across the organization.
Forecast_category*TextCategory for Opportunity Forecast.
Lead_source*TextSource for Lead related to Opportunity.
Opportunity_closed*BooleanWhether the Opportunity has been closed.
Opportunity_name*TextOpportunity Name.
Opportunity_probability*TextProbability of Winning the opportunity.
Opportunity_won*BooleanWhether the Opportunity has been won.
Opportunity_creator*TextUser who created the opportunity.
Original_amount*DoubleValue for opportunity in original currency.
Record_type*TextRecord Type for the opportunity.
Person_account*BooleanWhether the Account is a person account.
Transaction_currency*TextOriginal transaction currency.

*Case attributes which need to be configured on top of standard TemplateOne case attributes.

Event_log_base

FieldData TypeDescription
Case_IDTextThe unique identifier of the case. Mandatory field.
ActivityTextThe name of the event. This describes the step in the process. Mandatory Field.
Event_endDate TimeThe timestamp associated with the end of executing the event. Mandatory Field.
Activity_type*TextType of activity.
Activity_orderIntegerIf activities take place on the same time (in parallel), you can define their order here.
AutomatedBooleanIndicates whether the event is manually executed or automated.
Event_detailTextInformation related to the event.
Event_IDIntegerA unique identifier of the event.
TeamTextThe team that executed the event.
UserTextThe user who executed the event.
User_type*TextUser Type – Related to the Salesforce License.

*Event attributes which need to be configured on top of standard TemplateOne event attributes.

Customizing the transformations

Configuration

Automated Users

In order to add data which will be defined by the end user, one additional file is loaded into the model which need to be prepared by the Analyst. This is the Automated_users_raw file, which contains the users that are flagged as automated. If this is not configured, the connector will still work properly but it will not have that extra information.

Amount of events

All contracts that get amended will generate automatically a new Opportunity_id that will be linked to the former. Therefore, all activities happening to the contract will be included in both case_id's: the original opportunity and the amended one. That can be seen when comparing the total amount of records in Events_all table vs Event_log_base table, thus it will be correct to have more records in the Event_log_base table.

Dbt Variables

Below is an overview of the variables that must be configured based on the Salesforce configuration for the end customer. These variables are defined in the dbt_project.yml file.

VariableTypeDescription
conversion_rate_start_datestringSpecifies the starting date for currency conversions, when there are no prior historic exchange rates. This replaces the null value that is used in Salesforce.
use_is_person_accountbooleanDefines whether the IsPersonAccount attribute will be used. This should be disabled in Salesforce Orgs where there are no Person Accounts. Setting this to true will enable the attribute to being queried in the transformations, and will enable associated tests. Default is false.
use_currency_conversionbooleanDefines whether the multi currency conversion will be used. This should be disabled in Salesforce Orgs where multi currency is not used. Setting this to true will enable currency conversion. Default is false.
use_record_typesbooleanDefines whether the record type conversions will be used. This should be disabled in Salesforce Orgs where record types are not used. Setting this to true will enable record types to be queried and added to the transformations. Default is false.

Limitations

CDATA Sync - Salesforce Connector Regarding CData Salesforce Provider Version 21.0.8097.0 When a table has an Incremental Check Column field predefined in CData, the SQL query cannot have both statements (WITH and WHERE) at the same time. If this is the version of CData that is being used, please remove the entire WHERE statement so the date filter done in the WITH statement works properly.

No Event Start

Salesforce does not store the start time for each change activity.

No flag to identify automated users

Salesforce does not have a field or special license for automated users. It does however have a default user named Automated Process which is used for automated processing for Salesforce changes, however any additional users such as interfaces or RPA will use normal licenses and are not differentiated by user type.

Salesforce Retention Policy

As of February 2022, Salesforce retains field history data for up to 18 months through the org and up to 24 months via the API.

In case the history needs to be stored for a longer period of time, Field Audit Trail must be activated. This allows copying of history data into a separate big data object and allows storage for up to 10 years.

Troubleshooting

General

Field not available in object during data extraction

Check Field Level Security in order to confirm the field is available and visible for the user profile extracting data. For CurrencyISOCode, IsPersonAccount, LastStageChangeDate, RecordTypeId check the specific issues in the following section.

Object not available during data extraction

The user profile might not have read access to the object. This can be corrected on the user profile or a different user should extract the data. For Order, Quote, CurrencyType, DatedConversionRate check the specific issues in the following section.

Object Specific

Campaign and CampaignMember objects not available

Check the user record for the user extracting data, and verify the Marketing User checkbox is Active.

CurrencyIsoCode is not available when extracting data from the Opportunity object

Multi-currency is not enabled within the Salesforce org. In case this happens, the conversions should be removed from the data model. This can be achieved by adjusting the variable use_currency_conversion in the dbt_project.yml to false.

CurrencyType object is not available when extracting data

Multi-currency is not enabled within the Salesforce org. In case this happens, the conversions should be removed from the data model. This can be achieved by adjusting the variable use_currency_conversion in the dbt_project.yml to false.

DatedConversionRate object is not available when extracting data

Effective currency rate management is not enabled within the Salesforce org. In case this happens, the conversions should be removed from the data model. This can be achieved by adjusting the variable use_currency_conversion in the dbt_project.yml to false.

IsPersonAccount field not available in Account object when extracting from Salesforce

When extracting data from Salesforce, IsPersonAccount may not be available as the organization may not have B2C customers. In case this happens, the field should be removed from the data model. This can be achieved by adjusting the variable use_is_person_account in the dbt_project.yml to false.

LastStageChangeDate field not available in Opportunity object when extracting from Salesforce

The field LastStageChangeDate was only made available starting with Salesforce REST API 52.0. Make sure the CData extraction or the extraction method used is using API 52.0 onwards.

RecordTypeId is not available when extracting data from the Opportunity object

Record Types are not used within the Salesforce org. In case this happens, the conversions should be removed from the data model. This can be achieved by adjusting the variable use_record_types in the dbt_project.yml to false.

ncG1vNJzZmicn5jCrrHNrZitoZ%2Bjvaqv066pnqqVpbxvrsuomWebn6eyb8PIp5uor6Nju6bAjp%2BgpZ2jZJ2zu8KeqqyXfZ67qrrGaGlpamJjfnF7spqjnquWpL%2BksYx8pqeemZzCs7GMiamim5WUnra7055mjJmcmsCnu9GcnGZ7n6OzqrPUq5xmiKKesKZ5sK6mrZ1encGuuA%3D%3D

Sebrina Pilcher

Update: 2024-04-25