From c9185b4ddb4e35123c1da9f91af737b233882234 Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Fri, 18 Oct 2024 19:45:12 -0500 Subject: [PATCH 01/17] added fix for the null TIN root id issue --- .../api/internal/pii/SpecPiiValidator.java | 24 +++++++++---------- .../internal/pii/SpecPiiValidatorTest.java | 14 +++++++++++ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java index dd598587d..16e90d89b 100644 --- a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java +++ b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java @@ -28,17 +28,21 @@ public SpecPiiValidator(PcfValidationInfoMap file) { @Override public void validateApmTinNpiCombination(Node node, NodeValidator validator) { - validateInvalidApmCombinations(node, validator); - validateMissingApmCombinations(node, validator); + List npiList = Arrays.asList( + node.getValue(NATIONAL_PROVIDER_IDENTIFIER).split(",")); + List tinList = Arrays.asList( + node.getValue(TAX_PAYER_IDENTIFICATION_NUMBER).split(",")); + if (npiList.size() != tinList.size()) { + validator.addError(Detail.forProblemAndNode(ProblemCode.INCORRECT_API_NPI_COMBINATION, node)); + } else { + validateInvalidApmCombinations(node, validator, npiList, tinList); + validateMissingApmCombinations(node, validator, npiList, tinList); + } } - private void validateInvalidApmCombinations(Node node, NodeValidator validator) { + private void validateInvalidApmCombinations(Node node, NodeValidator validator, List npiList, List tinList) { String program = node.getValue(PROGRAM_NAME); String apm = getApmEntityId(node, program); - List npiList = Arrays.asList( - node.getValue(NATIONAL_PROVIDER_IDENTIFIER).split(",")); - List tinList = Arrays.asList( - node.getValue(TAX_PAYER_IDENTIFICATION_NUMBER).split(",")); Map>> apmToTinNpiMap = file.getApmTinNpiCombinationMap(); if (apmToTinNpiMap == null || StringUtils.isEmpty(apm)) { @@ -59,13 +63,9 @@ private void validateInvalidApmCombinations(Node node, NodeValidator validator) } } - private void validateMissingApmCombinations(Node node, NodeValidator validator) { + private void validateMissingApmCombinations(Node node, NodeValidator validator, List npiList, List tinList) { String program = node.getValue(PROGRAM_NAME); String apm = getApmEntityId(node, program); - List npiList = Arrays.asList( - node.getValue(NATIONAL_PROVIDER_IDENTIFIER).split(",")); - List tinList = Arrays.asList( - node.getValue(TAX_PAYER_IDENTIFICATION_NUMBER).split(",")); List tinNpiCombinations = createTinNpiMap(tinList, npiList); diff --git a/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java b/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java index 7072efe69..f1ac9e447 100644 --- a/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java +++ b/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java @@ -110,6 +110,20 @@ protected void performValidation(Node node) { Truth.assertThat(nodeValidator.viewWarnings().get(0).getErrorCode()).isEqualTo(108); } + @Test + void testNpiTinSizeMismatch() throws Exception { + SpecPiiValidator validator = validator("DogCow_APM", "DogCow_NPI"); + Node node = node("Invalid_Apm", "DogCow_NPI,DogCow_NPI2", "DogCow", PCF_PROGRAM_NAME); + System.out.println(node); + NodeValidator nodeValidator = new NodeValidator() { + @Override + protected void performValidation(Node node) { + } + }; + validator.validateApmTinNpiCombination(node, nodeValidator); + Truth.assertThat(nodeValidator.viewWarnings().get(0).getErrorCode()).isEqualTo(80); + } + private SpecPiiValidator validator(String apm, String npi) throws Exception { return new SpecPiiValidator(createSpecFile(apm, npi)); } From 94ffdccdbeb8b588bdf595ff59b0171604aa38a4 Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Mon, 21 Oct 2024 16:01:54 -0500 Subject: [PATCH 02/17] fixed some sonar issues --- .../qpp/conversion/api/internal/pii/SpecPiiValidator.java | 8 +++++--- .../conversion/api/internal/pii/SpecPiiValidatorTest.java | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java index 16e90d89b..cd7185ca8 100644 --- a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java +++ b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java @@ -69,6 +69,8 @@ private void validateMissingApmCombinations(Node node, NodeValidator validator, List tinNpiCombinations = createTinNpiMap(tinList, npiList); + // Adding some sonar exclusions, to avoid cognitive complexity. + // The conditions here would probably need to be checked in the specific order Map>> apmToTinNpiMap = file.getApmTinNpiCombinationMap(); if (apmToTinNpiMap == null || StringUtils.isEmpty(apm)) { validator.addWarning(Detail.forProblemAndNode(ProblemCode.MISSING_API_TIN_NPI_FILE, node)); @@ -78,14 +80,14 @@ private void validateMissingApmCombinations(Node node, NodeValidator validator, for(final Map.Entry> currentEntry: tinNpisMap.entrySet()) { for (final String currentNpi : currentEntry.getValue()) { boolean combinationExists = false; - for (TinNpiCombination currentCombination : tinNpiCombinations) { - if (currentEntry.getKey().equalsIgnoreCase((currentCombination.getTin())) && + for (TinNpiCombination currentCombination : tinNpiCombinations) { //NOSONAR + if (currentEntry.getKey().equalsIgnoreCase((currentCombination.getTin())) && //NOSONAR currentNpi.equalsIgnoreCase(currentCombination.getNpi())) { combinationExists = true; break; } } - if (!combinationExists) { + if (!combinationExists) { //NOSONAR LocalizedProblem error = ProblemCode.PCF_MISSING_COMBINATION .format(currentNpi, getMaskedTin(currentEntry.getKey()), apm); validator.addWarning(Detail.forProblemAndNode(error, node)); diff --git a/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java b/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java index f1ac9e447..25a0c43db 100644 --- a/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java +++ b/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java @@ -117,7 +117,7 @@ void testNpiTinSizeMismatch() throws Exception { System.out.println(node); NodeValidator nodeValidator = new NodeValidator() { @Override - protected void performValidation(Node node) { + protected void performValidation(Node node) { //NOSONAR } }; validator.validateApmTinNpiCombination(node, nodeValidator); From 472b904d2cf56979298de042af70aaf036137165 Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Mon, 21 Oct 2024 16:17:19 -0500 Subject: [PATCH 03/17] moved cognitive complexity flagged code to another function --- .../api/internal/pii/SpecPiiValidator.java | 43 +++++++++++++------ .../internal/pii/SpecPiiValidatorTest.java | 3 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java index cd7185ca8..0a25a2d25 100644 --- a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java +++ b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java @@ -79,25 +79,42 @@ private void validateMissingApmCombinations(Node node, NodeValidator validator, if (tinNpisMap != null) { for(final Map.Entry> currentEntry: tinNpisMap.entrySet()) { for (final String currentNpi : currentEntry.getValue()) { - boolean combinationExists = false; - for (TinNpiCombination currentCombination : tinNpiCombinations) { //NOSONAR - if (currentEntry.getKey().equalsIgnoreCase((currentCombination.getTin())) && //NOSONAR - currentNpi.equalsIgnoreCase(currentCombination.getNpi())) { - combinationExists = true; - break; - } - } - if (!combinationExists) { //NOSONAR - LocalizedProblem error = ProblemCode.PCF_MISSING_COMBINATION - .format(currentNpi, getMaskedTin(currentEntry.getKey()), apm); - validator.addWarning(Detail.forProblemAndNode(error, node)); - } + checkTinNpiCombinations(node, validator, apm, currentEntry, tinNpiCombinations, currentNpi); +// boolean combinationExists = false; +// for (TinNpiCombination currentCombination : tinNpiCombinations) { //NOSONAR +// if (currentEntry.getKey().equalsIgnoreCase((currentCombination.getTin())) && //NOSONAR +// currentNpi.equalsIgnoreCase(currentCombination.getNpi())) { +// combinationExists = true; +// break; +// } +// } +// if (!combinationExists) { //NOSONAR +// LocalizedProblem error = ProblemCode.PCF_MISSING_COMBINATION +// .format(currentNpi, getMaskedTin(currentEntry.getKey()), apm); +// validator.addWarning(Detail.forProblemAndNode(error, node)); +// } } } } } } + private void checkTinNpiCombinations(Node node, NodeValidator validator, String apm, Map.Entry> currentEntry, List tinNpiCombinations, String currentNpi) { + boolean combinationExists = false; + for (TinNpiCombination currentCombination : tinNpiCombinations) { + if (currentEntry.getKey().equalsIgnoreCase((currentCombination.getTin())) && + currentNpi.equalsIgnoreCase(currentCombination.getNpi())) { + combinationExists = true; + break; + } + } + if (!combinationExists) { + LocalizedProblem error = ProblemCode.PCF_MISSING_COMBINATION + .format(currentNpi, getMaskedTin(currentEntry.getKey()), apm); + validator.addWarning(Detail.forProblemAndNode(error, node)); + } + } + private String getApmEntityId(final Node node, final String program) { String apm; if (PCF_PROGRAM_NAME.equalsIgnoreCase(program)) { diff --git a/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java b/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java index 25a0c43db..ae6063a7f 100644 --- a/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java +++ b/rest-api/src/test/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidatorTest.java @@ -117,7 +117,8 @@ void testNpiTinSizeMismatch() throws Exception { System.out.println(node); NodeValidator nodeValidator = new NodeValidator() { @Override - protected void performValidation(Node node) { //NOSONAR + protected void performValidation(Node node) { + // Empty Function. Just adding a comment to avoid sonar flag. } }; validator.validateApmTinNpiCombination(node, nodeValidator); From f471e8fc3888f57abe2eb39ae8ab46cc661406d8 Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Mon, 21 Oct 2024 16:19:40 -0500 Subject: [PATCH 04/17] removed comments that are not needed --- .../api/internal/pii/SpecPiiValidator.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java index 0a25a2d25..5cb0ba1eb 100644 --- a/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java +++ b/rest-api/src/main/java/gov/cms/qpp/conversion/api/internal/pii/SpecPiiValidator.java @@ -80,19 +80,6 @@ private void validateMissingApmCombinations(Node node, NodeValidator validator, for(final Map.Entry> currentEntry: tinNpisMap.entrySet()) { for (final String currentNpi : currentEntry.getValue()) { checkTinNpiCombinations(node, validator, apm, currentEntry, tinNpiCombinations, currentNpi); -// boolean combinationExists = false; -// for (TinNpiCombination currentCombination : tinNpiCombinations) { //NOSONAR -// if (currentEntry.getKey().equalsIgnoreCase((currentCombination.getTin())) && //NOSONAR -// currentNpi.equalsIgnoreCase(currentCombination.getNpi())) { -// combinationExists = true; -// break; -// } -// } -// if (!combinationExists) { //NOSONAR -// LocalizedProblem error = ProblemCode.PCF_MISSING_COMBINATION -// .format(currentNpi, getMaskedTin(currentEntry.getKey()), apm); -// validator.addWarning(Detail.forProblemAndNode(error, node)); -// } } } } From c7d6003c4fff9acb2bb2dfdd9e297f5ee7450ba0 Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Thu, 24 Oct 2024 16:06:07 -0500 Subject: [PATCH 05/17] added participation file to S3 and updated the scripts --- tools/scripts/format-participation-file.py | 6 ++-- tools/scripts/retrieve-fms-file.py | 40 +++++++++++++--------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/tools/scripts/format-participation-file.py b/tools/scripts/format-participation-file.py index fb8b969cd..a04b8a26b 100755 --- a/tools/scripts/format-participation-file.py +++ b/tools/scripts/format-participation-file.py @@ -7,12 +7,12 @@ def main(argv): # Open the workbook and select the second sheet wb = load_workbook(filename = argv[0]) - sh = wb['2023_Providers'] + sh = wb['2024_Providers'] data_list = [] for row in sh.iter_rows(sh.min_row+1, sh.max_row): data = OrderedDict() - data['npi'] = row[12].value - data['tin'] = row[14].value + data['npi'] = row[10].value + data['tin'] = row[11].value data['apm_entity_id'] = row[0].value data_list.append(data) j = json.dumps(data_list) diff --git a/tools/scripts/retrieve-fms-file.py b/tools/scripts/retrieve-fms-file.py index 734592419..793e54866 100755 --- a/tools/scripts/retrieve-fms-file.py +++ b/tools/scripts/retrieve-fms-file.py @@ -1,15 +1,17 @@ #!/usr/bin/env python3 +import os import sys import boto3 import argparse import requests +import urllib.request import simplejson as json from io import BytesIO from dotenv import dotenv_values from openpyxl import load_workbook -config = dotenv_values("local.env") +config = dotenv_values("../../local.env") s3_client = boto3.client('s3') pcf_filename = "pcf_apm_entity_ids.json" @@ -29,7 +31,7 @@ def get_user_inputs(): return args -def download_from_fms(auth_url, fms_url, fms_token, fms_path): +def download_from_fms(auth_url, fms_url, fms_token, fms_path, filename): d = {'client_assertion': fms_token, 'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', 'grant_type': 'client_credentials', @@ -45,10 +47,10 @@ def download_from_fms(auth_url, fms_url, fms_token, fms_path): } ) s2s_token = get_s2s_token.json()["data"]["token"] - # print('starting download from fms for file - ' + fms_path) + # print('starting download from fms for file - ' + filename) get_download_url = requests.post( url=fms_url + '/get-file', - json={"path": fms_path}, + json={"path": fms_path + filename}, verify=False, headers={ 'Accept': 'application/vnd.qpp.cms.gov.v2+json', @@ -56,15 +58,13 @@ def download_from_fms(auth_url, fms_url, fms_token, fms_path): } ) download_url = get_download_url.json()['presigned_url'] - download_result = requests.get(url=download_url) - return download_result + urllib.request.urlretrieve(download_url, filename) -def process_file(download_result): +def process_file(filename): print('processing file') - file_object = BytesIO(download_result.content) - wb = load_workbook(file_object) - sh = wb['2023_Practices'] + wb = load_workbook(filename) + sh = wb['2024_Practices'] data_list = [] for row in sh.iter_rows(sh.min_row + 1, sh.max_row): data_list.append(row[0].value) @@ -72,8 +72,8 @@ def process_file(download_result): return str(json_data).replace(" ", "") def update_local_repo(data): - # print('writing ' + pcf_filename + ' to local repository') - with open('./converter/src/main/resources/' + pcf_filename, 'w') as f: + # print('writing ' + pcf_filename + ' to local repository') + with open('../../converter/src/main/resources/' + pcf_filename, 'w') as f: f.write(data) @@ -88,16 +88,24 @@ def upload_to_s3(data): ) print(upload_status) +def delete_file(filename): + if os.path.exists("./" + filename): + os.remove("./" + filename) + print("File " + filename + " has been processed and removed successfully!") + else: + print("Can not process or delete file " + filename + ", as it doesn't exists") def main(): try: # args = get_user_inputs() # s3_url = download_from_fms(args.auth_url, args.fms_url, args.fms_token, args.fms_path) - download_result = download_from_fms(config.get('auth_url'), config.get('fms_url'), config.get('fms_token'), - config.get('fms_path')) - processed_data = process_file(download_result) + filename = config.get('filename') + download_from_fms(config.get('auth_url'), config.get('fms_url'), config.get('fms_token'), + config.get('fms_path'), filename) + processed_data = process_file(filename) update_local_repo(processed_data) - upload_to_s3(processed_data) + # upload_to_s3(processed_data) + delete_file(filename) except Exception as err: print(f"Unexpected Error. {err = }, {type(err) = }") sys.exit(1) From 9a5a4838279d3bfa69a2f3011abaab0b4f5511c7 Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Thu, 24 Oct 2024 16:09:24 -0500 Subject: [PATCH 06/17] added new entity ids from the latest participation file --- converter/src/main/resources/pcf_apm_entity_ids.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/src/main/resources/pcf_apm_entity_ids.json b/converter/src/main/resources/pcf_apm_entity_ids.json index 92b2619e9..c77f7f98e 100644 --- a/converter/src/main/resources/pcf_apm_entity_ids.json +++ b/converter/src/main/resources/pcf_apm_entity_ids.json @@ -1 +1 @@ -["AR0437","AR0847","AR1052","AR2386","AR2409","AR2558","AR2574","AR2605","AR2621","AR2815","AR2933","AR2952","AR3280","AR3315","AR3328","AR3339","AR3458","AR3706","AR3718","AR3723","AR3746","AR3749","AR3761","AR3766","AR3767","AR3809","AR3938","AR3939","AR3942","AR3943","AR3945","AR3946","AR3947","AR4312","AR4348","AR4409","AR4629","AR4714","AR4763","AR4801","AR4803","AR4823","AR5016","AR5083","AR5170","AR5278","AR5314","AR5351","AR5371","AR5379","AR5380","AR5382","AR5702","AR5733","AR5896","AR5951","AR5970","AR5985","AR6239","AR6263","AR6267","AR6268","AR6297","AR6538","AR6560","AR6561","AR6564","AR6565","AR6570","AR6572","AR6579","AR6610","AR6621","AR6625","AR6692","AR6701","AR6704","AR6717","AR6731","AR6743","AR6827","AR6832","AR6837","AR7103","AR7104","CA0058","CA0495","CA0505","CA0519","CA0642","CA0780","CA0781","CA0782","CA0784","CA0785","CA0786","CA0788","CA0789","CA0790","CA0791","CA0792","CA0793","CA0795","CA0848","CA0880","CA0888","CA0915","CA0921","CA0924","CA0927","CA0928","CA0986","CA0988","CA0989","CA0990","CA0991","CA0992","CA1007","CA1008","CA1012","CA1015","CA1019","CA1026","CA1027","CA1028","CA1053","CA1056","CA1058","CA1068","CA1069","CA1092","CA1096","CA1103","CA1104","CA1105","CA1107","CA1161","CA1163","CA1164","CA1165","CA1189","CA1196","CA1220","CA1228","CA1244","CA1278","CA1286","CA1611","CA1852","CA2337","CA2338","CA2339","CA2915","CA3263","CA3264","CA3283","CA3764","CA4080","CA4082","CA4167","CA4190","CA4258","CA4392","CA4620","CA4621","CA4622","CA4623","CA4625","CA4626","CA4627","CA4655","CA4677","CA4712","CA4975","CA5198","CA5385","CA5480","CA5497","CA5521","CA5531","CA5570","CA5572","CA5688","CA5744","CA5767","CA5771","CA5772","CA5777","CA5782","CA5786","CA5788","CA5862","CA5870","CA5886","CA5893","CA5929","CA5934","CA5940","CA5991","CA6001","CA6221","CA6225","CA6255","CA6291","CA6299","CA6420","CA6432","CA6436","CA6443","CA6446","CA6478","CA6505","CA6510","CA6511","CA6512","CA6518","CA6527","CA6534","CA6545","CA6555","CA6556","CA6558","CA6584","CA6593","CA6640","CA6762","CA6774","CA6783","CA6795","CA6797","CA6806","CA6809","CA7105","CO0461","CO1612","CO1613","CO1942","CO1943","CO2086","CO2768","CO3279","CO3322","CO3342","CO3359","CO3362","CO3364","CO3387","CO3566","CO3699","CO3741","CO3744","CO3756","CO3760","CO3762","CO3807","CO3821","CO3846","CO3850","CO3851","CO3855","CO3856","CO3858","CO3860","CO3867","CO3930","CO3991","CO3993","CO3994","CO3997","CO4023","CO4065","CO4087","CO4151","CO4152","CO4277","CO4290","CO4293","CO4299","CO4319","CO4343","CO4345","CO4349","CO4353","CO4355","CO4356","CO4359","CO4387","CO4389","CO4433","CO4434","CO4436","CO4438","CO4443","CO4444","CO4482","CO4485","CO4489","CO4492","CO4531","CO4532","CO4533","CO4534","CO4536","CO4537","CO4538","CO4539","CO4540","CO4541","CO4542","CO4544","CO4545","CO4547","CO4548","CO4549","CO4551","CO4552","CO4570","CO4585","CO4586","CO4761","CO4805","CO4807","CO4811","CO4969","CO5028","CO5100","CO5116","CO5118","CO5119","CO5120","CO5121","CO5123","CO5124","CO5160","CO5161","CO5162","CO5163","CO5383","CO5510","CO5511","CO5512","CO5682","CO5779","CO5926","CO5955","CO5966","CO5973","CO5987","CO6000","CO6018","CO6091","CO6147","CO6189","CO6219","CO6249","CO6251","CO6254","CO6339","CO6363","CO6400","CO6417","CO6433","CO6441","CO6449","CO6455","CO6456","CO6480","CO6484","CO6487","CO6497","CO6502","CO6517","CO6526","CO6532","CO6540","CO6547","CO6549","CO6667","CO6747","CO6788","CO6793","CO6807","DE0514","DE0693","DE0697","DE0700","DE0705","DE0718","DE1031","DE1532","DE1533","DE1536","DE2793","DE3865","DE4210","DE4941","DE5206","FL0025","FL0084","FL0293","FL0385","FL0396","FL0433","FL0434","FL0439","FL0440","FL0442","FL0443","FL0508","FL0558","FL1077","FL1288","FL1582","FL1610","FL1625","FL1737","FL1742","FL1970","FL1971","FL1972","FL1978","FL1979","FL2015","FL2021","FL2025","FL2031","FL2036","FL2043","FL2048","FL2050","FL2051","FL2063","FL2072","FL2077","FL2087","FL2089","FL2134","FL2141","FL2144","FL2203","FL2219","FL2367","FL2577","FL2591","FL2603","FL2690","FL2752","FL2765","FL2770","FL2775","FL2780","FL2790","FL2795","FL2944","FL2957","FL2959","FL2972","FL2977","FL3077","FL3193","FL3382","FL3450","FL3453","FL3517","FL3520","FL4254","FL4369","FL4371","FL4372","FL4459","FL4484","FL4638","FL4942","FL4995","FL5249","FL5445","FL5686","FL5972","FL6020","FL6031","FL6063","FL6149","FL6153","FL6182","FL6192","FL6213","FL6223","FL6271","FL6272","FL6273","FL6275","FL6379","FL6466","FL6574","FL6580","FL6634","FL6647","FL6670","FL6696","FL6709","FL6722","FL6730","FL6742","FL6752","FL6784","FL6810","FL6814","FL6818","FL6819","FL6820","FL6822","FL6824","FL6826","FL6829","FL6830","FL6831","FL6835","FL6836","FL6841","FL6843","FL6849","FL6850","FL6875","FL7001","FL7002","FL7003","GB3457","GB3933","GB5318","GB5328","HI2082","HI3275","HI3393","HI3687","HI3716","HI3719","HI3725","HI3768","HI3771","HI3820","HI3823","HI3888","HI3966","HI3968","HI3969","HI3971","HI4001","HI4014","HI4019","HI4024","HI4025","HI4030","HI4031","HI4264","HI4437","HI4554","HI4588","HI4826","HI4828","HI4831","HI5045","HI5069","HI5200","HI5299","HI5740","HI5791","HI5794","HI5796","HI5801","HI6869","KC0219","KC0233","KC0478","KC1308","KC1762","KC2742","KC2829","KC2843","KC3410","KC3755","KC3795","KC3801","KC3852","KC3957","KC4104","KC4119","KC4126","KC4452","KC4616","KC4617","KC4635","KC4649","KC4650","KC4664","KC4667","KC4835","KC4836","KC4925","KC4939","KC5020","KC5033","KC5038","KC5040","KC5046","KC5086","KC5088","KC5129","KC5196","KC5199","KC5276","KC5287","KC5294","KC5449","KC5456","KC5458","KC5467","KC5474","KC5481","KC5488","KC5492","KC5513","KC5514","KC5515","KC5516","KC5551","KC5552","KC5558","KC5563","KC5564","KC5565","KC5567","KC5576","KC5605","KC5608","KC5609","KC5611","KC5612","KC5613","KC5641","KC5647","KC5658","KC5669","KC5672","KC5763","KC5765","KC5766","KC5813","KC5820","KC5878","KC6078","KC6087","KC6411","KC7106","LA3355","LA4049","LA4528","LA5035","LA5315","LA5695","LA5698","LA5700","MA0474","MA0475","MA0623","MA0708","MA0730","MA0758","MA0759","MA0761","MA0767","MA0770","MA0771","MA0778","MA0815","MA0821","MA0823","MA0825","MA0826","MA0829","MA0831","MA0832","MA0835","MA0837","MA0867","MA0869","MA0872","MA0874","MA0876","MA0881","MA0884","MA0886","MA0887","MA0897","MA0898","MA0902","MA0911","MA0935","MA0942","MA0974","MA0976","MA0979","MA1004","MA1023","MA1259","MA1334","MA1452","MA1580","MA1724","MA2198","MA2374","MA2478","MA2495","MA2510","MA2525","MA2598","MA3399","MA3416","MA3469","MA3472","MA3476","MA3477","MA3488","MA3489","MA3490","MA3495","MA3826","MA3955","MA3956","MA4075","MA4324","MA4325","MA4326","MA4327","MA4362","MA4363","MA4375","MA4384","MA4511","MA4512","MA4513","MA4514","MA4515","MA4516","MA4563","MA4564","MA4565","MA4656","MA4658","MA4705","MA4723","MA4741","MA4744","MA5070","MA5072","MA5127","ME0356","ME0388","ME0511","ME0634","ME0635","ME0654","ME0655","ME0802","ME0804","ME0805","ME0806","ME0877","ME0883","ME0885","ME0889","ME0891","ME0892","ME0894","ME0895","ME0896","ME0903","ME0909","ME0913","ME0918","ME0919","ME1100","ME1111","ME1114","ME1136","ME1179","ME1188","ME1198","ME1252","ME1384","ME1466","ME1491","ME1501","ME1503","ME1515","ME1517","ME3061","ME3689","ME3690","ME3691","ME3890","ME3891","ME3892","ME3909","ME3914","ME3915","ME3921","ME3922","ME3924","ME3927","ME5523","ME6021","ME6077","ME6088","ME6229","MI0191","MI0466","MI0873","MI0890","MI1744","MI1888","MI1895","MI2346","MI2358","MI2393","MI2404","MI2435","MI2446","MI2664","MI2667","MI2668","MI2679","MI2687","MI2692","MI2923","MI3354","MI3405","MI3411","MI3451","MI3463","MI3618","MI3619","MI3620","MI3621","MI3622","MI3623","MI3624","MI3625","MI3626","MI3627","MI3628","MI3629","MI3630","MI3632","MI3635","MI3636","MI3637","MI3638","MI3639","MI3640","MI3641","MI3643","MI3644","MI3645","MI3646","MI3648","MI3649","MI3650","MI3651","MI3652","MI3653","MI3667","MI3675","MI3688","MI3790","MI3797","MI3798","MI3827","MI3837","MI3847","MI3972","MI4007","MI4033","MI4037","MI4052","MI4058","MI4066","MI4125","MI4129","MI4130","MI4298","MI4332","MI4335","MI4350","MI4367","MI4429","MI4448","MI4458","MI4467","MI4474","MI4488","MI4574","MI4579","MI4611","MI4640","MI4662","MI4665","MI4666","MI4671","MI4675","MI4676","MI4680","MI4690","MI4692","MI4693","MI4702","MI4707","MI4709","MI4711","MI4722","MI4726","MI4729","MI4740","MI4745","MI4749","MI4751","MI4752","MI4755","MI4765","MI4768","MI4789","MI4790","MI4791","MI4792","MI4793","MI4794","MI4795","MI4796","MI4797","MI4798","MI4799","MI4839","MI4840","MI4841","MI4845","MI4848","MI4850","MI4876","MI4887","MI4888","MI4894","MI4895","MI4899","MI4900","MI4906","MI4909","MI4910","MI4915","MI4916","MI4917","MI4918","MI4930","MI4936","MI4945","MI4946","MI4953","MI4954","MI4955","MI4956","MI4957","MI4958","MI4959","MI4960","MI4961","MI4962","MI4963","MI4977","MI4981","MI5004","MI5130","MI5131","MI5132","MI5133","MI5134","MI5136","MI5137","MI5138","MI5139","MI5153","MI5165","MI5180","MI5211","MI5212","MI5213","MI5214","MI5219","MI5220","MI5319","MI5337","MI5358","MI5369","MI5405","MI5406","MI5407","MI5584","MI5585","MI5586","MI5588","MI5590","MI5598","MI5600","MI5602","MI5603","MI5604","MI5632","MI5655","MI5714","MI5806","MI5808","MI5809","MI5823","MI5824","MI5827","MI5834","MI5843","MI5845","MI5849","MI5859","MI5880","MI5932","MI5936","MI5944","MI5945","MI5946","MI5949","MI5959","MI5960","MI5961","MI5983","MI5992","MI5998","MI6024","MI6027","MI6039","MI6052","MI6053","MI6055","MI6059","MI6067","MI6073","MI6074","MI6099","MI6118","MI6126","MI6145","MI6164","MI6179","MI6180","MI6193","MI6206","MI6207","MI6270","MI6280","MI6287","MI6290","MI6318","MI6326","MI6330","MI6338","MI6349","MI6367","MI6368","MI6381","MI6419","MI6422","MI6457","MI6458","MI6461","MI6464","MI6465","MI6467","MI6472","MI6600","MI6613","MI6632","MI6871","MI6874","MI7100","MI7108","MT3526","MT3577","MT3581","MT3678","MT3985","MT4029","MT4078","MT4322","MT5172","MT5178","MT5181","MT5259","MT5373","MT5546","MT5554","MT6132","MT6238","MT6257","MT6258","MT6261","MT6262","MT6264","MT6288","ND3460","ND3462","ND5018","ND5553","ND5561","ND5566","ND5594","ND5596","ND5599","ND5601","ND5619","ND5620","ND5623","ND5624","ND5625","ND6098","ND6196","ND6398","NE0140","NE1523","NE1607","NE2271","NE2278","NE2282","NE2285","NE2288","NE2584","NE2596","NE2623","NE2625","NE3484","NE3669","NE3876","NE3999","NE4137","NE4141","NE4144","NE4147","NE4159","NE4186","NE4342","NE4529","NE4637","NE5311","NE5883","NE6306","NE6314","NE6589","NE7109","NH2060","NH2061","NH2064","NH2069","NH2743","NH3661","NH3754","NH3834","NH3838","NH3840","NH3843","NH6183","NH6602","NJ0241","NJ0242","NJ0319","NJ0543","NJ0581","NJ0586","NJ0612","NJ0613","NJ0614","NJ0618","NJ0619","NJ0644","NJ0652","NJ0739","NJ0748","NJ0766","NJ0774","NJ0905","NJ0965","NJ0971","NJ1040","NJ1128","NJ1258","NJ1340","NJ1356","NJ1362","NJ1464","NJ1631","NJ1641","NJ1647","NJ1663","NJ1670","NJ1677","NJ1680","NJ1713","NJ1717","NJ1723","NJ1726","NJ1730","NJ1786","NJ2078","NJ2245","NJ2256","NJ2272","NJ2494","NJ3045","NJ3088","NJ3285","NJ3287","NJ3290","NJ3302","NJ3340","NJ3366","NJ3367","NJ3384","NJ3448","NJ3454","NJ3507","NJ3509","NJ3515","NJ3521","NJ3534","NJ3555","NJ3677","NJ3681","NJ3722","NJ3745","NJ3751","NJ3757","NJ3769","NJ3772","NJ3775","NJ3776","NJ3777","NJ3778","NJ3779","NJ3780","NJ3781","NJ3782","NJ3783","NJ3784","NJ3785","NJ3786","NJ3787","NJ3788","NJ3789","NJ3815","NJ3836","NJ3842","NJ3845","NJ3848","NJ3882","NJ3894","NJ3895","NJ3896","NJ3897","NJ3898","NJ3900","NJ3901","NJ3904","NJ3905","NJ3908","NJ3911","NJ3916","NJ3951","NJ3954","NJ3960","NJ3973","NJ3975","NJ3979","NJ3982","NJ3986","NJ3988","NJ3989","NJ3990","NJ3992","NJ3996","NJ4000","NJ4004","NJ4005","NJ4010","NJ4012","NJ4020","NJ4022","NJ4039","NJ4044","NJ4063","NJ4072","NJ4088","NJ4094","NJ4097","NJ4099","NJ4102","NJ4123","NJ4127","NJ4134","NJ4135","NJ4140","NJ4172","NJ4174","NJ4175","NJ4176","NJ4179","NJ4180","NJ4181","NJ4189","NJ4273","NJ4311","NJ4316","NJ4334","NJ4339","NJ4341","NJ4346","NJ4347","NJ4360","NJ4374","NJ4377","NJ4379","NJ4382","NJ4385","NJ4393","NJ4395","NJ4396","NJ4441","NJ4442","NJ4472","NJ4494","NJ4498","NJ4505","NJ4507","NJ4508","NJ4520","NJ4524","NJ4530","NJ4567","NJ4576","NJ4581","NJ4605","NJ4614","NJ4615","NJ4632","NJ4686","NJ4721","NJ4737","NJ4834","NJ4837","NJ4922","NJ5039","NJ5128","NJ5148","NJ5154","NJ5159","NJ5205","NJ5268","NJ5274","NJ5303","NJ5332","NJ5333","NJ5334","NJ5339","NJ5340","NJ5341","NJ5342","NJ5343","NJ5345","NJ5352","NJ5370","NJ5376","NJ5378","NJ5491","NJ5493","NJ5500","NJ5518","NJ5536","NJ5616","NJ5642","NJ5666","NJ5687","NJ5711","NJ5732","NJ5742","NJ5760","NJ5847","NJ5863","NJ5875","NJ5922","NJ5931","NJ5937","NJ5953","NJ6035","NJ6048","NJ6082","NJ6104","NJ6113","NJ6121","NJ6142","NJ6200","NJ6209","NJ6281","NJ6295","NJ6309","NJ6323","NJ6607","NJ6646","NJ6719","NJ6754","NJ6771","NJ7110","NJ7111","NJ7112","NY1350","NY3101","NY3107","NY3108","NY3135","NY3151","NY3175","NY3184","NY3185","NY3192","NY3196","NY3198","NY3207","NY3482","NY3793","NY3824","NY3879","NY3889","NY3984","NY4061","NY4074","NY4077","NY4079","NY4105","NY4106","NY4108","NY4111","NY4128","NY4132","NY4138","NY4146","NY4155","NY4160","NY4171","NY4378","NY4408","NY4460","NY4463","NY4464","NY4473","NY4510","NY4572","NY4687","NY4896","NY4897","NY4902","NY4931","NY4933","NY5302","NY5359","NY5408","NY5409","NY5410","NY5412","NY5413","NY5414","NY5416","NY5420","NY5519","NY5562","NY5718","NY5819","NY5954","NY6030","NY6054","NY6355","NY6356","NY6357","NY6358","NY6453","NY6462","NY6479","OH0026","OH0091","OH0185","OH0267","OH0272","OH0284","OH0285","OH0290","OH0469","OH0485","OH0691","OH0715","OH0717","OH0720","OH0722","OH0724","OH0727","OH0764","OH0944","OH0947","OH0948","OH1048","OH1051","OH1076","OH1079","OH1083","OH1084","OH1088","OH1089","OH1090","OH1108","OH1109","OH1110","OH1121","OH1122","OH1127","OH1130","OH1132","OH1133","OH1142","OH1143","OH1146","OH1147","OH1149","OH1150","OH1152","OH1157","OH1159","OH1167","OH1292","OH1366","OH1367","OH1369","OH1371","OH1373","OH1374","OH1375","OH1376","OH1378","OH1392","OH1468","OH1493","OH1802","OH1812","OH1853","OH1856","OH1894","OH1903","OH1906","OH1953","OH1988","OH2037","OH2114","OH2372","OH2401","OH2422","OH2427","OH2515","OH2538","OH2811","OH2848","OH3148","OH3218","OH3219","OH3220","OH3297","OH3331","OH3335","OH3404","OH3406","OH3412","OH3440","OH3441","OH3445","OH3449","OH3452","OH3455","OH3459","OH3465","OH3466","OH3467","OH3483","OH3485","OH3486","OH3487","OH3492","OH3497","OH3498","OH3500","OH3502","OH3513","OH3518","OH3519","OH3522","OH3531","OH3533","OH3538","OH3540","OH3541","OH3542","OH3567","OH3569","OH3579","OH3582","OH3583","OH3584","OH3587","OH3588","OH3589","OH3590","OH3591","OH3593","OH3594","OH3595","OH3601","OH3602","OH3604","OH3605","OH3608","OH3612","OH3614","OH3633","OH3658","OH3692","OH3694","OH3695","OH3696","OH3697","OH3698","OH3701","OH3703","OH3710","OH3711","OH3727","OH3728","OH3729","OH3736","OH3743","OH3791","OH3792","OH3794","OH3803","OH3833","OH3841","OH3868","OH3995","OH4017","OH4032","OH4124","OH4184","OH4188","OH4200","OH4202","OH4207","OH4212","OH4213","OH4215","OH4216","OH4218","OH4219","OH4220","OH4221","OH4222","OH4223","OH4224","OH4225","OH4226","OH4227","OH4228","OH4229","OH4230","OH4231","OH4233","OH4235","OH4236","OH4237","OH4238","OH4239","OH4240","OH4241","OH4242","OH4243","OH4244","OH4245","OH4247","OH4248","OH4250","OH4251","OH4252","OH4253","OH4256","OH4257","OH4259","OH4260","OH4261","OH4271","OH4282","OH4301","OH4304","OH4308","OH4309","OH4413","OH4417","OH4418","OH4419","OH4420","OH4421","OH4422","OH4423","OH4424","OH4425","OH4428","OH4430","OH4435","OH4447","OH4509","OH4518","OH4519","OH4591","OH4592","OH4593","OH4594","OH4595","OH4596","OH4598","OH4600","OH4601","OH4628","OH4720","OH4739","OH4742","OH4775","OH4776","OH4778","OH4779","OH4780","OH4781","OH4782","OH4784","OH4785","OH4787","OH4800","OH4802","OH4868","OH4869","OH4870","OH4873","OH4874","OH4875","OH4877","OH4878","OH4879","OH4882","OH4885","OH4932","OH4978","OH4980","OH4986","OH4997","OH5000","OH5002","OH5013","OH5019","OH5021","OH5024","OH5031","OH5084","OH5094","OH5156","OH5157","OH5169","OH5171","OH5179","OH5188","OH5189","OH5190","OH5193","OH5194","OH5195","OH5263","OH5264","OH5266","OH5271","OH5289","OH5324","OH5350","OH5374","OH5442","OH5454","OH5462","OH5465","OH5468","OH5469","OH5475","OH5503","OH5533","OH5534","OH5557","OH5593","OH5621","OH5653","OH5662","OH5670","OH5676","OH5697","OH5708","OH5775","OH5778","OH5783","OH5784","OH5790","OH5795","OH5799","OH5828","OH5833","OH5842","OH5855","OH5865","OH5868","OH5869","OH5873","OH5876","OH5882","OH5888","OH5900","OH5918","OH5938","OH5943","OH6023","OH6025","OH6028","OH6044","OH6064","OH6071","OH6080","OH6083","OH6097","OH6103","OH6107","OH6114","OH6120","OH6122","OH6127","OH6133","OH6134","OH6158","OH6163","OH6165","OH6172","OH6176","OH6188","OH6191","OH6210","OH6211","OH6216","OH6217","OH6220","OH6227","OH6231","OH6232","OH6237","OH6240","OH6241","OH6244","OH6247","OH6259","OH6266","OH6277","OH6282","OH6289","OH6312","OH6320","OH6328","OH6346","OH6348","OH6354","OH6372","OH6384","OH6390","OH6392","OH6401","OH6405","OH6408","OH6416","OH6418","OH6428","OH6429","OH6435","OH6440","OH6454","OH6470","OH6473","OH6493","OH6496","OH6513","OH6519","OH6523","OH6533","OH6541","OH6543","OH6548","OH6550","OH6585","OH6588","OH6592","OH6597","OH6604","OH6609","OH6619","OH6622","OH6627","OH6653","OH6654","OH6657","OH6668","OH6672","OH6676","OH6681","OH6688","OH6693","OH6702","OH6712","OH6720","OH6726","OH6727","OH6732","OH6738","OH6740","OH6741","OH6744","OH6748","OH6749","OH6750","OH6756","OH6768","OH6773","OH6781","OH6794","OH6815","OH6821","OH6891","OK0331","OK0402","OK0410","OK0411","OK0412","OK0413","OK0415","OK0416","OK0418","OK0419","OK0420","OK0422","OK0423","OK0424","OK0425","OK0426","OK0427","OK0428","OK0429","OK0430","OK0525","OK1093","OK1115","OK2068","OK2094","OK3361","OK3424","OK3428","OK3431","OK3432","OK3433","OK3434","OK3435","OK3436","OK3437","OK3438","OK3439","OK4193","OK4194","OK4201","OK4296","OK4337","OK4366","OK4453","OK4455","OK4456","OK4457","OK4465","OK4466","OK4468","OK4470","OK4471","OK4499","OK4501","OK4502","OK4503","OK4504","OK4561","OK4568","OK4606","OK4609","OK4660","OK4669","OK4673","OK4788","OK4967","OK5029","OK5037","OK5048","OK5053","OK5078","OK5093","OK5105","OK5224","OK5255","OK5281","OK5290","OK5361","OK5384","OK5386","OK5387","OK5388","OK5389","OK5391","OK5392","OK5394","OK5395","OK5396","OK5397","OK5398","OK5399","OK5400","OK5401","OK5402","OK5403","OK5404","OK5781","OK5996","OK6169","OK6195","OK6212","OK6307","OK6447","OK6474","OK6509","OK6524","OK6536","OK6618","OK6694","OK6755","OK7101","OR0332","OR0459","OR0467","OR0487","OR0502","OR0504","OR0547","OR0551","OR0630","OR0714","OR0908","OR1479","OR2590","OR2875","OR3344","OR3392","OR3408","OR3426","OR3503","OR3505","OR3546","OR3613","OR3656","OR3714","OR3726","OR3804","OR3862","OR4026","OR4116","OR4118","OR4122","OR4196","OR4267","OR4553","OR4562","OR4610","OR4645","OR4646","OR4652","OR4653","OR4654","OR4683","OR4760","OR4821","OR5007","OR5010","OR5030","OR5054","OR5058","OR5061","OR5067","OR5068","OR5113","OR5115","OR5167","OR5234","OR5258","OR5273","OR5292","OR5326","OR5444","OR5549","OR5660","OR5683","OR5696","OR5704","OR5734","OR5804","OR5923","OR5963","OR5967","OR5974","OR6186","OR6199","OR6269","OR6352","OR6359","OR6370","OR6371","OR6376","OR6387","OR6389","OR6490","OR6514","OR6515","OR6520","OR6522","OR6529","OR6552","OR6554","OR6616","OR6628","OR6641","OR6651","OR6663","OR6689","OR6751","OR6802","OR6805","OR6811","PA0240","PA0367","PA0541","PA0637","PA1049","PA1260","PA1277","PA1281","PA1402","PA1408","PA1414","PA1418","PA1578","PA1586","PA1668","PA1760","PA1765","PA1851","PA1890","PA1934","PA1954","PA1956","PA2124","PA2125","PA2359","PA2395","PA2466","PA2486","PA2496","PA2506","PA2517","PA2528","PA2539","PA2649","PA3353","PA3360","PA3379","PA3418","PA3523","PA3529","PA3666","PA3705","PA3708","PA3839","PA3874","PA3880","PA3885","PA3934","PA3936","PA3940","PA3959","PA3961","PA3998","PA4003","PA4009","PA4015","PA4016","PA4018","PA4035","PA4038","PA4040","PA4051","PA4054","PA4059","PA4062","PA4067","PA4069","PA4073","PA4083","PA4085","PA4086","PA4121","PA4145","PA4187","PA4302","PA4303","PA4305","PA4306","PA4307","PA4313","PA4575","PA4577","PA4636","PA4736","PA4748","PA4757","PA4889","PA4893","PA4903","PA4905","PA5027","PA5034","PA5036","PA5041","PA5051","PA5055","PA5062","PA5141","PA5144","PA5147","PA5150","PA5174","PA5207","PA5208","PA5221","PA5223","PA5225","PA5231","PA5233","PA5236","PA5239","PA5244","PA5245","PA5257","PA5269","PA5272","PA5286","PA5288","PA5308","PA5312","PA5320","PA5327","PA5411","PA5415","PA5418","PA5421","PA5422","PA5423","PA5426","PA5427","PA5428","PA5437","PA5447","PA5452","PA5470","PA5482","PA5483","PA5484","PA5490","PA5508","PA5509","PA5538","PA5542","PA5577","PA5629","PA5649","PA5657","PA5659","PA5661","PA5664","PA5668","PA5673","PA5678","PA5689","PA5703","PA5729","PA5841","PA5887","PA5914","PA5964","PA5971","PA5981","PA5984","PA5986","PA6043","PA6050","PA6056","PA6070","PA6089","PA6154","PA6279","PA6332","PA6426","PA6468","PA6498","PA6606","PA6645","PA6669","PA6840","PA6860","RI3298","RI3464","RI3730","RI3822","RI3864","RI3872","RI3875","RI3893","RI3913","RI3917","RI3923","RI3925","RI4070","RI4924","RI5152","RI5677","RI5701","RI5710","RI5731","RI5737","RI5752","RI5838","RI5854","RI5874","RI5884","RI5919","RI6009","RI6178","RI6278","RI6615","RI6630","RI6660","RI6808","RI7114","RI7115","TN1255","TN1256","TN2616","TN2846","TN2861","TN2898","TN2942","TN2991","TN3009","TN3023","TN3700","TN4681","TN4695","TN4708","TN5209","TN5627","TN5667","TN5780","TN5856","TN5895","TN5898","TN5915","TN5928","TN5947","TN5980","TN6037","TN6102","TN6425","VA0208","VA0473","VA0620","VA1922","VA1936","VA1938","VA1973","VA1987","VA2052","VA2056","VA2090","VA2113","VA2122","VA2135","VA2415","VA2682","VA2689","VA2712","VA4331","VA5151","VA5355","VA6203","VA6204"] \ No newline at end of file +["AR0437","AR0847","AR1052","AR2386","AR2409","AR2574","AR2605","AR2621","AR2815","AR2933","AR2952","AR3315","AR3328","AR3706","AR3718","AR3723","AR3746","AR3749","AR3761","AR3766","AR3767","AR3809","AR3938","AR3939","AR3942","AR3943","AR3945","AR3946","AR3947","AR4348","AR4409","AR4629","AR4714","AR4763","AR4823","AR5016","AR5083","AR5170","AR5278","AR5314","AR5351","AR5371","AR5379","AR5380","AR5382","AR5702","AR5733","AR5896","AR5951","AR5970","AR5985","AR6239","AR6263","AR6268","AR6538","AR6560","AR6561","AR6564","AR6565","AR6570","AR6572","AR6579","AR6610","AR6621","AR6692","AR6701","AR6704","AR6717","AR6731","AR6743","AR6827","AR6832","AR6837","AR7103","AR7104","AR7200","CA0058","CA0495","CA0642","CA0781","CA0782","CA0784","CA0785","CA0786","CA0788","CA0789","CA0790","CA0791","CA0792","CA0793","CA0848","CA0880","CA0888","CA0915","CA0921","CA0924","CA0927","CA0928","CA0986","CA0988","CA0989","CA0990","CA0991","CA0992","CA1007","CA1008","CA1012","CA1015","CA1019","CA1026","CA1027","CA1028","CA1053","CA1056","CA1058","CA1068","CA1069","CA1092","CA1096","CA1103","CA1104","CA1105","CA1107","CA1161","CA1163","CA1164","CA1165","CA1189","CA1196","CA1220","CA1228","CA1244","CA1278","CA1286","CA1611","CA1852","CA2337","CA2338","CA2339","CA2915","CA3263","CA3264","CA3283","CA3764","CA4080","CA4082","CA4167","CA4190","CA4258","CA4392","CA4620","CA4621","CA4622","CA4623","CA4625","CA4626","CA4627","CA4655","CA4712","CA4975","CA5198","CA5385","CA5480","CA5497","CA5521","CA5531","CA5570","CA5572","CA5688","CA5744","CA5767","CA5771","CA5777","CA5787","CA5788","CA5862","CA5870","CA5886","CA5893","CA5929","CA5934","CA5940","CA5991","CA6001","CA6008","CA6221","CA6225","CA6255","CA6291","CA6299","CA6420","CA6432","CA6436","CA6443","CA6446","CA6505","CA6510","CA6512","CA6518","CA6527","CA6534","CA6545","CA6555","CA6556","CA6558","CA6584","CA6593","CA6640","CA6762","CA6774","CA6783","CA6795","CA6797","CA6806","CA6809","CA7105","CO0461","CO1612","CO1613","CO1942","CO1943","CO2086","CO2768","CO3279","CO3322","CO3387","CO3566","CO3699","CO3741","CO3744","CO3756","CO3760","CO3762","CO3807","CO3821","CO3846","CO3850","CO3851","CO3855","CO3856","CO3858","CO3860","CO3867","CO3930","CO3991","CO3993","CO3994","CO3997","CO4023","CO4065","CO4087","CO4151","CO4152","CO4277","CO4290","CO4299","CO4319","CO4343","CO4345","CO4349","CO4353","CO4355","CO4356","CO4359","CO4387","CO4389","CO4433","CO4434","CO4436","CO4438","CO4443","CO4444","CO4482","CO4485","CO4489","CO4492","CO4531","CO4532","CO4533","CO4536","CO4537","CO4538","CO4539","CO4540","CO4541","CO4542","CO4544","CO4545","CO4547","CO4548","CO4549","CO4551","CO4552","CO4570","CO4585","CO4586","CO4761","CO4807","CO4969","CO5116","CO5118","CO5119","CO5120","CO5121","CO5123","CO5124","CO5160","CO5161","CO5162","CO5163","CO5383","CO5510","CO5511","CO5512","CO5682","CO5779","CO5926","CO5955","CO5966","CO5973","CO5987","CO6000","CO6091","CO6147","CO6189","CO6219","CO6249","CO6251","CO6254","CO6339","CO6363","CO6400","CO6417","CO6433","CO6441","CO6449","CO6455","CO6456","CO6480","CO6484","CO6487","CO6497","CO6502","CO6517","CO6526","CO6532","CO6540","CO6547","CO6549","CO6667","CO6747","CO6788","CO6793","CO6807","DE0514","DE0693","DE0697","DE0700","DE0705","DE0718","DE1031","DE1532","DE1533","DE1536","DE3865","DE4941","FL0025","FL0084","FL0558","FL1288","FL1582","FL1610","FL1737","FL1742","FL1970","FL1971","FL1972","FL1978","FL1979","FL2015","FL2021","FL2025","FL2031","FL2036","FL2043","FL2048","FL2050","FL2051","FL2063","FL2072","FL2077","FL2087","FL2089","FL2134","FL2141","FL2144","FL2203","FL2219","FL2367","FL2577","FL2591","FL2603","FL2690","FL2752","FL2765","FL2770","FL2775","FL2780","FL2790","FL2795","FL3193","FL3382","FL3450","FL3453","FL3517","FL3520","FL4254","FL4369","FL4371","FL4372","FL4459","FL4484","FL4942","FL5249","FL5445","FL6015","FL6020","FL6031","FL6153","FL6223","FL6466","FL6709","FL7001","FL7002","FL7003","GB3457","GB3933","GB5318","HI2082","HI3275","HI3687","HI3716","HI3719","HI3725","HI3768","HI3771","HI3820","HI3823","HI3888","HI3966","HI3968","HI3969","HI3971","HI4001","HI4019","HI4024","HI4025","HI4030","HI4031","HI4264","HI4437","HI4554","HI4588","HI4826","HI4828","HI4831","HI5045","HI5069","HI5200","HI5299","HI5740","HI5794","HI5801","HI6869","KC0219","KC0478","KC1308","KC1762","KC2742","KC2829","KC2843","KC3410","KC3755","KC3795","KC3801","KC3852","KC3957","KC4104","KC4119","KC4126","KC4452","KC4635","KC4649","KC4650","KC4664","KC4667","KC4925","KC4939","KC5020","KC5033","KC5038","KC5040","KC5046","KC5086","KC5088","KC5129","KC5196","KC5199","KC5276","KC5287","KC5294","KC5449","KC5456","KC5458","KC5467","KC5474","KC5481","KC5488","KC5492","KC5513","KC5514","KC5515","KC5516","KC5551","KC5552","KC5558","KC5563","KC5564","KC5565","KC5567","KC5576","KC5605","KC5608","KC5609","KC5611","KC5612","KC5613","KC5641","KC5647","KC5658","KC5669","KC5672","KC5763","KC5765","KC5766","KC5813","KC5820","KC5878","KC6078","KC6087","KC6411","KC7106","LA4049","LA4528","LA5035","LA5315","LA5695","LA5698","LA5700","MA0474","MA0475","MA0623","MA0708","MA0730","MA0758","MA0759","MA0761","MA0767","MA0770","MA0771","MA0778","MA0815","MA0821","MA0823","MA0825","MA0826","MA0829","MA0831","MA0832","MA0835","MA0837","MA0867","MA0869","MA0872","MA0874","MA0876","MA0881","MA0884","MA0886","MA0887","MA0897","MA0898","MA0902","MA0911","MA0935","MA0942","MA0974","MA0976","MA0979","MA1004","MA1023","MA1259","MA1334","MA1580","MA1724","MA2374","MA2495","MA2525","MA2598","MA3399","MA3416","MA3469","MA3472","MA3476","MA3477","MA3488","MA3489","MA3490","MA3495","MA3826","MA3955","MA3956","MA4324","MA4325","MA4326","MA4327","MA4362","MA4363","MA4375","MA4384","MA4511","MA4512","MA4513","MA4514","MA4515","MA4516","MA4563","MA4564","MA4565","MA4656","MA4658","MA4705","MA4723","MA4741","MA4744","MA5070","MA5072","MA5127","ME0356","ME0388","ME0511","ME0634","ME0635","ME0654","ME0655","ME0802","ME0804","ME0805","ME0806","ME0877","ME0883","ME0885","ME0889","ME0891","ME0892","ME0894","ME0895","ME0896","ME0903","ME0909","ME0913","ME0918","ME0919","ME1100","ME1111","ME1114","ME1136","ME1179","ME1188","ME1198","ME1252","ME1384","ME1466","ME1491","ME1501","ME1503","ME1515","ME1517","ME3061","ME3689","ME3691","ME5523","ME6021","ME6077","ME6088","ME6229","MI0466","MI0873","MI1888","MI1895","MI2346","MI2358","MI2393","MI2404","MI2446","MI2664","MI2667","MI2668","MI2679","MI2692","MI2923","MI3354","MI3405","MI3411","MI3451","MI3463","MI3618","MI3619","MI3620","MI3621","MI3622","MI3623","MI3624","MI3625","MI3626","MI3627","MI3628","MI3629","MI3630","MI3632","MI3635","MI3636","MI3637","MI3638","MI3639","MI3640","MI3643","MI3644","MI3645","MI3646","MI3648","MI3649","MI3650","MI3652","MI3653","MI3675","MI3688","MI3790","MI3798","MI3837","MI4125","MI4129","MI4130","MI4367","MI4448","MI4458","MI4574","MI4611","MI4640","MI4662","MI4666","MI4671","MI4675","MI4680","MI4690","MI4692","MI4693","MI4702","MI4707","MI4709","MI4711","MI4722","MI4726","MI4729","MI4740","MI4745","MI4749","MI4751","MI4752","MI4755","MI4789","MI4790","MI4791","MI4792","MI4793","MI4794","MI4795","MI4796","MI4797","MI4798","MI4799","MI4839","MI4840","MI4841","MI4845","MI4848","MI4850","MI4876","MI4887","MI4888","MI4895","MI4899","MI4906","MI4909","MI4910","MI4915","MI4916","MI4917","MI4918","MI4930","MI4936","MI4945","MI4946","MI4963","MI5004","MI5130","MI5131","MI5132","MI5133","MI5134","MI5136","MI5137","MI5138","MI5139","MI5153","MI5165","MI5180","MI5211","MI5212","MI5213","MI5214","MI5219","MI5220","MI5319","MI5337","MI5358","MI5369","MI5405","MI5406","MI5407","MI5584","MI5585","MI5586","MI5588","MI5590","MI5598","MI5600","MI5602","MI5603","MI5604","MI5632","MI5714","MI5806","MI5808","MI5809","MI5843","MI5849","MI5859","MI5936","MI5998","MI6027","MI6039","MI6053","MI6067","MI6207","MI6280","MI6287","MI6330","MI6368","MI6381","MI6419","MI6457","MI6458","MI6461","MI6464","MI6465","MI6472","MI6871","MI6874","MI7100","MI7108","MT3526","MT3577","MT3581","MT3678","MT3985","MT4029","MT4078","MT4322","MT5172","MT5178","MT5181","MT5259","MT5373","MT5546","MT5554","MT6132","MT6238","MT6257","MT6258","MT6261","MT6262","MT6264","MT6288","ND5018","ND5553","ND5561","ND5566","ND5594","ND5596","ND5599","ND5601","ND5619","ND5620","ND5623","ND5624","ND5625","ND6098","ND6196","ND6398","NE0140","NE1523","NE1607","NE2271","NE2278","NE2282","NE2285","NE2288","NE2584","NE2596","NE2623","NE2625","NE3484","NE3669","NE3876","NE3999","NE4137","NE4141","NE4144","NE4147","NE4159","NE4186","NE4342","NE4529","NE4637","NE5311","NE5883","NE6306","NE6314","NE6589","NE7109","NH2060","NH2061","NH2064","NH2069","NH2743","NH6183","NJ0241","NJ0242","NJ0319","NJ0543","NJ0581","NJ0586","NJ0612","NJ0613","NJ0614","NJ0618","NJ0619","NJ0644","NJ0652","NJ0739","NJ0748","NJ0766","NJ0774","NJ0905","NJ0965","NJ1040","NJ1128","NJ1258","NJ1340","NJ1356","NJ1464","NJ1631","NJ1641","NJ1647","NJ1663","NJ1670","NJ1677","NJ1680","NJ1717","NJ1723","NJ1726","NJ1730","NJ1786","NJ2494","NJ3045","NJ3088","NJ3287","NJ3290","NJ3366","NJ3367","NJ3384","NJ3448","NJ3454","NJ3507","NJ3509","NJ3515","NJ3521","NJ3534","NJ3555","NJ3677","NJ3681","NJ3722","NJ3745","NJ3751","NJ3757","NJ3769","NJ3775","NJ3776","NJ3777","NJ3778","NJ3779","NJ3780","NJ3781","NJ3782","NJ3783","NJ3784","NJ3785","NJ3786","NJ3787","NJ3788","NJ3789","NJ3815","NJ3819","NJ3836","NJ3842","NJ3845","NJ3848","NJ3882","NJ3894","NJ3895","NJ3896","NJ3897","NJ3898","NJ3900","NJ3901","NJ3904","NJ3905","NJ3908","NJ3911","NJ3916","NJ3951","NJ3954","NJ3960","NJ3973","NJ3975","NJ3979","NJ3982","NJ3986","NJ3988","NJ3990","NJ3992","NJ3996","NJ4000","NJ4004","NJ4005","NJ4010","NJ4012","NJ4020","NJ4022","NJ4039","NJ4044","NJ4057","NJ4063","NJ4072","NJ4088","NJ4094","NJ4097","NJ4102","NJ4123","NJ4127","NJ4134","NJ4135","NJ4140","NJ4172","NJ4174","NJ4175","NJ4176","NJ4179","NJ4180","NJ4181","NJ4189","NJ4273","NJ4311","NJ4316","NJ4334","NJ4339","NJ4341","NJ4346","NJ4347","NJ4360","NJ4374","NJ4377","NJ4379","NJ4382","NJ4385","NJ4393","NJ4395","NJ4396","NJ4472","NJ4494","NJ4498","NJ4505","NJ4508","NJ4520","NJ4524","NJ4530","NJ4567","NJ4576","NJ4581","NJ4605","NJ4614","NJ4615","NJ4632","NJ4686","NJ4721","NJ4834","NJ4837","NJ4922","NJ5128","NJ5148","NJ5154","NJ5205","NJ5268","NJ5274","NJ5303","NJ5332","NJ5334","NJ5339","NJ5340","NJ5341","NJ5342","NJ5343","NJ5345","NJ5352","NJ5378","NJ5493","NJ5500","NJ5518","NJ5616","NJ5642","NJ5666","NJ5687","NJ5711","NJ5732","NJ5742","NJ5760","NJ5847","NJ5863","NJ5875","NJ5922","NJ5931","NJ5937","NJ5953","NJ6048","NJ6082","NJ6104","NJ6113","NJ6121","NJ6142","NJ6281","NJ6295","NJ6309","NJ6323","NJ6646","NJ7110","NJ7111","NJ7202","NJ7203","NY1350","NY3101","NY3107","NY3108","NY3135","NY3151","NY3175","NY3184","NY3185","NY3192","NY3196","NY3198","NY3207","NY3482","NY3793","NY3824","NY3879","NY4061","NY4074","NY4077","NY4079","NY4105","NY4106","NY4108","NY4111","NY4132","NY4138","NY4146","NY4155","NY4160","NY4171","NY4378","NY4408","NY4460","NY4463","NY4473","NY4510","NY4572","NY4687","NY4896","NY4897","NY4902","NY4931","NY4933","NY5302","NY5359","NY5408","NY5409","NY5410","NY5412","NY5413","NY5414","NY5416","NY5420","NY5562","NY5718","NY5819","NY5954","NY6030","NY6054","NY6355","NY6356","NY6357","NY6358","NY6462","NY6479","OH0026","OH0091","OH0185","OH0267","OH0272","OH0284","OH0285","OH0290","OH0469","OH0485","OH0691","OH0715","OH0717","OH0720","OH0722","OH0724","OH0727","OH0764","OH0944","OH0947","OH0948","OH1048","OH1051","OH1076","OH1079","OH1083","OH1084","OH1088","OH1089","OH1090","OH1108","OH1109","OH1110","OH1121","OH1122","OH1127","OH1130","OH1133","OH1142","OH1143","OH1146","OH1147","OH1149","OH1150","OH1152","OH1157","OH1159","OH1167","OH1292","OH1366","OH1367","OH1369","OH1371","OH1373","OH1374","OH1375","OH1376","OH1378","OH1392","OH1468","OH1493","OH1802","OH1812","OH1853","OH1856","OH1894","OH1903","OH1906","OH1953","OH1988","OH2037","OH2114","OH2372","OH2401","OH2422","OH2427","OH2515","OH2538","OH2811","OH2848","OH3148","OH3218","OH3219","OH3220","OH3297","OH3404","OH3406","OH3412","OH3440","OH3441","OH3445","OH3449","OH3452","OH3455","OH3459","OH3465","OH3466","OH3467","OH3483","OH3485","OH3486","OH3487","OH3492","OH3497","OH3498","OH3500","OH3502","OH3513","OH3518","OH3519","OH3522","OH3531","OH3533","OH3538","OH3540","OH3541","OH3542","OH3567","OH3569","OH3579","OH3582","OH3583","OH3584","OH3587","OH3588","OH3589","OH3590","OH3591","OH3593","OH3594","OH3595","OH3601","OH3602","OH3604","OH3605","OH3608","OH3612","OH3614","OH3633","OH3658","OH3692","OH3694","OH3695","OH3698","OH3701","OH3703","OH3710","OH3711","OH3727","OH3728","OH3729","OH3736","OH3743","OH3791","OH3792","OH3794","OH3803","OH3833","OH3841","OH3868","OH3995","OH4017","OH4124","OH4184","OH4188","OH4200","OH4202","OH4207","OH4212","OH4213","OH4215","OH4216","OH4218","OH4219","OH4220","OH4221","OH4222","OH4223","OH4224","OH4225","OH4226","OH4227","OH4228","OH4229","OH4230","OH4233","OH4236","OH4237","OH4238","OH4239","OH4240","OH4241","OH4242","OH4243","OH4244","OH4245","OH4247","OH4248","OH4250","OH4251","OH4252","OH4253","OH4256","OH4257","OH4259","OH4260","OH4261","OH4271","OH4282","OH4301","OH4308","OH4309","OH4413","OH4417","OH4418","OH4419","OH4420","OH4421","OH4422","OH4424","OH4425","OH4428","OH4435","OH4447","OH4509","OH4518","OH4519","OH4591","OH4592","OH4594","OH4595","OH4598","OH4600","OH4601","OH4628","OH4739","OH4775","OH4778","OH4779","OH4780","OH4781","OH4784","OH4785","OH4787","OH4800","OH4802","OH4868","OH4869","OH4870","OH4873","OH4874","OH4875","OH4877","OH4878","OH4879","OH4882","OH4885","OH4932","OH4978","OH4980","OH4986","OH4997","OH5000","OH5002","OH5013","OH5019","OH5021","OH5024","OH5031","OH5084","OH5094","OH5156","OH5157","OH5169","OH5171","OH5179","OH5188","OH5189","OH5190","OH5193","OH5194","OH5195","OH5263","OH5264","OH5266","OH5271","OH5289","OH5324","OH5350","OH5374","OH5442","OH5454","OH5462","OH5465","OH5468","OH5469","OH5475","OH5503","OH5533","OH5534","OH5557","OH5593","OH5621","OH5662","OH5665","OH5670","OH5676","OH5697","OH5708","OH5775","OH5778","OH5783","OH5784","OH5790","OH5795","OH5799","OH5828","OH5833","OH5855","OH5865","OH5868","OH5869","OH5873","OH5876","OH5882","OH5888","OH5900","OH5918","OH5938","OH5943","OH6023","OH6025","OH6028","OH6064","OH6080","OH6083","OH6097","OH6103","OH6107","OH6114","OH6120","OH6122","OH6127","OH6133","OH6134","OH6158","OH6163","OH6172","OH6176","OH6188","OH6191","OH6210","OH6211","OH6216","OH6217","OH6220","OH6227","OH6231","OH6232","OH6237","OH6240","OH6241","OH6244","OH6247","OH6259","OH6266","OH6277","OH6282","OH6289","OH6312","OH6328","OH6346","OH6348","OH6354","OH6372","OH6392","OH6401","OH6405","OH6408","OH6416","OH6418","OH6428","OH6435","OH6440","OH6454","OH6470","OH6473","OH6493","OH6496","OH6513","OH6519","OH6523","OH6533","OH6541","OH6543","OH6548","OH6550","OH6585","OH6588","OH6592","OH6597","OH6604","OH6609","OH6619","OH6622","OH6627","OH6653","OH6654","OH6657","OH6668","OH6672","OH6676","OH6681","OH6688","OH6693","OH6702","OH6712","OH6720","OH6726","OH6727","OH6732","OH6738","OH6740","OH6741","OH6744","OH6748","OH6749","OH6750","OH6756","OH6768","OH6773","OH6781","OH6794","OH6815","OH6821","OH6891","OK0331","OK0402","OK0410","OK0411","OK0412","OK0413","OK0415","OK0416","OK0418","OK0419","OK0420","OK0422","OK0423","OK0424","OK0425","OK0426","OK0427","OK0428","OK0429","OK0430","OK0525","OK1093","OK1115","OK2068","OK2094","OK3424","OK3428","OK3431","OK3432","OK3434","OK3435","OK3436","OK3437","OK3438","OK3439","OK4193","OK4194","OK4201","OK4337","OK4366","OK4453","OK4455","OK4456","OK4457","OK4465","OK4466","OK4468","OK4470","OK4471","OK4499","OK4502","OK4503","OK4504","OK4561","OK4660","OK4669","OK4673","OK4967","OK5029","OK5037","OK5048","OK5053","OK5066","OK5078","OK5093","OK5105","OK5255","OK5281","OK5290","OK5361","OK5996","OK6307","OK6447","OK6509","OK6524","OK6618","OK6694","OK6755","OK7101","OR0332","OR0459","OR0487","OR0502","OR0551","OR0630","OR0714","OR0908","OR2590","OR3344","OR3392","OR3408","OR3426","OR3503","OR3505","OR3546","OR3613","OR3714","OR3726","OR3804","OR3862","OR4026","OR4116","OR4118","OR4122","OR4196","OR4267","OR4683","OR4760","OR4821","OR5010","OR5030","OR5061","OR5067","OR5068","OR5113","OR5115","OR5167","OR5234","OR5258","OR5273","OR5292","OR5326","OR5444","OR5549","OR5660","OR5683","OR5696","OR5704","OR5734","OR5804","OR5923","OR5967","OR5974","OR6186","OR6199","OR6269","OR6352","OR6359","OR6370","OR6371","OR6376","OR6387","OR6389","OR6490","OR6514","OR6515","OR6520","OR6522","OR6529","OR6552","OR6554","OR6616","OR6628","OR6641","OR6651","OR6663","OR6689","OR6751","OR6805","OR6811","OR7204","PA0240","PA0541","PA0637","PA1049","PA1260","PA1281","PA1578","PA1851","PA2528","PA2571","PA2649","PA3353","PA3360","PA3379","PA3418","PA3523","PA3529","PA3705","PA3708","PA3839","PA3874","PA3880","PA3934","PA3940","PA3959","PA3961","PA3998","PA4003","PA4009","PA4016","PA4035","PA4038","PA4040","PA4051","PA4054","PA4059","PA4062","PA4067","PA4069","PA4073","PA4083","PA4085","PA4086","PA4121","PA4145","PA4187","PA4302","PA4303","PA4305","PA4306","PA4307","PA4313","PA4575","PA4577","PA4636","PA4736","PA4748","PA4757","PA4889","PA4893","PA4903","PA4905","PA5036","PA5041","PA5150","PA5174","PA5207","PA5288","PA5415","PA5447","PA5452","PA5470","PA5483","PA5490","PA5508","PA5509","PA5577","PA5629","PA5649","PA5657","PA5659","PA5661","PA5664","PA5668","PA5673","PA5678","PA5689","PA5703","PA5729","PA5841","PA5914","PA5964","PA5971","PA5981","PA5984","PA5986","PA6043","PA6050","PA6056","PA6070","PA6089","PA6154","PA6279","PA6332","PA6426","PA6498","PA6645","PA6669","PA6840","PA6860","PA7201","RI3298","RI3464","RI3730","RI3822","RI3864","RI3872","RI3875","RI3893","RI3913","RI3917","RI3923","RI3925","RI4070","RI4924","RI5152","RI5677","RI5701","RI5710","RI5731","RI5737","RI5752","RI5854","RI5874","RI5884","RI5919","RI6009","RI6178","RI6278","RI6615","RI6630","RI6660","RI6808","RI7114","RI7115","TN1255","TN1256","TN2616","TN2846","TN2861","TN2942","TN3009","TN3023","TN3700","TN4681","TN4695","TN4708","TN5209","TN5627","TN5667","TN5780","TN5856","TN5895","TN5898","TN5915","TN5928","TN5947","TN5980","TN6037","TN6102","VA0208","VA0473","VA1922","VA1936","VA1938","VA1973","VA1987","VA2052","VA2056","VA2090","VA2113","VA2122","VA2135","VA2415","VA2682","VA2689","VA2712","VA5151","VA5355","VA6203","VA6204"] \ No newline at end of file From 2232b2c98383b843438347fe7d84861cf045b912 Mon Sep 17 00:00:00 2001 From: Dinesh-kantamneni Date: Tue, 29 Oct 2024 11:10:07 -0700 Subject: [PATCH 07/17] testing codebuild job --- .github/workflows/ecr-publish.yml | 3 - buildspec/build_deploy.yaml | 128 ++++++++++++++++++++++++ buildspec/manual_deploy.yaml | 161 ++++++++++++++++++++++++++++++ buildspec/pr_build.yaml | 73 ++++++++++++++ buildspec/readme | 42 ++++++++ 5 files changed, 404 insertions(+), 3 deletions(-) create mode 100644 buildspec/build_deploy.yaml create mode 100644 buildspec/manual_deploy.yaml create mode 100644 buildspec/pr_build.yaml create mode 100644 buildspec/readme diff --git a/.github/workflows/ecr-publish.yml b/.github/workflows/ecr-publish.yml index b5d0b8db3..1df6c118f 100644 --- a/.github/workflows/ecr-publish.yml +++ b/.github/workflows/ecr-publish.yml @@ -4,9 +4,6 @@ on: push: branches: - ecr-deploy - - develop - - release/* - - master env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/buildspec/build_deploy.yaml b/buildspec/build_deploy.yaml new file mode 100644 index 000000000..c99df727e --- /dev/null +++ b/buildspec/build_deploy.yaml @@ -0,0 +1,128 @@ +version: 0.2 + +env: + variables: + SLACK_COLOR: "good" + BUILD_STATUS: "completed successfully" + SLACK_CHANNEL: "p-qppsf-deploys" + CODEBUILD_ICON: "https://upload.wikimedia.org/wikipedia/commons/9/93/Amazon_Web_Services_Logo.svg" + AWS_DEFAULT_REGION: "us-east-1" + TEXT_VALUE: "" + + parameter-store: + SLACK_URL: "/slack/p-qppsf-deploys" + DOCKERHUB_TOKEN: "/global/dockerhub_token" + DOCKERHUB_USER: "/global/dockerhub_user" + AWS_ACCOUNT : "/global/aws_account" + REPO_PAT: "/global/scoring_api_repo_pat" + BRANCH_STATUS_URL: "/global/branch_status_url" + PART_FILE: "/qppar-sf/conversion_tool/CPC_PLUS_FILE_NAME" # create secret + PART_FILE_BUCKET: "/qppar-sf/$ENV/conversion_tool/CPC_PLUS_BUCKET_NAME" + OUTPUT_PART_FILE: "/qppar-sf/$ENV/conversion_tool/CPC_PLUS_VALIDATION_FILE" + +phases: + install: + runtime-versions: + python: 3.12 + commands: + - | + CURL_PAYLOAD=$( jq -n \ + --arg state "pending" \ + --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-conversion-tool;stream=${CODEBUILD_LOG_PATH}" \ + --arg description "The build job has started." \ + --arg context "CodeBuild Status" \ + '{state: $state, target_url: $target_url, description: $description, context: $context}' ) + + echo "$CURL_PAYLOAD" + + curl \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${REPO_PAT}" \ + ${BRANCH_STATUSES_URL} \ + -d "${CURL_PAYLOAD}" + - docker --version + - aws --version + - jq --version + - pip install ecs-deploy + - pwd + - ls -la + + pre_build: + commands: + - touch .env + - echo ${CODEBUILD_SRC_DIR} + - ECS_ENV="${ENV}" + - | + if [ "$ENV" = "prod" || "$ENV" = "devpre" ]; then + CLUSTER_NAME="qppa-${ENV}-api-ecs" + else + CLUSTER_NAME="${ENV}-api-ecs" + fi + - SERVICE_NAME="${ENV}-conversion-tool" + - BRANCH=$(echo "${CODEBUILD_SOURCE_VERSION}") + - echo ${CODEBUILD_RESOLVED_SOURCE_VERSION} + - echo "${BRANCH}" + - COMMIT_SHORT_SHA=$(echo "${CODEBUILD_RESOLVED_SOURCE_VERSION}" | cut -c1-7) + - echo "${COMMIT_SHORT_SHA}" + - TAG_BUILD="${ENV}-conversion-tool:${BRANCH}-${COMMIT_SHORT_SHA}" + - TAG_GIT="${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/${SERVICE_NAME}:${BRANCH}-${COMMIT_SHORT_SHA}" + - TAG_LATEST="${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/${SERVICE_NAME}:latest" + - echo Getting Certificates for ${ENV} + - chmod +x ./qppsfct-copy-certs.sh + - ./qppsfct-copy-certs.sh $ENV $AWS_DEFAULT_REGION + - pip install openpyxl + - echo "Updating participation file" + - chmod +x ./upload-part-file.sh + - ./upload-part-file.sh $PART_FILE_BUCKET $PART_FILE $OUTPUT_PART_FILE $AWS_DEFAULT_REGION + - echo "Logging in to Amazon ECR..." + - echo $DOCKERHUB_TOKEN | docker login --username $DOCKERHUB_USER --password-stdin + - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com + - TEXT_VALUE="Deploying QPP conversion tool service branch ${BRANCH} to ${ECS_ENV}-conversion-tool..." + - curl -X POST --fail --data-urlencode "payload={\"text\":\"Deployment Status\",\"channel\":\"${SLACK_CHANNEL}\",\"username\":\"CodeBuild\",\"icon_url\":\"${CODEBUILD_ICON}\",\"attachments\":[{\"title\":\"${TEXT_VALUE}\",\"color\":\"${SLACK_COLOR}\"}]}" ${SLACK_URL} + + build: + commands: + - echo "Deploying..." + - echo "Build started on `date`..." + - echo "Building the Docker image for conversion tool..." + - docker build -t $TAG_LATEST -t $TAG_GIT .; + - echo "Pushing the Docker image to AWS ECR..." + - docker push $TAG_LATEST; + - docker push $TAG_GIT; + - echo "Branch is ${ENV}, Deploying to ${ENV}-conversion-tool service..." + - ecs deploy $CLUSTER_NAME $SERVICE_NAME -t $BRANCH-$COMMIT_SHORT_SHA --no-deregister --region us-east-1 --timeout 900 --task $SERVICE_NAME; + - aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME --region us-east-1; + - echo "Branch is ${ENV}, Deployment to ${ENV}-conversion-tool service completed..." + + post_build: + commands: + # Check the build status and set the slack message to reflect pass or fail status + - echo "Code build exit number (1 is success) = $CODEBUILD_BUILD_SUCCEEDING" + - if [ $CODEBUILD_BUILD_SUCCEEDING = 0 ]; then SLACK_COLOR="danger" && BUILD_STATUS="FAILED"; fi + - TEXT_VALUE="Deployment of branch ${BRANCH} to QPP Conversion Tool service in $ENV-conversion-tool $BUILD_STATUS" + - curl -X POST --fail --data-urlencode "payload={\"text\":\"Deployment Status\",\"channel\":\"${SLACK_CHANNEL}\",\"username\":\"CodeBuild\",\"icon_url\":\"${CODEBUILD_ICON}\",\"attachments\":[{\"title\":\"${TEXT_VALUE}\",\"color\":\"${SLACK_COLOR}\"}]}" ${SLACK_URL} + - | + if [ "${CODEBUILD_BUILD_SUCCEEDING}" = 1 ]; then + STATE="success" + DESCRIPTION="The build succeeded!" + else + STATE="failure" + DESCRIPTION="The build failed. Click Details for the logs." + fi + + CURL_PAYLOAD=$( jq -n \ + --arg state "$STATE" \ + --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-scoring-api;stream=${CODEBUILD_LOG_PATH}" \ + --arg description "$DESCRIPTION" \ + --arg context "CodeBuild Status" \ + '{state: $state, target_url: $target_url, description: $description, context: $context}' ) + + echo "$CURL_PAYLOAD" + + curl \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ + ${BRANCH_STATUSES_URL} \ + -d "${CURL_PAYLOAD}" diff --git a/buildspec/manual_deploy.yaml b/buildspec/manual_deploy.yaml new file mode 100644 index 000000000..584f6588b --- /dev/null +++ b/buildspec/manual_deploy.yaml @@ -0,0 +1,161 @@ +version: 0.2 + +env: + variables: + SLACK_COLOR: "good" + BUILD_STATUS: "completed successfully" + SLACK_CHANNEL: "p-qppsf-deploys" + CODEBUILD_ICON: "https://upload.wikimedia.org/wikipedia/commons/9/93/Amazon_Web_Services_Logo.svg" + AWS_DEFAULT_REGION: "us-east-1" + TEXT_VALUE: "" + + parameter-store: + SLACK_URL: "/slack/p-qppsf-deploys" + DOCKERHUB_TOKEN: "/global/dockerhub_token" + DOCKERHUB_USER: "/global/dockerhub_user" + NPM_TOKEN: "/global/npm_token" + NR_API_TOKEN: "/global/nr_api_key" + IMPL_SR_NR_APP_ID: "/global/impl_sr_nr_app_id" + AWS_ACCOUNT : "/global/aws_account" + PROD_SR_NR_APP_ID: "/global/prod_sr_nr_app_id" + BRANCH_STATUS_URL: "/global/branch_status_url" + SCORING_REPO_PAT: "/global/scoring_api_repo_pat" + +phases: + install: + runtime-versions: + nodejs: 18 + commands: + - | + CURL_PAYLOAD=$( jq -n \ + --arg state "pending" \ + --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-scoring-api;stream=${CODEBUILD_LOG_PATH}" \ + --arg description "The build job has started." \ + --arg context "CodeBuild Status" \ + '{state: $state, target_url: $target_url, description: $description, context: $context}' ) + + echo "$CURL_PAYLOAD" + + curl \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ + "${BRANCH_STATUS_URL}/${CODEBUILD_RESOLVED_SOURCE_VERSION}" \ + -d "${CURL_PAYLOAD}" + - node -v + - npm -v + - docker --version + - aws --version + - jq --version + - pip install ecs-deploy + - pwd + - ls -la + + pre_build: + commands: + - | + if [ "$ENV" = "prod" ]; then + CLUSTER_NAME="qppa-prod-api-ecs" + SERVICE_NAME="prod-scoring-api-v4" + else + CLUSTER_NAME="${ENV}-api-ecs" + SERVICE_NAME="${ENV}-scoring-ssl-api" + fi + - BRANCH=$(echo "${CODEBUILD_SOURCE_VERSION}") + - echo "${BRANCH}" + - COMMIT_SHORT_SHA=$(echo "${CODEBUILD_RESOLVED_SOURCE_VERSION}" | cut -c1-7) + - echo "${COMMIT_SHORT_SHA}" + - TAG_BUILD="build-${ENV}-scoring-ssl-api:${BRANCH}-${COMMIT_SHORT_SHA}" + - TAG_GIT="${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/${SERVICE_NAME}:${BRANCH}-${COMMIT_SHORT_SHA}" + - TAG_LATEST="${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/${SERVICE_NAME}:latest" + - ECS_ENV="${ENV}" + - API_VERSION=$( jq -r '.version' build_properties.json ) + - echo "$API_VERSION" + - ConfluencePageId=$( jq -r '.confluenceReleasePageId' build_properties.json ) + - echo "$ConfluencePageId" + - Type=$( jq -r '.releaseType' build_properties.json ) + - echo "$Type" + - touch .env + - echo "Logging in to Amazon ECR..." + - echo $DOCKERHUB_TOKEN | docker login --username $DOCKERHUB_USER --password-stdin + - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com + - TEXT_VALUE="Deploying QPP Scoring API service version branch ${BRANCH} to ${ECS_ENV}-scoring-ssl-api..." + - curl -X POST --fail --data-urlencode "payload={\"text\":\"Deployment Status\",\"channel\":\"${SLACK_CHANNEL}\",\"username\":\"CodeBuild\",\"icon_url\":\"${CODEBUILD_ICON}\",\"attachments\":[{\"title\":\"${TEXT_VALUE}\",\"color\":\"${SLACK_COLOR}\"}]}" ${SLACK_URL} + + build: + commands: + - echo "Deploying..." + - echo "Build started on `date`..." + - echo "Building the Docker image and running tests..." + - docker build -t $TAG_BUILD --target build . + - docker run --rm --env-file example.env $TAG_BUILD npm run lint + - docker run --rm --env-file example.env $TAG_BUILD npm run test:cov + - | + if [ $ECS_ENV != "feature" ]; then + echo "Branch ${ECS_ENV} is deployable to ECS..." + echo "Building the Docker image..." + docker build -t $TAG_LATEST -t $TAG_GIT .; + echo "Building tools container image..." + docker build --build-arg NPM_TOKEN=${NPM_TOKEN} -t $TAG_TOOLS . -f docker-tools.dockerfile; + echo "Pushing the Docker image to AWS ECR..." + docker push $TAG_LATEST; + docker push $TAG_TOOLS; + docker push $TAG_GIT; + if [ $ECS_ENV = "prod" ]; then + echo "Branch is ${ECS_ENV}, Deploying to ${ECS_ENV}-api-ecs cluster and ${ECS_ENV}-scoring-ssl-api service..." + echo "Sending deployment mark to NewRelic..." + ecs deploy $CLUSTER_NAME $SERVICE_NAME --newrelic-apikey ${NR_API_TOKEN} --newrelic-appid ${PROD_SR_NR_APP_ID} -t $BRANCH-$COMMIT_SHORT_SHA --newrelic-revision $API_VERSION --no-deregister --region us-east-1 --timeout 900 --task $SERVICE_NAME; + aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME --region us-east-1; + elif [ $ECS_ENV = "impl" ]; then + echo "Branch is ${ECS_ENV}, Deploying to ${ECS_ENV}-api-ecs cluster and ${ECS_ENV}-scoring-ssl-api service..." + echo "Sending deployment mark to NewRelic..." + ecs deploy $CLUSTER_NAME $SERVICE_NAME --newrelic-apikey ${NR_API_TOKEN} --newrelic-appid ${IMPL_SR_NR_APP_ID} -t $BRANCH-$COMMIT_SHORT_SHA --newrelic-revision $API_VERSION --no-deregister --region us-east-1 --timeout 900 --task $SERVICE_NAME; + aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME --region us-east-1; + else + echo "Branch is ${ECS_ENV}, Deploying to ${ECS_ENV}-api-ecs cluster and ${ECS_ENV}-scoring-ssl-api service..." + ecs deploy $CLUSTER_NAME $SERVICE_NAME -t $BRANCH-$COMMIT_SHORT_SHA --no-deregister --region us-east-1 --timeout 900 --task $SERVICE_NAME; + aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME --region us-east-1; + echo "Environment ${ECS_ENV} is not imp or prod, deployment mark is not recorded to NewRelic..." + fi + else + echo "Environmnet ${ECS_ENV} is not dev/impl/prod, so not building image and deploying to ecs..." + fi + + post_build: + commands: + # Check the build status and set the slack message to reflect pass or fail status + - | + if [ $ECS_ENV = "prod" ]; then + echo "Starting smoke tests for prod" + cd buildspec + aws codebuild start-build --cli-input-json file://start_smoke_tests_prod.json + cd .. + fi + - echo "Code build exit number (1 is success) = $CODEBUILD_BUILD_SUCCEEDING" + - if [ $CODEBUILD_BUILD_SUCCEEDING = 0 ]; then SLACK_COLOR="danger" && BUILD_STATUS="FAILED"; fi + - TEXT_VALUE="Deployment of branch ${BRANCH} to QPP Scoring API service in $ECS_ENV-scoring-ssl-api $BUILD_STATUS" + - curl -X POST --fail --data-urlencode "payload={\"text\":\"Deployment Status\",\"channel\":\"${SLACK_CHANNEL}\",\"username\":\"CodeBuild\",\"icon_url\":\"${CODEBUILD_ICON}\",\"attachments\":[{\"title\":\"${TEXT_VALUE}\",\"color\":\"${SLACK_COLOR}\"}]}" ${SLACK_URL} + - | + if [ "${CODEBUILD_BUILD_SUCCEEDING}" = 1 ]; then + STATE="success" + DESCRIPTION="The build succeeded!" + else + STATE="failure" + DESCRIPTION="The build failed. Click Details for the logs." + fi + + CURL_PAYLOAD=$( jq -n \ + --arg state "$STATE" \ + --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-scoring-api;stream=${CODEBUILD_LOG_PATH}" \ + --arg description "$DESCRIPTION" \ + --arg context "CodeBuild Status" \ + '{state: $state, target_url: $target_url, description: $description, context: $context}' ) + + echo "$CURL_PAYLOAD" + + curl \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ + "${BRANCH_STATUS_URL}/${CODEBUILD_RESOLVED_SOURCE_VERSION}" \ + -d "${CURL_PAYLOAD}" diff --git a/buildspec/pr_build.yaml b/buildspec/pr_build.yaml new file mode 100644 index 000000000..1dcd0e855 --- /dev/null +++ b/buildspec/pr_build.yaml @@ -0,0 +1,73 @@ +version: 0.2 + +env: + variables: + ENV: "local" + NODE_ENV: "development" + + parameter-store: + DOCKERHUB_TOKEN: "/global/dockerhub_token" + DOCKERHUB_USER: "/global/dockerhub_user" + SCORING_REPO_PAT: "/global/scoring_api_repo_pat" + +phases: + install: + commands: + - | + CURL_PAYLOAD=$( jq -n \ + --arg state "pending" \ + --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/scoring-api-pr;stream=${CODEBUILD_LOG_PATH}" \ + --arg description "The build job has started." \ + --arg context "CodeBuild Status" \ + '{state: $state, target_url: $target_url, description: $description, context: $context}' ) + + echo "$CURL_PAYLOAD" + + curl \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ + ${BRANCH_STATUSES_URL} \ + -d "${CURL_PAYLOAD}" + - node -v + - npm -v + - docker --version + - aws --version + - jq --version + + build: + commands: + - echo $DOCKERHUB_TOKEN | docker login --username $DOCKERHUB_USER --password-stdin + - echo "Building the Docker image and running tests..." + - docker build --no-cache -t $TAG_BUILD --target build . + - docker run --rm --env-file example.env $TAG_BUILD npm run lint + - docker run --rm --env-file example.env $TAG_BUILD npm run test:cov + + post_build: + commands: + # Check the build status and set the slack message to reflect pass or fail status + - echo "Code build exit number (1 is success, 0 is failed) = $CODEBUILD_BUILD_SUCCEEDING" + - | + if [ "${CODEBUILD_BUILD_SUCCEEDING}" = 1 ]; then + STATE="success" + DESCRIPTION="The build succeeded!" + else + STATE="failure" + DESCRIPTION="The build failed. Click Details for the logs." + fi + + CURL_PAYLOAD=$( jq -n \ + --arg state "$STATE" \ + --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/scoring-api-pr;stream=${CODEBUILD_LOG_PATH}" \ + --arg description "$DESCRIPTION" \ + --arg context "CodeBuild Status" \ + '{state: $state, target_url: $target_url, description: $description, context: $context}' ) + + echo "$CURL_PAYLOAD" + + curl \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ + ${BRANCH_STATUSES_URL} \ + -d "${CURL_PAYLOAD}" diff --git a/buildspec/readme b/buildspec/readme new file mode 100644 index 000000000..0131194bb --- /dev/null +++ b/buildspec/readme @@ -0,0 +1,42 @@ + +variable : + These environment variables can also be defined in example.env file which is in root directory (custom environent variables). + +parameter-store : + Used to retrive (sensitive) custom environment variabe stored in EC2 system manager parameter store (To store sensitive values we use system manager-parameter store). + +Phases : + Required sequence. represents the commands codebuild runs during each phase of build. different phases of build steps defined below. + +install : + install phase only for installing packages in the build environment. example we can install code testing framework such as mocha. + +runtime-versions phase : + runtime-versions phase specifying run time version of the build. + +commands phase: + Contains a sequence of scalars, where each scalar represents a single command that CodeBuild runs during installation. CodeBuild runs each command, one at a time, in the order listed, from beginning to end. + +pre_build phase : + Represents the commands, if any, that CodeBuild runs before the build. For example, you might use this phase to sign in to Amazon ECR, or you might install npm dependencies. + +pre_build/commands : + Required sequence if pre_build is specified. Contains a sequence of scalars, where each scalar represents a single command that CodeBuild runs before the build. CodeBuild runs each command, one at a time, in the order listed, from beginning to end. + +build phase : + Represents the commands, if any, that CodeBuild runs during the build. + +build/commands : + Represents the commands + +post_build : + Represents the commands, if any, that CodeBuild runs after the build. example: slack notification + +post_build/commands : + Represents the commands + +artifacsts : + location for build output artifacts + + +#ecs deploy $CLUSTER_NAME $SERVICE_NAME --newrelic-apikey ${NR_API_KEY} --newrelic-appid ${APP_ID} -t $BRANCH-$COMMIT_SHORT_SHA --newrelic-revision 1.0.0 From 9372fe4d7b3e66395714459b7560834b323ef884 Mon Sep 17 00:00:00 2001 From: Dinesh-kantamneni Date: Tue, 29 Oct 2024 11:21:13 -0700 Subject: [PATCH 08/17] testing codebuild job --- buildspec/build_deploy.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/buildspec/build_deploy.yaml b/buildspec/build_deploy.yaml index c99df727e..3402b29da 100644 --- a/buildspec/build_deploy.yaml +++ b/buildspec/build_deploy.yaml @@ -39,7 +39,7 @@ phases: -X POST \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer ${REPO_PAT}" \ - ${BRANCH_STATUSES_URL} \ + "${BRANCH_STATUS_URL}/${CODEBUILD_RESOLVED_SOURCE_VERSION}" \ -d "${CURL_PAYLOAD}" - docker --version - aws --version @@ -113,7 +113,7 @@ phases: CURL_PAYLOAD=$( jq -n \ --arg state "$STATE" \ - --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-scoring-api;stream=${CODEBUILD_LOG_PATH}" \ + --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-conversion-tool;stream=${CODEBUILD_LOG_PATH}" \ --arg description "$DESCRIPTION" \ --arg context "CodeBuild Status" \ '{state: $state, target_url: $target_url, description: $description, context: $context}' ) @@ -123,6 +123,6 @@ phases: curl \ -X POST \ -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ - ${BRANCH_STATUSES_URL} \ - -d "${CURL_PAYLOAD}" + -H "Authorization: Bearer ${REPO_PAT}" \ + "${BRANCH_STATUS_URL}/${CODEBUILD_RESOLVED_SOURCE_VERSION}" \ + -d "${CURL_PAYLOAD}" \ No newline at end of file From 29e01dc52d610063bb112c6eeb9f080cfbbf21fe Mon Sep 17 00:00:00 2001 From: Dinesh-kantamneni Date: Tue, 29 Oct 2024 11:24:33 -0700 Subject: [PATCH 09/17] testing codebuild job --- buildspec/build_deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildspec/build_deploy.yaml b/buildspec/build_deploy.yaml index 3402b29da..8c5588feb 100644 --- a/buildspec/build_deploy.yaml +++ b/buildspec/build_deploy.yaml @@ -23,7 +23,7 @@ env: phases: install: runtime-versions: - python: 3.12 + python: 3.8 commands: - | CURL_PAYLOAD=$( jq -n \ From 988e30c07b8c4c5f6a4b39c9176501f9c1c6cf83 Mon Sep 17 00:00:00 2001 From: Dinesh-kantamneni Date: Tue, 29 Oct 2024 14:22:10 -0700 Subject: [PATCH 10/17] parameter name change --- buildspec/build_deploy.yaml | 3 ++- qppsfct-copy-certs.sh | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/buildspec/build_deploy.yaml b/buildspec/build_deploy.yaml index 8c5588feb..c5a94dd91 100644 --- a/buildspec/build_deploy.yaml +++ b/buildspec/build_deploy.yaml @@ -16,7 +16,7 @@ env: AWS_ACCOUNT : "/global/aws_account" REPO_PAT: "/global/scoring_api_repo_pat" BRANCH_STATUS_URL: "/global/branch_status_url" - PART_FILE: "/qppar-sf/conversion_tool/CPC_PLUS_FILE_NAME" # create secret + PART_FILE: "/qppar-sf/conversion_tool/CPC_PLUS_FILE_NAME" # create secret with hypen not underscore PART_FILE_BUCKET: "/qppar-sf/$ENV/conversion_tool/CPC_PLUS_BUCKET_NAME" OUTPUT_PART_FILE: "/qppar-sf/$ENV/conversion_tool/CPC_PLUS_VALIDATION_FILE" @@ -59,6 +59,7 @@ phases: else CLUSTER_NAME="${ENV}-api-ecs" fi + - echo "${CLUSTER_NAME}" - SERVICE_NAME="${ENV}-conversion-tool" - BRANCH=$(echo "${CODEBUILD_SOURCE_VERSION}") - echo ${CODEBUILD_RESOLVED_SOURCE_VERSION} diff --git a/qppsfct-copy-certs.sh b/qppsfct-copy-certs.sh index 2e285e344..d8f20a644 100644 --- a/qppsfct-copy-certs.sh +++ b/qppsfct-copy-certs.sh @@ -9,10 +9,10 @@ export ENV_CERT=${ENV_CERT} export AWS_REGION=${AWS_REGION} #Export Passphrase for Environment -export SSL_PASS=$(aws ssm get-parameters --name /qppar-sf/${ENV_CERT}/conversion_tool/SSL_SECRET --with-decryption --query "Parameters[0].Value" | tr -d '"') +export SSL_PASS=$(aws ssm get-parameters --name /qppar-sf/${ENV_CERT}/conversion-tool/SSL_SECRET --with-decryption --query "Parameters[0].Value" | tr -d '"') #Export Certificate ARN for Environment -export CERT_ARN=$(aws ssm get-parameters --name /qppar-sf/${ENV_CERT}/conversion_tool/CERT_ARN --with-decryption --query "Parameters[0].Value" | tr -d '"') +export CERT_ARN=$(aws ssm get-parameters --name /qppar-sf/${ENV_CERT}/conversion-tool/CERT_ARN --with-decryption --query "Parameters[0].Value" | tr -d '"') cd ./${CERT_CP_PATH} From c1a6b538b7109e6292bc11061a317336c00e2866 Mon Sep 17 00:00:00 2001 From: Dinesh-kantamneni Date: Tue, 29 Oct 2024 22:23:57 -0700 Subject: [PATCH 11/17] updates to buildspec file --- buildspec/build_deploy.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/buildspec/build_deploy.yaml b/buildspec/build_deploy.yaml index c5a94dd91..507cb656d 100644 --- a/buildspec/build_deploy.yaml +++ b/buildspec/build_deploy.yaml @@ -16,9 +16,9 @@ env: AWS_ACCOUNT : "/global/aws_account" REPO_PAT: "/global/scoring_api_repo_pat" BRANCH_STATUS_URL: "/global/branch_status_url" - PART_FILE: "/qppar-sf/conversion_tool/CPC_PLUS_FILE_NAME" # create secret with hypen not underscore - PART_FILE_BUCKET: "/qppar-sf/$ENV/conversion_tool/CPC_PLUS_BUCKET_NAME" - OUTPUT_PART_FILE: "/qppar-sf/$ENV/conversion_tool/CPC_PLUS_VALIDATION_FILE" + PART_FILE: "/qppar-sf/conversion-tool/CPC_PLUS_FILE_NAME" + PART_FILE_BUCKET: "/qppar-sf/$ENV/conversion-tool/CPC_PLUS_BUCKET_NAME" + OUTPUT_PART_FILE: "/qppar-sf/$ENV/conversion-tool/CPC_PLUS_VALIDATION_FILE" phases: install: @@ -50,7 +50,6 @@ phases: pre_build: commands: - - touch .env - echo ${CODEBUILD_SRC_DIR} - ECS_ENV="${ENV}" - | From 146f94bd1c7e97ca4c6fd0d62fe488b2bea6326f Mon Sep 17 00:00:00 2001 From: Dinesh-kantamneni Date: Wed, 30 Oct 2024 14:06:42 -0700 Subject: [PATCH 12/17] updates to buildspec file --- buildspec/manual_deploy.yaml | 161 ----------------------------------- buildspec/pr_build.yaml | 1 + 2 files changed, 1 insertion(+), 161 deletions(-) delete mode 100644 buildspec/manual_deploy.yaml diff --git a/buildspec/manual_deploy.yaml b/buildspec/manual_deploy.yaml deleted file mode 100644 index 584f6588b..000000000 --- a/buildspec/manual_deploy.yaml +++ /dev/null @@ -1,161 +0,0 @@ -version: 0.2 - -env: - variables: - SLACK_COLOR: "good" - BUILD_STATUS: "completed successfully" - SLACK_CHANNEL: "p-qppsf-deploys" - CODEBUILD_ICON: "https://upload.wikimedia.org/wikipedia/commons/9/93/Amazon_Web_Services_Logo.svg" - AWS_DEFAULT_REGION: "us-east-1" - TEXT_VALUE: "" - - parameter-store: - SLACK_URL: "/slack/p-qppsf-deploys" - DOCKERHUB_TOKEN: "/global/dockerhub_token" - DOCKERHUB_USER: "/global/dockerhub_user" - NPM_TOKEN: "/global/npm_token" - NR_API_TOKEN: "/global/nr_api_key" - IMPL_SR_NR_APP_ID: "/global/impl_sr_nr_app_id" - AWS_ACCOUNT : "/global/aws_account" - PROD_SR_NR_APP_ID: "/global/prod_sr_nr_app_id" - BRANCH_STATUS_URL: "/global/branch_status_url" - SCORING_REPO_PAT: "/global/scoring_api_repo_pat" - -phases: - install: - runtime-versions: - nodejs: 18 - commands: - - | - CURL_PAYLOAD=$( jq -n \ - --arg state "pending" \ - --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-scoring-api;stream=${CODEBUILD_LOG_PATH}" \ - --arg description "The build job has started." \ - --arg context "CodeBuild Status" \ - '{state: $state, target_url: $target_url, description: $description, context: $context}' ) - - echo "$CURL_PAYLOAD" - - curl \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ - "${BRANCH_STATUS_URL}/${CODEBUILD_RESOLVED_SOURCE_VERSION}" \ - -d "${CURL_PAYLOAD}" - - node -v - - npm -v - - docker --version - - aws --version - - jq --version - - pip install ecs-deploy - - pwd - - ls -la - - pre_build: - commands: - - | - if [ "$ENV" = "prod" ]; then - CLUSTER_NAME="qppa-prod-api-ecs" - SERVICE_NAME="prod-scoring-api-v4" - else - CLUSTER_NAME="${ENV}-api-ecs" - SERVICE_NAME="${ENV}-scoring-ssl-api" - fi - - BRANCH=$(echo "${CODEBUILD_SOURCE_VERSION}") - - echo "${BRANCH}" - - COMMIT_SHORT_SHA=$(echo "${CODEBUILD_RESOLVED_SOURCE_VERSION}" | cut -c1-7) - - echo "${COMMIT_SHORT_SHA}" - - TAG_BUILD="build-${ENV}-scoring-ssl-api:${BRANCH}-${COMMIT_SHORT_SHA}" - - TAG_GIT="${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/${SERVICE_NAME}:${BRANCH}-${COMMIT_SHORT_SHA}" - - TAG_LATEST="${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/${SERVICE_NAME}:latest" - - ECS_ENV="${ENV}" - - API_VERSION=$( jq -r '.version' build_properties.json ) - - echo "$API_VERSION" - - ConfluencePageId=$( jq -r '.confluenceReleasePageId' build_properties.json ) - - echo "$ConfluencePageId" - - Type=$( jq -r '.releaseType' build_properties.json ) - - echo "$Type" - - touch .env - - echo "Logging in to Amazon ECR..." - - echo $DOCKERHUB_TOKEN | docker login --username $DOCKERHUB_USER --password-stdin - - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com - - TEXT_VALUE="Deploying QPP Scoring API service version branch ${BRANCH} to ${ECS_ENV}-scoring-ssl-api..." - - curl -X POST --fail --data-urlencode "payload={\"text\":\"Deployment Status\",\"channel\":\"${SLACK_CHANNEL}\",\"username\":\"CodeBuild\",\"icon_url\":\"${CODEBUILD_ICON}\",\"attachments\":[{\"title\":\"${TEXT_VALUE}\",\"color\":\"${SLACK_COLOR}\"}]}" ${SLACK_URL} - - build: - commands: - - echo "Deploying..." - - echo "Build started on `date`..." - - echo "Building the Docker image and running tests..." - - docker build -t $TAG_BUILD --target build . - - docker run --rm --env-file example.env $TAG_BUILD npm run lint - - docker run --rm --env-file example.env $TAG_BUILD npm run test:cov - - | - if [ $ECS_ENV != "feature" ]; then - echo "Branch ${ECS_ENV} is deployable to ECS..." - echo "Building the Docker image..." - docker build -t $TAG_LATEST -t $TAG_GIT .; - echo "Building tools container image..." - docker build --build-arg NPM_TOKEN=${NPM_TOKEN} -t $TAG_TOOLS . -f docker-tools.dockerfile; - echo "Pushing the Docker image to AWS ECR..." - docker push $TAG_LATEST; - docker push $TAG_TOOLS; - docker push $TAG_GIT; - if [ $ECS_ENV = "prod" ]; then - echo "Branch is ${ECS_ENV}, Deploying to ${ECS_ENV}-api-ecs cluster and ${ECS_ENV}-scoring-ssl-api service..." - echo "Sending deployment mark to NewRelic..." - ecs deploy $CLUSTER_NAME $SERVICE_NAME --newrelic-apikey ${NR_API_TOKEN} --newrelic-appid ${PROD_SR_NR_APP_ID} -t $BRANCH-$COMMIT_SHORT_SHA --newrelic-revision $API_VERSION --no-deregister --region us-east-1 --timeout 900 --task $SERVICE_NAME; - aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME --region us-east-1; - elif [ $ECS_ENV = "impl" ]; then - echo "Branch is ${ECS_ENV}, Deploying to ${ECS_ENV}-api-ecs cluster and ${ECS_ENV}-scoring-ssl-api service..." - echo "Sending deployment mark to NewRelic..." - ecs deploy $CLUSTER_NAME $SERVICE_NAME --newrelic-apikey ${NR_API_TOKEN} --newrelic-appid ${IMPL_SR_NR_APP_ID} -t $BRANCH-$COMMIT_SHORT_SHA --newrelic-revision $API_VERSION --no-deregister --region us-east-1 --timeout 900 --task $SERVICE_NAME; - aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME --region us-east-1; - else - echo "Branch is ${ECS_ENV}, Deploying to ${ECS_ENV}-api-ecs cluster and ${ECS_ENV}-scoring-ssl-api service..." - ecs deploy $CLUSTER_NAME $SERVICE_NAME -t $BRANCH-$COMMIT_SHORT_SHA --no-deregister --region us-east-1 --timeout 900 --task $SERVICE_NAME; - aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME --region us-east-1; - echo "Environment ${ECS_ENV} is not imp or prod, deployment mark is not recorded to NewRelic..." - fi - else - echo "Environmnet ${ECS_ENV} is not dev/impl/prod, so not building image and deploying to ecs..." - fi - - post_build: - commands: - # Check the build status and set the slack message to reflect pass or fail status - - | - if [ $ECS_ENV = "prod" ]; then - echo "Starting smoke tests for prod" - cd buildspec - aws codebuild start-build --cli-input-json file://start_smoke_tests_prod.json - cd .. - fi - - echo "Code build exit number (1 is success) = $CODEBUILD_BUILD_SUCCEEDING" - - if [ $CODEBUILD_BUILD_SUCCEEDING = 0 ]; then SLACK_COLOR="danger" && BUILD_STATUS="FAILED"; fi - - TEXT_VALUE="Deployment of branch ${BRANCH} to QPP Scoring API service in $ECS_ENV-scoring-ssl-api $BUILD_STATUS" - - curl -X POST --fail --data-urlencode "payload={\"text\":\"Deployment Status\",\"channel\":\"${SLACK_CHANNEL}\",\"username\":\"CodeBuild\",\"icon_url\":\"${CODEBUILD_ICON}\",\"attachments\":[{\"title\":\"${TEXT_VALUE}\",\"color\":\"${SLACK_COLOR}\"}]}" ${SLACK_URL} - - | - if [ "${CODEBUILD_BUILD_SUCCEEDING}" = 1 ]; then - STATE="success" - DESCRIPTION="The build succeeded!" - else - STATE="failure" - DESCRIPTION="The build failed. Click Details for the logs." - fi - - CURL_PAYLOAD=$( jq -n \ - --arg state "$STATE" \ - --arg target_url "https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEvent:group=/aws/codebuild/${ENV}-scoring-api;stream=${CODEBUILD_LOG_PATH}" \ - --arg description "$DESCRIPTION" \ - --arg context "CodeBuild Status" \ - '{state: $state, target_url: $target_url, description: $description, context: $context}' ) - - echo "$CURL_PAYLOAD" - - curl \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer ${SCORING_REPO_PAT}" \ - "${BRANCH_STATUS_URL}/${CODEBUILD_RESOLVED_SOURCE_VERSION}" \ - -d "${CURL_PAYLOAD}" diff --git a/buildspec/pr_build.yaml b/buildspec/pr_build.yaml index 1dcd0e855..4685b96b1 100644 --- a/buildspec/pr_build.yaml +++ b/buildspec/pr_build.yaml @@ -1,3 +1,4 @@ +### Future purpose pr file version: 0.2 env: From 9866e16613b5bf6a64f1dfd369b51f1eaf537d2a Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Fri, 1 Nov 2024 10:50:08 -0500 Subject: [PATCH 13/17] updated error codes as per HCD suggestions --- ERROR_MESSAGES.md | 170 +- .../conversion/DocumentationReference.java | 1 + .../conversion/model/error/ProblemCode.java | 377 ++-- commons/src/main/resources/measures-data.json | 6 +- .../validate/ClinicalDocumentValidator.java | 2 +- .../CommonNumeratorDenominatorValidator.java | 2 +- .../validate/MeasureDataValidator.java | 6 +- .../PcfClinicalDocumentValidator.java | 2 +- .../validate/PcfMeasureDataValidator.java | 5 +- .../PcfQualityMeasureIdValidator.java | 2 +- .../validate/QualityMeasureIdValidator.java | 2 +- .../QualityMeasureIdRoundTripTest.java | 2 +- .../PiNumeratorDenominatorEncoderTest.java | 2 +- .../encode/PiSectionEncoderTest.java | 2 +- .../validate/AciDenominatorValidatorTest.java | 6 +- .../validate/AciNumeratorValidatorTest.java | 4 +- .../ClinicalDocumentValidatorTest.java | 2 +- .../validate/MeasureDataValidatorTest.java | 6 +- .../validate/PcfMeasureDataValidatorTest.java | 4 +- .../PcfQualityMeasureIdValidatorTest.java | 6 +- .../success/PCF-1e-MIPS_INDIV_09182024.xml | 42 +- .../success/PCF-1f-MIPS_GROUP_09182024.xml | 14 +- .../PCF-1g-MIPS_VIRTUALGROUP_09182024.xml | 14 +- ...3a-AdditionalMeasuresReported_09182024.xml | 1882 ----------------- 24 files changed, 335 insertions(+), 2226 deletions(-) diff --git a/ERROR_MESSAGES.md b/ERROR_MESSAGES.md index 07aeedf69..fdf97f395 100644 --- a/ERROR_MESSAGES.md +++ b/ERROR_MESSAGES.md @@ -3,91 +3,91 @@ Current list of all error messages being output by the converter. Any text in the following format `(Example)` are considered variables to be filled in. ### Format - Error Code : Error Message -* 1 : CT - Failed to find an encoder -* 2 : CT - The file is not a valid XML document. The file you are submitting is not a properly formatted XML document. Please check your document to ensure proper formatting. -* 3 : CT - Unexpected exception occurred during conversion. Please contact the Service Center for assistance via phone at 1-866-288-8292 or TTY: 1-877-715-6222, or by emailing QPP@cms.hhs.gov -* 4 : CT - Unexpected exception occurred during encoding. Please contact the Service Center for assistance via phone at 1-866-288-8292 or TTY: 1-877-715-6222, or by emailing QPP@cms.hhs.gov -* 5 : CT - The file is not a QRDA-III XML document. Please ensure that the submission complies with the `(Submission year's)` implementation guide. `(Implementation guide link)` -* 6 : CT - The measure GUID `(Provided measure id)` is invalid. Please see the Table 15 of the `(Submission year's)` Implementation Guide for valid measure GUIDs: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 -* 7 : CT - The measure reference results must have at least one measure. Please review the measures section of your file as it cannot be empty. -* 8 : CT - The `(Parent element)` has `(number of aggregate counts)` aggregate count values. A single aggregate count value is required. -* 9 : CT - Aggregate count value must be an integer -* 11 : CT - This PI Reference and Results is missing a required Measure Performed child -* 12 : CT - This PI Measure Performed Reference and Results requires a single Measure ID -* 13 : CT - Denominator count must be less than or equal to Initial Population count for the measure population `(measure population id)`. Please see the Table 15 of the `(Submission Year)` Implementation guide for valid measure GUIDs: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 1 : CT - The system could not complete the request, please try again. +* 2 : CT - Contact you Health IT vendor to review your file and confirm it's properly formatted as an XML document. +* 3 : CT - There was an unexpected system error during the file conversion. Contact the customer service center for assistance by email at QPP@cms.hhs.gov or by phone at 288-8292 (TTY: 1-877-715-6222) +* 4 : CT - There was an unexpected error during the file encoding. Contact the customer service center for assistance by email at QPP@cms.hhs.gov or by phone at 288-8292 (TTY: 1-877-715-6222) +* 5 : CT - Verify that your file is a QRDA III XML document and that it complies with the `(Submission year's)` implementation guide. `(Implementation guide link)` +* 6 : CT - Verify the measure GUID for `(Provided measure id)` against table 15 of the `(Submission year's)` Implementation Guide for valid measure GUIDs: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 7 : CT - Review the measure section of your file to confirm it contains at least 1 measure. +* 8 : CT - Review `(Parent element)`. It shows `(number of aggregate counts)` but it can only have 1. +* 9 : CT - The aggregate count must be a whole number without decimals. +* 11 : CT - Review this Promoting Interoperability reference for a missing required measure. +* 12 : CT - Review this Promoting Interoperability measure for multiple measure IDs. There can only be 1 measure ID. +* 13 : CT - The denominator count must be less than or equal to the initial population count for the measure population `(measure population id)`. You can check Table 15 of the `(Submission Year)` Implementation guide for valid measure GUIDs: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 * 14 : CT - The electronic measure id: `(Current eMeasure ID)` requires `(Number of Subpopulations required)` `(Type of Subpopulation required)`(s) but there are `(Number of Subpopulations existing)` -* 15 : CT - PI Numerator Denominator element should have a PI Section element as a parent -* 16 : CT - PI Numerator Denominator element does not contain a measure name ID -* 17 : CT - PI Numerator Denominator element does not have any child elements -* 18 : CT - This PI Numerator Denominator element requires exactly one `(Denominator|Numerator)` element child -* 22 : CT - The PI Section must have one Reporting Parameter Act. Please ensure the Reporting Parameters Act complies with the Implementation Guide (IG). Here is a link to the IG Reporting Parameter Act section: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 -* 23 : CT - Clinical Document element must have at least one child element of type PI, IA, or Measure section -* 24 : CT - Clinical Document must have one and only one program name. Valid program names are `(list of valid program names)` -* 25 : CT - The Clinical Document program name `(program name)` is not recognized. Valid program names are `(list of valid program names)`. -* 26 : CT - Clinical Document contains duplicate PI sections -* 27 : CT - Clinical Document contains duplicate IA sections -* 28 : CT - Clinical Document contains duplicate Measure sections -* 29 : CT - Must have one and only one performance period start. Please see the Implementation Guide for information on the performance period here: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 -* 30 : CT - Must have one and only one performance period end. Please see the Implementation Guide for information on the performance period here: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 -* 31 : CT - Must have a performance year. Please see the Implementation Guide for information on the performance period here: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 -* 32 : CT - The Quality Measure Section must have exactly one Reporting Parameter Act. Please ensure the Reporting Parameters Act complies with the Implementation Guide (IG). Here is a link to the IG Reporting Parameter Act section: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 -* 33 : CT - The Performance Rate `(supplied value)` is invalid. It must be a decimal between 0 and 1. -* 34 : CT - PCF submissions must contain a practice site address. Please refer to the `(Submission year's)` IG for more details https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=22 regarding practice site addresses. -* 35 : CT - One and only one Alternative Payment Model (APM) Entity Identifier should be specified. Here is a link to the IG section on identifiers: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=15 -* 36 : CT - PCF submissions must contain one Measure section -* 37 : CT - PCF submissions must contain correct number of performance rate(s). Correct Number is `(Expected value)` for measure `(Given measure id)` -* 39 : CT - This PI `(Numerator or Denominator)` element has an incorrect number of Aggregate Count children. A PI `(Numerator or Denominator)` must have exactly one Aggregate Count element -* 41 : CT - This PI `(Numerator or Denominator)` element Aggregate Value '`(value)`' is not an integer -* 42 : CT - This PI `(Numerator or Denominator)` element Aggregate Value has an invalid value of '`(value)`' -* 43 : CT - The IA Section must have at least one Improvement Activity -* 44 : CT - The IA Section must have one Reporting Parameter Act. Please ensure the Reporting Parameters Act complies with the Implementation Guide (IG). Here is a link to the IG Reporting Parameter Act section: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 -* 45 : CT - The IA Section must contain only Improvement Activities and a Reporting Parameter Act -* 48 : CT - Missing strata `(Reporting Stratum UUID)` for `(Current subpopulation type)` measure `(Current subpopulation UUID)`. Here is a link to the IG valid Measure Ids section: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 -* 49 : CT - Amount of stratifications `(Current number of Reporting Stratifiers)` does not meet expectations `(Number of stratifiers required)` for `(Current subpopulation type)` measure `(Current Subpopulation UUID)`. Expected strata: `(Expected strata uuid list)`. Please refer to the Implementation Guide for correct stratification UUID's here: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 -* 50 : CT - An IA performed measure reference and results must have exactly one measure performed child -* 51 : CT - A single measure performed value is required and must be either a Y or an N. -* 52 : CT - The measure data with population id '`(population id)`' must have exactly one Aggregate Count. Please see the Table 15 of `(Submission year's)` Implementation Guide for valid measure GUIDs: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 -* 53 : CT - Measure data with population id '`(population id)`' must be a whole number greater than or equal to 0. Please see the Table 15 of `(Submission year's)` Implementation Guide for valid measure GUIDs: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 -* 55 : CT - A `(Program name)` Performance period start must be 01/01/2024Please refer to the IG for more information here: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=12 -* 56 : CT - A `(Program name)` Performance period end must be 12/31/2024Please refer to the IG for more information here: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=12 -* 57 : CT - The measure reference results must have a single measure population -* 58 : CT - The measure reference results must have a single measure type -* 59 : CT - The electronic measure id: `(Current eMeasure ID)` requires a `(Subpopulation type)` with the correct UUID of `(Correct uuid required)`. Here is a link to the IG containing all the valid measure ids: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 -* 61 : CT - A Performance Rate must contain a single Numerator UUID reference. -* 62 : CT - The Alternative Payment Model (APM) Entity Identifier must not be empty. Here is a link to the IG section on identifiers: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=15 -* 63 : CT - The Alternative Payment Model (APM) Entity Identifier is not valid. Here is a link to the IG section on identifiers: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=15 -* 66 : CT - Missing the `(Supplemental Type)` - `(Type Qualification)` supplemental data for code `(Supplemental Data Code)` for the measure id `(Measure Id)`'s Sub-population `(Sub Population)` -* 67 : CT - Must have one count for Supplemental Data `(Supplemental Data Code)` on Sub-population `(Sub Population)` for the measure id `(Measure Id)` -* 68 : CT - Your `(Program name)` submission was made after the `(Program name)` Measure section submission deadline of `(Submission end date)`. Your `(Program name)` QRDA III file has not been processed. Please contact `(Program name)` Support at `(PCF+ contact email)` for assistance. -* 69 : CT - `(Performance period start or end date)` is an invalid date format. Please use a standard ISO date format. Example valid values are 2019-02-26, 2019/02/26T01:45:23, or 2019-02-26T01:45:23.123. Please see the Implementation Guide for information on the performance period here: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 -* 70 : CT - The measure section measure reference and results has an incorrect number of measure GUID supplied. Please ensure that only one measure GUID is provided per measure. -* 71 : CT - Two or more different measure section measure reference and results have the same measure GUID. Please ensure that each measure section measure reference and results do not have the same measure GUID. -* 72 : CT - The Performance Rate is missing -* 78 : CT - The Program 'Mips Virtual Group' was found. The required entity id for this program name was missing. Please provide a virtual group identifier with the 'Mips Virtual Group' program name. -* 79 : CT - There is no TIN validator present, so NPI/Alternative Payment Model (APM) combinations cannot be verified -* 80 : CT - NPI `(npi)` and TIN `(tin)` are not reported as expected. This NPI/TIN combination is missing from the QRDA III file or is not in the `(program)` Practitioner Roster for `(apm)`. Please ensure your submission contains all required NPI/TIN combinations and your `(program)` Practitioner Roster is up-to-date. +* 15 : CT - Review the Promoting Interoperability Numerator Denominator element. It must have a parent Promoting Interoperability Section. +* 16 : CT - Review the Promoting Interoperability Numerator Denominator element. It must have a measure name ID +* 17 : CT - Review the Pomoting Interoperability Numerator Denominator element. it must have a child element. +* 18 : CT - This Promoting Interoperability Numerator Denominator element requires exactly one `(Denominator|Numerator)` element child +* 22 : CT - Review the Reporting Parameter Act in the Promoting Interoperability section. It must comply with the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 23 : CT - Review the element "Clinical Document." It must have at least one measure section or a child element of type Promoting Interoperability or Improvement Activities. +* 24 : CT - Review the QRDA III file. It must only have one program name from this list: `(list of valid program names)` +* 25 : CT - Review the Clinical Document for a valid program name from this list: `(list of valid program names)`. `(program name)` is not valid. +* 26 : CT - Review the QRDA III file for duplicate Promoting Interoperability sections. +* 27 : CT - Review the QRDA III file for duplicate Improvement Activity sections. +* 28 : CT - Review the QRDA III file for duplicate measure sections. +* 29 : CT - The file must only have one performance period start. You can find more information on performance periods in the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 30 : CT - The file must only have one performance period end. You can find more information on performance periods in the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 31 : CT - The file must have a performance year. You can find more information on performance periods in the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 32 : CT - The Quality Measure section must only have one Reporting Parameter Act. You can find more information on performance periods in the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 33 : CT - The Performance Rate `(supplied value)` must be a decimal between 0 and 1. +* 34 : CT - PCF submissions must have a practice site address. You canfind more information on the `(Submission year's)` Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=22 +* 35 : CT - Review the file. It must only have one Alternative Payment Model (APM) Entity Identifier. You can find more information in the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=15 +* 36 : CT - Review the file. It must have at least one measure section. +* 37 : CT - Review the performance rate(s) in the file. The number for measure `(Given measure id)` is `(Expected value)` +* 39 : CT - Review the aggregate count children for the Promoting Interoperability `(Numerator or Denominator)` element. It must have exactly one aggregate count element +* 41 : CT - Review the Promoting Interoperability `(Numerator or Denominator)` element's aggregate value. '`(value)`' must be a whole number. +* 42 : CT - Review the Promoting Interoperability `(Numerator or Denominator)` element's aggregate value. '`(value)`' is not valid. +* 43 : CT - The Improvement Activities section must have at least one Improvement Activity +* 44 : CT - The Improvement Activities section must have one Reporting Parameter Act. You can find more information on the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 45 : CT - The Improvement Activities section must only contain Improvement Activities and a Reporting Parameter Act +* 48 : CT - There's missing strata `(Reporting Stratum UUID)` for `(Current subpopulation type)` measure `(Current subpopulation UUID)`. You can find more information on the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 49 : CT - The amount of stratifications `(Current number of Reporting Stratifiers)` does not meet the `(Number of stratifiers required)` required for `(Current subpopulation type)` measure `(Current Subpopulation UUID)`. The strata required is: `(Expected strata uuid list)`. You can find more information on the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 50 : CT - Review your data. An Improvement Activities performed measure reference and results must have exactly one measure performed child. +* 51 : CT - Review your data. The data for a performed measure is required and must be either a Y or an N. +* 52 : CT - The measure data with population id `(population id)` must have exactly one Aggregate Count. You can find more information on GUIDs on the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 53 : CT - The measure data with population id '`(population id)`' must be a whole number greater than or equal to 0. You can find more information on GUIDs on the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 55 : CT - A `(Program name)` performance period must start on 01/01/2024. You can find additional information on the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=12 +* 56 : CT - A `(Program name)` performance period must end on 12/31/2024. You can find additional information on the Implementation Guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=12 +* 57 : CT - The reference results for the measure must have a single measure population +* 58 : CT - The reference results for the measure must have a single measure type +* 59 : CT - The electronic measure id: `(Current eMeasure ID)` requires a `(Subpopulation type)` with the correct UUID of `(Correct uuid required)`. You can find additional information on the implementation guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 61 : CT - Review your data. A performance rate must contain a single numerator UUID reference. +* 62 : CT - Review your data. The Alternative Payment Model (APM) Entity Identifier must not be empty. You can find additional information on the implementation guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=15 +* 63 : CT - Review the Alternative Payment Model (APM) Entity Identifier. You can find additional information on the implementation guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=15 +* 66 : CT - There's missing data. Enter the `(Supplemental Type)` - `(Type Qualification)` supplemental data for code `(Supplemental Data Code)` for the Sub-population `(Sub Population)` of measure id `(Measure Id)`. +* 67 : CT - Review measure id `(Measure Id)`. It must have one count for Supplemental Data `(Supplemental Data Code)` on Sub-population `(Sub Population)`. +* 68 : CT - Your submission for `(Program name)` was made after the submission deadline of `(Submission end date)` for `(Program name)` measure section. Your `(Program name)` QRDA III file has not been processed. Please contact `(Program name)` Support at `(PCF+ contact email)` for assistance. +* 69 : CT - Review the `(Performance period start or end date)` format. Valid date formats are 2024-02-26, 2024/02/26T01:45:23, or 2024-02-26T01:45:23.123. You cn find more information on the implementation guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 70 : CT - Review the measure GUID for measure section, measure reference, and results. There must only be one GUID per measure. Refer to page 36 of the implementation guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=36 +* 71 : CT - Review the file for duplicate GUIDs. Each measure section, measure reference, and results must have its own GUID. +* 72 : CT - Contact your Health IT vendor. The QRDA III file is missing a performance rate. Performance rate is required for PCF reporting. You can find more information on page 17 of the implementation guide: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=17 +* 78 : CT - Enter an entity ID for the program 'MIPS Virtual Group'. +* 79 : CT - Enter a TIN number to verify the NPI/Alternative Payment Model (APM) combinations. +* 80 : CT - Review NPI `(npi)` and TIN `(tin)`. This NPI/TIN combination is missing from the QRDA III file or is not in the `(program)` practitioner roster for `(apm)`. Ensure your submission contains all required NPI/TIN combinations and your `(program)` practitioner roster is up-to-date. * 81 : CT - At least one measure is required in a measure section -* 82 : CT - There are too many errors associated with this QRDA-III file. Showing 100 out of `(Error amount)` errors. Please fix the given errors and re-submit -* 84 : CT - `(Program name)` QRDA-III Submissions require at least one TIN to be present. -* 85 : CT - `(Program name)` QRDA-III Submission TINs require a 9 digit numerical value -* 86 : CT - This `(Program name)` QRDA-III submission is missing a TIN. Please ensure there is a TIN associated with every NPI submitted -* 87 : CT - `(Program name)` QRDA-III Submissions require at least one NPI to be present -* 88 : CT - `(Program name)` QRDA-III Submission NPIs require a 10 digit numerical value -* 89 : CT - This `(Program name)` QRDA-III submission is missing a NPI. Please ensure there is an NPI associated with every TIN submitted -* 90 : CT - `(Program name)` QRDA-III submissions should not contain an IA section. IA data will be ignored. -* 91 : CT - The performance rate `(performanceRateUuid)` for measure `(measure id)` has an invalid null value. A performance rate cannot be null unless the performance denominator is 0 -* 92 : CT - The performance denominator for measure `(measureId)` was less than 0. A performance rate cannot be null unless the performance denominator is 0 -* 93 : CT - The numerator id `(numeratorUuid)` for measure `(measure id)` has a count value that is greater than the denominator and/or the performance denominator (Denominator count - Denominator exclusion count - Denominator Exception count) -* 94 : CT - The denominator exclusion id `(denexUuid)` for measure `(measure id)` has a count value that is greater than the denominator. The Denominator exclusion cannot be a greater value than the denominator. -* 95 : CT - The Clinical Document must contain one Category Section v5 with the extension 2020-12-01 +* 82 : CT - This QRDA III file shows 100 out of `(Error amount)` errors. Correct and re-submit the file. +* 84 : CT - `(Program name)` QRDA-III Submissions require at least one TIN number. +* 85 : CT - `(Program name)` QRDA-III Submission TINs must be 9 numbers long. +* 86 : CT - The QRDA-III submission for `(Program name)` is missing a TIN. Ensure there is a TIN associated with every NPI submitted. +* 87 : CT - The QRDA-III submission for `(Program name)` must have at least one NPI number. +* 88 : CT - The NPIs for `(Program name)`'s QRDA-III submission must be 10 numbers long. +* 89 : CT - The QRDA-III submission for `(Program name)` is missing an NPI. Ensure there is an NPI associated with every TIN submitted. +* 90 : CT - The QRDA-III submission for `(Program name)` should not contain an Improvement Activities section. The Improvement Activities data will be ignored. +* 91 : CT - Review the performance rate `(performanceRateUuid)` for measure `(measure id)`. A performance rate cannot be null unless the performance denominator is 0 +* 92 : CT - Review the performance denominator for measure `(measureId)`. A performance rate cannot be null unless the performance denominator is 0. +* 93 : CT - Review numerator ID `(numeratorUuid)` for measure `(measure id)`. It has a count value that is greater than the denominator and/or the performance denominator (Denominator count - Denominator exclusion count - Denominator Exception count) +* 94 : CT - Review the denominator exclusion id `(denexUuid)` for measure `(measure id)`. It cannot have a greater value than the denominator. +* 95 : CT - The QRDA III file must contain one Category Section v5 with the extension 2020-12-01 * 96 : CT - The APM to TIN/NPI Combination file is missing. -* 97 : CT - `(Program name)` QRDA-III Submissions require a valid CMS EHR Certification ID (Valid Formats: XX15CXXXXXXXXXX) -* 98 : CT - The performance rate cannot have a value of 0 and must be of value Null Attribute (NA). -* 100 : CT - More than one CMS EHR Certification ID was found. Please submit with only one CMS EHR Certification id. -* 101 : CT - Denominator count must be equal to Initial Population count for `(Program name)` measure population `(measure population id)`.Please see the Table 15 of `(Submission year's)` Implementation Guide for valid measure GUIDs: https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 -* 102 : CT - A PI section cannot contain PI_HIE_5 with PI_HIE_1, PI_LVOTC_1, PI_HIE_4, or PI_LVITC_2 -* 103 : CT - PCF Submissions must have the `(PCF Measure minimum)` following measures: `(Listing of valid measure ids)` -* 105 : CT - If multiple TINs/NPIs are submitted, each must be reported within a separate performer -* 106 : CT - PI submissions are not allowed within PCF -* 107 : CT - NPI/TIN Warning: Missing NPI/TIN Combination Identified. NPI/TIN `(npi)`-`(tin)` was active on the PCF practitioner roster for `(apm)` during the performance year but was not found in the file. Please ensure your submission contains all NPI/TIN combinations that were active on your roster at any point during the performance year. Your QRDA III file and/or roster may require updates. Note: The QPP website does not have access to roster updates made after December 1, 2024. It is therefore critical that you ensure your roster is up to date and your QRDA III file contains all NPI/TIN values that were active on your roster during the performance year. Please contact your health IT vendor if your QRDA III file requires updates. Instructions on how to update your roster are available in the PCF Practice Management Guide (https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y). -* 108 : CT - NPI/TIN Warning: Unexpected NPI/TIN Combination Found. NPI/TIN `(npi)`-`(tin)` was reported in the file but does not exist at the practice or was not active on the PCF practitioner roster for `(apm)` during the performance year. Please ensure your submission only contains NPI/TIN combinations that were active on your roster at any point during the performance year. Your QRDA III file and/or roster may require updates. Note: The QPP website does not have access to roster updates made after December 1, 2024. It is therefore critical that you ensure your roster is up to date and your QRDA III file contains all NPI/TIN values that were active on your roster during the performance year. Please contact your health IT vendor if your QRDA III file requires updates. Instructions on how to update your roster are available in the PCF Practice Management Guide (https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y). +* 97 : CT - The QRDA-III submissions for `(Program name)` must have a valid CMS EHR Certification ID (Valid Formats: XX15CXXXXXXXXXX) +* 98 : CT - Review the performance rate. It must be of value Null Attribute (NA), not 0. +* 100 : CT - Found more than one CMS EHR Certification ID in your file. The submission must have only one CMS EHR Certification ID. +* 101 : CT - The measure population `(measure population id)` for `(Program name)` needs the Denominator count to be equal to Initial population count. You can find additional information on table 15 of the implementation guide:https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page=43 +* 102 : CT - The Promoting Interoperability section cannot contain PI_HIE_5 with PI_HIE_1, PI_LVOTC_1, PI_HIE_4, or PI_LVITC_2 +* 103 : CT - The PCF submissions must have the `(PCF Measure minimum)` following measures: `(Listing of valid measure ids)` +* 105 : CT - If multiple TINs/NPIs are submitted, each must be reported within a separate performer. +* 106 : CT - Promoting Interoperability data should not be reported in a PCF QRDA III file. +* 107 : CT - There's missing NPI/TIN combination. The NPI/TIN `(npi)`-`(tin)` was active on the PCF practitioner roster for `(apm)` during the performance year but was not found in the file. Ensure your submission contains all NPI/TIN combinations that were active on your roster at any point during the performance year. Your QRDA III file and/or roster may require updates. The QPP website doesn't have access to roster updates made after December 1, 2024. It's critical to ensure your roster is up to date and your QRDA III file contains all NPI/TIN values that were active on your roster during the performance year. Contact your health IT vendor if your QRDA III file requires updates. You can find instructions on updating rosters in the PCF Practice Management Guide: (https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y). +* 108 : CT - Found an unexpected NPI/TIN combination. The NPI/TIN `(npi)`-`(tin)` was reported in the file but does not exist at the practice or was not active on the PCF practitioner roster for `(apm)` during the performance year. Ensure your submission only contains NPI/TIN combinations that were active on your roster at any point during the performance year. Your QRDA III file and/or roster may require updates. Note: The QPP website does not have access to roster updates made after December 1, 2024. It's critical that you ensure your roster is up to date and your QRDA III file contains all NPI/TIN values that were active on your roster during the performance year. Please contact your health IT vendor if your QRDA III file requires updates. You can find instructions on how updating rosters in the PCF Practice Management Guide (https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y). diff --git a/commons/src/main/java/gov/cms/qpp/conversion/DocumentationReference.java b/commons/src/main/java/gov/cms/qpp/conversion/DocumentationReference.java index 89b0cab04..4642a85c0 100644 --- a/commons/src/main/java/gov/cms/qpp/conversion/DocumentationReference.java +++ b/commons/src/main/java/gov/cms/qpp/conversion/DocumentationReference.java @@ -9,6 +9,7 @@ public enum DocumentationReference { PRACTICE_SITE_ADDRESS(22), REPORTING_PARAMETERS_ACT(17), MEASURE_IDS(43), + MEASURE_REFERENCE(36), CEHRT(22); private static final String BASE_PATH = "https://ecqi.healthit.gov/sites/default/files/2024-CMS-QRDA-III-EC-IG-v1.1-508.pdf#page="; diff --git a/commons/src/main/java/gov/cms/qpp/conversion/model/error/ProblemCode.java b/commons/src/main/java/gov/cms/qpp/conversion/model/error/ProblemCode.java index d2e3ca3e8..ded847f30 100644 --- a/commons/src/main/java/gov/cms/qpp/conversion/model/error/ProblemCode.java +++ b/commons/src/main/java/gov/cms/qpp/conversion/model/error/ProblemCode.java @@ -20,200 +20,191 @@ */ public enum ProblemCode implements LocalizedProblem { - ENCODER_MISSING(1, "Failed to find an encoder"), - NOT_VALID_XML_DOCUMENT(2, "The file is not a valid XML document. The file you are submitting is not a " - + "properly formatted XML document. Please check your document to ensure proper formatting."), - UNEXPECTED_ERROR(3, "Unexpected exception occurred during conversion. " + ServiceCenter.MESSAGE), - UNEXPECTED_ENCODE_ERROR(4, "Unexpected exception occurred during encoding. " + ServiceCenter.MESSAGE), - NOT_VALID_QRDA_DOCUMENT(5, "The file is not a QRDA-III XML document. " - + "Please ensure that the submission complies with the `(Submission year's)` implementation guide. " - + "`(Implementation guide link)`", true), - MEASURE_GUID_MISSING(6, "The measure GUID `(Provided measure id)` is invalid. " - + "Please see the Table 15 of the `(Submission year's)` Implementation Guide for valid measure GUIDs: " - + DocumentationReference.MEASURE_IDS, true), - CHILD_MEASURE_MISSING(7, "The measure reference results must have at least one measure. " - + "Please review the measures section of your file as it cannot be empty."), - AGGREGATE_COUNT_VALUE_NOT_SINGULAR(8, "The `(Parent element)` has `(number of aggregate counts)` aggregate count values." - + " A single aggregate count value is required.", true), - AGGREGATE_COUNT_VALUE_NOT_INTEGER(9, "Aggregate count value must be an integer"), - PI_MEASURE_PERFORMED_RNR_MEASURE_PERFORMED_EXACT(11, "This PI Reference and Results is missing a required " - + "Measure Performed child"), - PI_MEASURE_PERFORMED_RNR_MEASURE_ID_NOT_SINGULAR(12, "This PI Measure Performed Reference and Results requires " - + "a single Measure ID"), - DENOMINATOR_COUNT_INVALID(13, "Denominator count must be less than or equal to Initial Population count " - + "for the measure population `(measure population id)`. Please see the Table 15 of the `(Submission Year)` Implementation guide for valid measure GUIDs: " - + DocumentationReference.MEASURE_IDS, true), - POPULATION_CRITERIA_COUNT_INCORRECT(14, - "The electronic measure id: `(Current eMeasure ID)` requires `(Number of Subpopulations required)` " - + "`(Type of Subpopulation required)`(s) but there are `(Number of Subpopulations existing)`", true), - PI_NUMERATOR_DENOMINATOR_PARENT_NOT_PI_SECTION(15, "PI Numerator Denominator element should have a PI " - + "Section element as a parent"), - PI_NUMERATOR_DENOMINATOR_MISSING_MEASURE_ID(16, "PI Numerator Denominator element does not contain a " - + "measure name ID"), - PI_NUMERATOR_DENOMINATOR_MISSING_CHILDREN(17, "PI Numerator Denominator element does not have any child " - + "elements"), - PI_NUMERATOR_DENOMINATOR_VALIDATOR_EXACTLY_ONE_NUMERATOR_OR_DENOMINATOR_CHILD_NODE(18, "This PI Numerator Denominator " - + "element requires exactly one `(Denominator|Numerator)` element child", true), - PI_SECTION_MISSING_REPORTING_PARAMETER_ACT(22, "The PI Section must have one Reporting Parameter Act." - + " Please ensure the Reporting Parameters Act complies with the Implementation Guide (IG)." - + " Here is a link to the IG Reporting Parameter Act section: " + DocumentationReference.REPORTING_PARAMETERS_ACT), - CLINICAL_DOCUMENT_MISSING_PI_OR_IA_OR_ECQM_CHILD(23, "Clinical Document element must have at least one child " - + "element of type PI, IA, or Measure section"), - CLINICAL_DOCUMENT_MISSING_PROGRAM_NAME(24, "Clinical Document must have one and only one program name." - + " Valid program names are `(list of valid program names)`", true), - CLINICAL_DOCUMENT_INCORRECT_PROGRAM_NAME(25, "The Clinical Document program name `(program name)` is not recognized. Valid " - + "program names are `(list of valid program names)`.", true), - CLINICAL_DOCUMENT_CONTAINS_DUPLICATE_PI_SECTIONS(26, "Clinical Document contains duplicate PI sections"), - CLINICAL_DOCUMENT_CONTAINS_DUPLICATE_IA_SECTIONS(27, "Clinical Document contains duplicate IA sections"), - CLINICAL_DOCUMENT_CONTAINS_DUPLICATE_ECQM_SECTIONS(28, "Clinical Document contains duplicate Measure " - + "sections"), - REPORTING_PARAMETERS_MUST_CONTAIN_SINGLE_PERFORMANCE_START(29, "Must have one and only one performance period " - + "start. Please see the Implementation Guide for information on the performance period here: " //NOSONAR - + DocumentationReference.PERFORMANCE_PERIOD), - REPORTING_PARAMETERS_MUST_CONTAIN_SINGLE_PERFORMANCE_END(30, "Must have one and only one performance period end. " - + "Please see the Implementation Guide for information on the performance period here: " //NOSONAR - + DocumentationReference.PERFORMANCE_PERIOD), - REPORTING_PARAMETERS_MISSING_PERFORMANCE_YEAR(31, "Must have a performance year. " - + "Please see the Implementation Guide for information on the performance period here: " //NOSONAR - + DocumentationReference.PERFORMANCE_PERIOD), - QUALITY_MEASURE_SECTION_REQUIRED_REPORTING_PARAM_REQUIREMENT(32, "The Quality Measure Section must have " - + "exactly one Reporting Parameter Act. " - + "Please ensure the Reporting Parameters Act complies with the Implementation Guide (IG). " - + "Here is a link to the IG Reporting Parameter Act section: " + DocumentationReference.REPORTING_PARAMETERS_ACT), - PERFORMANCE_RATE_INVALID_VALUE(33, "The Performance Rate `(supplied value)` is invalid. " - + "It must be a decimal between 0 and 1.", true), - PCF_CLINICAL_DOCUMENT_MISSING_PRACTICE_SITE_ADDRESS(34, "PCF submissions must contain a practice site address." - + " Please refer to the `(Submission year's)` IG for more details " + DocumentationReference.PRACTICE_SITE_ADDRESS - + " regarding practice site addresses.", true), - PCF_CLINICAL_DOCUMENT_ONLY_ONE_APM_ALLOWED(35, "One and only one Alternative Payment Model (APM) Entity " - + "Identifier should be specified. Here is a link to the IG section on identifiers: " + DocumentationReference.IDENTIFIERS), - PCF_CLINICAL_DOCUMENT_ONE_MEASURE_SECTION_REQUIRED(36, "PCF submissions must contain one Measure section"), - PCF_QUALITY_MEASURE_ID_INVALID_PERFORMANCE_RATE_COUNT(37, "PCF submissions must contain correct number of performance rate(s). " - + "Correct Number is `(Expected value)` for measure `(Given measure id)`", true), - NUMERATOR_DENOMINATOR_CHILD_EXACT(39, - "This PI `(Numerator or Denominator)` element has an incorrect number of Aggregate Count children. A PI " - + "`(Numerator or Denominator)` must have exactly one Aggregate Count element", true), - NUMERATOR_DENOMINATOR_MUST_BE_INTEGER(41, - "This PI `(Numerator or Denominator)` element Aggregate Value '`(value)`' is not an integer", true), - NUMERATOR_DENOMINATOR_INVALID_VALUE(42, - "This PI `(Numerator or Denominator)` element Aggregate Value has an invalid value of '`(value)`'", true), - IA_SECTION_MISSING_IA_MEASURE(43, "The IA Section must have at least one Improvement Activity"), - IA_SECTION_MISSING_REPORTING_PARAM(44, "The IA Section must have one Reporting Parameter Act. " - + "Please ensure the Reporting Parameters Act complies with the Implementation Guide (IG). " - + "Here is a link to the IG Reporting Parameter Act section: " + DocumentationReference.REPORTING_PARAMETERS_ACT), - IA_SECTION_WRONG_CHILD(45, "The IA Section must contain only Improvement Activities and a Reporting Parameter Act"), - PCF_QUALITY_MEASURE_ID_MISSING_STRATA(48, "Missing strata `(Reporting Stratum UUID)` for " - + "`(Current subpopulation type)` measure `(Current subpopulation UUID)`. " - + "Here is a link to the IG valid Measure Ids section: " + DocumentationReference.MEASURE_IDS, true), - PCF_QUALITY_MEASURE_ID_STRATA_MISMATCH(49,"Amount of stratifications `(Current number of " - + "Reporting Stratifiers)` does not meet expectations " - + "`(Number of stratifiers required)` for `(Current subpopulation type)` measure " - + "`(Current Subpopulation UUID)`. Expected strata: `(Expected strata uuid list)`. " - + "Please refer to the Implementation Guide for correct stratification UUID's here: " - + DocumentationReference.MEASURE_IDS, true), - IA_MEASURE_INCORRECT_CHILDREN_COUNT(50, "An IA performed measure reference and results must " - + "have exactly one measure performed child"), - IA_MEASURE_INVALID_TYPE(51, "A single measure performed value is required and must be either a Y or an N."), - MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT(52, - " The measure data with population id '`(population id)`' must have exactly one Aggregate Count. " - + "Please see the Table 15 of `(Submission year's)` Implementation Guide for valid measure GUIDs: " //NOSONAR - + DocumentationReference.MEASURE_IDS, true), - MEASURE_DATA_VALUE_NOT_INTEGER(53, "Measure data with population id '`(population id)`' " - + "must be a whole number greater than or equal to 0. " - + "Please see the Table 15 of `(Submission year's)` Implementation Guide for valid measure GUIDs: " //NOSONAR - + DocumentationReference.MEASURE_IDS, true), - PCF_PERFORMANCE_PERIOD_START(55, "A `(Program name)` Performance period start must be " + DocumentationReference.PERFORMANCE_START_DATE - + "Please refer to the IG for more information here: " + DocumentationReference.PCF_SUBMISSIONS, true), - PCF_PERFORMANCE_PERIOD_END(56, "A `(Program name)` Performance period end must be " + DocumentationReference.PERFORMANCE_END_DATE - + "Please refer to the IG for more information here: " + DocumentationReference.PCF_SUBMISSIONS, true), - QUALITY_MEASURE_ID_MISSING_SINGLE_MEASURE_POPULATION(57, "The measure reference results must have a single " - + "measure population"), - QUALITY_MEASURE_ID_MISSING_SINGLE_MEASURE_TYPE(58, "The measure reference results must have a single " - + "measure type"), - QUALITY_MEASURE_ID_INCORRECT_UUID(59, "The electronic measure id: `(Current eMeasure ID)` requires a " - + "`(Subpopulation type)` with the correct UUID of `(Correct uuid required)`. Here is a link to the IG " - + "containing all the valid measure ids: " + DocumentationReference.MEASURE_IDS, true), - QUALITY_MEASURE_ID_MISSING_SINGLE_PERFORMANCE_RATE(61, "A Performance Rate must contain a single " - + "Numerator UUID reference."), - PCF_CLINICAL_DOCUMENT_EMPTY_APM(62, "The Alternative Payment Model (APM) Entity Identifier must not be empty. " - + "Here is a link to the IG section on identifiers: " + DocumentationReference.IDENTIFIERS), - PCF_CLINICAL_DOCUMENT_INVALID_APM(63, "The Alternative Payment Model (APM) Entity Identifier is not valid. " - + " Here is a link to the IG section on identifiers: " + DocumentationReference.IDENTIFIERS), - PCF_MISSING_SUPPLEMENTAL_CODE(66, "Missing the `(Supplemental Type)` - `(Type Qualification)` supplemental data for code " - + "`(Supplemental Data Code)` for the measure id `(Measure Id)`'s Sub-population `(Sub Population)`", true), - PCF_SUPPLEMENTAL_DATA_MISSING_COUNT(67, "Must have one count for Supplemental Data `(Supplemental Data Code)` " - + "on Sub-population `(Sub Population)` for the measure id `(Measure Id)`", true), - PCF_SUBMISSION_ENDED(68, "Your `(Program name)` submission was made after the `(Program name)` Measure section submission deadline of " - + "`(Submission end date)`. Your `(Program name)` QRDA III file has not been processed. Please contact `(Program name)` Support at " - + "`(PCF+ contact email)` for assistance.", true), - INVALID_PERFORMANCE_PERIOD_FORMAT(69, "`(Performance period start or end date)` is an invalid date format. " - + "Please use a standard ISO date format. " - + "Example valid values are 2019-02-26, 2019/02/26T01:45:23, or 2019-02-26T01:45:23.123. " - + "Please see the Implementation Guide for information on the performance period here: " - + DocumentationReference.PERFORMANCE_PERIOD, true), - MISSING_OR_DUPLICATED_MEASURE_GUID(70, "The measure section measure reference and results has an incorrect number of " - + "measure GUID supplied. Please ensure that only one measure GUID is provided per measure."), - MEASURES_RNR_WITH_DUPLICATED_MEASURE_GUID(71, "Two or more different measure section measure reference and results have " - + "the same measure GUID. Please ensure that each measure section measure reference and results do not have " - + "the same measure GUID."), - PERFORMANCE_RATE_MISSING(72, "The Performance Rate is missing"), - VIRTUAL_GROUP_ID_REQUIRED(78, "The Program 'Mips Virtual Group' was found. The required entity id for this " - + "program name was missing. Please provide a virtual group identifier with the 'Mips Virtual Group' program name."), - MISSING_PII_VALIDATOR(79, "There is no TIN validator present, so NPI/Alternative Payment Model (APM) " - + "combinations cannot be verified"), - INCORRECT_API_NPI_COMBINATION(80, "NPI `(npi)` and TIN `(tin)` are not reported as expected. " - + "This NPI/TIN combination is missing from the QRDA III file or is not in the `(program)` Practitioner Roster for `(apm)`." - + " Please ensure your submission contains all required NPI/TIN combinations and your `(program)` Practitioner Roster is up-to-date.", true), + ENCODER_MISSING(1, "The system could not complete the request, please try again."), + NOT_VALID_XML_DOCUMENT(2, "Contact you Health IT vendor to review your file and confirm " + + "it's properly formatted as an XML document."), + UNEXPECTED_ERROR(3, "There was an unexpected system error during the file conversion. " + ServiceCenter.MESSAGE), + UNEXPECTED_ENCODE_ERROR(4, "There was an unexpected error during the file encoding. " + ServiceCenter.MESSAGE), + NOT_VALID_QRDA_DOCUMENT(5, "Verify that your file is a QRDA III XML document and that it " + + "complies with the `(Submission year's)` implementation guide. `(Implementation guide link)`", true), + MEASURE_GUID_MISSING(6, "Verify the measure GUID for `(Provided measure id)` against table 15 of the " + + "`(Submission year's)` Implementation Guide for valid measure GUIDs: " + DocumentationReference.MEASURE_IDS, true), + CHILD_MEASURE_MISSING(7, "Review the measure section of your file to confirm it contains at least 1 measure. "), + AGGREGATE_COUNT_VALUE_NOT_SINGULAR(8, "Review `(Parent element)`. It shows " + + "`(number of aggregate counts)` but it can only have 1.", true), + AGGREGATE_COUNT_VALUE_NOT_INTEGER(9, "The aggregate count must be a whole number without decimals."), + PI_MEASURE_PERFORMED_RNR_MEASURE_PERFORMED_EXACT(11, "Review this Promoting Interoperability reference " + + "for a missing required measure."), + PI_MEASURE_PERFORMED_RNR_MEASURE_ID_NOT_SINGULAR(12, "Review this Promoting Interoperability measure for " + + "multiple measure IDs. There can only be 1 measure ID."), + DENOMINATOR_COUNT_INVALID(13, "The denominator count must be less than or equal to the initial population " + + "count for the measure population `(measure population id)`. You can check Table 15 of the " + + "`(Submission Year)` Implementation guide for valid measure GUIDs: " + DocumentationReference.MEASURE_IDS, true), + POPULATION_CRITERIA_COUNT_INCORRECT(14, "The electronic measure id: `(Current eMeasure ID)` " + + "requires `(Number of Subpopulations required)` `(Type of Subpopulation required)`(s) but " + + "there are `(Number of Subpopulations existing)`", true), + PI_NUMERATOR_DENOMINATOR_PARENT_NOT_PI_SECTION(15, "Review the Promoting Interoperability " + + "Numerator Denominator element. It must have a parent Promoting Interoperability Section."), + PI_NUMERATOR_DENOMINATOR_MISSING_MEASURE_ID(16, "Review the Promoting Interoperability " + + "Numerator Denominator element. It must have a measure name ID"), + PI_NUMERATOR_DENOMINATOR_MISSING_CHILDREN(17, "Review the Pomoting Interoperability " + + "Numerator Denominator element. it must have a child element."), + PI_NUMERATOR_DENOMINATOR_VALIDATOR_EXACTLY_ONE_NUMERATOR_OR_DENOMINATOR_CHILD_NODE(18, "This Promoting " + + "Interoperability Numerator Denominator element requires exactly one `(Denominator|Numerator)` element child", true), + PI_SECTION_MISSING_REPORTING_PARAMETER_ACT(22, "Review the Reporting Parameter Act in the " + + "Promoting Interoperability section. It must comply with the Implementation Guide: " + DocumentationReference.REPORTING_PARAMETERS_ACT), + CLINICAL_DOCUMENT_MISSING_PI_OR_IA_OR_ECQM_CHILD(23, "Review the element \"Clinical Document.\" It must have " + + "at least one measure section or a child element of type Promoting Interoperability or Improvement Activities."), + CLINICAL_DOCUMENT_MISSING_PROGRAM_NAME(24, "Review the QRDA III file. It must only have " + + "one program name from this list: `(list of valid program names)`", true), + CLINICAL_DOCUMENT_INCORRECT_PROGRAM_NAME(25, "Review the Clinical Document for a valid program name " + + "from this list: `(list of valid program names)`. `(program name)` is not valid.", true), + CLINICAL_DOCUMENT_CONTAINS_DUPLICATE_PI_SECTIONS(26, "Review the QRDA III file " + + "for duplicate Promoting Interoperability sections."), + CLINICAL_DOCUMENT_CONTAINS_DUPLICATE_IA_SECTIONS(27, "Review the QRDA III file " + + "for duplicate Improvement Activity sections."), + CLINICAL_DOCUMENT_CONTAINS_DUPLICATE_ECQM_SECTIONS(28, "Review the QRDA III file " + + "for duplicate measure sections."), + REPORTING_PARAMETERS_MUST_CONTAIN_SINGLE_PERFORMANCE_START(29, "The file must only have one performance period start. " + + "You can find more information on performance periods in the Implementation Guide: " + DocumentationReference.PERFORMANCE_PERIOD), //NOSONAR + REPORTING_PARAMETERS_MUST_CONTAIN_SINGLE_PERFORMANCE_END(30, "The file must only have one performance period end. " + + "You can find more information on performance periods in the Implementation Guide: " + DocumentationReference.PERFORMANCE_PERIOD), //NOSONAR + REPORTING_PARAMETERS_MISSING_PERFORMANCE_YEAR(31, "The file must have a performance year. " + + "You can find more information on performance periods in the Implementation Guide: " + DocumentationReference.PERFORMANCE_PERIOD), //NOSONAR + QUALITY_MEASURE_SECTION_REQUIRED_REPORTING_PARAM_REQUIREMENT(32, "The Quality Measure section must only have one Reporting Parameter Act. " + + "You can find more information on performance periods in the Implementation Guide: " + DocumentationReference.PERFORMANCE_PERIOD), //NOSONAR + PERFORMANCE_RATE_INVALID_VALUE(33, "The Performance Rate `(supplied value)` must be a decimal between 0 and 1.", true), + PCF_CLINICAL_DOCUMENT_MISSING_PRACTICE_SITE_ADDRESS(34, "PCF submissions must have a practice site address. You can" + + "find more information on the `(Submission year's)` Implementation Guide: " + DocumentationReference.PRACTICE_SITE_ADDRESS, true), + PCF_CLINICAL_DOCUMENT_ONLY_ONE_APM_ALLOWED(35, "Review the file. It must only have one Alternative Payment Model (APM) " + + "Entity Identifier. You can find more information in the Implementation Guide: " + DocumentationReference.IDENTIFIERS), + PCF_CLINICAL_DOCUMENT_ONE_MEASURE_SECTION_REQUIRED(36, "Review the file. It must have at least one measure section."), + PCF_QUALITY_MEASURE_ID_INVALID_PERFORMANCE_RATE_COUNT(37, "Review the performance rate(s) in the file. " + + "The number for measure `(Given measure id)` is `(Expected value)`", true), + NUMERATOR_DENOMINATOR_CHILD_EXACT(39, "Review the aggregate count children for the Promoting Interoperability " + + "`(Numerator or Denominator)` element. It must have exactly one aggregate count element", true), + NUMERATOR_DENOMINATOR_MUST_BE_INTEGER(41, "Review the Promoting Interoperability `(Numerator or Denominator)` " + + "element's aggregate value. '`(value)`' must be a whole number.", true), + NUMERATOR_DENOMINATOR_INVALID_VALUE(42, "Review the Promoting Interoperability `(Numerator or Denominator)` " + + "element's aggregate value. '`(value)`' is not valid.", true), + IA_SECTION_MISSING_IA_MEASURE(43, "The Improvement Activities section must have at least one Improvement Activity"), + IA_SECTION_MISSING_REPORTING_PARAM(44, "The Improvement Activities section must have one Reporting Parameter Act. " + + "You can find more information on the Implementation Guide: " + DocumentationReference.REPORTING_PARAMETERS_ACT), + IA_SECTION_WRONG_CHILD(45, "The Improvement Activities section must only contain " + + "Improvement Activities and a Reporting Parameter Act"), + PCF_QUALITY_MEASURE_ID_MISSING_STRATA(48, "There's missing strata `(Reporting Stratum UUID)` for " + + "`(Current subpopulation type)` measure `(Current subpopulation UUID)`. You can find more information " + + "on the Implementation Guide: " + DocumentationReference.MEASURE_IDS, true), + PCF_QUALITY_MEASURE_ID_STRATA_MISMATCH(49, "The amount of stratifications " + + "`(Current number of Reporting Stratifiers)` does not meet the `(Number of stratifiers required)` " + + "required for `(Current subpopulation type)` measure `(Current Subpopulation UUID)`. " + + "The strata required is: `(Expected strata uuid list)`. You can find more information " + + "on the Implementation Guide: " + DocumentationReference.MEASURE_IDS, true), + IA_MEASURE_INCORRECT_CHILDREN_COUNT(50, "Review your data. An Improvement Activities performed " + + "measure reference and results must have exactly one measure performed child."), + IA_MEASURE_INVALID_TYPE(51, "Review your data. The data for a performed measure is required and must be either a Y or an N."), + MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT(52, "The measure data with population id `(population id)` must have exactly one " + + "Aggregate Count. You can find more information on GUIDs on the Implementation Guide: " + DocumentationReference.MEASURE_IDS, true), + MEASURE_DATA_VALUE_NOT_INTEGER(53, "The measure data with population id '`(population id)`' must be a whole number greater than " + + "or equal to 0. You can find more information on GUIDs on the Implementation Guide: " + DocumentationReference.MEASURE_IDS, true), + PCF_PERFORMANCE_PERIOD_START(55, "A `(Program name)` performance period must start on " + DocumentationReference.PERFORMANCE_START_DATE + + ". You can find additional information on the Implementation Guide: " + DocumentationReference.PCF_SUBMISSIONS, true), + PCF_PERFORMANCE_PERIOD_END(56, "A `(Program name)` performance period must end on " + DocumentationReference.PERFORMANCE_END_DATE + + ". You can find additional information on the Implementation Guide: " + DocumentationReference.PCF_SUBMISSIONS, true), + QUALITY_MEASURE_ID_MISSING_SINGLE_MEASURE_POPULATION(57, "The reference results for the measure must have a " + + "single measure population"), + QUALITY_MEASURE_ID_MISSING_SINGLE_MEASURE_TYPE(58, "The reference results for the measure must have " + + "a single measure type"), + QUALITY_MEASURE_ID_INCORRECT_UUID(59, "The electronic measure id: `(Current eMeasure ID)` requires " + + "a `(Subpopulation type)` with the correct UUID of `(Correct uuid required)`. You can find additional " + + "information on the implementation guide: " + DocumentationReference.MEASURE_IDS, true), + QUALITY_MEASURE_ID_MISSING_SINGLE_PERFORMANCE_RATE(61, "Review your data. A performance rate must " + + "contain a single numerator UUID reference."), + PCF_CLINICAL_DOCUMENT_EMPTY_APM(62, "Review your data. The Alternative Payment Model (APM) Entity Identifier must " + + "not be empty. You can find additional information on the implementation guide: " + DocumentationReference.IDENTIFIERS), + PCF_CLINICAL_DOCUMENT_INVALID_APM(63, "Review the Alternative Payment Model (APM) Entity Identifier. You " + + "can find additional information on the implementation guide: " + DocumentationReference.IDENTIFIERS), + PCF_MISSING_SUPPLEMENTAL_CODE(66, "There's missing data. Enter the `(Supplemental Type)` - " + + "`(Type Qualification)` supplemental data for code `(Supplemental Data Code)` for the " + + "Sub-population `(Sub Population)` of measure id `(Measure Id)`.", true), + PCF_SUPPLEMENTAL_DATA_MISSING_COUNT(67, "Review measure id `(Measure Id)`. It must have one count for " + + "Supplemental Data `(Supplemental Data Code)` on Sub-population `(Sub Population)`.", true), + PCF_SUBMISSION_ENDED(68, "Your submission for `(Program name)` was made after the submission " + + "deadline of `(Submission end date)` for `(Program name)` measure section. Your `(Program name)` QRDA III file " + + "has not been processed. Please contact `(Program name)` Support at `(PCF+ contact email)` for assistance.", true), + INVALID_PERFORMANCE_PERIOD_FORMAT(69, "Review the `(Performance period start or end date)` format. " + + "Valid date formats are 2024-02-26, 2024/02/26T01:45:23, or 2024-02-26T01:45:23.123. You cn find more " + + "information on the implementation guide: " + DocumentationReference.PERFORMANCE_PERIOD, true), + MISSING_OR_DUPLICATED_MEASURE_GUID(70, "Review the measure GUID for measure section, " + + "measure reference, and results. There must only be one GUID per measure. Refer to page 36 " + + "of the implementation guide: " + DocumentationReference.MEASURE_REFERENCE), + MEASURES_RNR_WITH_DUPLICATED_MEASURE_GUID(71, "Review the file for duplicate GUIDs. " + + "Each measure section, measure reference, and results must have its own GUID."), + PERFORMANCE_RATE_MISSING(72, "Contact your Health IT vendor. The QRDA III file is missing " + + "a performance rate. Performance rate is required for PCF reporting. You can find more information " + + "on page 17 of the implementation guide: " + DocumentationReference.REPORTING_PARAMETERS_ACT), + VIRTUAL_GROUP_ID_REQUIRED(78, "Enter an entity ID for the program 'MIPS Virtual Group'."), + MISSING_PII_VALIDATOR(79, "Enter a TIN number to verify the NPI/Alternative Payment Model (APM) combinations."), + INCORRECT_API_NPI_COMBINATION(80, "Review NPI `(npi)` and TIN `(tin)`. This NPI/TIN combination is missing " + + "from the QRDA III file or is not in the `(program)` practitioner roster for `(apm)`. Ensure your submission " + + "contains all required NPI/TIN combinations and your `(program)` practitioner roster is up-to-date.", true), MEASURE_SECTION_MISSING_MEASURE(81, "At least one measure is required in a measure section"), - TOO_MANY_ERRORS(82, "There are too many errors associated with this QRDA-III file. Showing 100 out of `(Error amount)` errors." - + " Please fix the given errors and re-submit", true), - PCF_TIN_REQUIRED(84, "`(Program name)` QRDA-III Submissions require at least one TIN to be present.", true), - PCF_INVALID_TIN(85, "`(Program name)` QRDA-III Submission TINs require a 9 digit numerical value", true), - PCF_MISSING_TIN(86, "This `(Program name)` QRDA-III submission is missing a TIN. Please ensure there is a TIN associated with every " - + "NPI submitted", true), - PCF_NPI_REQUIRED(87, "`(Program name)` QRDA-III Submissions require at least one NPI to be present", true), - PCF_INVALID_NPI(88, "`(Program name)` QRDA-III Submission NPIs require a 10 digit numerical value",true ), - PCF_MISSING_NPI(89, "This `(Program name)` QRDA-III submission is missing a NPI. Please ensure there is an NPI associated with " - + "every TIN submitted", true), - PCF_NO_IA_OR_PI(90, "`(Program name)` QRDA-III submissions should not contain an IA section. IA data will be ignored.", true), - PCF_INVALID_NULL_PERFORMANCE_RATE(91, "The performance rate `(performanceRateUuid)` for measure `(measure id)` has an invalid null value. " - + "A performance rate cannot be null unless the performance denominator is 0", true), - PCF_PERFORMANCE_DENOM_LESS_THAN_ZERO(92, "The performance denominator for measure `(measureId)` was less than 0. " - + "A performance rate cannot be null unless the performance denominator is 0", true), - PCF_NUMERATOR_GREATER_THAN_EITHER_DENOMINATORS(93, "The numerator id `(numeratorUuid)` for measure `(measure id)` has a count value that is " - + "greater than the denominator and/or the performance denominator " - + "(Denominator count - Denominator exclusion count - Denominator Exception count)", true), - PCF_DENEX_GREATER_THAN_DENOMINATOR(94, "The denominator exclusion id `(denexUuid)` for measure `(measure id)` has a count value that is greater than the " - + "denominator. The Denominator exclusion cannot be a greater value than the denominator.", true), - MEASURE_SECTION_V5_REQUIRES_CATEGORY_SECTION(95, "The Clinical Document must contain one Category Section v5 with the extension 2020-12-01"), + TOO_MANY_ERRORS(82, "This QRDA III file shows 100 out of `(Error amount)` errors. Correct and re-submit the file. ", true), + PCF_TIN_REQUIRED(84, "`(Program name)` QRDA-III Submissions require at least one TIN number.", true), + PCF_INVALID_TIN(85, "`(Program name)` QRDA-III Submission TINs must be 9 numbers long.", true), + PCF_MISSING_TIN(86, "The QRDA-III submission for `(Program name)` is missing a TIN. " + + "Ensure there is a TIN associated with every NPI submitted.", true), + PCF_NPI_REQUIRED(87, "The QRDA-III submission for `(Program name)` must have at least one NPI number.", true), + PCF_INVALID_NPI(88, "The NPIs for `(Program name)`'s QRDA-III submission must be 10 numbers long.",true ), + PCF_MISSING_NPI(89, "The QRDA-III submission for `(Program name)` is missing an NPI. " + + "Ensure there is an NPI associated with every TIN submitted.", true), + PCF_NO_IA_OR_PI(90, "The QRDA-III submission for `(Program name)` should not contain an " + + "Improvement Activities section. The Improvement Activities data will be ignored.", true), + PCF_INVALID_NULL_PERFORMANCE_RATE(91, "Review the performance rate `(performanceRateUuid)` for measure " + + "`(measure id)`. A performance rate cannot be null unless the performance denominator is 0", true), + PCF_PERFORMANCE_DENOM_LESS_THAN_ZERO(92, "Review the performance denominator for measure `(measureId)`. " + + "A performance rate cannot be null unless the performance denominator is 0.", true), + PCF_NUMERATOR_GREATER_THAN_EITHER_DENOMINATORS(93, "Review numerator ID `(numeratorUuid)` for " + + "measure `(measure id)`. It has a count value that is greater than the denominator and/or the performance " + + "denominator (Denominator count - Denominator exclusion count - Denominator Exception count)", true), + PCF_DENEX_GREATER_THAN_DENOMINATOR(94, "Review the denominator exclusion id `(denexUuid)` for " + + "measure `(measure id)`. It cannot have a greater value than the denominator.", true), + MEASURE_SECTION_V5_REQUIRES_CATEGORY_SECTION(95, "The QRDA III file must contain one Category Section v5 with the extension 2020-12-01"), MISSING_API_TIN_NPI_FILE(96, "The APM to TIN/NPI Combination file is missing."), - PCF_MISSING_CEHRT_ID(97, "`(Program name)` QRDA-III Submissions require a valid CMS EHR Certification ID (Valid Formats: XX15CXXXXXXXXXX)", true), - PCF_ZERO_PERFORMANCE_RATE(98, "The performance rate cannot have a value of 0 and must be of value Null Attribute (NA)."), - PCF_DUPLICATE_CEHRT(100, "More than one CMS EHR Certification ID was found. Please submit with only one CMS EHR Certification id."), - PCF_DENOMINATOR_COUNT_INVALID(101, "Denominator count must be equal to Initial Population count for `(Program name)` measure population `(measure population id)`." - + "Please see the Table 15 of `(Submission year's)` Implementation Guide for valid measure GUIDs: " //NOSONAR - + DocumentationReference.MEASURE_IDS, true), - PI_RESTRICTED_MEASURES(102, "A PI section cannot contain PI_HIE_5 with PI_HIE_1, PI_LVOTC_1, PI_HIE_4, or PI_LVITC_2", false), - PCF_TOO_FEW_QUALITY_MEASURE_CATEGORY(103, "PCF Submissions must have the `(PCF Measure minimum)` " + PCF_MISSING_CEHRT_ID(97, "The QRDA-III submissions for `(Program name)` must have a valid " + + "CMS EHR Certification ID (Valid Formats: XX15CXXXXXXXXXX)", true), + PCF_ZERO_PERFORMANCE_RATE(98, "Review the performance rate. It must be of value Null Attribute (NA), not 0."), + PCF_DUPLICATE_CEHRT(100, "Found more than one CMS EHR Certification ID in your file. The submission " + + "must have only one CMS EHR Certification ID."), + PCF_DENOMINATOR_COUNT_INVALID(101, "The measure population `(measure population id)` for " + + "`(Program name)` needs the Denominator count to be equal to Initial population count. You can find " + + "additional information on table 15 of the implementation guide:" + DocumentationReference.MEASURE_IDS, true), + PI_RESTRICTED_MEASURES(102, "The Promoting Interoperability section cannot contain " + + "PI_HIE_5 with PI_HIE_1, PI_LVOTC_1, PI_HIE_4, or PI_LVITC_2", false), + PCF_TOO_FEW_QUALITY_MEASURE_CATEGORY(103, "The PCF submissions must have the `(PCF Measure minimum)` " + "following measures: `(Listing of valid measure ids)`", true), - PCF_MULTI_TIN_NPI_SINGLE_PERFORMER(105, "If multiple TINs/NPIs are submitted, each must be reported within a separate performer"), - PCF_NO_PI(106, "PI submissions are not allowed within PCF"), - PCF_MISSING_COMBINATION(107, - "NPI/TIN Warning: Missing NPI/TIN Combination Identified. NPI/TIN `(npi)`-`(tin)` was active on the PCF practitioner roster for `(apm)` during the performance year but was not found in the file. " - + "Please ensure your submission contains all NPI/TIN combinations that were active on your roster at any point during the performance year. " - + "Your QRDA III file and/or roster may require updates. Note: The QPP website does not have access to roster updates made after " + DocumentationReference.ROSTER_UPDATE_DATE + ". " - + "It is therefore critical that you ensure your roster is up to date and your QRDA III file contains all NPI/TIN values that were active on your roster during the performance year. " - + "Please contact your health IT vendor if your QRDA III file requires updates. " - + "Instructions on how to update your roster are available in the PCF Practice Management Guide (https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y).", - true), - PCF_INVALID_COMBINATION(108, - "NPI/TIN Warning: Unexpected NPI/TIN Combination Found. NPI/TIN `(npi)`-`(tin)` was reported in the file but does not exist at the practice or was not active on the PCF practitioner roster for `(apm)` during the performance year. " - + "Please ensure your submission only contains NPI/TIN combinations that were active on your roster at any point during the performance year. " - + "Your QRDA III file and/or roster may require updates. Note: The QPP website does not have access to roster updates made after " + DocumentationReference.ROSTER_UPDATE_DATE + ". " - + "It is therefore critical that you ensure your roster is up to date and your QRDA III file contains all NPI/TIN values that were active on your roster during the performance year. " - + "Please contact your health IT vendor if your QRDA III file requires updates. " - + "Instructions on how to update your roster are available in the PCF Practice Management Guide (https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y).", - true); + PCF_MULTI_TIN_NPI_SINGLE_PERFORMER(105, "If multiple TINs/NPIs are submitted, each must be reported within a separate performer."), + PCF_NO_PI(106, "Promoting Interoperability data should not be reported in a PCF QRDA III file."), + PCF_MISSING_COMBINATION(107, "There's missing NPI/TIN combination. The NPI/TIN `(npi)`-`(tin)` was " + + "active on the PCF practitioner roster for `(apm)` during the performance year but was not found in the file. " + + "Ensure your submission contains all NPI/TIN combinations that were active on your roster at any point " + + "during the performance year. Your QRDA III file and/or roster may require updates. " + + "The QPP website doesn't have access to roster updates made after " + DocumentationReference.ROSTER_UPDATE_DATE + ". " + + "It's critical to ensure your roster is up to date and your QRDA III file contains all NPI/TIN values that were active " + + "on your roster during the performance year. Contact your health IT vendor if your QRDA III file requires updates. " + + "You can find instructions on updating rosters in the PCF Practice Management Guide: " + + "(https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y).", true), + PCF_INVALID_COMBINATION(108, "Found an unexpected NPI/TIN combination. The NPI/TIN " + + "`(npi)`-`(tin)` was reported in the file but does not exist at the practice or was not " + + "active on the PCF practitioner roster for `(apm)` during the performance year. " + + "Ensure your submission only contains NPI/TIN combinations that were active on your roster at " + + "any point during the performance year. Your QRDA III file and/or roster may require updates. " + + "Note: The QPP website does not have access to roster updates made after " + DocumentationReference.ROSTER_UPDATE_DATE + ". " + + "It's critical that you ensure your roster is up to date and your QRDA III file contains " + + "all NPI/TIN values that were active on your roster during the performance year. " + + "Please contact your health IT vendor if your QRDA III file requires updates. " + + "You can find instructions on how updating rosters in the PCF Practice Management Guide " + + "(https://cmmi.my.salesforce.com/sfc/p/#i0000000iryR/a/t00000028RsP/dMF_romOmf5VLe7p5lUj8vch11mPmELP6ZuyI16vS.Y).", true); private static final Map CODE_TO_VALUE = Arrays.stream(values()) .collect(Collectors.toMap(ProblemCode::getCode, Function.identity())); @@ -294,8 +285,8 @@ private static final class VariableMarker { } private static final class ServiceCenter { - static final String MESSAGE = "Please contact the Service Center for assistance via phone at " - + "1-866-288-8292 or TTY: 1-877-715-6222, or by emailing QPP@cms.hhs.gov"; + static final String MESSAGE = "Contact the customer service center for assistance by email at QPP@cms.hhs.gov " + + "or by phone at 288-8292 (TTY: 1-877-715-6222)"; } } diff --git a/commons/src/main/resources/measures-data.json b/commons/src/main/resources/measures-data.json index db7795dca..965cb3988 100644 --- a/commons/src/main/resources/measures-data.json +++ b/commons/src/main/resources/measures-data.json @@ -9636,7 +9636,7 @@ "nqfEMeasureId": null, "nqfId": "0053", "measureId": "418", - "description": "The percentage of women 65–85 years of age who suffered a fracture and who had either a bone mineral density (BMD) test or prescription for a drug to treat osteoporosis in the six months after the fracture.", + "description": "The percentage of women 50-85 years of age who suffered a fracture and who had either a bone mineral density (BMD) test or prescription for a drug to treat osteoporosis in the six months after the fracture.", "measureType": "process", "isHighPriority": false, "primarySteward": "National Committee for Quality Assurance", @@ -11983,7 +11983,7 @@ "preventiveMedicine" ], "measureSpecification": { - "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_497_MIPSCQM_Spec_and_Addendum.zip " + "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_497_MIPSCQM_Spec_and_Addendum.zip" }, "overallAlgorithm": "weightedAverage", "strata": [ @@ -12296,7 +12296,7 @@ "urology" ], "measureSpecification": { - "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_503_MIPSCQM_Spec_and_Addendum.zip " + "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_503_MIPSCQM_Spec_and_Addendum.zip" }, "overallAlgorithm": "overallStratumOnly", "strata": [ diff --git a/converter/src/main/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidator.java b/converter/src/main/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidator.java index a8d1c2e49..592059cf9 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidator.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidator.java @@ -52,7 +52,7 @@ protected void performValidation(final Node node) { String programName = Optional.ofNullable(node.getValue(PROGRAM_NAME)).orElse(""); String entityType = Optional.ofNullable(node.getValue(ENTITY_TYPE)).orElse(""); - forceCheckErrors(node).valueIn(ProblemCode.CLINICAL_DOCUMENT_INCORRECT_PROGRAM_NAME.format(programName, VALID_PROGRAM_NAMES), + forceCheckErrors(node).valueIn(ProblemCode.CLINICAL_DOCUMENT_INCORRECT_PROGRAM_NAME.format(VALID_PROGRAM_NAMES, programName), PROGRAM_NAME, MIPS_PROGRAM_NAME, PCF, APP_PROGRAM_NAME); if (ENTITY_VIRTUAL_GROUP.equals(entityType)) { diff --git a/converter/src/main/java/gov/cms/qpp/conversion/validate/CommonNumeratorDenominatorValidator.java b/converter/src/main/java/gov/cms/qpp/conversion/validate/CommonNumeratorDenominatorValidator.java index b3f594cc2..6c33583e9 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/validate/CommonNumeratorDenominatorValidator.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/validate/CommonNumeratorDenominatorValidator.java @@ -54,7 +54,7 @@ private void validateAggregateCount(Node aggregateCountNode) { } private LocalizedProblem format(ProblemCode error) { - return error.format(nodeName, nodeName); + return error.format(nodeName); } private LocalizedProblem format(ProblemCode error, String value) { diff --git a/converter/src/main/java/gov/cms/qpp/conversion/validate/MeasureDataValidator.java b/converter/src/main/java/gov/cms/qpp/conversion/validate/MeasureDataValidator.java index 7616c5124..7adac1d58 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/validate/MeasureDataValidator.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/validate/MeasureDataValidator.java @@ -37,8 +37,8 @@ protected void performValidation(Node node) { } Checker checker = checkErrors(node) - .hasChildren(ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(populationId, Context.REPORTING_YEAR)) - .childExact(ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(populationId, Context.REPORTING_YEAR), + .hasChildren(ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(populationId)) + .childExact(ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(populationId), 1, TemplateId.PI_AGGREGATE_COUNT); if (!checker.shouldShortcut()) { @@ -48,7 +48,7 @@ protected void performValidation(Node node) { DuplicationCheckHelper.calculateDuplications(child, AGGREGATE_COUNT)), AGGREGATE_COUNT) .intValue(ProblemCode.AGGREGATE_COUNT_VALUE_NOT_INTEGER, AGGREGATE_COUNT) - .greaterThan(ProblemCode.MEASURE_DATA_VALUE_NOT_INTEGER.format(populationId, Context.REPORTING_YEAR), -1); + .greaterThan(ProblemCode.MEASURE_DATA_VALUE_NOT_INTEGER.format(populationId), -1); } } } \ No newline at end of file diff --git a/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfClinicalDocumentValidator.java b/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfClinicalDocumentValidator.java index 907a3d5cf..02dd66280 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfClinicalDocumentValidator.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfClinicalDocumentValidator.java @@ -206,7 +206,7 @@ private void validateSubmissionDate(Node node) { String formatted = endDate.format(OUTPUT_END_DATE_FORMAT); String program = node.getValue(PROGRAM_NAME); addError(Detail.forProblemAndNode( - ProblemCode.PCF_SUBMISSION_ENDED.format(program, program, formatted, program, program, + ProblemCode.PCF_SUBMISSION_ENDED.format(program, formatted, program, program, program, EnvironmentHelper.getOrDefault(CPC_PLUS_CONTACT_EMAIL, DEFAULT_CPC_PLUS_CONTACT_EMAIL)), node)); } diff --git a/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidator.java b/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidator.java index ba6d52a11..a5dcdf40e 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidator.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidator.java @@ -114,7 +114,7 @@ private void addSupplementalValidationError(Node node, SupplementalData suppleme LocalizedProblem error = ProblemCode.PCF_MISSING_SUPPLEMENTAL_CODE.format( supplementalData.getType(), supplementalData, supplementalData.getCode(), - measureId, node.getValue(MEASURE_TYPE)); + node.getValue(MEASURE_TYPE), measureId); addError(Detail.forProblemAndNode(error, node)); } @@ -128,7 +128,6 @@ private void addSupplementalValidationError(Node node, SupplementalData suppleme */ private LocalizedProblem makeIncorrectCountSizeLocalizedError(Node node, String supplementalCode, String measureId) { return ProblemCode.PCF_SUPPLEMENTAL_DATA_MISSING_COUNT.format( - supplementalCode, node.getValue(MEASURE_TYPE), - measureId); + measureId, supplementalCode, node.getValue(MEASURE_TYPE)); } } diff --git a/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidator.java b/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidator.java index a17b8aac4..3f24e26ca 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidator.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidator.java @@ -44,7 +44,7 @@ protected void performValidation(Node node) { forceCheckErrors(node) .childExact( ProblemCode.PCF_QUALITY_MEASURE_ID_INVALID_PERFORMANCE_RATE_COUNT - .format(requiredPerformanceRateCount, MeasureConfigHelper.getPrioritizedId(node)), + .format(MeasureConfigHelper.getPrioritizedId(node), requiredPerformanceRateCount), requiredPerformanceRateCount, TemplateId.PERFORMANCE_RATE_PROPORTION_MEASURE); } diff --git a/converter/src/main/java/gov/cms/qpp/conversion/validate/QualityMeasureIdValidator.java b/converter/src/main/java/gov/cms/qpp/conversion/validate/QualityMeasureIdValidator.java index fc5d02ee6..2cba46b16 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/validate/QualityMeasureIdValidator.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/validate/QualityMeasureIdValidator.java @@ -245,7 +245,7 @@ private void validateCpcDenominatorCount(Node denomCount, Node ipopCount, String .incompleteValidation() .intValue(ProblemCode.AGGREGATE_COUNT_VALUE_NOT_INTEGER, AGGREGATE_COUNT) - .valueIn(ProblemCode.PCF_DENOMINATOR_COUNT_INVALID.format(program, denominatorUuid, Context.REPORTING_YEAR), AGGREGATE_COUNT, + .valueIn(ProblemCode.PCF_DENOMINATOR_COUNT_INVALID.format(program, denominatorUuid), AGGREGATE_COUNT, ipopCount.getValue(AGGREGATE_COUNT)); } diff --git a/converter/src/test/java/gov/cms/qpp/acceptance/QualityMeasureIdRoundTripTest.java b/converter/src/test/java/gov/cms/qpp/acceptance/QualityMeasureIdRoundTripTest.java index 641d901e6..bb7a36053 100644 --- a/converter/src/test/java/gov/cms/qpp/acceptance/QualityMeasureIdRoundTripTest.java +++ b/converter/src/test/java/gov/cms/qpp/acceptance/QualityMeasureIdRoundTripTest.java @@ -207,7 +207,7 @@ void testMissingPerfDenomAggregateCount() { String populationId = "F50E5334-415D-482F-A30D-0623C082B602"; - LocalizedProblem error = ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(populationId, Context.REPORTING_YEAR); + LocalizedProblem error = ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(populationId); assertThat(details).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .contains(error); } diff --git a/converter/src/test/java/gov/cms/qpp/conversion/encode/PiNumeratorDenominatorEncoderTest.java b/converter/src/test/java/gov/cms/qpp/conversion/encode/PiNumeratorDenominatorEncoderTest.java index 03be2b2de..ecc10cb75 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/encode/PiNumeratorDenominatorEncoderTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/encode/PiNumeratorDenominatorEncoderTest.java @@ -107,6 +107,6 @@ void testNoChildEncoder() throws EncodeException { .hasSize(1); assertWithMessage("The validation error must be the inability to find an encoder") .that(objectUnderTest.getErrors().get(0).getMessage()) - .isEqualTo(ProblemCode.CT_LABEL + "Failed to find an encoder"); + .isEqualTo(ProblemCode.ENCODER_MISSING.getMessage()); } } diff --git a/converter/src/test/java/gov/cms/qpp/conversion/encode/PiSectionEncoderTest.java b/converter/src/test/java/gov/cms/qpp/conversion/encode/PiSectionEncoderTest.java index 5cbb49fe2..10a66dd28 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/encode/PiSectionEncoderTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/encode/PiSectionEncoderTest.java @@ -122,7 +122,7 @@ void testInternalEncodeWithNoChildren() { assertThat(piSectionEncoder.getErrors()).isNotNull(); assertThat(piSectionEncoder.getErrors().get(0).getMessage()) - .isEqualTo(ProblemCode.CT_LABEL + "Failed to find an encoder"); + .isEqualTo(ProblemCode.ENCODER_MISSING.getMessage()); } @Test diff --git a/converter/src/test/java/gov/cms/qpp/conversion/validate/AciDenominatorValidatorTest.java b/converter/src/test/java/gov/cms/qpp/conversion/validate/AciDenominatorValidatorTest.java index 2f201ddfd..abdcd9034 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/validate/AciDenominatorValidatorTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/validate/AciDenominatorValidatorTest.java @@ -50,7 +50,7 @@ void noChildrenTest() { assertWithMessage("No Children Validation Error not issued") .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .containsExactly(ProblemCode.NUMERATOR_DENOMINATOR_CHILD_EXACT - .format(AciDenominatorValidator.DENOMINATOR_NAME, AciDenominatorValidator.DENOMINATOR_NAME)); + .format(AciDenominatorValidator.DENOMINATOR_NAME)); } @Test @@ -67,7 +67,7 @@ void incorrectChildrenTest() { assertWithMessage("Incorrect child Validation Error not issued") .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .containsExactly(ProblemCode.NUMERATOR_DENOMINATOR_CHILD_EXACT.format( - AciDenominatorValidator.DENOMINATOR_NAME, AciDenominatorValidator.DENOMINATOR_NAME)); + AciDenominatorValidator.DENOMINATOR_NAME)); } @@ -89,7 +89,7 @@ void tooManyChildrenTest() { assertWithMessage("Too many children Validation Error not issued") .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .containsExactly(ProblemCode.NUMERATOR_DENOMINATOR_CHILD_EXACT.format( - AciDenominatorValidator.DENOMINATOR_NAME, AciDenominatorValidator.DENOMINATOR_NAME)); + AciDenominatorValidator.DENOMINATOR_NAME)); } @Test diff --git a/converter/src/test/java/gov/cms/qpp/conversion/validate/AciNumeratorValidatorTest.java b/converter/src/test/java/gov/cms/qpp/conversion/validate/AciNumeratorValidatorTest.java index 5a36e2fe7..b687a08b4 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/validate/AciNumeratorValidatorTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/validate/AciNumeratorValidatorTest.java @@ -51,7 +51,7 @@ void noChildrenTest() { .that(errors) .comparingElementsUsing(DetailsErrorEquals.INSTANCE) .containsExactly(ProblemCode.NUMERATOR_DENOMINATOR_CHILD_EXACT - .format(AciNumeratorValidator.NUMERATOR_NAME, AciNumeratorValidator.NUMERATOR_NAME)); + .format(AciNumeratorValidator.NUMERATOR_NAME)); } @Test @@ -90,7 +90,7 @@ void tooManyChildrenTest() { assertWithMessage("Too many children Validation Error not issued") .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .containsExactly(ProblemCode.NUMERATOR_DENOMINATOR_CHILD_EXACT.format( - AciNumeratorValidator.NUMERATOR_NAME, AciNumeratorValidator.NUMERATOR_NAME)); + AciNumeratorValidator.NUMERATOR_NAME)); } @Test diff --git a/converter/src/test/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidatorTest.java b/converter/src/test/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidatorTest.java index 6fb0132f4..c38d17424 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidatorTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/validate/ClinicalDocumentValidatorTest.java @@ -252,7 +252,7 @@ void testInvalidProgramName() { assertWithMessage("Must contain the error") .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) - .containsExactly(ProblemCode.CLINICAL_DOCUMENT_INCORRECT_PROGRAM_NAME.format(invalidProgramName, ClinicalDocumentValidator.VALID_PROGRAM_NAMES)); + .containsExactly(ProblemCode.CLINICAL_DOCUMENT_INCORRECT_PROGRAM_NAME.format(ClinicalDocumentValidator.VALID_PROGRAM_NAMES, invalidProgramName)); } @Test diff --git a/converter/src/test/java/gov/cms/qpp/conversion/validate/MeasureDataValidatorTest.java b/converter/src/test/java/gov/cms/qpp/conversion/validate/MeasureDataValidatorTest.java index 939312eb2..bd509cc74 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/validate/MeasureDataValidatorTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/validate/MeasureDataValidatorTest.java @@ -46,7 +46,7 @@ void missingAggregateCount() { List errors = validator.validateSingleNode(testNode).getErrors(); assertWithMessage("missing error") .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) - .containsExactly(ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(EMPTY_POPULATION_ID, Context.REPORTING_YEAR)); + .containsExactly(ProblemCode.MEASURE_PERFORMED_MISSING_AGGREGATE_COUNT.format(EMPTY_POPULATION_ID)); } @Test @@ -86,7 +86,7 @@ void negativeAggregateCountsFails() throws Exception { List errors = validator.validateSingleNode(testNode).getErrors(); assertWithMessage("missing error") .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) - .containsExactly(ProblemCode.MEASURE_DATA_VALUE_NOT_INTEGER.format(EMPTY_POPULATION_ID, Context.REPORTING_YEAR)); + .containsExactly(ProblemCode.MEASURE_DATA_VALUE_NOT_INTEGER.format(EMPTY_POPULATION_ID)); } @Test @@ -109,7 +109,7 @@ void multipleNegativeMeasureDataTest() { .that(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .containsAtLeast(ProblemCode.AGGREGATE_COUNT_VALUE_NOT_INTEGER, ProblemCode.AGGREGATE_COUNT_VALUE_NOT_SINGULAR.format(TemplateId.MEASURE_DATA_CMS_V4.name(), 2), - ProblemCode.MEASURE_DATA_VALUE_NOT_INTEGER.format("58347456-D1F3-4BBB-9B35-5D42825A0AB3", Context.REPORTING_YEAR)); + ProblemCode.MEASURE_DATA_VALUE_NOT_INTEGER.format("58347456-D1F3-4BBB-9B35-5D42825A0AB3")); } private List getErrors(AllErrors content) { diff --git a/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidatorTest.java b/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidatorTest.java index 2f914cede..c5083215e 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidatorTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfMeasureDataValidatorTest.java @@ -59,7 +59,7 @@ void testFailureSupplementalDataMissingCountTest() throws Exception { List errors = validator.validateSingleNode(underTest).getErrors(); LocalizedProblem expectedError = ProblemCode.PCF_SUPPLEMENTAL_DATA_MISSING_COUNT.format( - SupplementalData.MALE.getCode(), SubPopulationLabel.IPOP.name(), MEASURE_ID); + MEASURE_ID, SupplementalData.MALE.getCode(), SubPopulationLabel.IPOP.name()); assertThat(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .contains(expectedError); @@ -117,7 +117,7 @@ private Consumer supplementalDataCheck(final String scenarioFi LocalizedProblem expectedError = ProblemCode.PCF_MISSING_SUPPLEMENTAL_CODE .format(supplementalData.getType(), supplementalData, supplementalData.getCode(), - MEASURE_ID, SubPopulationLabel.IPOP.name()); + SubPopulationLabel.IPOP.name(), MEASURE_ID); assertThat(errors).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .contains(expectedError); diff --git a/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidatorTest.java b/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidatorTest.java index 2b9765467..b612ed490 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidatorTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/validate/PcfQualityMeasureIdValidatorTest.java @@ -48,7 +48,7 @@ void testPerformanceCountWithNoErrors() { assertWithMessage("Must contain 0 invalid performance rate count errors") .that(details).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .doesNotContain(ProblemCode.PCF_QUALITY_MEASURE_ID_INVALID_PERFORMANCE_RATE_COUNT - .format(2, E_MEASURE_ID)); + .format(E_MEASURE_ID, 2)); } @Test @@ -59,7 +59,7 @@ void testPerformanceCountWithIncreasedSizeError() { assertWithMessage("Must contain 2 invalid performance rate count errors") .that(details).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .contains(ProblemCode.PCF_QUALITY_MEASURE_ID_INVALID_PERFORMANCE_RATE_COUNT - .format(2, E_MEASURE_ID)); + .format(E_MEASURE_ID, 2)); } @Test @@ -70,7 +70,7 @@ void testPerformanceCountWithDecreasedSizeError() { assertWithMessage("Must contain 2 invalid performance rate count errors") .that(details).comparingElementsUsing(DetailsErrorEquals.INSTANCE) .contains(ProblemCode.PCF_QUALITY_MEASURE_ID_INVALID_PERFORMANCE_RATE_COUNT - .format(2, E_MEASURE_ID)); + .format(E_MEASURE_ID, 2)); } @Test diff --git a/converter/src/test/resources/pcf/acceptance2024/success/PCF-1e-MIPS_INDIV_09182024.xml b/converter/src/test/resources/pcf/acceptance2024/success/PCF-1e-MIPS_INDIV_09182024.xml index c99cd5bda..282872d41 100644 --- a/converter/src/test/resources/pcf/acceptance2024/success/PCF-1e-MIPS_INDIV_09182024.xml +++ b/converter/src/test/resources/pcf/acceptance2024/success/PCF-1e-MIPS_INDIV_09182024.xml @@ -2869,7 +2869,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -2882,7 +2882,7 @@ QRDA Category III Measure Section (CMS EP) + extension="2c928084-8389-524e-0183-cd90c213122b"/> Colorectal Cancer Screening @@ -2903,7 +2903,7 @@ QRDA Category III Measure Section (CMS EP) value=".888889"/> - + - - - - @@ -2982,9 +2982,9 @@ QRDA Category III Measure Section (CMS EP) - @@ -2993,15 +2993,15 @@ QRDA Category III Measure Section (CMS EP) - - - @@ -3499,7 +3499,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -4094,7 +4094,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -4686,7 +4686,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -5277,7 +5277,7 @@ QRDA Category III Measure Section (CMS EP) - + diff --git a/converter/src/test/resources/pcf/acceptance2024/success/PCF-1f-MIPS_GROUP_09182024.xml b/converter/src/test/resources/pcf/acceptance2024/success/PCF-1f-MIPS_GROUP_09182024.xml index 87dd26ced..b51c86e29 100644 --- a/converter/src/test/resources/pcf/acceptance2024/success/PCF-1f-MIPS_GROUP_09182024.xml +++ b/converter/src/test/resources/pcf/acceptance2024/success/PCF-1f-MIPS_GROUP_09182024.xml @@ -2869,7 +2869,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -2882,7 +2882,7 @@ QRDA Category III Measure Section (CMS EP) + extension="2c928084-8389-524e-0183-cd90c213122b"/> Colorectal Cancer Screening @@ -2903,7 +2903,7 @@ QRDA Category III Measure Section (CMS EP) value=".888889"/> - + - + @@ -4094,7 +4094,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -4686,7 +4686,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -5277,7 +5277,7 @@ QRDA Category III Measure Section (CMS EP) - + diff --git a/converter/src/test/resources/pcf/acceptance2024/success/PCF-1g-MIPS_VIRTUALGROUP_09182024.xml b/converter/src/test/resources/pcf/acceptance2024/success/PCF-1g-MIPS_VIRTUALGROUP_09182024.xml index c1095af64..e4290d23e 100644 --- a/converter/src/test/resources/pcf/acceptance2024/success/PCF-1g-MIPS_VIRTUALGROUP_09182024.xml +++ b/converter/src/test/resources/pcf/acceptance2024/success/PCF-1g-MIPS_VIRTUALGROUP_09182024.xml @@ -2843,7 +2843,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -2856,7 +2856,7 @@ QRDA Category III Measure Section (CMS EP) + extension="2c928084-8389-524e-0183-cd90c213122b"/> Colorectal Cancer Screening @@ -2877,7 +2877,7 @@ QRDA Category III Measure Section (CMS EP) value=".888889"/> - + - + @@ -4068,7 +4068,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -4660,7 +4660,7 @@ QRDA Category III Measure Section (CMS EP) - + @@ -5251,7 +5251,7 @@ QRDA Category III Measure Section (CMS EP) - + diff --git a/converter/src/test/resources/pcf/acceptance2024/success/PCF-23a-AdditionalMeasuresReported_09182024.xml b/converter/src/test/resources/pcf/acceptance2024/success/PCF-23a-AdditionalMeasuresReported_09182024.xml index 87368d33f..5d502d215 100644 --- a/converter/src/test/resources/pcf/acceptance2024/success/PCF-23a-AdditionalMeasuresReported_09182024.xml +++ b/converter/src/test/resources/pcf/acceptance2024/success/PCF-23a-AdditionalMeasuresReported_09182024.xml @@ -12482,1888 +12482,6 @@ QRDA Category III Measure Section - - - - - - - - - - - - - - - Breast Cancer Screening - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 245b7dea7d009bc0a979ede4c5de6fc72f8b54b4 Mon Sep 17 00:00:00 2001 From: Sivakumar Srinivasulu Date: Fri, 1 Nov 2024 15:24:19 -0500 Subject: [PATCH 14/17] fixed error details duplication --- commons/src/main/resources/measures-data.json | 6 +++--- .../cms/qpp/conversion/model/error/AllErrors.java | 8 ++++++++ .../qpp/conversion/model/error/AllErrorsTest.java | 13 +++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/commons/src/main/resources/measures-data.json b/commons/src/main/resources/measures-data.json index db7795dca..965cb3988 100644 --- a/commons/src/main/resources/measures-data.json +++ b/commons/src/main/resources/measures-data.json @@ -9636,7 +9636,7 @@ "nqfEMeasureId": null, "nqfId": "0053", "measureId": "418", - "description": "The percentage of women 65–85 years of age who suffered a fracture and who had either a bone mineral density (BMD) test or prescription for a drug to treat osteoporosis in the six months after the fracture.", + "description": "The percentage of women 50-85 years of age who suffered a fracture and who had either a bone mineral density (BMD) test or prescription for a drug to treat osteoporosis in the six months after the fracture.", "measureType": "process", "isHighPriority": false, "primarySteward": "National Committee for Quality Assurance", @@ -11983,7 +11983,7 @@ "preventiveMedicine" ], "measureSpecification": { - "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_497_MIPSCQM_Spec_and_Addendum.zip " + "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_497_MIPSCQM_Spec_and_Addendum.zip" }, "overallAlgorithm": "weightedAverage", "strata": [ @@ -12296,7 +12296,7 @@ "urology" ], "measureSpecification": { - "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_503_MIPSCQM_Spec_and_Addendum.zip " + "registry": "http://qpp.cms.gov/docs/QPP_quality_measure_specifications/CQM-Measures/2024_Measure_503_MIPSCQM_Spec_and_Addendum.zip" }, "overallAlgorithm": "overallStratumOnly", "strata": [ diff --git a/converter/src/main/java/gov/cms/qpp/conversion/model/error/AllErrors.java b/converter/src/main/java/gov/cms/qpp/conversion/model/error/AllErrors.java index 923a6aba1..a81f8af01 100644 --- a/converter/src/main/java/gov/cms/qpp/conversion/model/error/AllErrors.java +++ b/converter/src/main/java/gov/cms/qpp/conversion/model/error/AllErrors.java @@ -3,6 +3,7 @@ import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; /** @@ -34,6 +35,13 @@ public AllErrors(List errors) { * @return All the {@code Error}s. */ public List getErrors() { + if (null == errors) return errors; + errors.forEach(error -> { + if (!error.getDetails().isEmpty()) { + List details = new ArrayList<>(new LinkedHashSet<>(error.getDetails())); + error.setDetails(details); + } + }); return errors; } diff --git a/converter/src/test/java/gov/cms/qpp/conversion/model/error/AllErrorsTest.java b/converter/src/test/java/gov/cms/qpp/conversion/model/error/AllErrorsTest.java index 8387f2b7f..3d4c4a55e 100644 --- a/converter/src/test/java/gov/cms/qpp/conversion/model/error/AllErrorsTest.java +++ b/converter/src/test/java/gov/cms/qpp/conversion/model/error/AllErrorsTest.java @@ -65,4 +65,17 @@ void testArgConstructor() { assertThat(new AllErrors(errors).getErrors()) .containsAtLeastElementsIn(errors); } + + @Test + void testGetErrorDuplicateDetails() { + AllErrors objectUnderTest = new AllErrors(); + List details = new ArrayList(); + details.add(new Detail("test")); + details.add(new Detail("test")); + Error error = new Error(); + error.setDetails(details); + objectUnderTest.addError(error); + assertWithMessage("The error details should be one") + .that(objectUnderTest.getErrors().get(0).getDetails()).hasSize(1); + } } \ No newline at end of file From ee83bdf2b7e7a9209b2ae1f20c6d2295731f6514 Mon Sep 17 00:00:00 2001 From: Dinesh-kantamneni Date: Tue, 5 Nov 2024 12:12:21 -0800 Subject: [PATCH 15/17] update branch status url to ct --- buildspec/build_deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildspec/build_deploy.yaml b/buildspec/build_deploy.yaml index 507cb656d..c21964c02 100644 --- a/buildspec/build_deploy.yaml +++ b/buildspec/build_deploy.yaml @@ -15,7 +15,7 @@ env: DOCKERHUB_USER: "/global/dockerhub_user" AWS_ACCOUNT : "/global/aws_account" REPO_PAT: "/global/scoring_api_repo_pat" - BRANCH_STATUS_URL: "/global/branch_status_url" + BRANCH_STATUS_URL: "/global/ct_branch_status_url" PART_FILE: "/qppar-sf/conversion-tool/CPC_PLUS_FILE_NAME" PART_FILE_BUCKET: "/qppar-sf/$ENV/conversion-tool/CPC_PLUS_BUCKET_NAME" OUTPUT_PART_FILE: "/qppar-sf/$ENV/conversion-tool/CPC_PLUS_VALIDATION_FILE" From 886a861f330c26ca47b90a8368700af72725a19f Mon Sep 17 00:00:00 2001 From: Chetan Munegowda Date: Wed, 6 Nov 2024 18:18:16 -0500 Subject: [PATCH 16/17] QPPA-9684: fix snyk issue --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index e72033eed..6648c8e5a 100644 --- a/pom.xml +++ b/pom.xml @@ -436,6 +436,10 @@ spring-security-jwt 1.1.0.RELEASE + + org.springframework.security + spring-security-web + org.bouncycastle bcprov-jdk15on @@ -443,6 +447,12 @@ + + org.springframework.security + spring-security-web + 5.7.13 + + org.bouncycastle bcprov-jdk15on From 1130185ddf841b92720cbed23ec5a79fbab059ef Mon Sep 17 00:00:00 2001 From: Chetan Munegowda Date: Fri, 8 Nov 2024 11:32:16 -0500 Subject: [PATCH 17/17] QPPA-9695: update version to 2024.2.4 --- acceptance-tests/pom.xml | 2 +- commandline/pom.xml | 2 +- commons/pom.xml | 2 +- converter/pom.xml | 4 ++-- generate-race-cpcplus/pom.xml | 2 +- generate/pom.xml | 2 +- pom.xml | 2 +- qrda3-update-measures/pom.xml | 2 +- rest-api/pom.xml | 2 +- test-commons/pom.xml | 2 +- test-coverage/pom.xml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/acceptance-tests/pom.xml b/acceptance-tests/pom.xml index a634b2547..3d62c1c51 100644 --- a/acceptance-tests/pom.xml +++ b/acceptance-tests/pom.xml @@ -3,7 +3,7 @@ 4.0.0 acceptance-tests gov.cms.qpp.conversion - 2024.2.3 + 2024.2.4 conversion-tests jar diff --git a/commandline/pom.xml b/commandline/pom.xml index a5b17170d..0616b9337 100644 --- a/commandline/pom.xml +++ b/commandline/pom.xml @@ -6,7 +6,7 @@ gov.cms.qpp.conversion qpp-conversion-tool-parent - 2024.2.3 + 2024.2.4 ../pom.xml diff --git a/commons/pom.xml b/commons/pom.xml index 44d1620f4..f41acae30 100644 --- a/commons/pom.xml +++ b/commons/pom.xml @@ -6,7 +6,7 @@ gov.cms.qpp.conversion qpp-conversion-tool-parent - 2024.2.3 + 2024.2.4 ../pom.xml diff --git a/converter/pom.xml b/converter/pom.xml index 1c7544cba..d0a9a7029 100644 --- a/converter/pom.xml +++ b/converter/pom.xml @@ -6,7 +6,7 @@ gov.cms.qpp.conversion qpp-conversion-tool-parent - 2024.2.3 + 2024.2.4 ../pom.xml @@ -170,7 +170,7 @@ gov.cms.qpp.conversion commons - 2024.2.3 + 2024.2.4 compile diff --git a/generate-race-cpcplus/pom.xml b/generate-race-cpcplus/pom.xml index 9766597db..1ad9dcfd2 100644 --- a/generate-race-cpcplus/pom.xml +++ b/generate-race-cpcplus/pom.xml @@ -5,7 +5,7 @@ qpp-conversion-tool-parent gov.cms.qpp.conversion - 2024.2.3 + 2024.2.4 ../ 4.0.0 diff --git a/generate/pom.xml b/generate/pom.xml index 57d4e33b3..86e0bbfe4 100644 --- a/generate/pom.xml +++ b/generate/pom.xml @@ -5,7 +5,7 @@ qpp-conversion-tool-parent gov.cms.qpp.conversion - 2024.2.3 + 2024.2.4 ../pom.xml 4.0.0 diff --git a/pom.xml b/pom.xml index 6648c8e5a..bfe28a0e9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ gov.cms.qpp.conversion qpp-conversion-tool-parent pom - 2024.2.3 + 2024.2.4 QPP Conversion Tool diff --git a/qrda3-update-measures/pom.xml b/qrda3-update-measures/pom.xml index 8d16febed..7f1dec9f2 100644 --- a/qrda3-update-measures/pom.xml +++ b/qrda3-update-measures/pom.xml @@ -3,7 +3,7 @@ qpp-conversion-tool-parent gov.cms.qpp.conversion - 2024.2.3 + 2024.2.4 ../ diff --git a/rest-api/pom.xml b/rest-api/pom.xml index 01f63167d..9d979d94f 100644 --- a/rest-api/pom.xml +++ b/rest-api/pom.xml @@ -6,7 +6,7 @@ gov.cms.qpp.conversion qpp-conversion-tool-parent - 2024.2.3 + 2024.2.4 ../pom.xml diff --git a/test-commons/pom.xml b/test-commons/pom.xml index c6eb4d138..46f1b80a3 100644 --- a/test-commons/pom.xml +++ b/test-commons/pom.xml @@ -6,7 +6,7 @@ gov.cms.qpp.conversion qpp-conversion-tool-parent - 2024.2.3 + 2024.2.4 ../pom.xml diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml index 8a367dd2c..affb1e27e 100644 --- a/test-coverage/pom.xml +++ b/test-coverage/pom.xml @@ -6,7 +6,7 @@ gov.cms.qpp.conversion qpp-conversion-tool-parent - 2024.2.3 + 2024.2.4 ../pom.xml