ERP: Extending an existing integration

Integration Framework v1 has been phased out. This documentation is no longer maintained - we recommend using Integration Framework v2 instead.

The Integration Framework is a collection of components for transferring data and maintaining data consistency between a Dynamicweb solution and a remote system - read more here if you are not familiar with the integration framework in general.

You are reading this article because you want to either:

  • Extend an existing feature to include more data
  • Add a new feature to an integration

The features included in our plugins/code units out of the box are fairly limited – by design, we import only the standard fields from your ERP which are directly relevant for a Dynamicweb solution.

Broadly speaking, extending or adding a feature requires you to:

  • Modify the ERP plugin/code unit code to extract more data when receiving a request
  • Wrap the data in the appropriate XML format
  • Return it to Dynamicweb

Here are some of the most common scenarios explained.

To extend product or user synchronization with additional information, simply add more columns to the response and return them with the appropriate data.

There are two possible scenarios when extending product and users sync:

  • The data is appropriate for a standard field in Dynamicweb
    If the data fits seamlessly into the standard Dynamicweb fields, e.g. if it’s a product description or a tax code, the column name should be named after the system name of the field is in Dynamicweb. If the Dynamicweb side of the integration uses automatic mapping in their integration activities, everything will be linked up automatically.
  • Dynamicweb does not contain an appropriate standard field
    If Dynamicweb does not contain an appropriate standard field, the Dynamicweb side of the integration must create a custom field for the data to be stored in. The column should be named after the system name of the custom field. Both sides of the integration – your side and the Dynamicweb side – must keep the data type in mind when deciding on the type of custom field needed.

If you want to import variants using the Dynamicweb Provider, you need to add data to the following tables:

  • EcomVariantGroups must contain one row for each language version of each variantGroup you are importing.
  • EcomVariantsOptions must contain one row for each language version of each option for each group.

So, if you have color and size as variant groups, and color options are red and blue, size options are small and large, this table must contain 4 rows. The VariantOptionId can be any string, as long as it is unique for each variant option, when combined with the languageID.

Naturally, you must also add data to the EcomProducts table – and there are several things you need to be aware of:

  • Add one row to the EcomProducts table for each variant and a “base” row for the product. This means that if you have a product “shoe”, which is available in colors red and blue, sizes large and small, you will add 5 rows to the database – one for “shoe” and one for each variant.
  • Add values to the ProductVariantCounter. The ProductVariantCounter must contain the total number of variants for this product, so each of the mentioned 5 rows should contain the value 4, since there are a total of 4 variants of the product.
  • Add values to the ProductVariantGroupCounter. The ProductVariantGroupCounter must contain the total number of variants for this product, so each of the mentioned 5 rows should contain the value 2, since there are two variant groups, color and size.
  • The VariantID column must contain a concatenation of the variantIDs for the variant options a given row fall under, combined by a period. So assuming “red” has variantID V01 and “small” has variantID “V05”, the small red variant row must have variantID “V01.V05”. The order of the variant IDs is not important.

Then you need to associate a product with a variant group, in order to determine which variants are available for the product:

<tables> <table tableName="EcomVariantgroupProductRelation"> <item table="EcomVariantgroupProductRelation"> <column columnName="VariantgroupProductRelationID"><![CDATA[VARGRPPRODREL_147954024_115085237]]></column> <column columnName="VariantgroupProductRelationProductID"><![CDATA[PROD1]]></column> <column columnName="VariantgroupProductRelationVariantGroupID"><![CDATA[VAR_113117498]]></column> <column columnName="VariantgroupProductRelationSorting"><![CDATA[0]]></column> <column columnName="VariantgroupProductRelationPriceDif"><![CDATA[False]]></column> </item> </table> </tables>

The mandatory fields are:

  • VariantgroupProductRelationID
  • VariantgroupProductRelationProductID
  • VariantgroupProductRelationVariantGroupID

Finally, you need to import the active variants for a product:

<item table="EcomVariantOptionsProductRelation"> <column columnName="VariantOptionsProductRelationProductID"><![CDATA[PROD1]]></column> <column columnName="VariantOptionsProductRelationVariantID"><![CDATA[V1.V2.V3.V4]]></column> </item>

To extend user synchronization with user segments (groups), you must add the following tables and columns to the user import response:

<table tableName="AccessUserGroup"> <item table="AccessUserGroup"> <column columnName="AccessGroupGroupName"><![CDATA[ParentGroup]]></column> <column columnName="AccessGroupName"><![CDATA[ParentGroup]]></column> <column columnName="AccessGroupParentGroupName"><![CDATA[]]></column> <column columnName="AccessGroupExternalId" ><![CDATA[ExternalGroup1]]></column> </item> <item table="AccessUserGroup"> <column columnName="AccessGroupGroupName"><![CDATA[SubGroup]]></column> <column columnName="AccessGroupName"><![CDATA[SubGroup]]></column> <column columnName="AccessGroupParentGroupName"><![CDATA[ParentGroup]]></column> <column columnName="AccessGroupExternalId" ><![CDATA[ExternalGroup2]]></column> </item> </table>

The AccessUserGroup table contains user groups, and has a column called AccessGroupParentGroupName. This column can contain either the name of the parent group (AccessGroupName) or a groupID. Group names are used if importing from an external source – please note that if you have more than one group with the same name, your product will be added to one of them at random.

To relate users to groups, add the name of the group to the column AccessUserGroups in the AccessUser table. This column can contain a comma separated list of the groups that the user should be added to:

<column columnName="AccessUserGroup"><![CDATA[ParentGroup]]></column>

To extend user synchronization with impersonation information, you must add data to the AccessUserSecondaryRelation table.

It has two relevant columns:

  • AccessUserSecondaryRelationUserID
  • AccessUserSecondaryRelationSecondaryUserId

Both columns may contain either an AccessUserID (if known) or the AccessUserUserName for both the impersonator and the user being impersonated.

<table tableName="AccessUserSecondaryRelation"> <item table="AccessUserSecondaryRelation"> <column columnName="AccessUserSecondaryRelationUserId"><![CDATA[UserInParentGroup]]></column> <column columnName="AccessUserSecondaryRelationSecondaryUserId"><![CDATA[UserInSubgroup]]></column> </item> </table>

When importing data to these columns, Dynamicweb first checks if a user exists with the included UserID. If that’s not the case, we check if a user exists with an ExternalUserID that matches the included ID.

If not, the row will be ignored.

The AccessUserSecondaryRelationSecondaryUserId column can also contain a customer number - AccessUser.AccessCustomerNumber - which does not have to be a unique number, so several users can share the same customer number.

The following code imports all customers with customer number 1234 to be impersonated by user 321654987 - so if 10 users have the customer number 1234, 10 records will be generated in the AccessUserSecondaryRelation table matching the impersonator and the impersonatees.

<table tableName="AccessUserSecondaryRelation"> <item table="AccessUserSecondaryRelation"> <column columnName="AccessUserSecondaryRelationUserID"><![CDATA[321654987]]></column> <!-- Ref: AccessUser.AccessUserExternalID --> <column columnName="AccessUserSecondaryRelationSecondaryUserID"><![CDATA[1234]]></column> <!-- Ref: AccessUser.AccessCustomerNumber --> </item> </table>

Assortments are subsets of a product catalog, which are accessible to only specific users or user segments.

When importing assortments, the target data format is as follows:

<?xml version="1.0" encoding="utf-8"?> <tables> <table tableName="EcomAssortmentGroupRelations"> <item table="EcomAssortmentGroupRelations"> <column columnName="AssortmentGroupRelationAssortmentID"><![CDATA[ASSORTMENT1]]></column> <column columnName="AssortmentGroupRelationGroupID"><![CDATA[GROUP35]]></column> <column columnName="AssortmentGroupRelationAutoID"><![CDATA[1]]></column> </item> </table> <table tableName="EcomAssortmentPermissions"> <item table="EcomAssortmentPermissions"> <column columnName="AssortmentPermissionAssortmentID"><![CDATA[ASSORTMENT1]]></column> <column columnName="AssortmentPermissionAccessUserID"><![CDATA[363]]></column> <column columnName="AssortmentPermissionAutoID"><![CDATA[7]]></column> <column columnName="AssortmentPermissionCustomerNumber"><![CDATA[]]></column> </item> </table> <table tableName="EcomAssortmentProductRelations"> <item table="EcomAssortmentProductRelations"> <column columnName="AssortmentProductRelationAssortmentID"><![CDATA[ASSORTMENT1]]></column> <column columnName="AssortmentProductRelationProductID"><![CDATA[PROD16]]></column> <column columnName="AssortmentProductRelationProductVariantID"><![CDATA[]]></column> <column columnName="AssortmentProductRelationAutoID"><![CDATA[1]]></column> <column columnName="AssortmentProductRelationProductNumber" isNull="true" /> </item> </table> <table tableName="EcomAssortments"> <item table="EcomAssortments"> <column columnName="AssortmentID"><![CDATA[ASSORTMENT1]]></column> <column columnName="AssortmentLanguageID"><![CDATA[LANG1]]></column> <column columnName="AssortmentName"><![CDATA[My assortment]]></column> <column columnName="AssortmentNumber"><![CDATA[]]></column> <column columnName="AssortmentPeriodID" isNull="true" /> <column columnName="AssortmentLastBuildDate"><![CDATA[22-06-2016 16:00:01:623]]></column> <column columnName="AssortmentRebuildRequired"><![CDATA[False]]></column> <column columnName="AssortmentAutoID"><![CDATA[1]]></column> <column columnName="AssortmentActive"><![CDATA[True]]></column> <column columnName="AssortmentIncludeSubgroups"><![CDATA[False]]></column> <column columnName="AssortmentAllowAnonymousUsers"><![CDATA[False]]></column> </item> </table> <table tableName="EcomAssortmentShopRelations"> <item table="EcomAssortmentShopRelations"> <column columnName="AssortmentShopRelationAssortmentID"><![CDATA[ASSORTMENT1]]></column> <column columnName="AssortmentShopRelationShopID"><![CDATA[SHOP4]]></column> <column columnName="AssortmentShopRelationAutoID"><![CDATA[1]]></column> </item> </table> </tables>

The following tables and fields are mandatory:

  • EcomAssortments
    • AssortmentID
    • AssortmentActive
  • EcomAssortmentPermissions
    • AssortmentPermissionAssortmentID (ID of assortment)
    • AssortmentPermissionCustomerNumber (customer number the assortment is for)

At least one of these tables and its mandatory fields is also required:

  • EcomAssortmentProductRelations
    • AssortmentProductRelationAssortmentID (id of assortment)
    • AssortmentProductRelationProductID (id of product in the assortment)
  • EcomAssortmentShopRelations
    • AssortmentShopRelationAssortmentID
    • AssortmentShopRelationShopID
  • EcomAssortmentGroupRelations
    • AssortmentGroupRelationAssortmentID (ID of assortment)
    • AssortmentGroupRelationGroupID (ID of product group)