Curriculum: integration with Core and Data/Activity Manager
This guide provides information on the standard integration options from Curriculum to Core and Data/Activity Manager. Supporting the exchange of activity related information and user availability.

Supported Curriculum to Core and Data/Activity Manager integrations
The integration from Curriculum to Core and Data Manager supports different levels of integration and object detail.
Depending on the use case and required details on the scheduling object one or a combination of the supported 3 options can be used:
- Core integration
Exchange of the curriculum objects (Course / Teaching method) to Core - Data/Activity Manager integration
Exchange of the curriculum module scheduling preferences including activity-series, activities, lecturers, location, room type, etc. to Data/Activity Manager - (Un)availability integration (Core)
Exchange of the person weekly availability pattern and ad-hoc unavailabilities to Core.
Core integration
The integration with core exchanges Curriculum data on a low granular level. The standard object exchanged is the Course (Module), its offering and teaching / assessment methods. The provided details are configurable in the mapping, allowing to extend the course information with optional and required Relations and fields to support filtering and scheduling in Core.
Data/Activity Manager integration
The integration with Data/Activity manager exchanges Curriculum data on a high granular level. The object exchanged are the activity-series and its activities, including the relation to the module, its offerings and activity preferences such as lecturers, duration, number of groups, location, room type, etc.
The provided details are configurable in the mapping, allowing to extend the course information with optional and required Relations and fields to support filtering and scheduling in Data/Activity Manager.
(Un)availability integration (Core)
The (un)availability integration with Core exchanges person (un)availability information defined in Curriculum to Core. Both the weekly pattern that allows the user to specify the availability (not, available, preferably not) based on time-blocks and the ad-hoc unavailabilities (conference on December 5 and 6).
Basic setup and configuration integration Curriculum to Core and Data/Activity Manager
The integration setup required is based on the standard integration capabilities described in the integration manual. The relevant parts are copied over to provide all necessary information on the Curriculum, Core and Data Manager integration in one single guide.
The integration is based on the event-based mechanism that can be used both for process (status) based exchange of information as mentioned in the process configuration guide in the section about usage of hooks and as ad-hoc based exchange by the process manager that can sent a single or bulk selection of objects from the process manager.
External system
The integration is based on defining the connectivity from Curriculum to an external system and the relevant events that use this configured connection. The configuration of the connection is managed via the Administration -> External systems menu.
The system support the definition and configuration of the system and its standard behaviour. The external system can NOT only be done via the menu, since support needs to setup the technical infrastructure behind the scenes that will be bound to the configuration defined. This setup will cover authentication, firewall, IP-addresses and other technical requirements to create a safe and working connection.
In this configuration we will cover both the integration with Core and Data/Activity Manager. The setup requires the definition of two end-points, e.g. External systems.

The configuration of the data exchange to Core is shown in the image below.
Configuration options are:
- Code - The unique code identifying the external system. This will be used to connect the 'technical backend setup' with the configuration.
- Description - Description of the defined external system
- Default - Event-based integration can be setup without specified end-point (bad habit, never do this !!). In that case it will always use the external system configured as Default.
- Exportable - Indicator that the information should be marked as exportable, e.g. approve data.
- Also show unpublished - Indicator the event message sent will be the 'latest version'. With this configuration unapproved data (data with pending change requests) can be sent.
- Including removed - Indicator if removed objects (methods, assessments) will be sent and removed from Core or Data/Activity Manager
- First sent to - Option not used for internal integration, but can be used to fire off an event to another system, prior to sending to this one

The configuration of the data exchange to Data/Activity Manager is shown in the image below.

Hooks
In the event-based context a hook is a piece of code (function) that can be fired as an event and will sent data via the API to a receiving system, e.g. Core or Data Manager.
Based on external system configuration the hook will know the destination (endpoint) of the receiving system and the data to be sent.
The hook configuration shows the configuration to sent data to Core or Data Manager and is managed using the Administration -> Hooks menu.

The configuration of the hook (event) configuration to Core is shown in the image below.
Configuration options are:
- Name - The hook mechanism to use. Both integrations are based on the standard hook 'Export data'
- Description - Description of the defined hook
- Object type - Defines the object to be sent via the hook. This is in this context for information only. The configuration uses he custom-type export settings that provides more flexibility and configuration options to steer the sending of the individual object types.
- System - The end-point (configured external system) the event message should be sent to.
The configuration of the hook to core doesn't specify the object type, since it's information only. The actual configuration is at the module custom-type.

The configuration of the hook to Data/Activity Manager does specify the object type, but even then the actual configuration is at the module custom-type..

The hooks are used to extend the process configuration with the event-based messaging options based on status or transitions. In case in a specific situation multiple hooks are required, the option to combine hooks into a single hook can be used. The example below shows an example hook configuration for data exchange to Core where in case the status 'approved' is reached the object is give a 'publish date' (which means the changes are applied and the new object will contain the latest information) and then immediately sent this object to Core.

Additional 'object sending' information
In the above example is was noted actual sending behaviour of the object type is detailed further in the Custom type -> Export types configuration.
The Core configuration below shows the configuration that module data needs to be sent to core with the Automatic strategy. The supported configuration options are:
- Strategy - the approval strategy to be executed prior to sending. Strategies supported are:
- Automatic - Data will be sent as configured to the external system.
- Manual - Data is marked to be ready for the external system, but will be manually processed in the external system
- Ignore - Data is marked as 'sent', but will not be sent since the data is considered Curriculum only.
- Request - the Curriculum request method to be used:
- te:sendObject - used to sent data from Curriculum to Core using the Curriculum configured mapping
- te:sendActivities - used to sent data from Curriculum to Data/Activity manager using the Curriculum configured mapping
- te:sendAvailabilities - used to sent (un)availability information from Curriculum to Data/Activity Manager
Some other options are available, but not relevant in the context of the internal TimeEdit integration. These are covered in the generic integration documentation.

The Data/Activity manager configuration below shows the configuration for module data to be sent to core with the Automatic strategy.

Both the integration to Core and Data/Activity Manager will use the Module as the foundation to exchange the relevant object and/or activity information.
For the Core integration it depends of multiple object will be extended with the Export type configuration. It could be the case that next to the module (course) objects also study and or module-group objects need to be exchanged. For instance to keep the 'propedeuse' or 'year 3' modules together while scheduling. In that cases the Core te:sendObject configuration should be applied to the other relevant Curriculum custom-type objects.

Modules and teaching methods to Core
The integration with Core exchanges Curriculum data on a low granular level. The standard object exchanged is the Course (Module), its offering and teaching / assessment methods. The provided details are configurable in the mapping, allowing to extend the course information with optional and required Relations and fields to support filtering and scheduling in Core.
The setup of the integration consists of two steps:
- Configure the connectivity (external system and hook)
- Define the mapping
The first step is covered in section 2.
The mapping is the next step and will process and translate the Curriculum data model and its (custom) defined fields to the relevant object, relations and fields in Core. The mapping is always required, since the naming of objects and fields is in both systems 'free' and therefor not guaranteed the same names are used. Furthermore the mapping also defines how the message is processed and what optional and required relations should be created in Core.
The mapping can be configured using the Administration -> Config menu.

Click on Edit to manage the mapping. A rudimentary editor pops-up to create (or copy/paste) the configuration to be used.

Core object mapping explained based on a practical example
Before posting the full mapping example first the basic structure and options are defined to fully understand the options and requirements.
The mapping file has a specific format that consists of the following base layout:
- mappings - the root configuration element that starts the definition of the mapping
- <object to map> - the object to map. Depending on the 'delegates' configuration this is either the Curriculum or Core object type.
- delegates - the reference to the object to process and map
- <curriculum object type> - in case the processing from the main object to map is handed over to it's children, the child object is defined as the delegated object. For instance processing start based on a published Study, but the processing itself should create objects of the module-groups to keep track of years, propedeuse, optional and required module-groups.
- target - in case the 'delegation' in Curriculum has reached the object to be processed the target object is used to define the destination Core object
- objectType - the Core object type definition
- fields - the fields to be mapped, following the construction <core field>: <curriculum field or expression>
- relations - the mapping part that will process the optional and required relations to Core.
- delegates - the reference to the object to process and map
- <object to map> - the object to map. Depending on the 'delegates' configuration this is either the Curriculum or Core object type.
A short snippet of the basic structure with the above mentioned structure looks like:
{
"mappings":{
"study":{
"delegates":{
"groups":"study-module-group"
}
},
"study-module-group":{
"delegates":{
"target":"programme"
}
},
"programme":{
"objectType":"programme",
"fields":{
"programme.code":"${code}-${year.code}",
"programme.name":"${study.names[EN]} ${names[EN]} (${year.code})",
"programme.academicyear":"year.code",
"programme.specification":"study.specification.code"
},
"relations":[
{
...
}
The example contains the mapping with the following base setup:
- The mapping starts with processing the Curriculum study object
This implies that the te:sendObject is set as export type for Study and the hook for Study is fired to sent data to Core - The study delegates the processing to top-level module-groups, which are represented with the Curriculum object study-module-group (check the standard data model)
This implies that the requirement for Core is that the main object is not the study, but the module-groups. Which makes sense in case the object is used to keep modules together that are modelled in module-groups. In this case it are the root module-groups, so this could be keeping modules together for Year 1, Year 2, Year 3, etc. - The study-module-group delegates with the configuration target to 'programme'.
This implies that the delegation in Curriculum stops and the actual Core object configuration will be defined by the target programme configuration that will map the data to the Core programme object. - The programme is in this example the actual mapping configuration from the Curriculum objects/fields to the Core object/fields, where the objectType specifies the Core object
- The fields configuration define the actual mapping.
- On the left side the exact Core code for the receiving field / object is defined
- On the right side the Curriculum custom-field or expression is defined that is used to define and model the data to meet the Core requirement
- The relations config will be used to configure the different relations from the programme to underlying objects (e.g. modules).
The mapping for relations consists of the following base layout:
- relations - the root configuration element that starts the definition of the mapping
- delegates - the reference to the object to process and map
- property - single value mapping used to identify the relation in Core.
The property defines the source Curriculum object(s) - target - single value mapping used to identify the relation in Core.
The target defines the target Core object/field - type - the Curriculum object type to be processed.
This is used as a filter in case the delegation could result in multiple Curriculum object types. As will be shown in the example below the delegation will process the module-group child objects. In Curriculum a module-group can have both module-group and module child objects. The type is used to specify which of the types should be processed. - filters - optional filter to prevent processing specific objects
- properties - define the field to match
- values - define the field or values to match against
- optionals - definition of the optional relations to be created in Core
The other relations will be required relations, the optionals section will set the relations that match the optional configuration to an optional relation in Core.- properties - define the field to match
- values - define the field or values to match against
- delegates - the reference to the object to process and map
A short snippet of the relation configuration with the above mentioned structure looks like:
"programme":{
"objectType":"programme",
"fields":{
"programme.code":"${code}-${year.code}",
"programme.name":"${study.names[EN]} ${names[EN]} (${year.code})",
"programme.academicyear":"year.code",
"programme.specification":"study.specification.code"
},
"relations":[
{
"delegates": ["children[*].target"],
"property":"modules[*].offerings[*]",
"target":"offerings.uid",
"type": "module",
"filters": [
{
"properties": ["offerings.Location"],
"values": [":study.Location"]
}
],
"optionals":[
{
"properties":["last.type.code"],
"values":["OPT", "RO"]
}
]
}
]
},
"module":{
"delegates":{
"offerings":"module-offering"
}
},
"module-offering":{
"objectType":"module",
"fields":{
"module.id":"${code}-${module.year.code}",
"module.name":"module.names[EN]",
"module.credits":"module.credits.optimum",
"module.level":"module.additional.level",
"module.term":"period.code",
"module.location":"Location"
}
}
}
}
The example contains the mapping with the following base setup:
- The relations are defined in the context of the Core programme object
- The relation generation is delegated to the children of the Curriculum module-groups, which can be both module-groups and modules
- A property to uniquely identify the relationship in Core is set: the Core offering.uid is set for each found module-offering in Curriculum
- The processing of the type is limited to the child modules of the module-group
- A filter is applied that will match the study location with the offering location, to prevent creating module offerings that are given at a different location then the program.
- Optional relations are created for modules that are defined in the context of module-groups where the type is either OPT (optional) or RO (restricted optional). This means that the other relations are build as required, for instance for the modules in a required module-group
- The delegation from the relations configuration is set to process the module. The module delegates the processing to its defined offerings (module-offering).
- The module-offering will perform the mapping of the fields to the generated relation based on the relation configuration.
- On the left side the exact Core code for the receiving field / object is defined
- On the right side the Curriculum custom-field or expression is defined that is used to define and model the data to meet the Core requirement
Bonus example configuration
The example below is a practical configuration that is using the same structure and convention as described earlier. This example has more relations and more complexity in the mapping and filter configurations.
It's listed to get an idea of the broadness (and complexity) of the mapping configuration and can be used as inspiration.
{
"mappings":{
"study":{
"delegates":{
"groups":"module-group-node"
}
},
"module-group-node":{
"delegates":{
"target":"module-group"
}
},
"module-group":{
"subType":"type.code",
"delegates":{
"children":"module-group-node"
},
"overrides":{
"R":"diet",
"P":"diet",
"SP":"diet",
"AC":"diet"
}
},
"diet":{
"objectType":"diet",
"organization":"faculty.id",
"fields":{
"diet.code":"${code}_${year.code}",
"diet.name":"${study.names[EN]} ${names[EN]} (${year.code})"
},
"relations":[
{
"property":"modules",
"target":"module.methods[*].method.activities[*].uid",
"type": "course",
"delegates":[
"children[*].target"
],
"members":[
{
"properties":[
"first.faculty.code"
],
"values":[
"UGS"
],
"and":[
{
"properties":[
"first.study.faculty.code"
],
"values":[
":module.faculty.code"
],
"exclude":true
}
]
},
{
"properties":[
"first.faculty.code"
],
"values":[
"UGS"
],
"exclude":true,
"and":[
{
"properties":[
"first.faculty.code"
],
"values":[
":module.faculty.code"
],
"exclude":true
}
]
}
],
"optionals":[
{
"properties":[
"last.type.code"
],
"values":[
"C"
],
"exclude":true
}
]
}
]
},
"module":{
"delegates":{
"methods":"method-schema"
}
},
"method-schema":{
"delegates":{
"method":"method"
}
},
"method":{
"delegates":{
"activities":"method-activity"
}
},
"method-activity":{
"objectType":"course",
"organization":"module.faculty.id",
"active":[
{
"properties":[
"active",
"method.active",
"method-schema.active"
],
"values":[
true
],
"and":[
{
"properties":[
"module.additional.active"
],
"exclude":true,
"values":[
"N"
]
}
]
}
],
"fields":{
"course.title":"${module.names[EN]} - Group ${method.occurrence}",
"course.code":"${method.code}_${period.code}_${module.year.code}",
"course.term":"period.code",
"course.occurence":"method.occurrence",
"course.academic_year":"module.year.code",
"course.level_code":"method.level",
"course.actual_no":"method.expectedStudents",
"course.begin":"startDate",
"course.end":"endDate",
"course.credit":"module.credits.optimum",
"course.frequency":"method.frequency",
"course.taught":"module.additional.active",
"course.target_no":"expectedStudents",
"general.department_code":"module.faculty.code"
},
"relations":[
{
"property":"module.relations",
"filters":[
{
"properties":[
"role.code"
],
"values":[
"instructor"
]
}
],
"strict":true,
"target":"person.id",
"type": "person"
}
]
}
}
}
Activity-series and activities to Data/Activity Manager
The integration with Data/Activity manager exchanges Curriculum data on a high granular level. The standard object exchanged is the activity-serie, its activities and relation to lecturer and module. Also additional field information like duration, number of groups, number of students, location and other preferences are exchanged. The provided details are configurable in the mapping, allowing to extend the exchanged information with optional and required Relations and fields to support filtering and prepare scheduling in Data/Activity Manager.
The setup of the integration consists of two steps:
- Configure the connectivity (external system and hook)
- Define the mapping
The first step is covered in section 2.
The mapping is the next step and will process and translate the Curriculum data model and its (custom) defined fields to the relevant object, relations and fields in Data/Activity Manager. The mapping is alway required, since the naming of objects and fields is in both systems 'free' and therefor not guaranteed the same names are used. Furthermore the mapping also defines how the message is processed and what optional and required relations should be created in Data/Activity Manager.
The mapping can be configured using the Administration -> Config menu.

Click on Edit to manage the mapping. A rudimentary editor pops-up to create (or copy/paste) the configuration to be used.

Data/Activity manager activity mapping explained based on a practical example
Before posting the full mapping example first the basic structure and options are defined to fully understand the options and requirements.
The mapping file has a specific format that consists of the following base layout:
- userId: the optional user ID that will be used to transfer the data from Curriculum to Data Manager
- templates: the import template configured in Data/Activity Manager defining the structure, objects and fields to be exchanged. Multiple templates can be configured in the mapping, using the filter option to distinct which template is applicable.
- sourceId: the required unique template identifier (UID) as defined in Data/Activity manager
- filters: the filter used to detail the for instance the category the activities are exchanged for, e.g. Teaching or Exam.
A filter for multiple values can be defined using a comma (,) as a separator, e.g. "T", "E". - properties: the list of fields and objects including their naming in Curriculum.
The mapping will be done from the Curriculum field/object to the corresponding 'column' in the defined Data/Activity Manager template.
A short snippet of the basic structure with one single property looks like:
{
"userId": "65bbc0f874de8a17837babe2",
"templates": [{
"sourceId": "67c1b70560667c02b2e2cb5f",
"filters": [
{
"properties": ["category"],
"values": ["E"]
}
],
"properties": [
{
"extId": "length",
"name": "activity.duration",
"defaultValues": [0],
"type": "TIMING"
}
},
{
"sourceId": "67585fce4a11761a98eaa595",
"filters": [
{
"properties": ["category"],
"values": [
"T"
]
}
],
"properties": [
{
"extId": "type.teaching",
"name": "type",
"type": "OBJECT"
}
]
}
]
}
The example contains 2 templates:
- The first template will be used to map and exchange the Curriculum activities of the type E (Exam)
- The second template will be used to map and exchange the Curriculum activities of the type T (Teaching)
Each template in this example contains just a single field. Fields are defined in the 'properties' element and support different options depending on the data-type in Curriculum and the data-type in Data/Activity Manager. The main caution is that the order and typing of the fields in the mapping MUST be exactly the same as the fields configured in the template. Missing a field, or swapping fields with different typing will cause import errors.
Now the basis is setup, the next step is said above the definition of all the fields/objects and their mapping.
The basic mapping configuration of a field consists of :
- extId: the external name of the field / object in Data/Activity Manager
- name: the internal Curriculum field/object name
- defaultValues: optional default values in case no data in Curriculum is defined and the field in Data/Activity Manager requires a value.
- type: the data type of the field / object in Data/Activity Manager. Supported values are:
- TIMING - Receiving template field in Data/Activity manager is an TIMING object
- FIELD - Receiving template field in Data/Activity manager is a standard field
- INFORMATION_FIELD - Receiving template field in Data/Activity manager is a custom definedfield
- OBJECT - Receiving template field in Data/Activity manager is an object
Below a basic set of mapping options is displayed to get an idea of the different options to map Curriculum data to the Data/Activity Manager template
The example below shows the mapping configuration for two fields of type TIMING.
The extId is the internal extId in Data/Activity Manager. The name is the custom-field name in Curriculum. The duration is set to a default value, since it cannot be empty.
{
"extId": "week",
"name": "activity.week",
"type": "TIMING"
},
{
"extId": "length",
"name": "activity.duration",
"defaultValues": [0],
"type": "TIMING"
},
The example below shows the mapping configuration for a standard fields of type FIELD.
The extId is the internal extId in Data/Activity Manager. The name is the custom-field name in Curriculum.
{
"extId": "r.internalcomment",
"name": "remark",
"type": "FIELD"
},
The example below shows the mapping configuration for custom fields of type INFORMATION_FIELD.
The extId is the internal extId in Data/Activity Manager. The name is the custom-field name in Curriculum.
{
"extId": "Remark",
"name": "remark",
"type": "INFORMATION_FIELD"
},
{
"extId": "Staff competence",
"name": "staffCompetence",
"type": "INFORMATION_FIELD"
},
{
"extId": "Suggested day",
"name": "suggestedDay",
"type": "INFORMATION_FIELD"
},
The example below shows the mapping configuration for fields of type OBJECT.
The extId is the internal extId in Data/Activity Manager. The name is the custom-field name in Curriculum.
The Curriculum name (object) can be a single object, e.g. the faculty (single value object) or the assigned lecturers (activity.persons) that is a multi-value object.
It is also supported to get related Curriculum object traversing the Curriculum hierarchy as is shown in the example to get the parent programs of the module.
{
"extId": "faculty",
"name": "module.faculty.id",
"type": "OBJECT"
},
{
"extId": "programmeoffering",
"name": "module.parents[*].target.id",
"type": "OBJECT"
},
{
"extId": "person.staff",
"name": "activity.persons",
"type": "OBJECT"
},
{
"extId": "time.slot.pattern",
"name": "timeslotPattern",
"type": "OBJECT"
},
The example below shows the mapping configuration for a field defined in the template, but not provided via the interface.
In this case the extId is defined, but no mapping information is added. This will set the field in the template to an empty value.
{
"extId": "r.comment"
},
(Un)availability from Curriculum to Core
The Curriculum to Core integration standard supports the exchange of the defined availability by the staff members. This includes both the weekly availability pattern and the ad-hoc unavailabilities.
Configuration in Curriculum
Step 1 - configure the start and end time on the element Timeblocks
The first step is to configure the relevant time-blocks in Curriculum. Time-blocks are used to define the users' weekly availability pattern, e.g. not available on Monday between 9:00 and 10:45 (first time-block), and rather not on Friday 15:00-22:00.

Step 2 - exclude the not relevant availabilities on the element Availability
The externalID used in configuring the Availability should match the used name in Core.
The example below exchanges the availability (when is the user available), with the externalID is set to A_AVAILABILITY. The availability is not excluded from import.
By using the configuration including the 'exclude from import' the exchange of unavailabilities, availabilities and both can be supported.

Step 3 - configure the usage of te:sendAvailability on the person export type
To 'tell' or the event on change of a persons' availability to use the event te:sendAvailability as the person Export type.
The configuration shows the system te-rest-api.
This must be configured by TimeEdit (implementation manager) and defines the technical integration (system to system connectivity) for the integration.

Step 4 - configure the hook (if that is not already available)
The next step is the configuration of the hook. The hook can be used in any process to fire of the availability event to Core.

The last thing is to enable the hook in the process for automatic sending from the process, or use the hook from the process manager to send availability to core.