Skip to main content

360degree

Auto-generated

This page is imported automatically from an external repository.

Source project: Open repository

Introduction

The 360Degree_entity models the relations between specific Entities and enables the user to work with these dependencies via the 360DegreeFilter_view, which includes the ViewTemplates "Tree" and "Timeline".

Currently, the 360Degree logic is restricted to relations of Contact_entity (i.e., of companies and persons). This means that

  • the 360Degree View can only be referenced in the MainViews of the Contexts "Organisation" and "Person" (appearing as tab "360 Degree");
  • the 360Degree View can only include datasets (records) of Contexts having a relation to Context "Contact" (directly or via a "junction Context") - such as the Contexts "Salesproject", "Offer", or "Order" do.
note

This documentation requires you to be familiar with the "ADITO xRM" project's data model, especially the data structure for managing datasets of persons and companies (i.e., the function of the database tables PERSON, ORGANISATION, and CONTACT - see chapter "Core tables of the xRM project" of the document "Customizing Manual").

This documentation will

  • explain the basics of the 360Degree logic, using examples of the ADITO xRM project;
  • teach you how you can include further Contexts in the existing 360Degree View implementations, using a plain and hands-on example.

This documentation does not include a description of how to implement a 360Degree View in the MainView of Contexts other than Organisation and Person. Nevertheless, in principle, you can customize this by yourself, according to you requirements, using the 360 Degree logic as pattern.

Basics

To understand how to modify the behavior of the 360DegreeFilter_view in existing implementations or how to add them to further Contexts, you need to be aware of some basics regarding specific mandatory fields as well as the configuration of specific Provider, Consumer, and Parameters.

RecordContainer

The core of the 360Degree_entity's logic is the contentProcess of its jDitoRecordContainer. There, a tree (or timeline) structure is created, with

  • the Entities' titles as root nodes
  • (if configured, see below:) specific sub-nodes, used for grouping
  • the datasets of the Entities on 2nd or, if a grouping applies, on 3rd level

Mandatory settings

The logic of the jDitoRecordContainer's contentProcess requires the Contexts, which are to be included in the 360Degree View, to have specific EntityFields and properties well-configured.

EntityFields

The following EntityFields must be present and configured in all Entities whose datasets are to be included in the 360Degree View:

  • ACTIVE The value of this EntityField determines whether or not a dataset will be shown. Often, the value of this EntityField is being calculated in property "expression" of the corresponding RecordFieldMapping (e.g., via a CASE/WHEN SQL statement).
  • DATE_NEW The value of this EntityField will be used in the ViewTemplate "Timeline". Its calculation follows the standard logic for this EntityField.
warning

Both EntityFields must be present and named exactly as shown above. Otherwise the logic will fail.

Properties

The following propertys are not essential, but if they are missing, the appearance of the Context's datasets will be suboptimal:

  • Entity properties:
    • contentTitleProcess: The result of this process will, in this case, appear as "headlines" of the datasets shown in the 360Degree View, including a hyperlink to the datasets' MainView. If this property is not set, the datasets' primary keys will be displayed.
    • contentDescriptionProcess: The result of this process will, in this case, appear as "sub-headlines" of the datasets shown in the 360Degree View.
  • Context properties:
    • icon/iconProcess: Specifies the icon that will be shown to the left of the headline/sub-headline. Usually, this should be the same icon as the icon of the Entity (i.e., the icon shown in the sidebar, to the left of the client) - except when a grouping (see below) is configured (in this case, the iconProcess should be used, in order to show different icons for each group).

Providers and Consumers

The dependencies (relations) between the 360Degree Context and the Contexts referencing the 360Degree View in their MainViews are, as usual in ADITO, established via a Provider and a Consumer (one for each dependency).

Providers

The 360Degree Context must have a Provider for each dependency, named according to the Pattern <Context name>Objects. Examples:

  • OrganisationObjects, for supplying the 360Degree tab in the OrganisationMain_view
  • PersonObjects, for supplying the 360Degree tab in the PersonMain_view

The following property values need to be set (they are the same for each Provider):

  • targetContextField: TARGET_CONTEXT
  • targetidField: TARGET_ID
  • initFilterMergeMode: AND

All other Provider properties should usually remain in default state.

Consumers

The above mentioned Providers need to be referenced by Consumers of the Contexts that show the 360Degree View in their MainView (i.e., currently, only the Contexts "Organisation" and "Person").

These Consumers should always be named 360DegreeObjects (spelling convention, no technical requirement) and have the following properties set:

  • entityName: 360Degree_entity
  • fieldName: name of specific provider - e.g., OrganisationObjects, or PersonObjects, respectively

All other Consumer properties should usually remain in default state.

Parameters

The 360Degree_entity has the following Parameters, each having property "expose" set to true:

  • BaseContextId_param
  • ObjectRowId_param
  • ObjectStatus_param
  • ObjectType_param
warning

These Parameters have been predefined by the ADITO xRM developers. Never rename them and never change the configuration of their originals under node "Parameters", but only modify their instances appearing under the nodes of the respective 360Degree_entity's Providers or under the Consumers connected to these Providers, respectively.

Services

In modularized Adito projects the 360Degree_entity has the following services:

  • 360DegreePersonObjectType_service: Used to set the value of ObjectType_param for Persons in the respective module. The implementation of this service returns a function which returns a json object.
  • 360DegreeOrganisationObjectType_service: Used to set the value of ObjectType_param for Organisations in the respective module. The implementation of this service returns a function which returns a json object
  • 360DegreeLibContextData_service: In case you want to extend the entity data shown in the 360degree_entity, you can implement this service.
  • 360DegreeLibContextRow_service: In case you want to extend the entity data shown in the 360degree_entity, you can implement this service.

For more general Information on modularization and services see ServicesDocumentation

Provider Parameter settings

The Parameters "ObjectRowId_param" and "ObjectStatus_param" are configured exclusively on Consumer side (see below). Therefore, leave their instances appearing under node "Providers" in default state (do NOT initialize them). This makes sure that their original property "expose" keeps its value "true", which makes them appear on Consumer side.

The Parameters "BaseContextId_param" and "ObjectType_param" are configured exclusively on Provider side. Therefore, their instances under the node "Provider" must be initialized and have their property "expose" set to "false". This overwrites the original setting ("true", see above) and thus makes sure that these Parameters do not appear on Consumer side.

The valueProcesses of the 2 Parameter instances need to be set as follows (all other properties should remain in default state):

BaseContextId_param

BaseContextId_param's valueProcess must supply the name of the Context, whose MainView should show the 360Degree View. Example:

360Degree_entity.OrganisationObjects.BaseContextId_param.valueProcess.js

import("system.result");

result.string("Organisation");
ObjectType_param

ObjectType_param's valueProcess must supply a JSON String including information about the names of all Contexts to be shown in the 360Degree View. In modularized Adito xrm projects the value process of this parameter is set in the respective modules of the contexts to be shown in the 360degree_view, via the service implementation of the services 360degreeOrganisationObjectType_service and 360DegreePersonObjectType_service.

Example:

result.string(JSON.stringify({
"Salesproject": {},
"Offer": {},
"Contract": {}));

Example service implementation:

// @ts-ignore
return function(pJson)
{
pJson["SerialLetter"] = {
"subContext": "LetterRecipient",
"childField": "SERIALLETTER_ID",
"parentField": "SERIALLETTERID",
"contactIdField": "CONTACT_ID"
};
};

(Scroll further down, in order to see the complete example code of a valueProcess. This might help you to understand the following explanations of optional settings better.)

Optionally, the following features can be specified via JSON properties (included in the curly brackets behind the Context name), separately for each Context:

  • connectionField: The name of the Context's EntityField that works as foreign key pointing to the other side of the relation, i.e., to EntityField CONTACTID of Context "Contact". Example: "connectionField":"TASK_REQUESTOR_CONTACT_ID" (enabling to show datasets of Context "SupportTicket"). This property must only be set if its value is other than "CONTACT_ID".
  • Grouping: If configured, the datasets of the respective Context are grouped into sub-nodes.
    • setGroupBy: This mandatory property specifies the EntityField whose values determine the grouping. Example (belonging to Context "Order"): "setGroupBy":"ORDERTYPE" effects a grouping of the "Order" datasets into sub-nodes labelled with the respective value of Order_entity's EntityField ORDERTYPE.
    • groupByKeyword (optional): If (as in the above example) the values of the EntityField specified via setGroupBy are KeywordEntry keys, then you can optionally specify the corresponding KeywordCategory via property groupByKeyword. The effect will be that the grouping nodes will no longer show the KeywordEntries' keys, but their titles. Example: If you specify "groupByKeyword":"OrderType", then "Invoice" (=TITLE) will be shown instead of "ORDTYPEINVO" (= KEYID).
  • Junction table: You can specify a Context that works as junction between the Context that shows the 360Degree View and the Context that is to be shown in this View. Example: Context "BulkMailRecipient" works as "junction Context" between the Context "BulkMail" and Context "Contact", in order to enable the user to assign a specific contact (person) to a specific bulk mail.

The configuration of a "junction Context" requires 4 properties to be set:

  • subContext: The name of the "junction Context". Example: "subContext":"BulkMailRecipient"
  • childField: The name of the EntityField of the subContext that includes the foreign key related to the primary key of the "parent" Context (i.e., of "BulkMail", in our example). Example: "childField":"BULKMAIL_ID"
  • parentField: The name of the EntityField of the "parent" Context that in cludes the primary key, to which the foreign key of the "child" context relates. Example: "parentField":"BULKMAILID"
  • contactIdField: The name of the subContext's EntityField that works as foreign key pointing to the other side of the relation, i.e., to EntityField CONTACTID of Context "Contact" (in our example, this is the CONTACTID of the recipient). Example: "contactIdField":"CONTACT_ID"

Example:

360Degree_entity.OrganisationObjects.ObjectType_param.valueProcess.js

import { result, vars } from "@aditosoftware/jdito-types";

var res = {
"Salesproject": {},
"Offer": {},
"Order": {
"setGroupBy":"ORDERTYPE",
"groupByKeyword":"OrderType"
},
"Contract": {},
"SupportTicket": {
"connectionField":"TASK_REQUESTOR_CONTACT_ID",
"setGroupBy":"NameFor360"
},
"Advertising": {},
"BulkMail": {
"subContext":"BulkMailRecipient",
"childField":"BULKMAIL_ID",
"parentField":"BULKMAILID",
"contactIdField":"CONTACT_ID"
},
"SerialLetter": {
"subContext":"LetterRecipient",
"childField":"SERIALLETTER_ID",
"parentField":"SERIALLETTERID",
"contactIdField":"CONTACT_ID"
}
}

result.string(JSON.stringify(res))

Consumer Parameter settings

If set correctly on Provider side (see above), instances of the Parameters "ObjectRowId_param" and "ObjectStatus_param" will appear under each Consumer "360DegreeObjects" (see above). As mentioned before, currently, there are only 2 Contexts having this Consumer: "Organisation" and "Person".

ObjectRowId_param

This Parameter's valueProcess retrieves (in JSON format) the CONTACTIDs of all involved Contact datasets - i.e., all CONTACTIDs to be used for retrieving the related Contexts' datasets, according to their "connectionField" (= foreign key, which is usually named "CONTACT_ID", but can also have a different name - see description of property "connectionField" above).

This means, in Context "Person", the result of this valueProcess is simply a JSON String with the CONTACTID connected to the Person dataset:

Person_entity.360DegreeObjects.ObjectRowId_param.valueProcess.js

import { result, vars } from "@aditosoftware/jdito-types";

result.string(JSON.stringify([vars.getString("$field.CONTACTID")]));

In Context "Organisation", the result of this valueProcess is a JSON String including the CONTACTIDs of both the selected company and all persons belonging to this company:

.Organisation_entity.360DegreeObjects.ObjectRowId_param.valueProcess.js

import { newSelect, newWhere } from "SqlBuilder_lib";
import { result, vars } from "@aditosoftware/jdito-types";

var contactids = newSelect( "CONTACTID" )
.from("CONTACT")
.where("CONTACT.ORGANISATION_ID", vars.getString("$field.ORGANISATIONID"))
.orderBy(new SqlMaskingUtils().isNull("PERSON_ID", "'0'"))
.arrayColumn();

result.string(JSON.stringify(contactids));
note

As already mentioned at the beginning of this documentation, currently, the 360Degree logic is restricted to relations of Contact_entity (i.e., of companies and persons). Therefore, the CONTACTID is the central reference here, as it (exlusively) identifies datasets of companies or persons, respectively. If you want to implement a 360Degree View in the MainView of Contexts other than Organisation and Person, you can use the 360 Degree logic as pattern, but you need to find another EntityField as central reference.

ObjectStatus_param

For both instances of Consumer "360Degree" (= in Contexts "Person" and "Organisation"), the result of this Parameter's valueProcess is simply the value of the EntityField holding the state of the selected person/company:

Person_entity.360DegreeObjects.ObjectStatus_param.valueProcess.js and Organisation_entity.360DegreeObjects.ObjectStatus_param.valueProcess.js

import { result, vars } from "@aditosoftware/jdito-types";

result.string(vars.get("$field.STATUS"));

This Parameter's value is evaluated in the stateProcess of 360Degree_entity's ActionGroup "newModule", which controls whether or not the 360Degree View shows a button for creating new datasets for the referenced Contexts (Sales Project, Contract, Order, etc.): If the selected person or company is in state "Inactive" or "To Delete" (i.e., if its EntityField "STATUS" has the keyword-related value "CONTACTSTATINACTIVE" or "CONTACTSTATDELETE"), then this button is disabled.

Example for extending 360Degree View

As a plain and hands-on teaching example, here are the instructions for the task "Include Activity datasets in the 360Degree View of the Contexts Person and Organisation". (By itself, this task is nonsense, of course, because the Activity datasets are already shown in the MainView's tab "Activities". Nevertheless, this task is well-suited to be used for learning purposes.)

The task should also include a grouping of the Activity records according to Activit_entity's keyword-related EntityField "CATEGORY".

Activity_entity: Mandatory settings

  • Property "contentTitleProcess" is already set: Its result is the value of EntityField "SUBJECT", which perfectly fits for our task. (Beside, you should never change it anyway, as it is also used in other parts of the client.)
  • Set property "contentDescriptionProcess" with a reasonable logic. EntityField "INFO" seems to be suitable to be shown below the contentTitle (see above), so the code to be set here is:

Activity_entity.contentDescriptionProcess.js

import { result, vars } from "@aditosoftware/jdito-types";

result.string(vars.get("$field.INFO"));
  • EntityField DATE_NEW is already present, so there is nothing to do.
  • Create the new EntityField "ACTIVE". For testing purposes, it is enough to configure the fix value "'true'", preferably via property "expression" of the respective RecordFieldMapping:

Activity_entity.db.ACTIVE.value.expression.js

import { result } from "@aditosoftware/jdito-types";

result.string("'true'");
  • Set the Context's property "icon" to the same icon that appears in the side bar to the left of the client - i.e., in this case, select the icon named "VAADIN:HOURGLASS_END".
  • If a grouping according to Activity_entity's EntityField CATEGORY is applied (see below), you may use propertyIcon process for setting code that enables CATEGORY-specific icons to appear beside the grouped datasets.

360Degree_entity: Extending ObjectType_param

In Order to extend the JSON configured in the valueProcess of Parameter ObjectType_param of Provider, both for Context "Organisation" and "Person", we need to add a service implementation to the services '360degreeOrganisationObjectType_service' and '360DegreePersonObjectType_service'. To do that we need to first add the 360degree Module as a dependency in the package.json. Afterwards we can go under services '360degreeOrganisationObjectType_service' and '360DegreePersonObjectType_service' and add an implementation.

360degreeOrganisationObjectType_service.activity_impl_process.js and .360degreePersonObjectType_service.activity_impl_process.js

*/
function mapping(pJson)
{
pJson["Activity"] = {
"setGroupBy:": "CATEGORY",
"groupByKeyword": "ActivityCategory",
"subContext": "ActivityLink",
"childField": "ACTIVITY_ID",
"parentField": "ACTIVITYID",
"contactIdField": "OBJECT_ROWID"
};
}

// @ts-ignore
return mapping;
}

Now, our task is completed. All other 360Degree-related settings explained in the chapters further above do not require any changes.