Conga Product Documentation

Welcome to the new doc site. Some of your old bookmarks will no longer work. Please use the search bar to find your desired topic.

Show Page Sections

Synchronization

In the following chapter we describe how to parameterize the Managed Package and Quote Models to handle data flows between the Salesforce Quote object and the CPQ Quote object.

Warning: These modifications require:

Knowledge of CPQ model setup

Basic understanding of Salesforce set-up capabilities.

Note: Please refer to Quote Model Specificities for SFDC to know how to access and modify the CPQ Quote model.

Understanding the Synchro IN - SFDC to CPQ



Salesforce data is often needed in the Quote Model such as information about the quote itself, or its opportunity, etc. One way of getting this information is to use what is referred as Mapping IN.

Note: There are limitations to data available by Mapping IN - only Quote fields, objects linked to the Quote (parent entity), or child objects of a parent entity.

For other objects see Custom Mapping IN & Fetching.

The Mapping IN consists in pushing context data from Salesforce to CPQ when:

  • The Quote is initialized - see below
  • The Quote fields are changed (Lightning Only)

Once data is pushed it can be accessed and handled in the Quote Model Definition.

Before detailing what information is included in the Mapping IN and how to retrieve it from the Quote Model, please review the process of Quote Initialization.

information: PASSED IN CONTEXT DATA
  • Quote Fields (implicit mapping)
  • Entities and child of entities (mapping set)
  • system fields such as quote ID and user profile (CRM Group)

MAPPING IN DATA STRUCTURE

Context data passed from Salesforce is stored in a map of key / values.

  • System fields each have their own key / values and can be retrieved as session variables in the Quote Model
  • Other data is stored in a JSON string and passed as one key / value in the map.

SYSTEM FIELDS

Two system fields are transmitted to the CPQ Quote and can be retrieved by configuring the Quote Model

  • ID of Salesforce Quote (CRM_QUOTE_ID) - mandatory to perform the synchronization back from CPQ to Salesforce.
  • CRM Group (CRM_GROUP) used for Access Right Management.

Two other system fields are automatically passed to the CPQ Quote. Any change in these values is passed to the CPQ Quote.

  • Reference currency
  • Language - the default language in the quote is the Salesforce user language.

There is no need to retrieve these values as they are automatically assigned to the quote currency and local.

IMPLICIT SMART CPQ QUOTE FIELDS MAPPING

The standard fields (default fields of the Smart CPQ Quote entity included in the managed package) and custom fields (of the Smart CPQ Quote entity) are automatically passed to the CPQ Quote. They can be accessed in the context as part of the CPQ Model Definition.

EXPLICIT EXTERNAL FIELDS MAPPING

In addition to Smart CPQ Quote fields being passed to the CPQ quote, more fields can be injected in the CPQ quote.

To do so:

  • Fields must be eligible
  • A Mapping Set must be defined
  • The Mapping Set must be referenced in the Smart CPQ setup for relevant Record Types.

These are explained in the following section.

FIELDS ELIGIBILITY

It is possible to inject values from Salesforce entity fields (external fields) into CPQ module on conditions that these entities are linked to the Smart CPQ Quote Object.

Note: We consider that an entity is linked to the Smart CPQ Quote Object if:
  • A look-up relationship has been defined between the Smart CPQ Quote and the entity (1-to-1 relationship - parent Entity)
    • For example, in the default managed package, the Account is a linked Salesforce entity
  • The entity is a child of an entity linked to the Smart CPQ Quote via a look-up type of relation (1-to-n relationship - a 2nd level Entity)
    • For example, in the default managed package, the Asset is a child entity of the AccountId.

DEFINING A MAPPING SET

To pass some eligible fields values into CPQ, you need to define a Smart CPQ Mapping Set.

  • [In the Smart CPQ Mapping Set]

    (If not activated check your access rights)

    Create a new (or edit an existing) Smart CPQ Mapping Set.

    • Click on New
    • Enter a name for your mapping set (Note: all names must be unique)
    • Select CPQx as the source.

  • [In the Smart CPQ Mapping Set Builder]

    Define the external fields you want to pass to the CPQ module:

    • Ensure that the Mapping IN is selected:
    • By default, the tree view shows all the ‘parent’ Entities:
    • If you want to map ‘2nd level’ Entities, you first need to add this entity in the mapping. To add a child entity (e.g. Assets) of a linked object (e.g. Account) select the entity in the tree, click on the ‘Add’ button, and select the chosen child entity in the displayed combo box.
    • Select the fields you want to pass to CPQ. Select the entity from the tree (on the left), and then check the boxes of the fields you want to map (on the right)
    • Click on Save

DEFINING THE SMART CPQ SETUP

In the Smart CPQ Setup tab, open a Record Type. Fill in the Mapping Set name that you want to use for that record. See Smart CPQ Setup and Record Type for more details.

Custom Mapping IN & Fetching

Standard Mapping IN allows you to get data from Salesforce to the Quote Model.

However, only a certain scope of objects can be reached: quote fields, entities linked to the quote object, and a child of these entities.

For other objects there are two ways to access them from the Quote:

  • Either by Fetching Context from Salesforce
  • Or by adding to the scope of the standard IN Synchro - Custom Mapping IN

Fetching context is powerful but does not allow a specific record to be fetched from a large list of assets. If you use Fetching, you will retrieve in the Quote Model all the Assets, and then you will have to filter them down.

When only specific assets need to be sent, it is advised to use Custom Mapping IN to add to the scope of the standard Mapping IN.

CUSTOM MAPPING IN

Specifying the additional information to include in the Mapping IN is done in an APEX class. There are no particular restrictions on what can be included, keeping in mind that you should only send to CPQ what is actually needed in CPQ.

You will need to create an APEX class and reference that class in Smart CPQ Setup for your Record Types: "Mapping IN Custom Apex Class."

The APEX class will add a new key/value pair to the context being sent to Smart CPQ.

The new value added is a JSON, similar to the "SFDC" JSON sent in the standard Mapping IN. The new JSON value can then be parsed in the quote or configurator to retrieve values in it.

Custom Mapping IN

global with sharing class QxCustomMappingIN implements CameleonCPQ.CPQMappingUtils.IMappingIN {

// Use this method to send all custom mapping IN values into one big JSON value (parsing mechanism to be defined in Qx model) - RECOMMENDED

global List<CameleonCPQ.CPQMappingUtils.Tuple> getCustomAttributes(Id entityId) {

final List<CameleonCPQ.CPQMappingUtils.Tuple> contextCustomEntries = new List<CameleonCPQ.CPQMappingUtils.Tuple>();

/*---------------------------------------------------------------------------

* Method 1 :All values are aggregated into a single JSON value (One entry in the Context)

* RECOMMENDED - EXECUTEJSONPATH formulas must be used in the quote model to extract values

*---------------------------------------------------------------------------

-*/

final Map<String,Object> jsonEntries = new Map<String,Object>();

/*

String field

*/

String myString = 'myString';

jsonEntries.put('string_Field',new Map<String,Object>{'string' => myString});

/*

Boolean field

*/

Boolean myBoolean = true;

jsonEntries.put('boolean_Field',new Map<String,Object>{'boolean' => myBoolean});

/*

Integer field

*/

Integer myInteger = 1;

jsonEntries.put('int_Field',new Map<String,Object>{'integer' => myInteger});

/*

BigDecimal field

*/

Decimal myDecimal = 100.5;

jsonEntries.put('dec_Field',new Map<String,Object>{'bigDecimal' => myDecimal});

/*

Percentage field

*/

Double myPercent = 10;

jsonEntries.put('percent_Field',new Map<String,Object>{'percentage' => (myPercent/100)});

/*

Monetary field

*/

Decimal myAmount = 100.5;

String myCurrency = UserInfo.getDefaultCurrency();

Map<String,Object> myMonetary = new Map<String,Object>{'amount' => myAmount, 'currencyCode' => myCurrency};

jsonEntries.put('monetary_Field',new Map<String,Object>{'monetary' => myMonetary});

/*

LocalDate field

*/

Date today = Date.today();

Map<String,Object> myDate = new Map<String,Object>{'year' => today.year(), 'month' => today.month(), 'day' => today.day()};

jsonEntries.put('date_Field',new Map<String,Object>{'localDate' => myDate});

/*

DateTime field

*/

DateTime now = DateTime.now();

jsonEntries.put('datetime_Field',new Map<String,Object>{'dateTime' => now.getTime()});

/*

Business field

*/

String myName = 'myName';

String myType = 'myType';

String myNamespace = 'myNamespace';

String myDescr = 'myDescription';

Map<String,Object> myBusiness = new Map<String,Object>{'name' => myName, 'type' => myType, 'namespace' => myNamespace, 'description' => myDescr};

jsonEntries.put('business_Field',new Map<String,Object>{'business' => myBusiness});

/*

Domain from Context (Business field)

*/

List<String> bvalValues = new List<String>

{'wksHiTech/SI/NET207','wksHiTech/SI/MOB_011','wksHiTech/SI/I14R-1440TMR'};

List<Object> domainValues1 = new List<Object>();

for(String v : bvalValues) {

domainValues1.add(new Map<String,Object>{'string' => v});

}

jsonEntries.put('domainFromContextBval_Field',new Map<String,Object>{'multiple' => domainValues1});

/*

Domain from Context (String field)

*/

List<String> strValues = new List<String> {'value1','value2','value3'};

List<Object> domainValues2 = new List<Object>();

for(String v : strValues) {

domainValues2.add(new Map<String,Object>{'string' => v});

}

jsonEntries.put('domainFromContextString_Field',new Map<String,Object>{'multiple' => domainValues2});

/*

Domain from Context (Integer field)

*/

List<Integer> intValues = new List<Integer> {1,2,3};

List<Object> domainValues3 = new List<Object>();

for(Integer v : intValues) {

domainValues3.add(new Map<String,Object>{'integer' => v});

}

jsonEntries.put('domainFromContextInt_Field',new Map<String,Object>{'multiple' => domainValues3});

/******

Finally, aggregate all entries into a single JSON entry (key=SFDC_CUSTOM_MAPPING_IN)

******/

contextCustomEntries.add(new CameleonCPQ.CPQMappingUtils.Tuple('SFDC_CUSTOM_MAPPING_IN',new JsonValue(JSON.serialize(jsonEntries,true))));

/*---------------------------------------------------------------------------

* Method 2 :Each value is sent in a separate entry of the Context

*---------------------------------------------------------------------------

-*/

final List<CameleonCPQ.CPQMappingUtils.Tuple> individualEntries = new List<CameleonCPQ.CPQMappingUtils.Tuple>();

individualEntries.add(new CameleonCPQ.CPQMappingUtils.Tuple('string_Field',new StringValue('myString')));

contextCustomEntries.addAll(individualEntries);

return contextCustomEntries;

}

/**

* A CPQx Public API Value.

*

* @author dev_sfdc

*/

@JsonAccess(serializable='always' deserializable='always') // This annotation must added when Apex class API level is 49.0 or higher

public abstract class QxValue

{

/** The value type (String, BigDecimal, Boolean, Business, Currency, DateTime, Integer, Json, LocalDate, Locale, Long, Monetary, Multiple, Percentage, UnitOfMeasure, Xml) */

public String valueType {public get; private set;}

}

/**

* A CPQx Public API String Value.

*

* @author dev_sfdc

*/

@JsonAccess(serializable='always' deserializable='always')

public class StringValue extends QxValue

{

/** The value */

public String value {public get; private set;}

/**

* Constructor.

*

* @param value The value.

*/

public StringValue(String value)

{

this.valueType = 'String';

this.value = value;

}

}

/**

* A CPQx Public API Json Value.

*

* @author dev_sfdc

*/

@JsonAccess(serializable='always' deserializable='always')

public class JsonValue extends QxValue

{

/** The value */

public String value {public get; private set;}

/**

* Constructor.

*

* @param value The value.

*/

public JsonValue(String value)

{

this.valueType = 'Json';

this.value = value;

}

}

}

FETCHING CONTEXT

Mapping IN is performed when the quote is initialized, then every time a field is changed on the Quote object.

For cases where data is out of reach by Mapping IN or when you don't want too much context data sent too often, you can use the Context Fetching.

Understanding the Synchro OUT - CPQ to Salesforce



Upon clicking the Close action (CloseSpreadsheet action) the Smart CPQ Quote entity is updated by implicit mapping.

Smart CPQ Quote and Smart CPQ Quote Lines are updated accordingly.

Defining what quote fields and lines should be synchronized is done as part of the CPQ Model Definition.

IMPLICIT SMART CPQ QUOTE FIELDS AND SMART CPQ QUOTE LINE FIELDS MAPPING

Warning:

The standard fields and custom fields (of the Smart CPQ Quote entity) are automatically synchronized if the name of the field (minus ‘c’) in the quote model is identical to the field name in the Force.com Smart CPQ Quote entity.

The case is sensitive.

In the case of managed fields (ex: total) the name in the QPC Model should include CameleonCPQ (ex: CameleonCPQ total)

For the specific case of a standard field (or custom field) of type ID (LookUp field) :

  • either the Salesforce field is valuated with the value of the CPQ field if (and only if) the CPQ value corresponds to the ID of an already existing entity on Salesforce side.
  • or the Salesforce field is valuated with the ID of the first entity whose Name matches the CPQ

    value.

Locked Quote or Read-Only Quote

Warning:

If the quote is locked or read-only (CRM_SESSION_LOCKEDQUOTE or CRM_SESSION_READONLYQUOTE equal true), then the OUT synchronization is not performed.

Status & Currency Synchronization

Any time the Quote object is created or updated, a standard trigger is executed to sync the following:

  • Currency
  • Status

Each of these fields has a property to enable or disable the synchronization by trigger. See below.

Currency Synchro:

In the case where Multi-currency is enabled in Salesforce, it is possible to synchronize the currency of the Quote object with the CPQ Quote reference currency field (the exact field name is CurrencyIsoCode. The other way around isn't currently supported.

The synchronization occurs any time the Quote object is created or updated (standard QxQuoteTrigger trigger), whether the Quote is modified via UI or by custom code (Apex).

To enable the currency sync, two actions are required:

  • In Smart CPQ Setup: Enable the currency sync (checkbox).
  • In the Quote Model: Declare the reference currency field (_SYS_REF_CURRENCY) properly and flag it as "User input", and map it with the CurrencyIsoCode.

Warning

The currencies you manipulate between systems must be defined in CPQ to prevent raising errors during the synchronization. When relevant, the conversion rates between the various currencies must also be known by CPQ.

Status Synchro

ARM (Access Rights) can be placed on the quote to restrict some operations.

When it comes to synchronizing the quote status, the status can be updated from CPQ to Salesforce and the other way around.

Synchronization from Salesforce to CPQ Quote is performed by the QxQuoteTrigger trigger that calls the setStatus API. This API call will take ARMs into consideration when attempting to update the status.

Synchronization from CPQ Quote is performed by usual Mapping Out.

To enable the status synchro, to actions are required:

  • In Smart CPQ Setup: Enable the status sync (checkbox).
  • In the Quote Model: Declare the status field properly and include it in the mapping out view.

Opportunity Products Synchronization

DESCRIPTION

What

Quote Lines Mapping to Products

The Managed Package maps quote lines with SFDC Products. Please note that SFDC Products are not created on the fly, only mapped.

Opportunity Product Synchronization

The Managed Package creates / updates / deletes Opportunity Products based on quote lines. There is no update to Price Books. Only quote lines mapped to actual products are synchronized. Folders are not synchronized.

When

  • Product Mapping; when the quote lines are created. Typically when we synchronize the CPQ quote with the SFDC quote
  • Opportunity Products Synch: there are two new APIs to create lines from a quote, or delete lines on an opportunity.
    • Either you use the “packaged” version, then the APIs are called in predefined cases to create opportunity products
      • When a quote is set as “Active”
      • When a quote is already active and quote lines have been created
      • When a quote is already active and its opportunity value is changed
    • Or you don’t. You can then create and delete opportunity products whenever you want leveraging the APIs in Apex.

How

Based on attributes filled in the Smart CPQ Mapping Set object.

  • Product Mapping: when a Smart CPQ Quote Line is being created, we check its Smart CPQ Item Name (this is the SI name in CPQ).

If a SFDC Product is found with the same value in its ProductCode, then we map the Smart CPQ Quote Line and SFDC Product. Otherwise, we assign the fallback product defined for the line type: Product (catalog items, configuration lines), or Specific.

  • Opportunity Products are created for each quote line mapped to a Product.

Opportunity Products are created on the Opportunity tied to the Quote. They are created following the same order as Quote Lines. Opportunity Products are created / updated / deleted based on a technical ID carried by the Smart CPQ Quote Line.

RUNTIME

Product Mapping

Product mapping is performed when we create Smart CPQ Quote Lines. Most often that is when we synchronize from CPQ to SFDC (Close Quote button). At that time if the CPQ product item matches with a SFDC product, then we store that product ID in the lookup field defined in the Mapping Set. If not, we store the fallback value provided for the given line template.



Note: To see the product reference you will need to edit the default Smart CPQ Quote Line layout.


When doing this match we compare the CPQ Quote Item Name (this is the SI name in CPQ) with SFDC Products ProductCode.

Opportunity Product Synchronization



The synchronization is performed in three cases:

  • When user clicks the “Set as Active” button of the quote The process is synchronous and will display a spinner until the synchronization is complete.
  • Quote is Active, then user selects a new Opportunity
  • Quote is Active, and we perform the quote synchronization and its status is Complete

In these cases, when synchronizing Opportunity Products:

  • We delete all existing Opportunity Products previously created by the Smart CPQ Managed Package
  • We create new Opportunity Products based on Quote lines
Note: The above algorithm, regardless of the order Opportunity Products are created, they can be displayed in the same order as Smart CPQ Quote Lines thanks to an ordering field that can be leveraged in the Opportunity Products layout.

SETUP

A number of fields are required to successfully drive the Opportunity Products synchronization. These fields must be created manually. The MP cannot create these by default as they are hosted on Opportunity and Product objects. The Managed Package cannot make reference to these entities.

Once the fields have been created, they can be filled in in the Mapping Set. Some fields MUST have a precise name. See the "Summary of fields to be created" section before creating any field.

Two new tabs are available:

Product Mapping: (OUT) Smart CPQ Quote Lines / Salesforce Products

This tab drives the mapping of Smart CPQ Quote Lines with Salesforce Products.

--
ActiveWhen enabled the mapping is performed
Product Lookup FieldThe name of the Smart CPQ Quote Line field to be filled at the time of mapping
Product Line Fallback CodeThe code of the Product to be used as fallback when a Smart CPQ Quote Line of type Product doesn't match with any Product.
Specific Line Fallback CodeThe code of the Product to be used as fallback when a Smart CPQ Quote Line of type Specific doesn't match with any Product.

Opportunity Product Synch: (OUT) Smart CPQ Quote Lines / Salesforce Opportunity Products

This tab drives the creation of Opportunity Products from Smart CPQ Quote Lines.

Salesforce Opportunity Products

--
ActiveWhen enabled the synchronization is performed
Parent Opportunity Lookup Field (Smart CPQ Quote)The name of the Smart CPQ Quote field that carries the parent Opportunity. Opportunity Products will be created on that Opportunity.
Active Quote Lookup Field (Opportunity)The name of the Opportunity field that carries the Active Quote.
Opportunity Products Synchronization Status (Opportunity)The name of the Opportunity field that gives the synchronization status of Opportunity Products. This is used to prevent concurrent synchronizations on a single Opportunity.
Note: The API that created / updates / deletes Opportunity Products will ignore the “Active” flag. This flag is only used to trigger or not the “packaged” version of Opportunity Products Synch.

Fields Mapping for Salesforce Opportunity Products

--
Synchronization identifier (Opp. Product field)The name of the Opportunity Product field that carries the unique ID used for managing create / update / delete.
Opportunity Product Field Responsible for OrderingThe name of the Opportunity Product field that will be used to order the Opportunity Products.

The table below allow you to choose how to map information from Smart CPQ Quote Lines to Opportunity Products.



Summary of fields to be created

WHATWHERETYPENAMING CONVENTIONNOTE
Parent Opportunity Lookup FieldSmart CPQ QuoteLookup toward OpportunityName is free. Example: OpportunityIdMake Visible for all profiles and add this field to all layouts, then save.
Product Lookup FieldSmart CPQ Quote LineLookup toward ProductName is free. Example Product2IdMake Visible for all profiles and add this field to all layouts, then save.
Active Quote Lookup FieldOpportunityLookup toward Smart CPQ Quote (QxQuote)Name is free. Example QxActiveQuoteIdMake Visible for all profiles and add this field to all layouts, then save.
Opportunity Synch StatusOpportunityPicklistNaming convention MUST be respected. Name = QxOppSyncStatus Values = IN_PROGRESS / ERROR / COMPLETEMake Visible for all profiles and add this field to all layouts, then save.
Opportunity Product Field Responsible for OrderingOpportunity ProductsNumber(6,0)Name is free. Example QxDisplaySequenceMake Visible for all profiles and add this field to all layouts, then save.
Synchronization identifierOpportunity ProductsText(255)Name is free. Example QxQuoteLineSynchIdMake Visible for all profiles and add this field to all layouts, then save.

Finally, you will want to add the “Set As Active” button to your Smart CPQ Quote page layout.

EDGE CASES, ERROR MANAGEMENT, LIMITATIONS

Concurrent Synchronizations

The Opportunity Synchronization Status field can inhibit the opportunity products synchronization.

We don’t want multiple synchronization to run concurrently on a same opportunity. Whenever the Opportunity Products Synch is triggered on an Opportunity that has its Opportunity Synch Status value to “In Progress”, the synchronization will not occur. Only in the case of the Activate button will we be able to show an error message. In other cases a status will be shown on the Quote.

Examples

  • Activate a Quote on an Opportunity that has its synch status to “In progress”
  • Synchronize an Active quote on an Opp that has its synch status to “In progress”
  • Assign a new Opportunity to a Quote, and the new opportunity has its synch status to “In progress”
  • Assign a new Opportunity to a Quote and the previous opportunity has its synch status to “In progress”
  • Clear the Opportunity of a Quote and the Opportunity has its synch status to “In progress”

Re-assigning Opportunities, Multiple Active Quotes

If an Opportunity (Opp1) has its Active quote re-assigned to another Opportunity (Opp2), then the relevant Opportunity Products in Opp1 (those that have a synch identifier) will be cleared. If a Quote is Activated on an Opportunity that already had an Active Quote, then we delete the Opportunity Products from the previous Active Quote.

Errors

Users will be prompted with an error message in the following cases:

  • Click on Set as Active and no Mapping Set associated at all for the Smart CPQ Quote.
  • Click on Set as Active and the flag Active is not checked in the Mapping Set.
  • Click on Set as Active but the Quote doesn’t have a parent Opportunity
  • Click on Set as Active but the quote was already Set as Active.

Limitations

  • There is no "Set as Inactive" button. You may create another quote and set it as Active. You may also clear the Opportunity field. In both cases the corresponding Opportunity Products will be cleared from the Opportunity.
  • There is no visual information on the quote that it is Active

Advanced Sync Modes

Options are available if you need to activate specific modes for the sync from Smart CPQ to the CRM.

As this synchronization is triggered from the Close & Synchronize action defined in the CPQ Quote Model, their activation must be done in the Quote Designer.

SYNC IN SYSTEM MODE

Note: The flag Sync in System Mode responsible for the activation of this sync mode is available as a parameter of the Close & Synchronize action in the Quote Designer.

This mode allows syncing back all the CPQ content defined in a given sync view, whatever your profile and access rights. You can thus synchronize data that you do not have access to. When the data is synced to the CRM, permissions defined by the CRM and CPQ administrators still apply, and only the data which access is authorized for your profile is visible to you.

Please note that this mode must be activated both in the CRM and CPQ to be operational. If it is activated in the CRM only, you might experience new behaviors on CRM environments with customizations running on top of the Smart CPQ Managed Package.

SYNC EMPTY VALUES

Note: The flag Sync Empty Values responsible for the activation of this sync mode is available as a parameter of the Close & Synchronize action in the Quote Designer.

Force the sync of fields and / or columns that have been emptied in CPQ. All the CRM fields mapped on emptied CPQ fields / columns are thus emptied during the sync.

The sync of empty values is deactivated by default. When the Sync Empty Value flag is checked, the CPQ fields and columns that have been emptied are synced back to the CRM. The consequence is that any CRM field mapped on an emptied CPQ field or column is also emptied during the sync back. Its previous value, if any, is thus overridden with an empty value.

If a CRM field cannot be overridden (e.g. read-only), then it is not emptied during the sync.

SYNC HIERARCHY AND FPK

Note: The flag Sync Hierarchy and FPK responsible for the activation of this sync mode is available as a parameter of the Close & Synchronize action in the Quote Designer.

Force the sync of parent hierarchy when quote lines are part of a sync view in CPQ without their hierarchy.

Example:

  • Let's consider a quote with the following lines:
    • Product A
    • Folder 1
      • Product B
  • Now let's assume that the following sync view has been defined by your Administrator:
    • Product A
    • Product B
  • In that example, if the flag Sync Hierarchy and FPK is checked then, the following lines will be synced to the CRM:
    • Product A
    • Folder 1
      • Product B
  • If the flag Sync Hierarchy and FPK is not checked, the following lines will be synced to the CRM:
    • Product A
    • Product B