Custom Service
Overview
The Custom Service gives you the flexibility to execute your own CCL scripts from within a Clinical Office payload. Your scripts can be run before or after the normal Clinical Office tasks, allowing you the flexibility to control the JSON output, but also control the list of visit and person records being used by Clinical Office data services.
To use this service, you must import the service, assign it to an object, execute a data collection operation (either with the load method on this or any other MPage Developer service, or with the MPage Service executeCCL method). Finally, you need to do something with the data you have retrieved.
Import
import {Component, inject, OnInit, ...etc...} from '@angular/core';
import {CustomService} from '@clinicaloffice/mpage-developer';
Object Assignment
Using the Angular inject command, assign the CustomService to a new object. It is recommended that you scope your object as "protected" to allow access to your component HTML.
@Component({...
...})
export class YourComponent implements OnInit {
protected customService = inject(CustomService);
....remaining code...
Data Collection
The examples below demonstrate data collection methods you can use.
// Typical custom service payload allowing one or more script entries.
this.customService.load({
customScript: {
script: [{
name: 'your_custom_ccl_script:group1',
run: 'pre',
id: 'PATIENT_INFO'
}]
}
});
// The load method offers a short-cut format when running a single custom script. You can pass a single object that
// you would have passed to the script array and the load method with automatically wrap it in the proper
// customScript: {script: [ ]}} format.
this.customService.load({
name: 'your_custom_ccl_script:group1',
run: 'pre',
id: 'PATIENT_INFO'
});
// Use the MPage Service to load multiple payload items including two custom CCL scripts, the first running (pre)
// before the Person Service and the second running (post) after everything else runs.
this.MPageService.executeCCL({
payload: {
patientSource: [{personId: 0, encntrId: 0}],
person: {
aliases: true,
},
customScript: {
script: [
{
name: 'your_custom_ccl_script:group1',
run: 'pre',
id: 'PATIENT_INFO'
},
{
name: 'your_second_ccl_script:group1',
run: 'post',
id: 'ORDERS',
parameters: {
orderTypes: ['PHARMACY', 'LAB']
}
}
]
}
}
});
Payload Options
The following payload options represent all available payload values for the CustomService.
{
payload: {
clearPatientSource: true,
patientSource: [
{personId: value, encntrId: value}
],
customScript: {
script: [
{name: 'ccl script name', run: 'pre', id: 'unique name', parameters: { anything you want }}
]
}
}
}
- The clearPatientSource payload tag is responsible for erasing the contents of the PATIENT_SOURCE record structure, which is used by all Clinical Office scripts to identify visit and person records. Once you have cleared the patient source, you can re-populate the record structure with your CCL script. For this to have any effect, you will also need to execute some Clinical Office payload tags such as person, allergy, etc. as the patient source is only clear for the current payload run.
- You can include multiple script tags within the customScript payload. The only requirement is that any parameters you include in your payload must have the same data types between scripts. For example, if you run two custom scripts in the same payload that have a parameter called startDate and in one script you are using a fully qualified JavaScript Date and in the second script you are using a simple string, your CCL scripts will error out and cause your MPage to fail.
- The name field in your script tag needs to be the executable name of your CCL script and include the group level the script runs at. We highly recommend that all of your custom scripts run at a level of GROUP1.
- Valid values for the run element are 'pre' and 'post'. Scripts identified as 'pre' will run before all other Clinical Office scripts. Scripts marked as 'post' will run at the end of the payload job.
- id represents a unique name that you will give your custom data. This name is the key name that will be used by the CustomService provider when using the get(key) method. Re-using an identifier will result in the old data being replaced.
-
The parameters payload tag has been designed to allow you the flexibility of passing any needed parameter
data such as date ranges to your CCL script. A parameter called fromDate in your payload will be available
in CCL as
PAYLOAD->CUSTOMSCRIPT->SCRIPT[nSCRIPT]->PARAMETERS.FROMDATE.
Using Callbacks
Both the service load method and MPageService executeCCL methods offer a callback parameter as the final parameter. You can use this callback or another option of your choosing to work with the data returned from Cerner.
this.MPageService.executeCCL({
payload: {
...
}
}, () => { ...do something here... }
Methods / Usable Objects
clear(key: string): voidClear one or all of the custom data values from memory. If '' is passed as the key, all custom data is removed from memory.
executeCustomDataAction(id: string, actionType: string, action: string, data: ICustomReference | ICustomReference[], callback: any = undefined): voidExecutes a read/write/delete action on the CUST_CO_REFERENCE table or your own custom table. Usage information is explained on the Custom Data documentation page.
emptyDmInfo(): IDmInfoThis get method returns an empty IDmInfo object. DMInfo usage is explained later on this page.
executeDmInfoAction(id: string, action: string, data: IDmInfo[], callback: any = undefined): voidExecute a read/write/delete action on the DM_INFO table. DMInfo usage is explained on the DMInfo documentation page.
executeDmInfoActions(id: string, actions: IDmInfoActions[], callback: any = undefined): voidPlural version of executeDMInfoAction where you can issue multiple DMInfoActions in the same call. DMInfo usage is explained on the DMInfo documentation page.
get(key: string): anyReturns the content created by your custom CCL script as a JavaScript object where the key is equal to the name of the unique id you passed in your payload. If you pass an empty string to the "id" field in your payload, no data will be returned to your MPage.
has(key: string): booleanReturns a boolean true or false indicating if the custom service has loaded and stored data under the key name. This is a useful method for determining if your custom script has finished running.
length(): numberReturns a count containing the number of custom service values loaded in memory.
load( payload: any, patientSource: IPatientSource[] = [{personId: 0, encntrId: 0}], callback: any = undefined): voidExecutes custom script(s) inside payload for the provided patientSource.
putLog(text: string, type: string = 'info', processId: number = -1, statusText: string = ''): voidWrites a line of text to the MPage Developer log. Valid values for type include 'info', 'error', 'payload', and 'debug'. You should only use the values 'info' or 'error' as 'payload' and 'debug' are reserved for system use. The processId and statusText values can safely be ignored.
custom(): Map<number, any>Direct reference to the custom Map object.
values(): IterableIterator<any>Returns an iterable iterator representation of all loaded custom service values.
CCL
For your custom CCL data service to work, you need a CCL script that is going to perform your task(s) and either update the PATIENT_SOURCE record structure or populate your MPage JSON stream.
You can use the 1co5_mpage_template.prg script that was included with your CCL repository as a starting point for your custom CCL scripts. Simply save the script under your own custom name, modify or remove the rCustom record structure and add your own code where indicated in the source. If you chose to remove the rCustom record structure and create your own new structure, you will need to put the name of your new record structure in the call to ADD_CUSTOM_OUTPUT at the bottom of the script.
The template script is predefined with a record structure called rCustom. This record structure does not contain any useful fields and you are expected to modify it to meet your needs.
free record rCustom
record rCustom (
1 data[*]
2 custom_string = vc
2 custom_date = dq8
2 custom_cd = f8
2 custom_prsnl[*]
3 person_id = f8
3 name_full_formatted = vc
3 position_cd = f8
3 position = vc
)
Any elements you place in your custom structure or the rCustom structure will be available as a
JavaScript object in your MPage through the get(key) method. For example, if you were to run the default
template script with a custom id equal to "test" in your payload, you could access record field called
YOUR_CUSTOM_FIELD in your MPage with this.customService.get("test").yourCustomField.
The MPage Developer Reference Service provides functionality for detailing reference information about your CCL script. To allow your custom script to be included in reference service lookups, you need to populate your rCustom record structure and optionally add code value references. The custom template CCL script includes a section of code to handle reference service lookups. The highlighted sections below need to be changed to match your rCustom definitions in your custom script if you plan on using the reference service in your MPage.
If you do not plan to use the reference service, you can safely delete the entire block of code show below from your custom CCL script.
; Alternate reference structure to be used with ReferenceService. If you are not implementing
; ReferenceService, simply remove this entire IF block from your script. If you plan on using the
; ReferenceService, please ensure that you populate your entire record structure with one
; empty row for each dynamic element.
if (run_stats->reference_ind = 1)
set stat = alterlist(rCustom->data, 1)
set stat = alterlist(rCustom->data[1]->custom_prsnl, 1)
; Populate the code sets to be matched up to your record structure. This will send the entire
; reference for all code values for a table unless you specify column_name filters as done
; in the example below.
select into "nl:"
from dm_columns_doc dcd
plan dcd
where dcd.table_name in ("PRSNL")
and dcd.code_set > 0
and dcd.column_name in ("POSITION_CD") ; Filter only the fields you need
detail
call add_ref_code_set(payload->customscript->script[nscript].id,
camel_field(dcd.column_name), dcd.description, dcd.code_set)
with counter
go to skip_logic
endif
Interfaces
ICustomReference {
refName: string;
refTask: string;
description?: string;
parentEntityId?: number;
parentEntityName?: string;
refText?: string;
}
ICustomReferenceActions {
id: string;
action: string;
data: ICustomReference[];
}
ICustomReferenceData extends ICustomReference {
createPrsnlId: number;
createPrsnlName: string;
createDtTm: Date;
activeInd: boolean;
updtId: number;
updtName: string;
updtDtTm: Date;
begEffectiveDtTm: Date;
endEffectiveDtTm: Date;
}
IDmInfo {
infoDomain: string;
infoName: string;
infoDate: Date;
infoChar: string;
infoNumber: number;
infoLongText: string;
infoDomainId: number;
}
IDmInfoActions {
id: string;
action: string;
data: IDmInfo[]
}
