- Created by Tushar Tajane , last modified by Srikanth Adiga on May 23, 2024
You are viewing an old version of this content. View the current version.
Compare with Current View Version History
« Previous Version 64 Next »
Data Validation Fields
We can set up data validation on these 3 types of fields and their combinations:
Core fields
Custom fields
Custom form fields
Combination of the core fields, custom fields, custom form fields
Core Fields Dictionary for Participants, Visits, and Specimens.
Level | Field Name | Field Expression |
---|---|---|
Participant | PPID | #cpr.ppid |
Participant | First Name | #cpr.participant.firstName |
Participant | Middle Name | #cpr.participant.middleName |
Participant | Last Name | #cpr.participant.lastName |
Participant | Registration Date | #cpr.registrationDate |
Participant | External Subject ID | #cpr.externalSubjectId |
Participant | Registration Site | #cpr.site |
Participant | Birth Date | #cpr.participant.birthDate |
Participant | Social Security Number | #cpr.participant.uid |
Participant | eMPI | #cpr.participant.empi |
Participant | Gender | #cpr.participant.gender |
Participant | Vital Status | #cpr.participant.vitalStatus |
Participant | Death Date | #cpr.participant.deathDate |
Participant | Races | #cpr.participant.races |
Participant | Ethnicity | #cpr.participant.ethnicities |
Participant | MRN | #cpr.participant.pmis |
Visit | Name | #cpr.participant.pmis |
Visit | Name | #visit.name |
Visit | Status | #visit.status |
Visit | Missed By | #visit.missedBy |
Visit | Missed Reason | #visit.missedReason |
Visit | Visit Date | #visit.visitDate |
Visit | Visit Site | #visit.site |
Visit | Clinical Diagnosis | #visit.clinicalDiagnoses |
Visit | Clinical Status | #visit.surgicalPathologyNumber |
Visit | SPR | #visit.clinicalStatus |
Visit | Visit Comments | #visit.comments |
Specimen | Label | #specimen.label |
Specimen | Barcode | #specimen.barcode |
Specimen | Lineage | #specimen.lineage |
Specimen | Collection Status | #specimen.status |
Specimen | Type | #specimen.type |
Specimen | Anatomic Site | #specimen.anatomicSite |
Specimen | Laterality | #specimen.laterality |
Specimen | Pathology Status | #specimen.pathology |
Specimen | Initial Qty | #specimen.initialQty |
Specimen | Available Qty | #specimen.availableQty |
Specimen | Concentration | #specimen.concentration |
Specimen | Parent Specimen Label | #specimen.parentLabel |
Specimen | Biohazard | #specimen.biohazards |
Specimen | Location | #specimen.storageLocation |
Specimen | Created On | #specimen.createdOn |
Specimen | Freezer Thaw Cycle | #specimen.freezeThawCycles |
Specimen | Increment Freeze Thaw Cycle | #specimen.incrParentFreezeThaw |
Specimen | Comments | #specimen.comments |
Specimen | Collection Date | #specimen.collectionEvent.time |
Specimen | Collector | #specimen.collectionEvent.user |
Specimen | Received Date | #specimen.receivedEvent.time |
Specimen | Receiver | #specimen.receivedEvent.user |
Specimen | Collection Container | #specimen.collectionEvent.container |
Specimen | Collection Procedure | #specimen.collectionEvent.procedure |
Specimen | Received Quality | #specimen.receivedEvent.receivedQuality |
Specimen | Frozen Time | #specimen.events.SpecimenFrozenEvent.time |
Specimen | Frozen Method | #specimen.events.SpecimenFrozenEvent.frozenMethod |
Specimen | Frozen Comments | #specimen.events.SpecimenFrozenEvent.comments |
Examples
Participant
We can add edit checks on participant fields using the record type as ‘cpr’
Attribute Type | Description | Example JSON |
---|---|---|
Text | Patient first name, last name should not be null. | { "records" : [ "cpr" ], "rules" : [ { "expr" : "#cpr.participant.firstName != null && #cpr.participant.lastName != null", "description" : "First name or last name should not be null" } ] }, |
Text | Allow only capital letters in the field first name | { "records" : [ "cpr" ], "rules" : [ { "expr" : "#cpr.participant.firstName.matches(\"^[A-Z]+$\")", "description" : "Only capital letters allowed for Initials" } ] } |
Numeric field | The participant’s age registered under the COVID protocol should be between 18-55 | { "records" : [ "cpr" ], "rules" : [ { "when" : "#cpr.participant.extensionDetail?.getAttrsMap()?.get('min_max_age') != null && !#cpr.participant.extensionDetail?.getAttrsMap()?.get('min_max_age').isEmpty()", "expr" : "T(java.lang.Integer).parseInt(#cpr.participant.extensionDetail?.getAttrsMap()?.get('min_max_age')) >= 18 && T(java.lang.Integer).parseInt(#cpr.participant.extensionDetail?.getAttrsMap()?.get('min_max_age')) <= 55", "description" : "Partiicpant's age should be between 18 and 55" } ] } |
Text Custom Field | If the patient is ‘Dead’ then, specify the value ‘Cause of death.’ | { "records" : [ "cpr" ], "rules" : [ { "when" : "#cpr.participant.vitalStatus == 'Dead'", "expr" : "#cpr.participant.extensionDetail?.getAttrsMap()?.get('ST2') != null ", "description" : "Specify Death Cause" } ] } |
Dropdown | Only male participant registrations are allowed | { "records" : [ "cpr" ], "rules" : [ { "expr" : "#cpr.participant.gender != null && !#containsAny(#cpr.participant.gender, {'Female', 'Unknown', 'Undifferentiated'})", "description" : "Only Male patient should be register" } ] } |
Multi-select field | If Race is one of (White or Asian), then Ethnicity should be 'American.' | { "records" : [ "cpr" ], "rules" : [ { "when" : "#containsAny(#cpr.participant.races, {'White', 'Asian'})", "expr" : "#cpr.participant.ethnicities.size() == 1 && #cpr.participant.ethnicities.contains('American')", "description" : "For White/Asian races, ethnicity should be American" } ] } |
Dropdown and Muliselect |
| { "records" : [ "cpr" ], "rules" : [ { "when" : "#cpr.site == 'MCRI Repository'", "expr" : "#containsAny(#cpr.participant.races, {'White', 'Asian'})", "description" : "Race should be White/Asin for 'MCRI Repository' site patient" } ] }, { "records" : [ "cpr" ], "rules" : [ { "when" : "#containsAny(#cpr.participant.vitalStatus, {'Alive'})", "expr" : "#containsAny(#cpr.participant.ethnicities, {'American', 'African'})", "description" : "For alive patient, the enthicity should be American/African" } ] } |
Custom Field | The email id of the participant should be of the form ‘example@something.com’ | { "records" : [ "cpr" ], "rules" : [ { "when" : "#cpr.registrationDate != null && #cpr.participant.extensionDetail?.getAttrsMap()?.get('ST6')!= null", "expr" : "#cpr.participant.extensionDetail?.getAttrsMap()?.get('ST6') matches '^\\w+(\\.\\w+)*@\\w+(\\.\\w+)*(\\.[A-Za-z]{2,})$'", "description" : "Please enter a valid email address" } ] } |
Custom Form Field | In the ‘Smoking History Form’ attached at the ‘Participant Forms’ level, if the value of ‘Have you ever smoked’ is ‘Yes’, the error ‘Smokers not allowed!’ should be thrown. | { "records": ["cpr"], "forms": { "cpr": [ "smokingHistoryForm" ] }, "rules": [ { "when": "#cprForms != null && #cprForms['smokingHistoryForm'] != null", "expr": "#cprForms['smokingHistoryForm']['haveYouEverSmoked'] != 'Yes'", "description": "SH:Smokers not allowed!" } ] } |
Custom Form Field | ‘Male’ participants with the value of ‘Have you ever smoked?’ as ‘Yes’ are not allowed. Error ‘Male smokers not allowed!’ should be thrown. | { "records": ["cpr"], "forms": { "cpr": [ "smokingHistoryForm" ] }, "rules": [ { "when": "#cprForms != null && #cprForms['smokingHistoryForm'] != null", "expr": "#cpr.participant.gender != 'Male' || #cprForms['smokingHistoryForm']['haveYouEverSmoked'] != 'Yes'", "description": "SH:Male Smokers Not allowed!" } ] } |
Custom form Date Field | ‘Date of participant signed' is a date type custom field. The date is valid if Valid Date = (Date signed ≤ Today’s Date) otherwise invalid | { "records" : [ "cpr" ], "rules" : [ { "expr" : "#cmp(#cpr.participant.extensionDetail?.getAttrValue('date_participant_signed'), #currentTime()) <= 0", "description" : "Participant date signed should be lesser than or equal to current date" } ] } |
Calculated Field (Age) | Participant age at the time of registration should be more than 18 years | { "records" : [ "cpr" ], "rules" : [ { "expr" : "#yearsBetween(#cpr.participant.birthDate, #cpr.registrationDate) >= 18", "description" : "Participant should be older than 18 years" } ] } |
Dropdown Custom Field | If the patient is ‘Dead’, enter the values for the 'Diagnosed With' field from the dropdown. | { "records" : [ "cpr" ], "rules" : [ { "when" : "#cpr.participant.vitalStatus == 'Dead'", "expr" : "#cpr.participant.extensionDetail?.getAttrsMap()?.get('DD3') != null ", "description" : "Specify the value for Diagnosed With" } ] } |
Dropdown Multiselect (Custom Field) | If the patient is 'Alive', enter the values for the 'City lived In field from the dropdown. | { "records" : [ "cpr" ], "rules" : [ { "when" : "#cpr.participant.vitalStatus == 'Alive'", "expr" : "#cpr.participant.extensionDetail?.getAttrsMap()?.get('MLB4') != null ", "description" : "Specify the cities where patient is lived" } ] } |
Fancy Control-User | If the user (Surgeon) is 'Krishna W' then the user needs to provide the death cause value (Custom Field) for the patient.
| { "records" : [ "cpr" ], "rules" : [ { "when" : "#cpr.participant.extensionDetail?.getAttrsMap()?.get('FC5') == 'Krishna W' ", "expr" : "#cpr.participant.extensionDetail?.getAttrsMap()?.get('ST2') != null ", "description" : "Specify the death cause if the surgeon is Krishna W" } ] }, |
Visit
We can add edit checks on visit fields using the record type as ‘visit’
Attribute Type | Description | Example JSON |
---|---|---|
Dropdown | Clinical diagnosis should be one of | { "records" : [ "visit"], "rules" : [ { "when" : "#visit.status == 'Complete'", "expr" : "#containsAny(#visit.clinicalDiagnoses, {'Cholera', 'Liver cell carcinoma'})", "description" : "Clinical diagnosis should be Cholera/Cholepe" } ] }, |
Dropdown custom field | If the clinical diagnosis is one of | { "records" : [ "visit"], "rules" : [ { "when" : "#containsAny(#visit.clinicalDiagnoses, {'Cholera', 'Liver cell carcinoma'})", "expr" : "#visit.extensionDetail?.getAttrsMap()?.get('DD2') == 'Negative' ", "description" : "Clinical Subtype should be Negative" } ] }, |
Date | Participant/Visit fields: "Visit date should be the same or later than the registration date!" | { "records" : [ "cpr", "visit" ], "rules" : [ { "expr" : "#cpr.registrationDate != null && #visit.visitDate != null && !#cpr.registrationDate.after(#visit.visitDate)", "description" : "Visit date should be same or later than the registration date!" } ] } |
Dropdown (Core fields) | The values for clinical diagnoses should be ‘Breast implant status’ and ‘Other disorders of breast.’ | { "records" : [ "visit" ], "rules" : [ { "when" : "#visit.status == 'Complete'", "expr" : "#visit.clinicalDiagnoses.size() == 2 && #visit.clinicalDiagnoses.contains('Breast implant status') && #visit.clinicalDiagnoses.contains('Other disorders of breast')", "description" : "Clinical diagnosis should be Breast implant status and Other disorders of breast" } ] }, |
Dropdown (Core fields) | If ‘Clinical Diagnoses’ is one of List a then acceptable ‘Anatomic Site’ values will be among List b. | { "records": ["visit"], "rules" : [ { "when" : "#specimen.status == 'Collected' && #visit.eventLabel == 'Baseline' && #containsAny(#visit.clinicalDiagnoses, {'10 weeks gestation of pregnancy', '11 weeks gestation of pregnancy', '12 weeks gestation of pregnancy', '13 weeks gestation of pregnancy', '14 weeks gestation of pregnancy'})", "expr" : "#containsAny(#specimen.anatomicSite, {'Extrahepatic bile duct', 'Intrahepatic bile duct', 'Liver'})", "description" : "CORE AS: Check the combo of CD AND AS" }, ] } |
Dropdown (Custom Form fields) | If the ‘Tumor Site/Anatomic site’ value from the custom form is ‘Extrahepatic bile duct', 'Intrahepatic bile duct', 'Liver', then the allowed values for the 'Tumor Morphology Diagnosis’ field from the custom form will be '10 weeks gestation of pregnancy', '11 weeks gestation of pregnancy', '12 weeks gestation of pregnancy, '13 weeks gestation of pregnancy, '14 weeks gestation of pregnancy' | { "records" : [ "visit" ], "forms" : { "visit" : [ "newPathologyForm" ] }, "rules" : [ { "when" : "#visitForms != null && #visitForms['newPathologyForm'] != null && {'Extrahepatic bile duct', 'Intrahepatic bile duct', 'Liver'}.contains(#visitForms['newPathologyForm']['tumourSiteAnatomicSite'])", "expr" : "{'10 weeks gestation of pregnancy', '11 weeks gestation of pregnancy', '12 weeks gestation of pregnancy', '13 weeks gestation of pregnancy', '14 weeks gestation of pregnancy'}.contains(#visitForms['newPathologyForm']['tumourMorphologyDiagnosis'])", "description" : "CF VISIT: Check the combination of diagnoses and anatomic sites" } ] } |
Dropdown (Core and Custom Form) | If the 'Primary Site' values (Custom Form) are 'Extrahepatic bile duct', 'Intrahepatic bile duct', 'Liver', the allowed value for Clinical Diagnosis (Core) should be in {'10 weeks gestation of pregnancy', '11 weeks gestation of pregnancy', '12 weeks gestation of pregnancy', '13 weeks gestation of pregnancy', '14 weeks gestation of pregnancy'} | { "records" : [ "visit" ], "forms" : { "visit" : [ "newPathologyForm" ] }, "rules" : [ { "when" : "#visitForms != null && #visitForms['newPathologyForm'] != null && {'Extrahepatic bile duct', 'Intrahepatic bile duct', 'Liver'}.contains(#visitForms['newPathologyForm']['tumourSiteAnatomicSite'])", "expr" : "#containsAny(#visit.clinicalDiagnoses, {'10 weeks gestation of pregnancy', '11 weeks gestation of pregnancy', '12 weeks gestation of pregnancy', '13 weeks gestation of pregnancy', '14 weeks gestation of pregnancy'})", "description" : "Check the combination of Form Anatomic Site and Core Clinical Diagnoses" } ] } |
Dropdown (Core and Custom Form) | If the diagnosis field from the visit level form contains values from the below List, then the allowed value for Clinical Diagnosis (Core) should be ' List: ‘8006/2 Observation for suspected malignant neoplasm’, '8009/1 Non-malignant diagnosis, no history of cancer (Other Medical Care)'. Why is RegEx used in the edit check? Providing these long multi-choice values in the edit check is not flexible, so RegEx checks for the statement and matches the values. | { "when" : "#visit.visitDate != null && #visit.status == 'Complete' && #visit.clinicalStatus != null && #visitForms != null && #visitForms['demoPathologyForm'] != null && #visitForms['demoPathologyForm']['diagnosis3'] != null && #visitForms['demoPathologyForm']['diagnosis3'] matches '^\\d+/[0-2].*'", "expr" : "#visit.clinicalStatus == 'Non-malignant'", "description" : "Check the clinical status value based on the diagnosis" }, |
Specimen
We can add edit checks on specimen fields using the record type as ‘specimen’
Attribute Type | Description | Example JSON |
---|---|---|
Dropdown core | If the participant gender is ‘Male’, then the anatomic site cannot include 'Female genital tract, NOS', 'Overlapping lesion of female genital organs', 'Other specified parts of female genital organs', 'Breast, NOS' | { "records" : [ "specimen", "cpr", "visit" ], "rules" : [ { "when" : "#cpr.participant.gender == 'Male' && #specimen.status == 'Collected' && #visit.eventLabel == 'Baseline'", "expr" : "!{'Female genital tract, NOS', 'Overlapping lesion of female genital organs', 'Other specified parts of female genital organs', 'Breast, NOS'}.contains(#specimen.anatomicSite)", "description" : "CORE GEN AS: Check the Gender ASite COMBO" } ] } |
Date | Registration Date vs. Collection Date The specimen collection date should be the same or later than the registration date. | { "when" : "#specimen.status == 'Collected'", "expr" : "!#cpr.registrationDate.after(#specimen.collectionEvent.time)", "description" : "The specimen #specimen.label (#specimen.type) collection date should be same or later than the registration date!" } |
Dropdown custom | The anatomic site should be Brain NOS OR Abdomen NOS for tissue samples | { "when" : "#specimen.status == 'Collected' && #specimen.specimenClass == 'Tissue'", "expr" : "#specimen.anatomicSite == 'Brain, NOS' || #specimen.anatomicSite == 'Abdomen, NOS'", "description" : "Anatomic site should be Brain NOS or Abdomen NOS for tissue samples" } |
Date field (core) | Specimen data should be the same or later than the Visit date! (Visit date allows only ‘Date' whereas Specimen collection date allows 'Date and time data entry. In this Edit check, similar date format is provided for both the date fields.) | { "records" : [ "visit", "specimen" ], "rules" : [ { "when" : "#visit.visitDate != null && #visit.status == 'Complete' && #specimen.collectionEvent.time != null && #specimen.status == 'Collected'", "expr" : "#formatDate(#visit.visitDate,'yyyyMMdd') == #formatDate(#specimen.collectionEvent.time,'yyyyMMdd')", "description" : "Correct the visit date to the specimen collection date" } ] } |
Shipment
We can add edit checks on shipment fields using the record type as ‘shipment’
Attribute Type | Description | Example JSON |
---|---|---|
Shipment Shipped Date | Shipment Shipped date should be lesser than current date/time | { "records": ["shipment"], "rules": [ { "when": "#shipment.status != 'Pending'", "expr": "#cmp(#shipment.shippedDate, #currentTime()) <= 0", "description": "1. Shipment date should be lesser than current date/time" } ] }, |
Received Date | Shipment received date should be lesser than current date/time | { "records": ["shipment"], "rules": [ { "when": "#shipment.status == 'Received'", "expr": "#cmp(#shipment.receivedDate, #currentTime()) <= 0", "description": "2. Shipment received date should be lesser than current date/time" } ] }, |
Shipment Shipped Date Vs. Specimen Collection Date | Shipment Shipped date should be greater than the specimen collection date
| {"records": ["shipment", "shipmentSpecimen"], "rules": [ { "when": "#shipment.status != 'Pending' && #shipment.shippedDate != null", "expr": "#cmp(#shipment.shippedDate, #specimen.collectionEvent.time) >= 0", "description": "3. Shipment date should be greater than the specimen (#specimen.label) collection date" } ] }, |
Shipment Received Date Vs. Specimen Collection Date | Shipment received date should be greater than the specimen collection date | { "records": ["shipment", "shipmentSpecimen"], "rules": [ { "when": "#shipment.status != 'Pending' && #shipment.receivedDate != null", "expr": "#cmp(#shipment.receivedDate, #specimen.collectionEvent.time) >= 0", "description": "4. Shipment receive date should be greater than the specimen (#specimen.label) collection date" } ] }, |
Shipment shipped Date Vs. Specimen Collection Date | Shipment shipped date should be greater than the specimen collection date, where the collection is date considered as one day earlier than actual. Passing condition: Shipped date:07-02-2023 00:00 Collection date:07-02-2023 22:14 Failed condition: Shipped date:07-02-2023 00:00 Collection date:08-02-2023 02.14 | { "records": ["shipment", "shipmentSpecimen"], "rules": [ { "when": "#shipment.status != 'Pending' && #shipment.shippedDate != null", "expr": "(#shipment.shippedDate.getTime() - (#specimen.collectionEvent.time.getTime() - 24 * 60 * 60 * 1000)) >= 0", "description": "Shipment date should be greater than the specimen collection date" } ] } |
Shipment shipped Date Vs. Specimen Collection Date | Shipment shipped date should be greater than the specimen collection date on specimen event page edit. The regular expression of comparing shipped Vs collection date doesn’t work on Specimen Event page. To ensure the check validate on ‘Editing' the ‘Collection Event date and time’ this expression is used. | { "records" : [ "specimen" ], "forms" : { "specimen" : [ "SpecimenShipmentShippedEvent" ] }, "rules" : [ { "when" : "#specimenForms != null && #specimenForms['SpecimenShipmentShippedEvent'] != null", "expr": "#collFns.forEvery(#specimenForms['SpecimenShipmentShippedEvent$Array'], 'se', \"#se['time'].after(#specimen.collectionEvent.time)\")", "description" : "Shipment date should be later than the collection date." } ] } |
Shipment shipped Date Vs. Specimen Collection Date | The Shipment shipped date can be lesser than specimen collection date by 24 hours, not more than that. Passing condition: Shipped date:06-02-2023 20:00 Collection date:07-02-2023 18:14 Failed condition: Shipped date:06-02-2023 20:00 Collection date:08-02-2023 22.14 | { "records": ["shipment", "shipmentSpecimen"], "rules": [ { "when": "#shipment.status != 'Pending' && #shipment.shippedDate != null", "expr": "(#shipment.shippedDate.getTime() - #specimen.collectionEvent.time.getTime()) >= -86400000", "description": "Shipment shipped date cannot occur more than 24 hours before the Specimen collection date." } ] }
|
Shipment shipped Date Vs. Specimen Collection Date | This expression only compares both shipped date Vs Collection Date and ignore the time attached to both fields. | { "records": ["shipment", "shipmentSpecimen"], "rules": [ { "when": "#shipment.status != 'Pending' && #shipment.shippedDate != null", "expr": "#shipment.shippedDate.getYear() > #specimen.collectionEvent.time.getYear() || (#shipment.shippedDate.getYear() == #specimen.collectionEvent.time.getYear() && #shipment.shippedDate.getMonth() > #specimen.collectionEvent.time.getMonth()) || (#shipment.shippedDate.getYear() == #specimen.collectionEvent.time.getYear() && #shipment.shippedDate.getMonth() == #specimen.collectionEvent.time.getMonth() && #shipment.shippedDate.getDate() >= #specimen.collectionEvent.time.getDate())", "description": "Shipment date should be greater than the specimen collection date" } ] } |
Order
We can add edit checks on order fields using the record type as ‘order’
Attribute Type | Description | Example JSON |
---|---|---|
Distribution date | Order date should be lesser than current date/time | { "records": ["order"], "rules": [ { "when": "#order.status != 'PENDING'", "expr": "#cmp(#order.executionDate, #currentTime()) <= 0", "description": "Order date should be lesser than current date/time" } ] }, |
Distribution date Vs. Collection Date | Order date should be greater than the specimen collection date | { "records": ["order", "orderItem"], "rules": [ { "when": "#order.status == 'EXECUTED' && #order.executionDate != null", "expr": "#cmp(#order.executionDate, #specimen.collectionEvent.time) >= 0", "description": "Order date should be greater than the specimen (#specimen.label) collection date" } ] } |
- No labels