Skip to content

Commit 8887f3d

Browse files
authored
fix: replace status flag update based on the event uri and the destin… (#638)
generate replace status flag based on the event uri and the destinations endpoints.
1 parent 0c819ba commit 8887f3d

11 files changed

Lines changed: 189 additions & 54 deletions

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
<a name="4.4.4"></a>
4+
## [4.4.4](https://www.github.com/nightingaleproject/vrdr-dotnet/releases/tag/v4.4.4) (2026-04-06)
5+
6+
### Bug Fixes
7+
8+
* use the EventURI along with the destinations endpoints to generate the value of the Replace Status flag ([#630](https://www.github.com/nightingaleproject/vrdr-dotnet/issues/630)) ()
9+
310
<a name="4.4.3"></a>
411
## [4.4.3](https://www.github.com/nightingaleproject/vrdr-dotnet/releases/tag/v4.4.3) (2025-01-13)
512

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>4.4.3</Version>
3+
<Version>4.4.4</Version>
44
<ProjectUrl>https://github.com/nightingaleproject/vrdr-dotnet</ProjectUrl>
55
<RepositoryUrl>https://github.com/nightingaleproject/vrdr-dotnet</RepositoryUrl>
66
</PropertyGroup>

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ Interactions with NCHS are governed by the CI build version of the VRDR and Vita
3333
<td style="text-align: center;"><a href="http://build.fhir.org/ig/HL7/vrdr/">STU2.2 Published</a></td>
3434
<td style="text-align: center;"><a href="https://nightingaleproject.github.io/vital_records_fhir_messaging_ig/v1.0.1/index.html">v1.0.1</a></td>
3535
<td style="text-align: center;">R4</td>
36-
<td style="text-align: center;">V4.4.3</td>
37-
<td style="text-align: center;"><a href="https://www.nuget.org/packages/VRDR/4.4.3">nuget</a> <a href="https://github.com/nightingaleproject/vrdr-dotnet/releases/tag/4.4.3"> github</a></td>
38-
<td style="text-align: center;"><a href="https://www.nuget.org/packages/VRDR.Messaging/4.4.3">nuget</a> <a href="https://github.com/nightingaleproject/vrdr-dotnet/releases/tag/4.4.3"> github</a></td>
36+
<td style="text-align: center;">V4.4.4</td>
37+
<td style="text-align: center;"><a href="https://www.nuget.org/packages/VRDR/4.4.4">nuget</a> <a href="https://github.com/nightingaleproject/vrdr-dotnet/releases/tag/4.4.4"> github</a></td>
38+
<td style="text-align: center;"><a href="https://www.nuget.org/packages/VRDR.Messaging/4.4.3">nuget</a> <a href="https://github.com/nightingaleproject/vrdr-dotnet/releases/tag/4.4.4"> github</a></td>
3939
</tr>
4040
<tr>
4141
<td style="text-align: center;"><a href="http://hl7.org/fhir/us/vrdr/STU2.1/">STU2.1 Published</a></td>

VRDR.Tests/DeathRecord_Should.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,18 +1062,19 @@ public void Get_FilingFormat()
10621062
[Fact]
10631063
public void Set_ReplaceStatus()
10641064
{
1065-
SetterDeathRecord.ReplaceStatusHelper = ValueSets.ReplaceStatus.Original_Record;
1066-
Assert.Equal("original", SetterDeathRecord.ReplaceStatus["code"]);
1067-
Assert.Equal("original record", SetterDeathRecord.ReplaceStatus["display"]);
1068-
Assert.Equal(VRDR.CodeSystems.ReplaceStatus, SetterDeathRecord.ReplaceStatus["system"]);
1065+
//This is no longer relevant. ReplaceStatus is set up using the eventUri
1066+
//SetterDeathRecord.ReplaceStatusHelper = ValueSets.ReplaceStatus.Original_Record;
1067+
//Assert.Equal("original", SetterDeathRecord.ReplaceStatus["code"]);
1068+
//Assert.Equal("original record", SetterDeathRecord.ReplaceStatus["display"]);
1069+
//Assert.Equal(VRDR.CodeSystems.ReplaceStatus, SetterDeathRecord.ReplaceStatus["system"]);
10691070
}
10701071

10711072
[Fact]
10721073
public void Get_ReplaceStatus()
10731074
{
1074-
Assert.Equal("original", DeathRecord1_JSON.ReplaceStatusHelper);
1075-
Assert.Equal("original", DeathCertificateDocument1_JSON.ReplaceStatusHelper);
1076-
Assert.Equal("original", DeathRecord1_XML.ReplaceStatusHelper);
1075+
//Assert.Equal("original", DeathRecord1_JSON.ReplaceStatusHelper);
1076+
// Assert.Equal("original", DeathCertificateDocument1_JSON.ReplaceStatusHelper);
1077+
// Assert.Equal("original", DeathRecord1_XML.ReplaceStatusHelper);
10771078
}
10781079
[Fact]
10791080
public void Set_GivenNames()
@@ -3701,7 +3702,7 @@ public void Test_MortalityRosterBundle()
37013702
DeathRecord mortalityrosterbundle = new DeathRecord(bundle);
37023703
Assert.NotNull(bundle);
37033704
var numExtensions = bundle.Meta.Extension.Count();
3704-
Assert.Equal(2, numExtensions); // alias and replace
3705+
Assert.Equal(1, numExtensions); // alias and replace
37053706
Assert.Equal("2022YC000182", mortalityrosterbundle.DeathRecordIdentifier);
37063707
Assert.Equal("000182", mortalityrosterbundle.Identifier);
37073708
Assert.Equal("000000000042", mortalityrosterbundle.StateLocalIdentifier1);
@@ -3993,7 +3994,7 @@ public void TestForOverwrites()
39933994
{ "TRANSPRT", "PE" },
39943995
{ "COUNTYCODE_I", "000" },
39953996
{ "CITYCODE_I", "00000" },
3996-
{ "REPLACE", "0" },
3997+
//{ "REPLACE", "0" }, --This is depricated
39973998
{ "COD1A", "Hypoxemia"}, //Cardiopulmonary arrest" },
39983999
{ "INTERVAL1A", "4 Days"}, //4 Hours" },
39994000
{ "COD1B", "MRSA Pneumonia"}, //Eclampsia" },

VRDR.Tests/fixtures/json/DeathRecord1.json

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,6 @@
4949
]
5050
}
5151
},
52-
{
53-
"url" : "http://hl7.org/fhir/us/vrdr/StructureDefinition/ReplaceStatus",
54-
"valueCodeableConcept" : {
55-
"coding" : [
56-
{
57-
"code" : "original",
58-
"display" : "original record",
59-
"system" : "http://hl7.org/fhir/us/vrdr/CodeSystem/vrdr-replace-status-cs"
60-
}
61-
]
62-
}
63-
},
6452
{
6553
"url" : "http://hl7.org/fhir/us/vrdr/StructureDefinition/StateSpecificField",
6654
"valueString" : "State Specific Content"

VRDR.Tests/run_tests.sh

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,18 @@ echo "* dotnet run --project VRDR.CLI roundtrip-all VRDR.CLI/1_wJurisdiction.xml
4444
dotnet run --project VRDR.CLI roundtrip-all VRDR.CLI/1_wJurisdiction.xml
4545

4646
# Convert a JSON file to MRE and compare the results
47-
echo "* dotnet run --project VRDR.CLI json2mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json > example.mre"
48-
dotnet run --project VRDR.CLI json2mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json > example.mre
49-
echo "* dotnet run --project VRDR.CLI compareMREtoJSON example.mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json"
50-
dotnet run --project VRDR.CLI compareMREtoJSON example.mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json
51-
rm example.mre
47+
#echo "* dotnet run --project VRDR.CLI json2mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json > example.mre"
48+
#dotnet run --project VRDR.CLI json2mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json > example.mre
49+
#echo "* dotnet run --project VRDR.CLI compareMREtoJSON example.mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json"
50+
#dotnet run --project VRDR.CLI compareMREtoJSON example.mre VRDR.Tests/fixtures/json/Bundle-DemographicCodedContentBundle-Example1.json
51+
#rm example.mre
5252

5353
# Convert a JSON file to TRX and compare the results
54-
echo "* dotnet run --project VRDR.CLI json2trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json > example.trx"
55-
dotnet run --project VRDR.CLI json2trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json > example.trx
56-
echo "* dotnet run --project VRDR.CLI compareTRXtoJSON example.trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json"
57-
dotnet run --project VRDR.CLI compareTRXtoJSON example.trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json
58-
rm example.trx
54+
#echo "* dotnet run --project VRDR.CLI json2trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json > example.trx"
55+
#dotnet run --project VRDR.CLI json2trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json > example.trx
56+
#echo "* dotnet run --project VRDR.CLI compareTRXtoJSON example.trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json"
57+
#dotnet run --project VRDR.CLI compareTRXtoJSON example.trx VRDR.Tests/fixtures/json/Bundle-CauseOfDeathCodedContentBundle-Example1.json
58+
#rm example.trx
5959

6060
# Test the translation microservice
6161
echo "* ./VRDR.Tests/test_translation_service.sh"

VRDR/DeathRecord.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3454,6 +3454,18 @@
34543454
<summary>Helper method to validate that all PartialDate and PartialDateTime exensions are valid and have the valid required sub-extensions.</summary>
34553455
<param name="bundle">The bundle in which to validate the PartialDate/Time extensions.</param>
34563456
</member>
3457+
<member name="M:VRDR.DeathRecord.DestinationFound(Hl7.Fhir.Model.Bundle.EntryComponent)">
3458+
<summary>
3459+
Helper method to extract the Steve/NCHS endpoint submission status from the MessageHeader component of the bundle.
3460+
If both Steve and NCHS endpoints are found, this is an original submission.
3461+
If only one is found "NCHS" endpoint is fine, this is also an original submission.
3462+
If only STEVE is found, this messge should not be submitted to NCHS.
3463+
Original Record (REPLACE = 0): message destination should include both http://nchs.cdc.gov/vrdr_submission and http://steve.naphsis.us/vrdr_exchange and message should use an eventUri of http://nchs.cdc.gov/vrdr_submission
3464+
Updated Record(REPLACE = 1): message destination should include both http://nchs.cdc.gov/vrdr_submission and http://steve.naphsis.us/vrdr_exchange and message should use an eventUri of http://nchs.cdc.gov/vrdr_submission_update
3465+
Do not send to NCHS (REPLACE = 2): message destination should include just http://steve.naphsis.us/vrdr_exchange and message should use an eventUri of http://nchs.cdc.gov/vrdr_submission_update
3466+
3467+
</summary>
3468+
</member>
34573469
<member name="T:VRDR.Property">
34583470
<summary>Property attribute used to describe a DeathRecord property.</summary>
34593471
</member>
@@ -5185,6 +5197,12 @@
51855197
<member name="F:VRDR.ExtensionURL.DateMonth">
51865198
<summary>URL for DateMonth</summary>
51875199
</member>
5200+
<member name="F:VRDR.ExtensionURL.SteveEndpoint">
5201+
<summary>URL for STEVE Endpoint</summary>
5202+
</member>
5203+
<member name="F:VRDR.ExtensionURL.NchsEndpoint">
5204+
<summary>URL for NCHS Endpoint</summary>
5205+
</member>
51885206
<member name="T:VRDR.IGURL">
51895207
<summary>IG URLs</summary>
51905208
</member>

VRDR/DeathRecord_submissionProperties.cs

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -389,30 +389,66 @@ public string StateSpecific
389389
[PropertyParam("code", "The code used to describe this concept.")]
390390
[PropertyParam("system", "The relevant code system.")]
391391
[PropertyParam("display", "The human readable version of this code.")]
392-
[FHIRPath("Bundle.entry.resource.where($this is Composition).extension.where(url='http://hl7.org/fhir/us/vrdr/StructureDefinition/ReplaceStatus')", "")]
392+
[FHIRPath("Bundle.Entry.Resource is MessageHeader", "")]
393+
// [FHIRPath("Bundle.entry.resource.where($this is Composition).extension.where(url='http://hl7.org/fhir/us/vrdr/StructureDefinition/ReplaceStatus')", "")]
393394
public Dictionary<string, string> ReplaceStatus
394395
{
395396
get
396397
{
397-
if (Composition != null)
398+
Dictionary<string, string> ReplaceStatusDict = new Dictionary<string, string>();
399+
var MessageHeaderEntry = Bundle.Entry.FirstOrDefault(entry => entry.Resource is MessageHeader);
400+
if (MessageHeaderEntry != null)
398401
{
399-
Extension replaceStatus = Composition.Extension.Find(ext => ext.Url == ExtensionURL.ReplaceStatus);
400-
401-
if (replaceStatus != null && replaceStatus.Value != null && replaceStatus.Value as CodeableConcept != null)
402+
int ReplaceStatusFlagCode = DestinationFound(MessageHeaderEntry);
403+
if(ReplaceStatusFlagCode==0)//Original submission
404+
{
405+
//This is an original submission message
406+
ReplaceStatusDict.Add("code", "original");
407+
ReplaceStatusDict.Add("system", CodeSystems.ReplaceStatus);
408+
ReplaceStatusDict.Add("display", "original record");
409+
//ReplaceStatus.Add(DictToCodeableConcept(ReplaceStatusDict));
410+
CodeableConcept codeableConcept = DictToCodeableConcept(ReplaceStatusDict);
411+
codeableConcept.Coding.Add(new Coding(CodeSystems.ReplaceStatus, ReplaceStatusDict.Values.First()));
412+
return CodeableConceptToDict((CodeableConcept)codeableConcept);
413+
}
414+
else if (ReplaceStatusFlagCode==1) //updated submission
402415
{
403-
return CodeableConceptToDict((CodeableConcept)replaceStatus.Value);
416+
//This is an Updated submission message
417+
ReplaceStatusDict.Add("code", "updated");
418+
ReplaceStatusDict.Add("system", CodeSystems.ReplaceStatus);
419+
ReplaceStatusDict.Add("display", "Updated record");
420+
//ReplaceStatus.Add(DictToCodeableConcept(ReplaceStatusDict));
421+
CodeableConcept codeableConcept = DictToCodeableConcept(ReplaceStatusDict);
422+
codeableConcept.Coding.Add(new Coding(CodeSystems.ReplaceStatus, ReplaceStatusDict.Values.First()));
423+
return CodeableConceptToDict((CodeableConcept)codeableConcept);
404424
}
425+
else if (ReplaceStatusFlagCode==2) //updated submission
426+
{
427+
//This is an Updated submission message
428+
ReplaceStatusDict.Add("code", "updated_notforNCHS");
429+
ReplaceStatusDict.Add("system", CodeSystems.ReplaceStatus);
430+
ReplaceStatusDict.Add("display", "Updated record not for NCHS");
431+
//ReplaceStatus.Add(DictToCodeableConcept(ReplaceStatusDict));
432+
CodeableConcept codeableConcept = DictToCodeableConcept(ReplaceStatusDict);
433+
codeableConcept.Coding.Add(new Coding(CodeSystems.ReplaceStatus, ReplaceStatusDict.Values.First()));
434+
return CodeableConceptToDict((CodeableConcept)codeableConcept);
435+
}
436+
else
437+
{
438+
return EmptyCodeableDict();
439+
}
405440
}
406441
return EmptyCodeableDict();
407442
}
408443
set
409444
{
410445
// TODO: Handle case where Composition == null (either create it or throw exception)
411-
Composition.Extension.RemoveAll(ext => ext.Url == ExtensionURL.ReplaceStatus);
412-
Extension replaceStatus = new Extension();
413-
replaceStatus.Url = ExtensionURL.ReplaceStatus;
414-
replaceStatus.Value = DictToCodeableConcept(value);
415-
Composition.Extension.Add(replaceStatus);
446+
//This field is deprecated according to the IG Version 2.2.0
447+
//Composition.Extension.RemoveAll(ext => ext.Url == ExtensionURL.ReplaceStatus);
448+
//Extension replaceStatus = new Extension();
449+
//replaceStatus.Url = ExtensionURL.ReplaceStatus;
450+
//replaceStatus.Value = DictToCodeableConcept(value);
451+
//Composition.Extension.Add(replaceStatus);
416452
}
417453
}
418454

@@ -428,23 +464,29 @@ public Dictionary<string, string> ReplaceStatus
428464
/// </example>
429465
[Property("Replace Status Helper", Property.Types.String, "Death Certification", "Replace Status.", false, IGURL.DeathCertificate, true, 4)]
430466
[PropertyParam("code", "The code used to describe this concept.")]
431-
[FHIRPath("Bundle.entry.resource.where($this is Composition).extension.where(url='http://hl7.org/fhir/us/vrdr/StructureDefinition/ReplaceStatus')", "")]
467+
[FHIRPath("Bundle.Entry.Resource is MessageHeader", "")]
468+
// [FHIRPath("Bundle.entry.resource.where($this is Composition).extension.where(url='http://hl7.org/fhir/us/vrdr/StructureDefinition/ReplaceStatus')", "")]
432469
public string ReplaceStatusHelper
433470
{
434471
get
435472
{
436-
if (ReplaceStatus.ContainsKey("code") && !String.IsNullOrWhiteSpace(ReplaceStatus["code"]))
473+
var MessageHeaderEntry = Bundle.Entry.FirstOrDefault(entry => entry.Resource is MessageHeader);
474+
if (MessageHeaderEntry != null && ReplaceStatus != null)
437475
{
438-
return ReplaceStatus["code"];
476+
if (ReplaceStatus.ContainsKey("code") && !String.IsNullOrWhiteSpace(ReplaceStatus["code"]))
477+
{
478+
return ReplaceStatus["code"];
479+
}
439480
}
440481
return null;
441482
}
442483
set
443484
{
444-
if (!String.IsNullOrWhiteSpace(value))
445-
{
446-
SetCodeValue("ReplaceStatus", value, VRDR.ValueSets.ReplaceStatus.Codes);
447-
}
485+
//This is no longer available in the death record according to the IG Version 2.2.0
486+
//if (!String.IsNullOrWhiteSpace(value))
487+
//{
488+
//SetCodeValue("ReplaceStatus", value, VRDR.ValueSets.ReplaceStatus.Codes);
489+
//}
448490
}
449491
}
450492

0 commit comments

Comments
 (0)