Skip to content

Commit

Permalink
Merge pull request #1467 from CMSgov/feature/QPPSE-2783-FIX_TIN_Valid…
Browse files Browse the repository at this point in the history
…ation_Errors

QPPSE-2783: Added fix for the null TIN root id issue
  • Loading branch information
sivaksb authored Oct 23, 2024
2 parents c7b9bbd + f471e8f commit 4337309
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,21 @@ public SpecPiiValidator(PcfValidationInfoMap file) {

@Override
public void validateApmTinNpiCombination(Node node, NodeValidator validator) {
validateInvalidApmCombinations(node, validator);
validateMissingApmCombinations(node, validator);
List<String> npiList = Arrays.asList(
node.getValue(NATIONAL_PROVIDER_IDENTIFIER).split(","));
List<String> 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<String> npiList, List<String> tinList) {
String program = node.getValue(PROGRAM_NAME);
String apm = getApmEntityId(node, program);
List<String> npiList = Arrays.asList(
node.getValue(NATIONAL_PROVIDER_IDENTIFIER).split(","));
List<String> tinList = Arrays.asList(
node.getValue(TAX_PAYER_IDENTIFICATION_NUMBER).split(","));

Map<String, Map<String, List<String>>> apmToTinNpiMap = file.getApmTinNpiCombinationMap();
if (apmToTinNpiMap == null || StringUtils.isEmpty(apm)) {
Expand All @@ -59,16 +63,14 @@ private void validateInvalidApmCombinations(Node node, NodeValidator validator)
}
}

private void validateMissingApmCombinations(Node node, NodeValidator validator) {
private void validateMissingApmCombinations(Node node, NodeValidator validator, List<String> npiList, List<String> tinList) {
String program = node.getValue(PROGRAM_NAME);
String apm = getApmEntityId(node, program);
List<String> npiList = Arrays.asList(
node.getValue(NATIONAL_PROVIDER_IDENTIFIER).split(","));
List<String> tinList = Arrays.asList(
node.getValue(TAX_PAYER_IDENTIFICATION_NUMBER).split(","));

List<TinNpiCombination> 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<String, Map<String, List<String>>> apmToTinNpiMap = file.getApmTinNpiCombinationMap();
if (apmToTinNpiMap == null || StringUtils.isEmpty(apm)) {
validator.addWarning(Detail.forProblemAndNode(ProblemCode.MISSING_API_TIN_NPI_FILE, node));
Expand All @@ -77,25 +79,29 @@ private void validateMissingApmCombinations(Node node, NodeValidator validator)
if (tinNpisMap != null) {
for(final Map.Entry<String, List<String>> currentEntry: tinNpisMap.entrySet()) {
for (final String currentNpi : currentEntry.getValue()) {
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));
}
checkTinNpiCombinations(node, validator, apm, currentEntry, tinNpiCombinations, currentNpi);
}
}
}
}
}

private void checkTinNpiCombinations(Node node, NodeValidator validator, String apm, Map.Entry<String, List<String>> currentEntry, List<TinNpiCombination> 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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,21 @@ 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) {
// Empty Function. Just adding a comment to avoid sonar flag.
}
};
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));
}
Expand Down

0 comments on commit 4337309

Please sign in to comment.