From d2748eef5311ae3bc1831e36694c87524824f5bb Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Thu, 28 Dec 2023 13:45:31 +1100 Subject: [PATCH] fill out expression and issue type on issues --- library/fhir/fhir_common.pas | 4 +- library/fhir2/fhir2_common.pas | 6 ++- library/fhir3/fhir3_common.pas | 9 ++-- library/fhir4/fhir4_common.pas | 7 ++- library/fhir4b/fhir4b_common.pas | 9 ++-- library/fhir5/fhir5_common.pas | 7 ++- library/ftx/fhir_valuesets.pas | 84 ++++++++++++++++---------------- 7 files changed, 71 insertions(+), 55 deletions(-) diff --git a/library/fhir/fhir_common.pas b/library/fhir/fhir_common.pas index d37d44ce5..06c998aed 100644 --- a/library/fhir/fhir_common.pas +++ b/library/fhir/fhir_common.pas @@ -61,11 +61,13 @@ interface TObservationStatus = (obssNull, obssRegistered, obssPreliminary, obssFinal, obssAmended, obssCorrected, obssCancelled, obssEnteredInError, obssUnknown); TTokenCategory = (tcClinical, tcData, tcMeds, tcSchedule, tcAudit, tcDocuments, tcFinancial, tcMedicationDefinition, tcOther); TIdentifierUse = (iuNull, iuUsual, iuOfficial, iuTemp, iuSecondary, iuOld); + TOpIssueCode = (oicVoid, oicNotInVS, oicThisNotInVS, oicInvalidCode, oicDisplay, oicNotFound, oicCodeRule, oicVSProcessing, oicInferFailed, oicStatusCheck); const CODES_TFhirFilterOperator: Array[TFilterOperator] of String = ('', '=', 'is-a', 'descendent-of', 'is-not-a', 'regex', 'in', 'not-in', 'generalizes', 'exists', 'child-of', 'descendent-leaf'); CODES_TPublicationStatus: Array[TPublicationStatus] of String = ('', 'draft', 'active', 'retired'); CODES_TTokenCategory : array [TTokenCategory] of String = ('Clinical', 'Data', 'Meds', 'Schedule', 'Audit', 'Documents', 'Financial', 'MedicationDefinitions', 'Other'); + CODES_TOpIssueCode : array [TOpIssueCode] of String = ('', 'not-in-vs', 'this-code-not-in-vs', 'invalid-code', 'invalid-display', 'not-found', 'code-rule', 'vs-invalid', 'cannot-infer', 'status-check'); type @@ -383,7 +385,7 @@ TFhirOperationOutcomeW = class (TFHIRXVersionResourceWrapper) function code : TFhirIssueType; virtual; abstract; procedure addIssue(issue : TFhirOperationOutcomeIssueW; free : boolean); overload; virtual; abstract; - procedure addIssue(level : TIssueSeverity; cause : TFhirIssueType; path, message : String; addIfDuplicate : boolean = false); overload; virtual; abstract; + procedure addIssue(level : TIssueSeverity; cause : TFhirIssueType; path, message : String; issueCode : TOpIssueCode; addIfDuplicate : boolean = false); overload; virtual; abstract; function hasIssues : boolean; virtual; abstract; function issues : TFslList; virtual; abstract; function rule(level : TIssueSeverity; source : String; typeCode : TFhirIssueType; path : string; test : boolean; msg : string) : boolean; virtual; abstract; diff --git a/library/fhir2/fhir2_common.pas b/library/fhir2/fhir2_common.pas index 2de2365f7..30f9e4e42 100644 --- a/library/fhir2/fhir2_common.pas +++ b/library/fhir2/fhir2_common.pas @@ -178,7 +178,7 @@ TFhirOperationOutcome2 = class (TFhirOperationOutcomeW) function text : String; override; function code : TFhirIssueType; override; procedure addIssue(issue : TFhirOperationOutcomeIssueW; owns : boolean); override; - procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; addIfDuplicate : boolean); override; + procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); override; function hasIssues : boolean; override; function issues : TFslList; override; function rule(level : TIssueSeverity; source : String; typeCode : TFhirIssueType; path : string; test : boolean; msg : string) : boolean; override; @@ -1252,7 +1252,7 @@ procedure TFhirOperationOutcome2.addIssue(issue: TFhirOperationOutcomeIssueW; ow issue.free; end; -procedure TFhirOperationOutcome2.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message: String; addIfDuplicate : boolean); +procedure TFhirOperationOutcome2.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); var iss : TFhirOperationOutcomeIssue; begin @@ -1267,6 +1267,8 @@ procedure TFhirOperationOutcome2.addIssue(level: TIssueSeverity; cause: TFHIRIss iss.code:= ExceptionTypeTranslations[cause]; iss.severity := ISSUE_SEVERITY_MAP2[level]; iss.details := TFHIRCodeableConcept.Create; + if (code <> oicVoid) then + iss.details.addCoding('http://hl7.org/fhir/tools/CodeSystem/tx-issue-type', '', CODES_TOpIssueCode[code], ''); iss.details.text := message; iss.locationList.Add(path); end; diff --git a/library/fhir3/fhir3_common.pas b/library/fhir3/fhir3_common.pas index e94043edc..32ff37765 100644 --- a/library/fhir3/fhir3_common.pas +++ b/library/fhir3/fhir3_common.pas @@ -178,7 +178,7 @@ TFhirOperationOutcome3 = class (TFhirOperationOutcomeW) function text : String; override; function code : TFhirIssueType; override; procedure addIssue(issue : TFhirOperationOutcomeIssueW; free : boolean); override; - procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; addIfDuplicate : boolean); override; + procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); override; function hasIssues : boolean; override; function issues : TFslList; override; function rule(level : TIssueSeverity; source : String; typeCode : TFhirIssueType; path : string; test : boolean; msg : string) : boolean; override; @@ -1394,7 +1394,7 @@ procedure TFhirOperationOutcome3.addIssue(issue: TFhirOperationOutcomeIssueW; fr issue.free; end; -procedure TFhirOperationOutcome3.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message: String; addIfDuplicate : boolean); +procedure TFhirOperationOutcome3.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); var iss : TFhirOperationOutcomeIssue; begin @@ -1408,9 +1408,12 @@ procedure TFhirOperationOutcome3.addIssue(level: TIssueSeverity; cause: TFHIRIss iss := (Fres as TFhirOperationOutcome).issueList.Append; iss.code:= ExceptionTypeTranslations[cause]; iss.severity := ISSUE_SEVERITY_MAP2[level]; - iss.details := TFHIRCodeableConcept.Create; + iss.details := TFHIRCodeableConcept.Create; + if (code <> oicVoid) then + iss.details.addCoding('http://hl7.org/fhir/tools/CodeSystem/tx-issue-type', '', CODES_TOpIssueCode[code], ''); iss.details.text := message; iss.locationList.Add(path); + iss.expressionList.Add(path); end; function TFhirOperationOutcome3.code: TFhirIssueType; diff --git a/library/fhir4/fhir4_common.pas b/library/fhir4/fhir4_common.pas index fa6d4ec5b..714e42d28 100644 --- a/library/fhir4/fhir4_common.pas +++ b/library/fhir4/fhir4_common.pas @@ -176,7 +176,7 @@ TFhirOperationOutcome4 = class (TFhirOperationOutcomeW) function text : String; override; function code : TFhirIssueType; override; procedure addIssue(issue : TFhirOperationOutcomeIssueW; free : boolean); override; - procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; addIfDuplicate : boolean); override; + procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); override; function hasIssues : boolean; override; function issues : TFslList; override; function rule(level : TIssueSeverity; source : String; typeCode : TFhirIssueType; path : string; test : boolean; msg : string) : boolean; override; @@ -1366,7 +1366,7 @@ procedure TFhirOperationOutcome4.addIssue(issue: TFhirOperationOutcomeIssueW; fr issue.free; end; -procedure TFhirOperationOutcome4.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message: String; addIfDuplicate : boolean); +procedure TFhirOperationOutcome4.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); var iss : TFhirOperationOutcomeIssue; begin @@ -1386,8 +1386,11 @@ procedure TFhirOperationOutcome4.addIssue(level: TIssueSeverity; cause: TFHIRIss iss.code:= ExceptionTypeTranslations[cause]; iss.severity := ISSUE_SEVERITY_MAP2[level]; iss.details := TFHIRCodeableConcept.Create; + if (code <> oicVoid) then + iss.details.addCoding('http://hl7.org/fhir/tools/CodeSystem/tx-issue-type', '', CODES_TOpIssueCode[code], ''); iss.details.text := message; iss.locationList.Add(path); + iss.expressionList.Add(path); end; function TFhirOperationOutcome4.code: TFhirIssueType; diff --git a/library/fhir4b/fhir4b_common.pas b/library/fhir4b/fhir4b_common.pas index ae276e4ae..0112d9471 100644 --- a/library/fhir4b/fhir4b_common.pas +++ b/library/fhir4b/fhir4b_common.pas @@ -177,7 +177,7 @@ TFhirOperationOutcome4B = class (TFhirOperationOutcomeW) function text : String; override; function code : TFhirIssueType; override; procedure addIssue(issue : TFhirOperationOutcomeIssueW; free : boolean); override; - procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; addIfDuplicate : boolean); override; + procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); override; function hasIssues : boolean; override; function issues : TFslList; override; function rule(level : TIssueSeverity; source : String; typeCode : TFhirIssueType; path : string; test : boolean; msg : string) : boolean; override; @@ -1365,7 +1365,7 @@ procedure TFhirOperationOutcome4B.addIssue(issue: TFhirOperationOutcomeIssueW; f issue.free; end; -procedure TFhirOperationOutcome4B.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message: String; addIfDuplicate : boolean); +procedure TFhirOperationOutcome4B.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); var iss : TFhirOperationOutcomeIssue; begin @@ -1379,9 +1379,12 @@ procedure TFhirOperationOutcome4B.addIssue(level: TIssueSeverity; cause: TFHIRIs iss := (Fres as TFhirOperationOutcome).issueList.Append; iss.code:= ExceptionTypeTranslations[cause]; iss.severity := ISSUE_SEVERITY_MAP2[level]; - iss.details := TFHIRCodeableConcept.Create; + iss.details := TFHIRCodeableConcept.Create; + if (code <> oicVoid) then + iss.details.addCoding('http://hl7.org/fhir/tools/CodeSystem/tx-issue-type', '', CODES_TOpIssueCode[code], ''); iss.details.text := message; iss.locationList.Add(path); + iss.expressionList.Add(path); end; function TFhirOperationOutcome4B.code: TFhirIssueType; diff --git a/library/fhir5/fhir5_common.pas b/library/fhir5/fhir5_common.pas index 8242b6bbd..acd663688 100644 --- a/library/fhir5/fhir5_common.pas +++ b/library/fhir5/fhir5_common.pas @@ -175,7 +175,7 @@ TFhirOperationOutcome5 = class (TFhirOperationOutcomeW) function text : String; override; function code : TFhirIssueType; override; procedure addIssue(issue : TFhirOperationOutcomeIssueW; free : boolean); override; - procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; addIfDuplicate : boolean); override; + procedure addIssue(level : TIssueSeverity; cause : TFHIRIssueType; path, message : String; code : TOpIssueCode; addIfDuplicate : boolean); override; function hasIssues : boolean; override; function issues : TFslList; override; function rule(level : TIssueSeverity; source : String; typeCode : TFhirIssueType; path : string; test : boolean; msg : string) : boolean; override; @@ -1375,7 +1375,7 @@ procedure TFhirOperationOutcome5.addIssue(issue: TFhirOperationOutcomeIssueW; fr issue.free; end; -procedure TFhirOperationOutcome5.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message: String; addIfDuplicate : boolean); +procedure TFhirOperationOutcome5.addIssue(level: TIssueSeverity; cause: TFHIRIssueType; path, message: String; code : TOpIssueCode; addIfDuplicate : boolean); var iss : TFhirOperationOutcomeIssue; begin @@ -1395,8 +1395,11 @@ procedure TFhirOperationOutcome5.addIssue(level: TIssueSeverity; cause: TFHIRIss iss.code:= ExceptionTypeTranslations[cause]; iss.severity := ISSUE_SEVERITY_MAP2[level]; iss.details := TFHIRCodeableConcept.Create; + if (code <> oicVoid) then + iss.details.addCoding('http://hl7.org/fhir/tools/CodeSystem/tx-issue-type', '', CODES_TOpIssueCode[code], ''); iss.details.text := message; iss.locationList.Add(path); + iss.expressionList.Add(path); end; function TFhirOperationOutcome5.code: TFhirIssueType; diff --git a/library/ftx/fhir_valuesets.pas b/library/ftx/fhir_valuesets.pas index 1f8ef2ca8..5916cad17 100644 --- a/library/ftx/fhir_valuesets.pas +++ b/library/ftx/fhir_valuesets.pas @@ -723,18 +723,18 @@ procedure TValueSetChecker.checkCanonicalStatus(path : string; op : TFhirOperati if op <> nil then begin if standardsStatus = 'deprecated' then - op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_DEPRECATED', FParams.languages, [vurl, '', rtype]), false) + op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_DEPRECATED', FParams.languages, [vurl, '', rtype]), oicStatusCheck, false) else if standardsStatus = 'withdrawn' then - op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_WITHDRAWN', FParams.languages, [vurl, '', rtype]), false) + op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_WITHDRAWN', FParams.languages, [vurl, '', rtype]), oicStatusCheck, false) else if status = psRetired then - op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_RETIRED', FParams.languages, [vurl, '', rtype]), false) + op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_RETIRED', FParams.languages, [vurl, '', rtype]), oicStatusCheck, false) else if (source <> nil) then begin if experimental and not source.experimental then - op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_EXPERIMENTAL', FParams.languages, [vurl, '', rtype]), false) + op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_EXPERIMENTAL', FParams.languages, [vurl, '', rtype]), oicStatusCheck, false) else if ((status = psDraft) or (standardsStatus = 'draft')) and not ((source.status = psDraft) or (source.getExtensionString('http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status') = 'draft')) then - op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_DRAFT', FParams.languages, [vurl, '', rtype]), false) + op.addIssue(isInformation, itBusinessRule, '', FI18n.translate('MSG_DRAFT', FParams.languages, [vurl, '', rtype]), oicStatusCheck, false) end; end; end; @@ -903,7 +903,7 @@ function TValueSetChecker.determineVersion(path, systemURI, versionVS, versionCo else begin message := 'The code system "'+systemUri+'" version "'+versionVS+'" in the ValueSet include is different to the one in the value ("'+versionCoding+'")'; - op.addIssue(isError, itNotFound, addToPath(path, 'version'), message); + op.addIssue(isError, itNotFound, addToPath(path, 'version'), message, oicVSProcessing); exit(''); end; if result = '' then @@ -1137,14 +1137,14 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, begin msg := FI18n.translate('UNKNOWN_CODESYSTEM_VERSION', FParams.languages, [system, version]); messages.add(msg); - op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg); + op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg, oicNotFound); unknownSystems.add(system+'|'+version); end else begin msg := FI18n.translate('UNKNOWN_CODESYSTEM', FParams.languages, [system]); messages.add(msg); - op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg); + op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg, oicNotFound); unknownSystems.add(system); end; end @@ -1165,7 +1165,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, FLog := 'Not found in Incomplete Code System'; msg := FI18n.translate('UNKNOWN_CODE_IN_FRAGMENT', FParams.languages, [code, cs.systemUri(nil), cs.version(nil)]); messages.add(msg); - op.addIssue(isWarning, itCodeInvalid, addToPath(path, 'code'), msg); + op.addIssue(isWarning, itCodeInvalid, addToPath(path, 'code'), msg, oicInvalidCode); end else begin @@ -1174,7 +1174,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, FLog := 'Unknown code'; msg := FI18n.translate('Unknown_Code_in_Version', FParams.languages, [code, cs.systemUri(nil), cs.version(nil)]); messages.add(msg); - op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), msg); + op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), msg, oicInvalidCode); end; end else @@ -1190,7 +1190,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, cause := itBusinessRule; msg := FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [system, code]); messages.add(msg); - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg); + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg, oicCodeRule); end else if ((FParams <> nil) and FParams.activeOnly and cs.isInactive(ctxt)) then begin @@ -1199,7 +1199,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, cause := itBusinessRule; msg := FI18n.translate('INACTIVE_CODE_NOT_ALLOWED', FParams.languages, [system, code]); messages.add(msg); - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg); + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg, oicCodeRule); end else begin @@ -1234,14 +1234,14 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, begin msg := FI18n.translate('UNKNOWN_CODESYSTEM_VERSION', FParams.languages, [system, version]); messages.add(msg); - op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg); + op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg, oicNotFound); unknownSystems.add(system+'|'+version); end else begin msg := FI18n.translate('UNKNOWN_CODESYSTEM', FParams.languages, [system]); messages.add(msg); - op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg); + op.addIssue(isError, itNotFound, addToPath(path, 'system'), msg, oicNotFound); unknownSystems.add(system); end; end @@ -1261,7 +1261,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, FLog := 'Not found in Incomplete Code System'; msg := FI18n.translate('UNKNOWN_CODE_IN_FRAGMENT', FParams.languages, [code, system, version]); messages.add(msg); - op.addIssue(isWarning, itCodeInvalid, addToPath(path, 'code'), msg); + op.addIssue(isWarning, itCodeInvalid, addToPath(path, 'code'), msg, oicInvalidCode); end else begin @@ -1270,7 +1270,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, FLog := 'Unknown code'; msg := FI18n.translate('Unknown_Code_in_Version', FParams.languages, [code, system, version]); messages.add(msg); - op.addIssue(isWarning, itCodeInvalid, addToPath(path, 'code'), msg); + op.addIssue(isWarning, itCodeInvalid, addToPath(path, 'code'), msg, oicInvalidCode); end; end else @@ -1284,7 +1284,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, cause := itBusinessRule; msg := FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [system, code]); messages.add(msg); - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg); + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg, oicCodeRule); end else if ((FParams <> nil) and FParams.activeOnly and cs.isInactive(ctxt)) then begin @@ -1293,7 +1293,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, cause := itBusinessRule; msg := FI18n.translate('INACTIVE_CODE_NOT_ALLOWED', FParams.languages, [system, code]); messages.add(msg); - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg); + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), msg, oicCodeRule); end else begin @@ -1319,7 +1319,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, begin message := FI18n.translate('UNABLE_TO_INFER_CODESYSTEM', FParams.languages, [code, FValueSet.url]); messages.add(message); - op.addIssue(isError, itNotFound, path, message); + op.addIssue(isError, itNotFound, path, message, oicInferFailed); exit(bFalse); end else @@ -1393,7 +1393,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, unknownSystems.add(system+'|'+v); end; messages.add(message); - op.addIssue(isError, itNotFound, addToPath(path, 'system'), message); + op.addIssue(isError, itNotFound, addToPath(path, 'system'), message, oicNotFound); exit(bUnknown); end else @@ -1472,7 +1472,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, begin message := 'The code system "'+ccc.systemUri+'" version "'+ccc.version+'" in the ValueSet expansion is different to the one in the value ("'+version+'")'; messages.add(message); - op.addIssue(isError, itNotFound, addToPath(path, 'version'), message); + op.addIssue(isError, itNotFound, addToPath(path, 'version'), message, oicVSProcessing); exit(bFalse); end; if (v = '') then @@ -1497,7 +1497,7 @@ function TValueSetChecker.check(path, system, version, code: String; abstractOk, end; messages.add(message); - op.addIssue(isError, itNotFound, addToPath(path, 'system'), message); + op.addIssue(isError, itNotFound, addToPath(path, 'system'), message, oicNotFound); exit(bUnknown); end else @@ -1765,7 +1765,7 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; m := FI18n.translate('None_of_the_provided_codes_are_in_the_value_set_one', FParams.languages, ['', FValueSet.vurl, ''''+cc+'''']); msg(m); p := issuePath + '.coding['+inttostr(i)+'].code'; - op.addIssue(isWarning, itCodeInvalid, p, m); + op.addIssue(isInformation, itCodeInvalid, p, m, oicThisNotInVS); if cause = itNull then cause := itUnknown; end; @@ -1780,7 +1780,7 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; begin m := 'The system '+c.systemUri+' was found but did not contain enough information to properly validate the code "'+c.code+'" ("'+c.display+'") (mode = '+CODES_TFhirCodeSystemContentMode[contentMode]+')'; msg(m); - op.addIssue(isWarning, itNotFound, path, m); + op.addIssue(isWarning, itNotFound, path, m, oicVSProcessing); end else if (c.display <> '') and (not list.hasDisplay(FParams.languages, c.display, dcsCaseInsensitive, diff)) then @@ -1804,7 +1804,7 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; m := FI18n.translate(baseMsg+'_other', FParams.languages, [inttostr(dc), c.systemUri, c.code, list.present(FParams.languages, true), c.display, FParams.langSummary]); msg(m); - op.addIssue(severity, itInvalid, addToPath(path, 'display'), m); + op.addIssue(severity, itInvalid, addToPath(path, 'display'), m, oicDisplay); end; psys := c.systemUri; pcode := c.code; @@ -1836,12 +1836,12 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; //if (valueSetDependsOnCodeSystem(ws, c.version)) then unknownSystems.add(ws+'|'+c.version); end; - op.addIssue(isError, itNotFound, addToPath(path, 'system'), m); + op.addIssue(isError, itNotFound, addToPath(path, 'system'), m, oicNotFound); if (valueSetDependsOnCodeSystem(ws, c.version)) then begin m := 'Unable to check whether the code is in the value set '+FValueSet.vurl; msg(m); - op.addIssue(isWarning, itNotFound, issuepath, m); + op.addIssue(isWarning, itNotFound, issuepath, m, oicVSProcessing); end else msg(m); @@ -1860,7 +1860,7 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; if (message <> '') then begin // msg(message); we just add this as an issue, but don't put it in the base message - op.addIssue(isInformation, cause, path, message); + op.addIssue(isInformation, cause, path, message, oicInvalidCode); message := ''; end; vcc.removeCoding(prov.systemUri(nil), prov.version(nil), c.code); @@ -1871,7 +1871,7 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; m := FI18N.translate('Unknown_Code_in_Version', FParams.languages, [c.code, ws, prov.version(nil)]); cause := itCodeInvalid; msg(m); - op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), m); + op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), m, oicInvalidCode); end; end else @@ -1899,7 +1899,7 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; m := FI18n.translate(baseMsg+'_other', FParams.languages, [inttostr(dc), prov.systemUri(ctxt), c.code, list.present(FParams.languages, true), c.display, FParams.langSummary]); msg(m); - op.addIssue(severity, itInvalid, addToPath(path, 'display'), m); + op.addIssue(severity, itInvalid, addToPath(path, 'display'), m, oicDisplay); end; if (prov.version(nil) <> '') then result.addParamStr('version', prov.version(nil)); @@ -1933,7 +1933,7 @@ function TValueSetChecker.check(issuePath : String; code: TFhirCodeableConceptW; else p := issuePath; - op.addIssue(isError, itCodeInvalid, p, m); + op.addIssue(isError, itCodeInvalid, p, m, oicNotInVS); if cause = itNull then cause := itUnknown; end; @@ -2043,7 +2043,7 @@ function TValueSetChecker.check(issuePath, system, version, code: String; inferS begin result.AddParamBool('result', false); result.AddParamStr('message', 'The system "'+system+'" is unknown so the /"'+code+'" cannot be confirmed to be in the value set '+FValueSet.name); - op.addIssue(isError, cause, 'code', 'The system "'+system+'" is unknown so the /"'+code+'" cannot be confirmed to be in the value set '+FValueSet.name); + op.addIssue(isError, cause, 'code', 'The system "'+system+'" is unknown so the /"'+code+'" cannot be confirmed to be in the value set '+FValueSet.name, oicNotFound); //result.AddParamCode('cause', CODES_TFhirIssueType[itNotFound]); for us in unknownSystems do result.addParamCanonical('x-caused-by-unknown-system', us); @@ -2052,7 +2052,7 @@ function TValueSetChecker.check(issuePath, system, version, code: String; inferS begin result.AddParamBool('result', false); result.AddParamStr('message', 'The system/code "'+system+'"/"'+code+'" is not in the value set '+FValueSet.name); - op.addIssue(isError, cause, 'code', 'The system/code "'+system+'"/"'+code+'" is not in the value set '+FValueSet.name); + op.addIssue(isError, cause, 'code', 'The system/code "'+system+'"/"'+code+'" is not in the value set '+FValueSet.name, oicNotInVS); if (message <> '') then result.AddParamStr('message', message); if cause <> itNull then @@ -2113,12 +2113,12 @@ function TValueSetChecker.checkConceptSet(path : String; cs: TCodeSystemProvider if loc = nil then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), FI18n.translate('Unknown_Code_in_Version', FParams.languages, [code, cs.systemUri(nil), cs.version(nil)])) + op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), FI18n.translate('Unknown_Code_in_Version', FParams.languages, [code, cs.systemUri(nil), cs.version(nil)]), oicInvalidCode) end else if not (abstractOk or not cs.IsAbstract(loc)) then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code])) + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code]), oicCodeRule) end else if FValueSet.excludeInactives and cs.IsInactive(loc) then begin @@ -2161,7 +2161,7 @@ function TValueSetChecker.checkConceptSet(path : String; cs: TCodeSystemProvider if not (abstractOk or not cs.IsAbstract(loc)) then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code])) + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code]), oicCodeRule) end else if FValueSet.excludeInactives and cs.IsInactive(loc) then begin @@ -2214,7 +2214,7 @@ function TValueSetChecker.checkConceptSet(path : String; cs: TCodeSystemProvider if not (abstractOk or not cs.IsAbstract(loc)) then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code])) + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code]), oicCodeRule) end else if FValueSet.excludeInactives and cs.IsInactive(loc) then begin @@ -2253,7 +2253,7 @@ function TValueSetChecker.checkConceptSet(path : String; cs: TCodeSystemProvider if not (abstractOk or not cs.IsAbstract(loc)) then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code])) + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code]), oicCodeRule) end else begin @@ -2283,7 +2283,7 @@ function TValueSetChecker.checkConceptSet(path : String; cs: TCodeSystemProvider if not (abstractOk or not cs.IsAbstract(loc)) then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code])) + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code]), oicCodeRule) end else if FValueSet.excludeInactives and cs.IsInactive(loc) then begin @@ -2321,7 +2321,7 @@ function TValueSetChecker.checkConceptSet(path : String; cs: TCodeSystemProvider if not (abstractOk or not cs.IsAbstract(loc)) then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code])) + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code]), oicCodeRule) end else if FValueSet.excludeInactives and cs.IsInactive(loc) then begin @@ -2372,12 +2372,12 @@ function TValueSetChecker.checkExpansion(path: String; cs: TCodeSystemProvider; if loc = nil then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), FI18n.translate('Unknown_Code_in_Version', FParams.languages, [code, cs.systemUri(nil), cs.version(nil)])) + op.addIssue(isError, itCodeInvalid, addToPath(path, 'code'), FI18n.translate('Unknown_Code_in_Version', FParams.languages, [code, cs.systemUri(nil), cs.version(nil)]), oicInvalidCode) end else if not (abstractOk or not cs.IsAbstract(loc)) then begin if (FParams.valueSetMode <> vsvmMembershipOnly) then - op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code])) + op.addIssue(isError, itBusinessRule, addToPath(path, 'code'), FI18n.translate('ABSTRACT_CODE_NOT_ALLOWED', FParams.languages, [cs.systemUri(nil), code]), oicCodeRule) end else begin