Data Flows
Global architecture
Performance Quoting service and User Interface interacts with other services of the PROS platform as well as potential external systems.
The figure above illustrates a typical data flow starting from a CRM providing contextual information for the quotation process and ending with the synchronization of data in that very same CRM.
| 1 | THE CRM CALLS PERFORMANCE QUOTING SERVICE TO INITIATE A QUOTE SESSION AND PUSHES DATA IN THE SESSION CONTEXT (DATA FLOWS - FROM CRM) |
|---|---|
| 2 | The conversion service sends currencies and conversion rates to the quote |
| 3 | The quote interacts with the Smart CPQ catalog/configurator services to provide a guided selling experience and get product information (Data flows - PROS Services) A Catalog service session is initiated based on data of the quote and eventually contextual data from the CRM context. |
| 3a | From a Catalog session, a subsequent Configurator session or Guided Selling session can possibly be instantiated and inherit from the Catalog context (3a) (Note that when the Configurator User Interface is used and embedded in a widget of Performance Quoting User Interface, it is enriched by additional specific technical information that are shared between both UI components - see Data flows - PROS Services) |
| 4 | The Catalog and Configurator services return product/offer data to the quote. That data is used by the quote to create a selling structure in the quote - Add to quote action. (Note that the quote line structure that is added to the quote is a combination of the product structure and the quote model selling rules and conditions) |
| 5 | Prices are retrieved from the Pricing Engine (Data flows - PROS Services) |
| 6 | Dynamic filters may apply to ensure that combination of values populated on quote llines are valid |
| 7 | Dimensions can be retrieved directly in the quote |
| 8 | External data can be retrieved in the quote (Data flows - External Systems) |
| 9 | An external UI can be displayed in the quote (Data flows - External Systems) |
| 10 | Data are synchronized in the CRM (Data flows - From CRM) |
| 11 | A document is generated based on quote content and by default synchronized into the CRM during the Sync process (proivded PROS standard managed solutions for CRMs are used) |
Data Flows - From CRM
Context Data Provider Usage
Data sent from the hosting app (CRM in particular) as part of the CONTEXT Dataproviders can contain:
- Quoting contextual data
- Selling Conditions
- User and Session-dependent information (current user profile, group etc.)
The quote model logic may use some specific information differently depending on the use case Some examples:
- A User Profile may be used as a volatile/session variable to control the visibility of some UI widgets and handle user permissions on quote actions
- It should not be stored as a quote data.
- A Ship To term can be used to be stored as quote header term to drive some quote-specific rules and agreement or pricing rules.
Session variables versus fields from the CRM quote context
Calculated quote data can depend on the quote context from the CRM, but must never depend on a particular user context.
This is because the next user accessing a quote will naturally re-populate the quote context from the CRM, and so the data cannot be altered according to the last user connected, bearing in mind that several users may see the quote in competition.
The same applies to the management of user rights, which may be based on fields, but which, in this case, cannot be conditioned by data from a particular user context, as otherwise one user could take advantage of the access rights of another user. However, in the case of user rights, session variables offer the very possibility of conditioning user rights to a particular user context, as these variables are specific to the user session.
In conclusion, it is imperative never to store data specific to a particular user in a field, although such data can be used to manage access rights via session variables.
SALESFORCE
The Managed Package sends the Salesforce context to Smart CPQ. From Smart CPQ you can retrieve these values from the quotation module and from the configurator / catalog (session settings).
The context is sent as a JSON text value.
In this section we will: Dataprovider model (for static value)
Speadsheet model (for dynamic value) - List the elements sent as part of the context. - Provide an example of context (JSON) being sent. - Point to links detailing how to retrieve the various context elements.
Context Name The name of the context sent by Salesforce is SfdcContext. You must use this name in your model to retrieve it (case sensitive).
Context Elements
Different elements are sent as part of the context:
- System information - such as user profile, status, quote ID, etc.
- Implicit Mapping IN information - all fields attached to the PROS quote entity
- Explicit Mapping IN information - by Mapping Set, you can point at any field related to the Quote object
- Custom Mapping IN information - in case you want to send data that is not tied to the quote itself, you can do so by custom mapping IN: an Apex class can find some data and attach it to the context sent by the MP.
System information is available directly in the JSON root.
All other information is stored within a JSON entry of the JSON context. The name of the entry is "SFDC".
System fields
The following fields are sent to Smart CPQ as system fields:
| KEY | DESCRIPTION | NATURE | TYPE | AVAILABLE IN | EXAMPLE |
|---|---|---|---|---|---|
| CRM_QUOTE_ID | Quote ID | Field | String | Quote module Configurator | a0F1I00000AezLJUAZ |
| CRM_GROUP | The profile name of user opening the quote | Session variable | String | Quote module Configurator | System Administrator |
| CRM_USERGROUP (deprecated) | The profile name of user opening the quote | Session variable | String | Quote module Configurator | System Administrator |
| CRM_SESSION_LOCKEDQUOTE | The locked state of the quote. It can be used to tune the quote access rights. Equals true if the Salesforce PROS Quote is locked. A quote gets locked while it is approved. Important note: by default this parameter is not computed and its value will always be "false". For the flag to be properly computed you need to check the "Enable record locking and unlocking in Apex" in the "Process Autmation" Settings setup menu. | Session variable | boolean | Quote module Configurator | false |
| If this flag is set to true, then the synchro OUT (from Smart CPQ to Salesforce) will not be executed. | |||||
| CRM_SESSION_READONLYQUOTE | The read-only state of the quote. It can be used to tune the quote access rights. Equals true if the Salesforce PROS Quote is locked. A quote is in read-only mode if the current user does not have permission to read or write on the Salesforce PROS Quote entity. | Session variable | boolean | Quote module Configurator | false |
| If this flag is set to true, then the synchro OUT (from Smart CPQ to Salesforce) will not be executed. |
Implicit Mapping IN
All fields of the PROS Quote entity are attached to the context being sent to Smart CPQ. The fields are stored within a JSON variable and may be extracted from there: either in the quote itself using a formula, or in the configurator (or catalog) using CPEs. The name of the key is "SFDC".
| KEY | DESCRIPTION | NATURE | TYPE | AVAILABLE | EXAMPLE |
|---|---|---|---|---|---|
| SFDC | Implicit Mapping IN | SFDC Data | JSON | Quote module Configurator | See below |
Explicit Mapping IN
Fields from entities related to PROS Quotes can be retrieved by explicit mapping in using Mapping Sets. The fields are stored within a JSON variable and may be extracted from there: either in the quote itself using a formula, or in the configurator (or catalog) using CPEs. The name of the key is
"SFDC" (Same entry as for the implicit Mapping IN). Examples are provided below on how to retrieve values from the JSON variable.
Custom Mapping IN
To retrieve other fields, you can use the custom Mapping In. Using Apex, you will be able to add additional data to the context sent to Smart CPQ. The name of the key used in the Context is determined by the Apex class.
| KEY | DESCRIPTION | NATURE | TYPE | AVAILABLE IN |
|---|---|---|---|---|
| MyCustomID | Any data returned by the Apex custom class | SFDC Data (usually) | Determined by Apex Class | Quote module Configurator |
Please find below an example of Salesforce context sent as JSON text value.
JSON Example
{
"refreshContext": false,
"quoteId": "c8b852c7-2ebf-461e-a2cf-5c4ff852d310",
"modelName": "HiTech Demo",
"dataProviderName": "SfdcContext",
"context": [
{
"value": {
"valueType": "String",
"value": "a0F1I00000Af6EeUAJ"
},
"key": "CRM_QUOTE_ID"
},
{
"value": {
"valueType": "String",
"value": "System Administrator"
},
"key": "CRM_GROUP"
},
{
"value": {
"valueType": "String",
"value": "System Administrator"
},
"key": "CRM_USERGROUP"
},
{
"value": {
"valueType": "Boolean",
"value": false
},
"key": "CRM_SESSION_READONLYQUOTE"
},
{
"value": {
"valueType": "Boolean",
"value": false
},
"key": "CRM_QUOTE_READONLY"
},
{
"value": {
"valueType": "Boolean",
"value": false
},
"key": "CRM_SESSION_LOCKEDQUOTE"
},
{
"value": {
"valueType": "Json",
"value": "{\"_SYS_STATUS\":{\"string\":\"Draft\"},\"checkbox_Field\":{\"boolean\":false},\"Par tnerAccountId\":{\"Assets\":[{\"SerialNumber\":{\"string\":\"785256954\"},\"Quantity\ ":{\"bigDecimal\":1.0},\"Price\":{\"monetary\":{\"currencyCode\":\"USD\",\"amount\":2 600}},\"Name\":{\"string\":\"Installation: Industrial - Medium\"},\"InstallDate\":{\"dateTime\":1517842800000}},{\"Status\":{\"string\":\"Ins talled\"},\"SerialNumber\":{\"string\":\"123456789\"},\"Quantity\":{\"bigDecimal\":3. 0},\"Price\":{\"monetary\":{\"currencyCode\":\"USD\",\"amount\":4000}},\"Name\":{\"st ring\":\"GenWatt Propane 1500kW\"},\"InstallDate\":{\"dateTime\":1517756400000}},{\"Status\":{\"string\":\"Ins talled\"},\"Quantity\":{\"bigDecimal\":2.0},\"Price\":{\"monetary\":{\"currencyCode\"
:\"USD\",\"amount\":5960}},\"Name\":{\"string\":\"GenWatt Diesel 1000kW\"},\"InstallDate\":{\"dateTime\":1549983600000}}],\"Website\":{\"string\":\"ht tp://www.uos.com\"},\"Type\":{\"string\":\"Customer - Direct\"},\"Phone\":{\"string\":\"(212)
842-5500\"},\"NumberOfEmployees\":{\"integer\":145000},\"Name\":{\"string\":\"United Oil & Gas Corp.\"},\"LastModifiedDate\":{\"dateTime\":1509023313000},\"BillingStreet\":{\"strin g\":\"1301 Avenue of the Americas \\nNew York, NY 10019\\nUSA\"},\"BillingState\":{\"string\":\"NY\"},\"BillingCity\":{\"string\":\"New York\"},\"BillingAddress\":{\"string\":\"1301 Avenue of the Americas \\nNew York, NY 10019\\nUSA\\nNew York\\nnull\\nNY\\nnull\"},\"AnnualRevenue\":{\"monetary\":{\"currencyCode\":\"USD\",
\"amount\":5600000000}}},\"Opportunity\":{\"Type\":{\"string\":\"New Customer\"},\"StageName\":{\"string\":\"Prospecting\"},\"Name\":{\"string\":\"OPPORTU NITY#1\"},\"Amount\":{\"monetary\":{\"currencyCode\":\"USD\",\"amount\":10000.00}}},\ "Status\":{\"string\":\"Draft\"},\"LocaleSidKey\":{\"string\":\"en_US\"},\"ExternalQu oteId\":{\"string\":\"c8b852c7-2ebf-461e-
a2cf-5c4ff852d310\"},\"LastReferencedDate\":{\"dateTime\":1578045620000},\"LastViewed Date\":{\"dateTime\":1578045620000},\"SystemModstamp\":{\"dateTime\":1578045321000},\ "LastModifiedById\":{\"string\":\"0051I000000VwuWQAS\"},\"LastModifiedDate\":{\"dateT ime\":1578045321000},\"CreatedById\":{\"string\":\"0051I000000VwuWQAS\"},\"CreatedDat e\":{\"dateTime\":1578045285000},\"RecordTypeId\":{\"string\":\"0121I0000007JyZQAU\"}
,\"CurrencyIsoCode\":{\"string\":\"USD\"},\"Name\":{\"string\":\"MAPPING_IN\"},\"IsDe leted\":{\"boolean\":false},\"OwnerId\":{\"string\":\"0051I000000VwuWQAS\"},\"Id\":{\ "string\":\"a0F1I00000Af6EeUAJ\"}}"
},
"key": "SFDC"
}
]
}
Retrieving Values
The values pushed through context can be retrieved from the quote or from the configurator.
MICROSOFT DYNAMICS
The Managed Solution sends the MSCRM context to Smart CPQ. From Smart CPQ you can retrieve these values: from the quotation module and from the configurator / catalog (session settings). The context is sent as a JSON text value.
In this section we will:
- List the elements sent as part of the context
- Provide an example of context (JSON) being sent
Context Name
The name of the context sent by MS Dynamics is MscrmContext. You must use this name in your model to retrieve it (case sensitive).
Context Elements
Different elements are sent from MSCRM to CPQ as part of the context:
- System Fields
- Explicit mapping driven by the Mapping In definition
- Explicit mapping driven by fetchXML queries
System information is available directly in the JSON root and thus automatically sent to CPQ. All other information is stored within a JSON entry of the JSON context.
System fields
The following fields are sent to Smart CPQ as system fields.
| KEY | DESCRIPTION | NATURE | TYPE | AVAILABLE IN | EXAMPLE |
|---|---|---|---|---|---|
| CRM_QUOTE_ID | Quote ID | Field | String | Quote module Configurator | 2bef001d-6b9d-4b59-aabf-063c8893a41a |
| CRM_GROUP | The position of the user opening the quote (if any) | Session variable | String | Quote module Configurator | Salesperson |
| Status Reason (statuscode) | The status of the quote stored in the Status Reason CRM field in the CRM Quote entity. | Option Set | String | Quote module Configurator | In progress |
It is also possible to override the locale.
Explicit Mapping IN
In addition to the system fields automatically sent by the CRM to CPQ, it is possible to explicitly define the data to retrieve from CRM entities to be sent to CPQ as part of the Mapping IN process. This mapping is explicit in the sense that you must finely define which fields from which entities you want to leverage. The definition of that explicit Mapping IN can be done in the PROS Mapping Set entity, in the Mapping IN tab. The PROS Mapping Set must then be linked to a PROS Setup entity.
The Mapping IN structure is split in three different sections:
- Quote elements to be synced in CPQ
- Elements from other entities to be synced in CPQ
Mapping IN - FetchXML queries
As described in the previous chapters, the Mapping IN structure allows sending to CPQ data coming from the Quote entity, Quote parent entities and children of the Quote parent entities (2nd level entities).
However, when setting up the Mapping IN, it could occur that you need to access fields from CRM entities at deeper levels or to leverage several instances of the same entity during the Quote sync (several Contacts of the Account linked to the Quote for instance). For that use case, the PROS Mapping Set entity provides a FetchXML query mechanism to retrieve data from virtually any entity in the CRM. The outcome of those queries is a JSON structure that is automatically integrated in the CRM Context sent to CPQ as part of the Mapping IN mechanism.
Please find below an example of MSCRM context sent as JSON text value.
JSON Example
{
"quoteId": "f2e38c95-9e36-4a5c-9e1b-1c6c017ac4d2",
"modelName": "DynamicsCrmSandboxModel",
"dataProviderName": "MscrmContext",
"refreshContext": false,
"context": [
{
"key": "crmquote.name",
"value": {
"valueType": "String",
"value": "Big Deal"
}
},
{
"key": "crmquote.quotenumber",
"value": {
"valueType": "String",
"value": "QUO-01013-X4Q9Y9"
}
},
{
"key": "account.name",
"value": {
"valueType": "String",
"value": "A. Datum Corporation"
}
},
{
"key": "account.telephone",
"value": {
"valueType": "String",
"value": "425-555-0158"
}
},
{
"key": "account.modifiedon",
"value": {
"valueType": "DateTime",
"value": 1629585751000
}
},
{
"key": "CRM_QUOTE_ID",
"value": {
"valueType": "String",
"value": "000f37e8-7b1b-ec11-b6e6-0022482262cc"
}
},
{
"key": "account.numberofemployees",
"value": {
"valueType": "Integer",
"value": 2000
}
},
{
"key": "account.accountguid",
"value": {
"valueType": "String",
"value": "83883308-7ad5-ea11-a813-000d3a33f3b4"
}
},
{
"key": "account.exchangerate",
"value": {
"valueType": "BigDecimal",
"value": 1
}
},
{
"key": "MSCRM",
"value": {
"valueType": "Json",
"value": "{\"crmquote.name\": {\"string\":\"Big Deal\"},\"crmquote.quotenumber\": {\"string\":\"QUO-01013-X4Q9Y9\"},\"account.name\":
{\"string\":\"A. Datum Corporation\"},\"account.telephone\":
{\"string\":\"425-555-0158\"},\"account.modifiedon\":
{\"dateTime\":1629585751000},\"CRM_QUOTE_ID\": {\"string\":\"000f37e8-7b1b-ec11-b6e6-0022482262cc\"},\"account.numberofemployees\":
{\"integer\":2000},\"account.accountguid\": {\"string\":\"83883308-7ad5-ea11-a813-000d3a33f3b4\"},\"account.exchangerate\":
{\"bigDecimal\":1.0000},\"account.customerid\":
{\"contact.parentcustomerid\":[{\"firstname\": {\"string\":\"Kevin\"},\"lastname\":
{\"string\":\"Martin\"},\"contactid\": {\"string\":\"678c7b32-3f72-ea11-a811-000d3a1b1f2c\"}}]}}"
}
}
]
}
Data flows - To CRM
SYNCHRONIZING DATA FROM CPQ TO CRM
When triggering the synchronization process from the CPQ Quote to the CRM Quote, PROS standard CRM Integration packages runs a Mapping OUT process which gathers data from the CPQ Quote.
That data is then retrieved by the CRM to update the CRM Quote and optionally some other CRM entities directly related or not to the Quote.
This occurs
- When clicking on Close Cart & Sync (from Performance Quoting UI or from the CRM depending on the type of the integration).
- Whenever the CPQ Quote is refreshed from the managed package.
MS Dynamics Solution for Performance Quoting
When Smart CPQ is integrated with MS Dynamics, the sync is triggered by a Close Cart & Sync action in the CRM Quote entity action bar:
This action is part of the PROS managed solution and does not need to be associated with any action as part of the CPQ Quote model. Therefore, no synchronization action has to be defined in the Quote Designer in the context of the integration with MS Dynamics CRM.
At the end of the sync process, you are redirected to the CRM Quote automatically.
The mapping OUT process handles both the CPQ Quote fields and CPQ Quote lines sync. Several elements can be part of the data synched back to the CRM from CPQ:
- CPQ elements to be synched with the CRM Quote.
- CPQ elements to be synched with CRM entities related to the Quote.
- CPQ Quote Lines Sync
- CPQ Quote Line items to be synched with CRM Product entities
Data Flows - PROS Services
CATALOG/CONFIGURATOR
Some settings are automatically sent when the catalog/configurator is called from the Quote. In addition, the settings can be configured from the Data Sources / Catalog page under the tab General Settings
Scope of Catalog Datasource Settings
It is important to understand that the parameters and information passed from the Quote to the Catalog (and then configuration) session and which are configured in the "Settings" section can only be Quote level data or static values. Moreover, they take precedence over the values that may have been used when a line was previously added to the quote.
Example:
Let's imagine that a business rule of a configurable product of the product catalog is driven by a
particular setting attached to the quote. The Catalog datasource will have a setting value configured as follow:
This will ensure that the value of the quote header field named "ConfSetting" is used to populate the "CPE.Settings.Session.MySetting" variable/setting of the catalog and then configurator session.
A user creates a quote and populates ConfSetting with the value "A".
They will configure a product and add it t the quote - ConfiguredProduct1 is added.
ConfiguredProduct1 has been configured with A as value for MySetting. Later on, the user modifies ConfSetting to "B"
- The user opens/runs a new catalog, configures a new product and adds it to the quote (ConfiguredProduct2 is added),
- ConfiguredProduct2 will have been configured with B as value for MySetting.
- The ConfiguredProduct1 that was initially added is not automatically refreshed. But if the user refreshes the line item, ConfiguredProduct1 will be refreshed with B as value
for MySetting.
| INPUT SETTINGS | DESCRIPTION | DEFAULT VALUE (IF NOT DEFINED) |
|---|---|---|
| MANDATORY | ||
| CPE.Settings.Session.Currency CPE.Settings.Session.CurrencySymbol | Mapped to the quote currency | |
| CPE.Settings.Session.Country CPE.Settings.Session.Language | Mapped to the quote locale | |
| CPE.Settings.Session.rootCL | Corresponds to the Root collection | |
| CPE.Settings.Session.Qty | Quantity associated to the root configurable product | 1 |
| CPE.Settings.Session.ModelVersion | Specify the version of model object that must be used. The value is the name of a released version (namely “RELEASE :<LABEL>”) or “WORKING” for the current working version or “WORKING :<LABEL>” to test a new fix on a released version. If empty, the version is the one valid for the Session.ApplicationDate. | Empty |
| CPE.Settings.Session.SavingPolicy | Specify the saving policy that is used during the catalog/configurator session. This saving policy will drive the data that is returned by the cat/conf service when a Save API is used. | Fast |
| CPE.Settings.Session.MonetaryFormat | The format for monetary data to use for the session | |
| CPE.Settings.Session.TimeZone | The timezone used for the session | |
| CPE.Settings.Session.NumericFormat | The format for numeric data used for the session | |
| CPE.Settings.Session.IntegerFormat | The format for integer data used for the session | |
| CPE.Settings.Session.LongDateFormat | The (long) format for dates used for the session | |
| CPE.Settings.Session.ShortDateFormat | The (short) format for dates used for the session | |
| OPTIONAL | ||
| CONTEXTUAL INFORMATION CPE.Settings.Session.Application ... | All SESSION data pushed from hosting app (CRM for example) as part of the Context Data source can be passed into the context of Catalog/Conf sessions/engine initiated from Performance Quoting.
To enable that behavior, the corresponding Context datasource must be selected on the Catalog datasource settings
This data is considered as volatile (not persisted)
By convention, each entry of the Context data source is accessible from the catalog and configurator service by using specific CPEs built by concatenating a static string (CPE.Settings.Session.Application) and the name of the entry in the context.
Examples CPE.Settings.Session.Application.SFDC CPE.Settings.Session.Application.CRM_GROUP CPE.Settings.Session.Application. ...
Note that PROS managed package or any custom context may push some data as JSON variables (e.g. CPE.Settings.Session.Application.SFDC)
If this JSON variable is of type JSONable, it is possible to browse its content by using CPEs from Catalog and Configurator models/engines (See Configurator documentation)
For example, in a
BRC: confML.getObjectByCPE("CPE.Settings.Session.Application.SFDC.AccountId.Name.string") | |
| CPE.Settings.Session.SalesMethodName | Specify the default Sales Method to run during the configuration. | |
| CPE.Settings.Session.PricingMethod[1] | Specify the PricingMethod to be used for the Catalog and Configurator (Several Pricing Methods can be used PricingMethod[1], PricingMethod[2] etc) | |
| CPE.Settings.Session.AllowIncompleteSave | Parameter of the session that allows (if “true”) or prevent from (if “false”) saving the configuration while the configuration is not completed. | True |
| CPE.Settings.Session.SavingPolicy | This setting defines the content of the saving file when saving the configuration. The value of this parameter can be given in two different formats: a text format and an XML format. See Integration Tools > Configurator > Focus on the Saving Policy setting for more details. | Fast |
| CPE.Settings.Session.ApplicationDate | Date used to run the configuration (for versioning and time-dependent treatments). Default value if not specified is the current date at the configuration start. | Empty |
| CPE.Settings.Session.mySetting | Custom settings can be sent from the quote to the catalog/configurator |
CONFIGURATOR USER INTERFACE SPECIFIC SHARED SETTINGS
Some settings are sent only when the Smart CPQ Configurator UI is used and surfaced in a standard Performance Quoting widget. These settings are not persisted and only available during the duration of the Configurator UI session.
| INPUT SETTINGS | DESCRIPTION | DEFAULT VALUE (IF NOT DEFINED) |
|---|---|---|
| OPTIONAL | ||
| CPE.Session.Settings.Quotex.ExternalContext.tenantId | Tenant ID | Current tenant ID |
| CPE.Session.Settings.Quotex.ExternalContext.userId | User ID | Current User ID |
| CPE.Session.Settings.Quotex.ExternalContext.sessionId | Session ID | Current Session ID |
| CPE.Session.Settings.Quotex.ExternalContext.quoteId | Quote ID | Current Quote ID |
| CPE.Session.Settings.Quotex.ExternalContext.dataproviderName | Dataprovider name | Dataprovider used to open the current configurator |
| CPE.Session.Settings.Quotex.ExternalContext.environmentId | Environment ID | Current environment ID |
| List of indexes | ||
| corresponding | Indexes of | |
| CPE.Session.Settings.Quotex.ExternalContext.insertionPoints | to the | the selected |
| selected lines | lines | |
| in the quote |
Usage of ExternalContext
The settings above should only be used to enable some interactive manipulation of data between the configurator UI (via an external component) and the performance quoting UI. They are not initialized /populated when running a headless (without UI) process. E.g. when the end-users refreshes a quote line, those settings are not available in the configurator engine.
PRICING
Info: Two types of Pricing Data Sources can be defined: one leveraging RTPE and the other one leveraging the CPQ pricing.
Only one can be made available at the same time for a given quote model (depending on feature flags).
The settings for each Pricing data provider are different (see below).
REAL TIME PRICING ENGINE
Some settings are automatically sent when the pricing engine is called from the Quote. The settings can be configured from the Data Sources > Pricing page under the General Settings tab:
| INPUT SETTINGS | DESCRIPTION | DEFAULT VALUE (IF NOT DEFINED) |
|---|---|---|
| MANDATORY | ||
| Pricing Method | Pricing method name used for the call | |
| on (at request level) | Specifies the relevant date and time for date-related computations in the evaluation. For example, retrieving cost or discount percentages at some time specified in the future. | Current date time |
| OPTIONAL | ||
| on (at line level) | Specifies the relevant date and time for date-related computations in the evaluation. For example, retrieving cost or discount percentages at some time specified in the future. | |
| serviceOn (at line level) | Supplies the date and time of scheduled fulfillment, or service. Intended for use by applications that consider the time-of-service as distinctly separate from the instant at which it was proposed, contracted, or transacted (as represented by the query parameter on). Frequently used by service industries that book reservations (fares, accommodations, rentals) for a specific time, where the value may vary based on how far in advance the transaction occurs. For example, use this as the departure date time of a flight or rental date of a car. |
CPQ PRICING
| INPUT SETTINGS | DESCRIPTION | DEFAULT VALUE (IF NOT DEFINED) |
|---|---|---|
| MANDATORY | ||
| Pricing Method | Pricing method CPE used for the call | |
| Model Version | Version of the quote model in the Catalog Designer. It can be defined either via a static value (e.g. WORKING) or a dynamic value based on a quote field. | |
| OPTIONAL | ||
| Application Date | Specifies the relevant date for date-related computations in the evaluation. For example, retrieving cost or discount percentages at some date specified in the future. | Current date time |
| Server Name | The Advanced section allows you to define the Smart CPQ instance where prices are stored. If you use only 1 Smart CPQ instance, which is the standard and most common setup, this parameter is not necessary. However, if several instances of Smart CPQ are provisioned for your quote environment, you need to define the server name. The server name is created during the setup of your platform. Please reach out to your PROS representative to get this information. |
DIMENSIONS
Some settings are automatically sent when the Dimension service is called from the Quote. The settings can be configured from the Data Sources / Dimension page under the tab General Settings.
| INPUT SETTINGS | DESCRIPTION |
|---|---|
| MANDATORY | |
| LOCALE | Locale used for description |
DYNAMIC DOMAINS/FILTERS
The dynamic filters allows the user to retrieve values filtered by previous selections (more detail Domain and Dynamic Filters).
An automatic mapping is performed between quote variables and relation columns. A dynamic filter can be associated at Quote Level or at line template Level.
WORD BASED DOC GEN
| INPUT SETTINGS | DESCRIPTION | DEFAULT VALUE (IF NOT DEFINED) | WHERE TO CONFIGURE |
|---|---|---|---|
| MANDATORY | |||
| Quote ID | The quote ID | Current quote ID (_SYS_ROW_QUOTE_ID) | |
| Template name | The name of the template | On the action | |
| Output format | The output format (PDF, DOCX, etc.) | On the action |
CURRENCY CONVERSION
The conversion service is used to retrieve currencies and conversion rates.
| INPUT SETTINGS | DESCRIPTION | DEFAULT VALUE (IF NOT DEFINED) |
|---|---|---|
| MANDATORY | ||
| Date | Conversion date | Quote creation date (_SYS_CREATION_DATE) |
Info: For CPQ Pricing, the currency conversion is not addressed via the conversion service. It relies on a flat file embedding all conversion rates to be managed within the quote.
This file must be posted on the CPQ instance and its use should be activated via feature flags by PROS.
Here is an example of the format of the file to be used in that scenario:
{
"localCurrencies": { "currencies": [{
"id": "USD",
"precision": { "numerator": 1,
"denominator": 100
},
"rounding": {
"mode": "HALF_UP"
},
"label": {
"locale": "en-US", "value": "US Dollar"
},
"labels": [{
"locale": "en-US", "value": "US Dollar"
}, {
"locale": "fr-FR", "value": "Dollar US"
}],
"symbol": { "locale": "en-US",
"left": "$",
"right": ""
},
"symbols": [{
"locale": "en-US",
"left": "$",
"right": ""
}, {
"locale": "fr-FR",
"left": "",
"right": "$"
}],
"source": "default"
},
{
"id": "EUR",
"precision": { "numerator": 1,
"denominator": 100
},
"rounding": {
"mode": "HALF_UP"
},
"label": {
"locale": "en-US",
"value": "Euro"
},
"labels": [{
"locale": "en-US",
"value": "Euro"
}],
"symbol": { "locale": "en-US",
"left": "",
"right": "€"
},
"symbols": [{
"locale": "en-US",
"left": "",
"right": "€"
}],
"source": "default"
},
{
"id": "GBP",
"precision": { "numerator": 1,
"denominator": 100
},
"rounding": {
"mode": "HALF_UP"
},
"label": {
"locale": "en-US", "value": "Pound Sterling"
},
"labels": [{
"locale": "en-US", "value": "Pound Sterling"
}],
"symbol": { "locale": "en-US",
"left": "£",
"right": ""
},
"symbols": [{
"locale": "en-US",
"left": "£",
"right": ""
}],
"source": "default"
},
{
"id": "JPY",
"precision": { "numerator": 1,
"denominator": 1
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Japanese Yen"
},
"labels": [{
"locale": "en-US", "value": "Japanese Yen"
}],
"symbol": { "locale": "en-US",
"left": "¥",
"right": ""
},
"symbols": [{
"locale": "en-US",
"left": "¥",
"right": ""
}],
"source": "default"
},
{
"id": "CHF",
"precision": { "numerator": 1,
"denominator": 100
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Swiss Franc"
},
"labels": [{
"locale": "en-US", "value": "Swiss Franc"
}],
"symbol": { "locale": "en-US",
"left": "",
"right": "Fr"
},
"symbols": [{
"locale": "en-US",
"left": "",
"right": "Fr"
}],
"source": "default"
},
{
"id": "CAD",
"precision": { "numerator": 1,
"denominator": 100
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Canadian Dollar"
},
"labels": [{
"locale": "en-US", "value": "Canadian Dollar"
}],
"symbol": { "locale": "en-US",
"left": "$C",
"right": ""
},
"symbols": [{
"locale": "en-US",
"left": "$C",
"right": ""
}],
"source": "default"
},
{
"id": "MAD",
"precision": { "numerator": 1,
"denominator": 20
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Moroccan Dirham"
},
"labels": [{
"locale": "en-US", "value": "Moroccan Dirham"
}],
"symbol": { "locale": "en-US",
"left": "",
"right": "DH"
},
"symbols": [{
"locale": "en-US",
"left": "",
"right": "DH"
}],
"source": "default"
},
{
"id": "TND",
"precision": { "numerator": 1,
"denominator": 1000
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Tunisian dinar"
},
"labels": [{
"locale": "en-US", "value": "Tunisian dinar"
}],
"symbol": { "locale": "en-US",
"left": "",
"right": "DT"
},
"symbols": [{
"locale": "en-US",
"left": "",
"right": "DT"
}],
"source": "default"
},
{
"id": "THB",
"precision": { "numerator": 1,
"denominator": 100
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Thai baht"
},
"labels": [{
"locale": "en-US", "value": "Thai baht"
}],
"symbol": { "locale": "en-US",
"left": "",
"right": "฿"
},
"symbols": [{
"locale": "en-US",
"left": "",
"right": "฿"
}],
"source": "default"
},
{
"id": "ETH",
"precision": { "numerator": 1,
"denominator": 100000000
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Ethereum"
},
"labels": [{
"locale": "en-US", "value": "Ethereum"
}],
"symbol": { "locale": "en-US",
"left": "",
"right": "Ξ"
},
"symbols": [{
"locale": "en-US",
"left": "",
"right": "Ξ"
}],
"source": "default"
},
{
"id": "BTC",
"precision": { "numerator": 1,
"denominator": 100000000
},
"rounding": {
"mode": "UP"
},
"label": {
"locale": "en-US", "value": "Bitcoin"
},
"labels": [{
"locale": "en-US", "value": "Bitcoin"
}],
"symbol": { "locale": "en-US",
"left": "",
"right": "₿"
},
"symbols": [{
"locale": "en-US",
"left": "",
"right": "₿"
}],
"source": "default"
}
],
"conversions": [{
"base": "USD",
"quote": "USD", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "USD",
"quote": "EUR", "rate": {
"numerator": 373,
"denominator": 400
},
"source": "default"
},
{
"base": "USD",
"quote": "GBP", "rate": {
"numerator": 743,
"denominator": 1000
},
"source": "default"
},
{
"base": "USD",
"quote": "JPY", "rate": {
"numerator": 10659,
"denominator": 100
},
"source": "default"
},
{
"base": "USD",
"quote": "CHF", "rate": {
"numerator": 300,
"denominator": 400
},
"source": "default"
},
{
"base": "USD",
"quote": "CAD", "rate": {
"numerator": 300,
"denominator": 350
},
"source": "default"
},
{
"base": "USD",
"quote": "MAD", "rate": {
"numerator": 1000,
"denominator": 100
},
"source": "default"
},
{
"base": "USD",
"quote": "TND", "rate": {
"numerator": 1200,
"denominator": 100
},
"source": "default"
},
{
"base": "USD",
"quote": "THB", "rate": {
"numerator": 5000,
"denominator": 100
},
"source": "default"
},
{
"base": "USD",
"quote": "ETH", "rate": {
"numerator": 100,
"denominator": 1000
},
"source": "default"
},
{
"base": "USD",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 5000
},
"source": "default"
},
{
"base": "EUR",
"quote": "USD", "rate": {
"numerator": 400,
"denominator": 375
},
"source": "default"
},
{
"base": "EUR",
"quote": "EUR", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "EUR",
"quote": "GBP", "rate": {
"numerator": 184,
"denominator": 200
},
"source": "default"
},
{
"base": "EUR",
"quote": "JPY", "rate": {
"numerator": 11598,
"denominator": 100
},
"source": "default"
},
{
"base": "EUR",
"quote": "CHF", "rate": {
"numerator": 400,
"denominator": 500
},
"source": "default"
},
{
"base": "EUR",
"quote": "CAD", "rate": {
"numerator": 300,
"denominator": 250
},
"source": "default"
},
{
"base": "EUR",
"quote": "MAD", "rate": {
"numerator": 500,
"denominator": 100
},
"source": "default"
},
{
"base": "EUR",
"quote": "TND", "rate": {
"numerator": 800,
"denominator": 100
},
"source": "default"
},
{
"base": "EUR",
"quote": "THB", "rate": {
"numerator": 1000,
"denominator": 100
},
"source": "default"
},
{
"base": "EUR",
"quote": "ETH", "rate": {
"numerator": 10000,
"denominator": 100
},
"source": "default"
},
{
"base": "EUR",
"quote": "BTC", "rate": {
"numerator": 15000,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "USD", "rate": {
"numerator": 200,
"denominator": 159
},
"source": "default"
},
{
"base": "GBP",
"quote": "EUR", "rate": {
"numerator": 100,
"denominator": 82
},
"source": "default"
},
{
"base": "GBP",
"quote": "GBP", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "GBP",
"quote": "JPY", "rate": {
"numerator": 12598,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "JPY", "rate": {
"numerator": 12598,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "CHF", "rate": {
"numerator": 110,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "CAD", "rate": {
"numerator": 300,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "MAD", "rate": {
"numerator": 800,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "TND", "rate": {
"numerator": 1000,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "THB", "rate": {
"numerator": 1200,
"denominator": 100
},
"source": "default"
},
{
"base": "GBP",
"quote": "ETH", "rate": {
"numerator": 100,
"denominator": 1000
},
"source": "default"
},
{
"base": "GBP",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 2500
},
"source": "default"
},
{
"base": "JPY",
"quote": "USD", "rate": {
"numerator": 10000,
"denominator": 102
},
"source": "default"
},
{
"base": "JPY",
"quote": "EUR", "rate": {
"numerator": 10000,
"denominator": 187
},
"source": "default"
},
{
"base": "JPY",
"quote": "GBP", "rate": {
"numerator": 10000,
"denominator": 235
},
"source": "default"
},
{
"base": "JPY",
"quote": "JPY", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "JPY",
"quote": "CHF", "rate": {
"numerator": 8000,
"denominator": 100
},
"source": "default"
},
{
"base": "JPY",
"quote": "CAD", "rate": {
"numerator": 7000,
"denominator": 100
},
"source": "default"
},
{
"base": "JPY",
"quote": "MAD", "rate": {
"numerator": 1000,
"denominator": 100
},
"source": "default"
},
{
"base": "JPY",
"quote": "TND", "rate": {
"numerator": 800,
"denominator": 100
},
"source": "default"
},
{
"base": "JPY",
"quote": "THB", "rate": {
"numerator": 700,
"denominator": 100
},
"source": "default"
},
{
"base": "JPY",
"quote": "ETH", "rate": {
"numerator": 100000,
"denominator": 100
},
"source": "default"
},
{
"base": "JPY",
"quote": "BTC", "rate": {
"numerator": 200000,
"denominator": 100
},
"source": "default"
},
{
"base": "CHF",
"quote": "USD", "rate": {
"numerator": 1000,
"denominator": 700
},
"source": "default"
},
{
"base": "CHF",
"quote": "EUR", "rate": {
"numerator": 500,
"denominator": 400
},
"source": "default"
},
{
"base": "CHF",
"quote": "GBP", "rate": {
"numerator": 900,
"denominator": 1000
},
"source": "default"
},
{
"base": "CHF",
"quote": "JPY", "rate": {
"numerator": 11659,
"denominator": 100
},
"source": "default"
},
{
"base": "CHF",
"quote": "CHF", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "CHF",
"quote": "CAD", "rate": {
"numerator": 400,
"denominator": 350
},
"source": "default"
},
{
"base": "CHF",
"quote": "MAD", "rate": {
"numerator": 1000,
"denominator": 100
},
"source": "default"
},
{
"base": "CHF",
"quote": "TND", "rate": {
"numerator": 1200,
"denominator": 100
},
"source": "default"
},
{
"base": "CHF",
"quote": "THB", "rate": {
"numerator": 5000,
"denominator": 100
},
"source": "default"
},
{
"base": "CHF",
"quote": "ETH", "rate": {
"numerator": 100,
"denominator": 1000
},
"source": "default"
},
{
"base": "CHF",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 5000
},
"source": "default"
},
{
"base": "CAD",
"quote": "USD", "rate": {
"numerator": 110,
"denominator": 100
},
"source": "default"
},
{
"base": "CAD",
"quote": "EUR", "rate": {
"numerator": 373,
"denominator": 400
},
"source": "default"
},
{
"base": "CAD",
"quote": "GBP", "rate": {
"numerator": 743,
"denominator": 1000
},
"source": "default"
},
{
"base": "CAD",
"quote": "JPY", "rate": {
"numerator": 10859,
"denominator": 100
},
"source": "default"
},
{
"base": "CAD",
"quote": "CHF", "rate": {
"numerator": 300,
"denominator": 400
},
"source": "default"
},
{
"base": "CAD",
"quote": "CAD", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "CAD",
"quote": "MAD", "rate": {
"numerator": 1000,
"denominator": 100
},
"source": "default"
},
{
"base": "CAD",
"quote": "TND", "rate": {
"numerator": 1200,
"denominator": 100
},
"source": "default"
},
{
"base": "CAD",
"quote": "THB", "rate": {
"numerator": 5000,
"denominator": 100
},
"source": "default"
},
{
"base": "CAD",
"quote": "ETH", "rate": {
"numerator": 100,
"denominator": 1000
},
"source": "default"
},
{
"base": "CAD",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 5000
},
"source": "default"
},
{
"base": "MAD",
"quote": "USD", "rate": {
"numerator": 100,
"denominator": 300
},
"source": "default"
},
{
"base": "MAD",
"quote": "EUR", "rate": {
"numerator": 373,
"denominator": 700
},
"source": "default"
},
{
"base": "MAD",
"quote": "GBP", "rate": {
"numerator": 743,
"denominator": 1500
},
"source": "default"
},
{
"base": "MAD",
"quote": "JPY", "rate": {
"numerator": 500,
"denominator": 100
},
"source": "default"
},
{
"base": "MAD",
"quote": "CHF", "rate": {
"numerator": 500,
"denominator": 400
},
"source": "default"
},
{
"base": "MAD",
"quote": "CAD", "rate": {
"numerator": 300,
"denominator": 900
},
"source": "default"
},
{
"base": "MAD",
"quote": "MAD", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "MAD",
"quote": "TND", "rate": {
"numerator": 200,
"denominator": 100
},
"source": "default"
},
{
"base": "MAD",
"quote": "THB", "rate": {
"numerator": 300,
"denominator": 100
},
"source": "default"
},
{
"base": "MAD",
"quote": "ETH", "rate": {
"numerator": 100,
"denominator": 10000
},
"source": "default"
},
{
"base": "MAD",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 50000
},
"source": "default"
},
{
"base": "TND",
"quote": "USD", "rate": {
"numerator": 100,
"denominator": 500
},
"source": "default"
},
{
"base": "TND",
"quote": "EUR", "rate": {
"numerator": 373,
"denominator": 1200
},
"source": "default"
},
{
"base": "TND",
"quote": "GBP", "rate": {
"numerator": 743,
"denominator": 3000
},
"source": "default"
},
{
"base": "TND",
"quote": "JPY", "rate": {
"numerator": 10659,
"denominator": 12200
},
"source": "default"
},
{
"base": "TND",
"quote": "CHF", "rate": {
"numerator": 300,
"denominator": 1800
},
"source": "default"
},
{
"base": "TND",
"quote": "CAD", "rate": {
"numerator": 300,
"denominator": 1000
},
"source": "default"
},
{
"base": "TND",
"quote": "MAD", "rate": {
"numerator": 120,
"denominator": 100
},
"source": "default"
},
{
"base": "TND",
"quote": "TND", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "TND",
"quote": "THB", "rate": {
"numerator": 300,
"denominator": 100
},
"source": "default"
},
{
"base": "TND",
"quote": "ETH", "rate": {
"numerator": 100,
"denominator": 15000
},
"source": "default"
},
{
"base": "TND",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 55000
},
"source": "default"
},
{
"base": "THB",
"quote": "USD", "rate": {
"numerator": 110,
"denominator": 700
},
"source": "default"
},
{
"base": "THB",
"quote": "EUR", "rate": {
"numerator": 110,
"denominator": 900
},
"source": "default"
},
{
"base": "THB",
"quote": "GBP", "rate": {
"numerator": 200,
"denominator": 1500
},
"source": "default"
},
{
"base": "THB",
"quote": "JPY", "rate": {
"numerator": 300,
"denominator": 100
},
"source": "default"
},
{
"base": "THB",
"quote": "CHF", "rate": {
"numerator": 300,
"denominator": 1800
},
"source": "default"
},
{
"base": "THB",
"quote": "CAD", "rate": {
"numerator": 300,
"denominator": 1300
},
"source": "default"
},
{
"base": "THB",
"quote": "MAD", "rate": {
"numerator": 1000,
"denominator": 1100
},
"source": "default"
},
{
"base": "THB",
"quote": "TND", "rate": {
"numerator": 1200,
"denominator": 1100
},
"source": "default"
},
{
"base": "THB",
"quote": "THB", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "THB",
"quote": "ETH", "rate": {
"numerator": 100,
"denominator": 12000
},
"source": "default"
},
{
"base": "THB",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 52000
},
"source": "default"
},
{
"base": "ETH",
"quote": "USD", "rate": {
"numerator": 2000,
"denominator": 100
},
"source": "default"
},
{
"base": "ETH",
"quote": "EUR", "rate": {
"numerator": 2000,
"denominator": 120
},
"source": "default"
},
{
"base": "ETH",
"quote": "GBP", "rate": {
"numerator": 2000,
"denominator": 150
},
"source": "default"
},
{
"base": "ETH",
"quote": "JPY", "rate": {
"numerator": 106590,
"denominator": 100
},
"source": "default"
},
{
"base": "ETH",
"quote": "CHF", "rate": {
"numerator": 2000,
"denominator": 500
},
"source": "default"
},
{
"base": "ETH",
"quote": "CAD", "rate": {
"numerator": 2000,
"denominator": 350
},
"source": "default"
},
{
"base": "ETH",
"quote": "MAD", "rate": {
"numerator": 5000,
"denominator": 100
},
"source": "default"
},
{
"base": "ETH",
"quote": "TND", "rate": {
"numerator": 6000,
"denominator": 100
},
"source": "default"
},
{
"base": "ETH",
"quote": "THB", "rate": {
"numerator": 5500,
"denominator": 100
},
"source": "default"
},
{
"base": "ETH",
"quote": "ETH", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
},
{
"base": "ETH",
"quote": "BTC", "rate": {
"numerator": 100,
"denominator": 200
},
"source": "default"
},
{
"base": "BTC",
"quote": "USD", "rate": {
"numerator": 5000,
"denominator": 100
},
"source": "default"
},
{
"base": "BTC",
"quote": "EUR", "rate": {
"numerator": 5730,
"denominator": 400
},
"source": "default"
},
{
"base": "BTC",
"quote": "GBP", "rate": {
"numerator": 7430,
"denominator": 500
},
"source": "default"
},
{
"base": "BTC",
"quote": "JPY", "rate": {
"numerator": 156590,
"denominator": 100
},
"source": "default"
},
{
"base": "BTC",
"quote": "CHF", "rate": {
"numerator": 5000,
"denominator": 400
},
"source": "default"
},
{
"base": "BTC",
"quote": "CAD", "rate": {
"numerator": 3000,
"denominator": 350
},
"source": "default"
},
{
"base": "BTC",
"quote": "MAD", "rate": {
"numerator": 10000,
"denominator": 100
},
"source": "default"
},
{
"base": "BTC",
"quote": "TND", "rate": {
"numerator": 12000,
"denominator": 100
},
"source": "default"
},
{
"base": "BTC",
"quote": "THB", "rate": {
"numerator": 15000,
"denominator": 100
},
"source": "default"
},
{
"base": "BTC",
"quote": "ETH", "rate": {
"numerator": 200,
"denominator": 100
},
"source": "default"
},
{
"base": "BTC",
"quote": "BTC", "rate": {
"numerator": 1,
"denominator": 1
},
"source": "default"
}
]
}
}
Please contact your PROS representative for more details.
External Systems
The PROS Platform can be connected to external systems to extend standard capabilities of the product.
These extensions can be:
- UI extensions - PROS Smart CPQ is able to display external user interfaces with the External Widgets
- Data extensions - PROS Smart CPQ is able to call or to retrieve some data from external sources with the External Data Sources or the Custom Processes
EXTERNAL WIDGET
Performance Quoting allows the administrator to add a widget in a page displaying an external UI: External widgets.
External widgets are configured with a URL. This URL can be built in Performance Quoting in order to send some context to the external UI (product name for example). However, some system tokens can be sent dynamically in the URL if they are needed in the external widget. These tokens will be replaced automatically at runtime:
https://URL.com/oauth2-client/secure/aad?login_hint=$USER_ID&tenant=$TENANT_ID&env=$ENV IRONMENT_ID&productId='ABC'
| SETTINGS | DESCRIPTION |
|---|---|
| OPTIONAL | |
| USER_ID | Current User ID |
| TENANT_ID | Tenant ID |
| ENVIRONMENT_ID | Environment ID |
EXTERNAL DATA SOURCES
In addition to the data sent by the quote and defined by the administrator in the quote model, some context data are sent automatically in the requestContext section of the query.
| SETTINGS | DESCRIPTION |
|---|---|
| MANDATORY | |
| tenantId | Tenant ID |
| environmentId | Environment ID |
| userId | User ID |
| quoteId | Quote ID |
| requestId | Request ID |
| locale | Quote locale |
CUSTOM PROCESS
In addition to the data sent by the quote and defined by the administrator in the quote model, some context data are sent automatically in the requestContext section of the query performed to the external system.
| SETTINGS | DESCRIPTION |
|---|---|
| MANDATORY | |
| tenantId | Tenant ID |
| environmentId | Environment ID |
| userId | User ID |
| quoteId | Quote ID |
| requestId | Request ID |
| locale | Quote locale |
Scaled Pricing
OVERVIEW
Scaled Pricing is a feature part of Smart CPQ but it leverages other modules of the PROS platform:
- Control: Scale grids are created and associated with component types. It is also where the negotiated scale grids are published at the end of the process via the Agreement module.
- Real Time Pricing: Real Time Pricing makes the connection between Control and Smart CPQ. It is responsible for providing scale grids to CPQ and to calculate projections/target prices for each scale break of a given grid.
- Smart CPQ: CPQ is the interface where you can see, create, and negotiate scale grids and where input is defined for RTPE to compute scaled prices.
- Agreements: Module responsible for building an Agreement from the CPQ quote and to publish negotiated scale grids to Control when approved.
Two main workflows can leverage scale pricing:
- Quote-to-Order: Scale data is available as read only. No scaled pricing negotiation is involved and the scale data is displayed as a support for decision on the quantity to agree on to get the right price.
- Quote-to-Agreement: Scale grids can be read, created, and edited. The negotiation is focused on
the scale grid content itself and not on the target price per se.
DATA FLOW
Here is the data flow associated with the scaled pricing feature. Depending on the scenario, some of the steps below are optional or executed in a different order.
This chapter describes in detail the different steps of the below diagram:
- - Define Scales in Control
This action is done by the Pricing Manager in Control. The main actions to perform consists in:
- Creating Scaled Component Types.
- Reviewing, editing and managing scaled prices from the Master Price List.
Find more details on this step on Connect: Scaled PricingNo Content found for /db/organizations/conga/repositories/current/content/documents/Production/Price_Management/user_guide/pricing_managing_prices/pricing_managing_prices_scaled_pricing.dita
- - Publish Scales from Control to Real Time Pricing
This step is done in Control. It consists of making the component types, scale structure, and data available to Real Time Pricing.
This is an admin task that must be performed in order for the data to be available for request from Smart CPQ to Real Time Pricing.
- - Get Scaled Grid
There are two use cases where Smart CPQ may need to retrieve a scale grid from Real Time Pricing:
- To visualize a given scale grid in the quote interface as an help to place quantities and negotiate prices. This is a typical use case in the Quote To Order scenario.
- To retrieve the reference scale grid that is currently in use and start negotiating a new one on that base as part of an agreement. This is more focused on the Quote To Agreement scenario.
In the second case above, if the product has no scale grid associated in Control yet, but is authorized to have one created from scratch in CPQ, the Get Scale Grid call returns the metadata of the grid to-be-created in CPQ (calculation method, offset type, etc.).
In order for CPQ to retrieve a scale grid, here are the elements sent to the Real Time Pricing Engine:
| Inputs - Quantity Scale | Mandatory? | Default Value | Where to Model |
| Key (Row Item + optional dimension) | Yes | Spreadsheet Model | |
| Outputs - Quantity Scale | |||
| Scale Grid |
- - Get Scaled Price
There are two use cases where Smart CPQ may need to retrieve a scale-based price from Real Time Pricing:
- To get a price in the Quote when the Sales Rep modifies the corresponding threshold (quantity).
- To compute the price projections, meaning the target price for each scale break, in a given scale grid.
In both scenarios, the price computation may be based on the reference scale grid or the negotiated one:
- If in a Quote To Order scenario, there is no negotiated scale grid and the price computation only requires to send elements related to the product (SKU, threshold value, etc.) to get a price. This price will be based on the reference scale grid.
- In a Quote To Agreement scenario, the scale grid to consider for price computation is the negotiated one as the Sales Rep wants to see the impact of changes in the Quote on the scaled prices. In addition to the elements related to the product (SKU, threshold value, etc), the negotiated scale grid also must be sent by CPQ to the pricing engine to get a price back.
- In addition, in the Quote To Agreement scenario, anytime the scale grid prices must be computed again, the overall grid must be sent to the pricing engine - as above. The re-computed scale grid is also sent back from the pricing engine to CPQ.
We also differentiate the case where the threshold is a volume (and has a UoM) from the case where the threshold is a quantity (no UoM, no currency).
Those elements are summarized in the below table:
| Inputs - Quantity Scale | Mandatory? | Default Value | Where to Model |
| Key (Row Item + optional dimension) | Yes | Spreadsheet Model | |
| Threshold (Quantity) | Yes | Spreadsheet Model | |
| Line Item UoM | Yes | A conversion occurs if necessary. If not possible, the UoM stored in Control is used. | Spreadsheet Model |
| Scale Grid | Optional (only if the CPQ scale grid must be used for computation) | Spreadsheet Model | |
| Outputs - Quantity Scale | |||
| Target Price (e.g. List Price) | |||
| Scale Grid (updated) |
- - Negotiate Scales
The Scales negotiation consists in modifying the structure or data within scale grids. It also consists in computing prices in the Quote based on scaled pricing. That negotiation leverages the "Get Scaled Price" and "Get Scale Grid" actions detailed above.
- - Render Scales
Once negotiated in Smart CPQ, Scale Grids can be rendered in a proposal document. The scale grids are retrieved as part of an export of the Quote and inserted in documents.
For more details on PROS Doc Gen data flow, see the corresponding section in Data flows - PROS Services.
More details on the export are given below.
- - Export Scales
As part of the Quote To Agreement scenario, scale grids must be shared by Smart CPQ to the Agreement module. The scale grids are stored in columns of the Quote. They can be exported as part of a standard Quote export. The Agreement module then retrieves the scale grids as part of that export.
- - Approve Scales
As part of the Agreement module, an approval process can be run to validate the Quote. This process is the standard process managed by the Agreement module.
- - Publish Scales
Once approved, Agreements are then published to Control. As part of that data flow, scale grids are also published. Component types, scale grids and prices are then updated in Control and become the new reference for future transactions.
In terms of the workflow, we are back to step 1 where the new reference scale grid and prices are published to Real Time Pricing for further use in CPQ.
- - Import Scales
As part of the Quote To Agreement workflow, it may happen that an agreement must be amended or renewed for instance.
In terms of workflow, it means that the process starts from an existing agreement/quote and not
from scratch like in steps 1 - 3 in the diagram.
In order to do so, Smart CPQ imports an agreement as part of a new quote to start negotiating the amendment / renewal.
Scale grids that may be part of that agreement are imported as well in Smart CPQ.
Scale pricing is not supported as part of the CPQ Pricing scenarios.
