Skip to main content

Updating a Data Group

In the Fenergo SaaS platform a Data Group is a collection of data points used to represent a Sub-Entity. It might be an Account or an Address. A comparison in more traditional Data Modelling would be a link table for an address which references a parent record. This is exactly how we model the staging files for Data Migration but when the Requirements In Scope call is made, one of the requirement types returned can be a data group.

Data Groups are created in Policy Configuration screen, and are like creating a new Data Type which can then be used across any policy that refers to that type.

APIs Referenced
Entity Data Command
Policy Query
Update Data Group Use Case
  AS: an API consumer:

GIVEN: I have created a new Client Legal Entity Draft Record

AND: The Requirements in Scope indicate I need to save a Data Group Type

WHEN: I send an update of data

THEN: I want to get all the details about the Data Group and save an entry in the Legal Entity Draft Record.

Getting Data Group Details

To create and add a Data Group to a Legal Entity Record you need to first understand the structure of that Data Group. From the previous section where we looked at Updating Entity Data and Advancing Journeys the call to retrieve Data Requirements returned the following. In the below example a Data Group has been added as an example.

Policy Query Get Requirements In Scope - JSON POST Response (Partial) Response
{
"data": [
.
.
. . . { . . .Other Data Fields . . .}
.
.
{
"dataField": {
"propertyName": "addresses",
"propertyType": "dataGroup",
"propertyTypeId": "8b4a9f2c-9747-467d-a90c-b915ec2210c9",
"propertyTypeVersion": 6,
"linkChildFieldPropertyName": null
},
"validationRule": {
"id": "09b4ce9c-b4d9-4761-a864-29c93160b096",
"setId": "4543c522-6242-444a-92ec-5865718ea0bc",
"propertyId": "63eda646-152c-4a8b-9fc5-d48d49ca4e66",
"propertyName": "addresses",
"friendlyName": "Addresses",
"validationType": "dataGroup",
"isDataGroup": false,
"dataGroupId": "8b4a9f2c-9747-467d-a90c-b915ec2210c9",
"validationData": {
"isMandatory": null,
"specialCharacters": null,
"noNumbers": null,
"onlyInteger": null,
"noNegative": null,
"onlyDecimal": null,
"regex": null,
"characterLimit": null,
"numberLimit": null,
"noFutureDates": null,
"noPastDates": null,
"dateLimit": null,
"multiSelectLimit": null,
"collectionMinimumCount": null,
"collectionMaximumCount": null
}
},
"order": null,
"defaultValue": null,
"isReadOnly": false,
"isIndexable": false,
"isMandatoryIndexable": false,
"conditionalValues": null,
"rootVersionId": "904f7166-3e78-4991-bb83-715464508816",
"versionNumber": 45,
"id": "e12cda39-b786-49bf-86fd-b7b5442fd7b2",
"tenant": null,
"category": "Basic Details",
"description": "Correspondence - The address that will be used to communicate with the client for mail and legal documents.",
"template": null,
"entityType": "Company",
"name": "Addresses",
"isSensitiveData": false,
"isMaterialData": true,
"isCoreDefinition": false,
"jurisdiction": "Global",
"dataProtectionJurisdiction": null,
"references": [],
"targetEntity": "Client",
"classification": null,
"type": "Data",
"conditions": [],
"RequirementSetId": "d8319029-0a83-43cc-b104-8f7f8526e94a",
"discriminator": "Data",
"version": -1,
"isLocked": false
},
.
.
. . . . { . . . Other Data Fields . . . }
.
.
.
],
"messages": null
}

In the above partial Requirements in Scope response we can see the main details needed to identify a Data Group Requirement Type. Highlighted in "propertyName" is the Name of the Requirement which is Addresses and the "propertyType" which is Data Group. Further down the message is the "dataGroupId" field. This identifier is passed into the Policy Query API where the Data Group Fields can be retrieved.

Retrieving the Structure of a Data Group

The Policy Query API has a Data Group GET method where we can retrieve the currently active version of a Data Group. The Data Group Id is passed as part of the URL. Data Groups themselves are complex data types, they have versions and can change over time along with potentially having conditionality and validation rules and containing lookups.

HTTP GET URL FORMAT:
================
{{baseURL}}/policyquery/api/v2/data-group/{dataGroupId}

HTTP PUT URL:
================
{{baseURL}}/policyquery/api/v2/data-group/**8b4a9f2c-9747-467d-a90c-b915ec2210c9**
Policy Query Get Data Group by Id - JSON GET Response (Partial)
{
"data": {
"dataGroupFields": [
{
"identifier": "570717dd-90df-42c3-8d34-4aebb6aae1c4",
"name": "Country",
"type": "DataGroup",
"order": 4,
"dataField": {
"propertyName": "country",
"propertyType": "select",
"propertyTypeId": "3f8c573c-ff7e-461d-a1d7-3080ae67b916",
"linkChildFieldPropertyName": null
},
"isSensitiveData": true,
"isCoreDefinition": false,
"validationRule": {
.
.
. . . {. . Validation Data . . }
.
.
}
},
"conditions": [],
"version": 27,
"defaultValue": null,
"isReadOnly": false,
"conditionalValues": null,
"hasEvaluatedConditionalValue": false,
"evaluatedConditionalValue": null
},
{
"identifier": "bf844911-0862-4554-9b22-0e0e32d9f636",
"name": "Address Line 1",
"type": "DataGroup",
"order": 2,
"dataField": {
"propertyName": "addressLine1" ,
"propertyType": "text" ,
"propertyTypeId": null,
"linkChildFieldPropertyName": null
},
"isSensitiveData": false,
"isCoreDefinition": false,
"validationRule": {
.
.
. . . {. . Validation Data . . }
.
.
}
},
"conditions": [],
"version": 27,
"defaultValue": null,
"isReadOnly": false,
"conditionalValues": null,
"hasEvaluatedConditionalValue": false,
"evaluatedConditionalValue": null
.
.
. . . {. . Other Data Group Fields . . }
.
.
],
"id": "548436b4-0c14-4801-9f40-f8c02d83456c",
"groupId": "8b4a9f2c-9747-467d-a90c-b915ec2210c9",
"name": "Addresses",
"description": "Geographical location of the client",
"primaryDataGroupField": "addressType",
"cardinality": true,
"template": null,
"versionNumber": 7,
"effectiveFrom": "2022-06-13T00:00:00+00:00",
"effectiveUntil": null,
"publicationDate": "2022-06-13T13:24:26.771+00:00",
"status": "Published",
"created": "2022-06-13T13:24:11.068+00:00",
"isActive": true,
"signees": [
{
"subject": "b6c4558f-5463-4113-906f-ea519ce214d4",
"successor": null,
"action": {
"comment": null,
"decision": "Approve",
"created": "2022-06-13T13:24:26.771+00:00"
},
"hasProcessedRequest": true
}
],
"version": 27
},
"messages": null
}

Updating a Data Group into a Draft Record

Updating the data for a legal entity is done by sending a PUT message to the entitydataCommand API. You reference the Legal Entity Id along with the Draft Id in the URL and send a JSON message with all the data points and values you want to update. The below example is similar to the one shown previously updating Legal Entity Data but this contains a Data Group Entry.

HTTP PUT URL FORMAT:
================
{{baseURL}}/entitydatacommand/api/v2/entity/{entityId}/draft/{entityDraftId}**

HTTP PUT URL:
================
{{baseURL}}/entitydatacommand/api/v2/entity/2ed9f965-342a-4dc8-afb8-58b8de41cd5f/draft/0b588152-85ef-4223-908b-684214144541**
Save Entity Data (including a Data Group Entry) PUT Request
  {
"data": {
"entityType": "Company",
"properties": {
"country": {
"type": "Single",
"value": "Ireland"
},
"dateOfIncorporation": {
"type": "Single",
"value": "2021-12-31"
},
"countyInIreland": {
"type": "Single",
"value": "Galway"
},
"companyType": {
"type": "Single",
"value": "Bank"
},
"legalEntityName": {
"type": "Single",
"value": "Acme Finance Group"
},
"category": {
"type": "Single",
"value": "Corporation"
},
"addresses": {
"type": "Collection",
"dataGroupId": "8b4a9f2c-9747-467d-a90c-b915ec2210c9",
"collections": {
"ee4ebf52-3bbf-4bb9-b2ed-c7d1868a7530": {
"properties": {
"addressType": "Registered",
"addressLine1": "10 The Rise",
"addressLine2": "Some Street",
"addressLine3": "Some Town",
"country": "Ireland"
}
}
}
}
},
"jurisdictions": [
{
"jurisdiction": "Global",
"versionId": "d8319029-0a83-43cc-b104-8f7f8526e94a"
}
],
"category": [
"Basic Details",
"Booking Details"
],
"version": 4,
"targetEntity": "Client"
}
}

  • "addresses" is the Data Group item. The Type property is Collection "type":"Collection" and there is a "collections array which stores all the entries.

  • "dataGroupId" is the identifier for the data group, this tells the system what KIND of data group being updated. This is validated against the Categories in the category field in the same way as any data type.

  • "properties" are are the keys and values of the Data Group entry. In this case it is just a simple address.

  • "ee4ebf52-3bbf-4bb9-b2ed-c7d1868a7530" At the root of the collections array is a GUID which is unlabelled. This is a collection Id, and can be thought of as a foreign key identifier for the Data Group Entry. If there were multiple addresses, this identifier is what differentiates each address. The client or calling application is responsible to create this GUID when adding a new Data Group entry.

info

When Updating Data Group Data, the collection Id must be referenced or else they system will not accept the update. If you supply a new collection Id, a new data group entry will be made and the previous data will stay in place.

How to Create a GUID for adding a collection Item

As mentioned, it is the responsibility of the client application to create a GUID. This is straightforward in most coding languages, some examples below:

Create a GUID in C# / Python / Javascript

Create a GUID in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication {
class Program {
static void Main(string[] args) {
Guid obj = new Guid();
Console.WriteLine("New Guid is " + obj.ToString());
}
}
}
Create a GUID in Python
import uuid
newGuid = uuid.uuid1()
print ("New Guid is "+ str(newGuid))

Unlike the other examples, Javascript does not have a library to create GUIDs so you would need to be creative in the implementation. In the below example using Math.Random() to generate identifiers.

Create a GUID in Javascript
**function** CreateUUID() {
function CreateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return 'New Guid is '+v.toString(16);
});
}