Summary Table

Categories Total Count
PII 0
URL 0
DNS 0
EKL 0
IP 0
PORT 0
VsID 0
CF 0
AI 0
VPD 0
PL 0
Other 0

File Content

package gov.va.med.ars.service.impl;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import gov.va.med.ars.constants.ErrorMessages;
import gov.va.med.ars.constants.IClaimAttachmentsViewConstants;
import gov.va.med.ars.dao.ars.IClaimAttachmentsViewRepository;
import gov.va.med.ars.exceptions.GenericException;
import gov.va.med.ars.model.request.SearchClaimAttachments275Request;
import gov.va.med.ars.model.response.GenericResponse;
import gov.va.med.ars.model.response.SearchClaimAttachments275Response;
import gov.va.med.ars.service.ISearchClaimAttachments275Service;
import gov.va.med.domain.ars.ClaimattachmentsView;

@Service
public class SearchClaimAttachments275ServiceImpl implements ISearchClaimAttachments275Service {

@Autowired
IClaimAttachmentsViewRepository claimAttachmentsViewRepository;

private static final Logger logger = LogManager.getLogger(SearchClaimAttachments275ServiceImpl.class);

private static final DateFormat frontend_dateFormat = new SimpleDateFormat("MM/dd/yyyy");
private static final DateFormat backend_dateFormat = new SimpleDateFormat("yyyyMMdd");

@Override
public GenericResponse getAll275SearchResult(SearchClaimAttachments275Request searchClaimAttachments275Request)
throws GenericException {

GenericResponse searchResponse = null;
// front-end sometimes sends "" as requested sortColumn
// and we need to eventually use the same sortColumn to return searchResponse
// setting it here to default sort value of attachIdLx if empty.
if (searchClaimAttachments275Request.getSortColumn().equals("")) {
searchClaimAttachments275Request.setSortColumn("attachIdLx");
}
PageRequest pageable = generatePagination(searchClaimAttachments275Request);

try {
boolean requestHasAtLeastOneField = checkRequestNullOrEmpty(searchClaimAttachments275Request);

if (!requestHasAtLeastOneField) {
logger.info("Request is empty.");
throw new GenericException(ErrorMessages.INVALID_REQUEST,
"At least one field information needs to be added.", HttpStatus.NOT_FOUND);
}
long countElements = claimAttachmentsViewRepository.count(new Specification<ClaimattachmentsView>() {

@Override
public Predicate toPredicate(Root<ClaimattachmentsView> root, CriteriaQuery<?> query,
CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();

getQueryData(searchClaimAttachments275Request, root, cb, predicates);

return cb.and(predicates.toArray(new Predicate[0]));
}

});
logger.info("The result count is " + countElements);

List<SearchClaimAttachments275Response> responseList = null;
if (countElements > 0) {
responseList = querySpecification(searchClaimAttachments275Request, pageable);
}

searchResponse = new GenericResponse(searchClaimAttachments275Request.getPageNumber(),
searchClaimAttachments275Request.getPageSize(), searchClaimAttachments275Request.getSortColumn(),
countElements, responseList);
} catch (Exception e) {
throw new GenericException(ErrorMessages.DATA_ACCESS_ERROR, e.getMessage(),
HttpStatus.INTERNAL_SERVER_ERROR);
}

if (searchResponse != null && searchResponse.getResponse() != null) {
logger.info("The search results are " + searchResponse.getResponse().toString());
}
return searchResponse;
}

private PageRequest generatePagination(SearchClaimAttachments275Request searchClaimAttachments275Request) {
PageRequest pageable;

String sortFields = sort275Fields(searchClaimAttachments275Request.getSortColumn());
boolean descending = searchClaimAttachments275Request.getDescending();
Sort.Direction direction = descending ? Sort.Direction.DESC : Sort.Direction.ASC;

// zero-based index
int pidx = searchClaimAttachments275Request.getPageNumber().intValue() - 1;
int psiz = searchClaimAttachments275Request.getPageSize().intValue();

logger.info("generatePagination(): The sort is" //
+ " sortFields " + sortFields //
+ ", descending: " + descending + " => " + (descending ? "descending" : "ascending") //
+ ", Sort.Direction " + direction //
+ ", pidx: " + pidx //
+ ", psiz: " + psiz //
);
String[] sortArray = sortFields.split(",");
logger.info("The sortArray is " + sortArray.toString() + " length " + sortArray.length);

pageable = new PageRequest(pidx, psiz, direction, sortArray);
return pageable;
}

private String sort275Fields(String sortColumn) {
// Map from requested sortColumn string used by the frontEnd.
String validSort;
sortColumn = isNotNullish(sortColumn) ? sortColumn : "";
switch (sortColumn) {
case IClaimAttachmentsViewConstants.ATTACHMENT_ID_LX:
validSort = "attachmentId,lx01";
break;
case IClaimAttachmentsViewConstants.ATTACHMENT_ID:
validSort = "attachmentId";
break;
case IClaimAttachmentsViewConstants.ATTACHMENT_CONTROL_NUMBER:
validSort = "attachmentControlNumber";
break;
case IClaimAttachmentsViewConstants.CLAIM_IDENTIFIER:
validSort = "externalClaimId";
break;
case IClaimAttachmentsViewConstants.EXTERNAL_CLAIM_ID:
validSort = "externalClaimId";
break;
case IClaimAttachmentsViewConstants.STATUS:
validSort = "status";
break;
case IClaimAttachmentsViewConstants.PATIENT_FIRST_NAME:
validSort = "patientFirstName,patientLastName";
break;
case IClaimAttachmentsViewConstants.PATIENT_LAST_NAME:
validSort = "patientLastName,patientFirstName";
break;
case IClaimAttachmentsViewConstants.PATIENT_CONTROL_NUMBER:
validSort = "patientControlNumber";
break;
case IClaimAttachmentsViewConstants.PATIENT_IDENTIFIER:
validSort = "patientIdentifierNumber";
break;
case IClaimAttachmentsViewConstants.PROVIDER_NAME:
validSort = "providerName";
break;
case IClaimAttachmentsViewConstants.PROVIDER_NPI:
validSort = "providerNpi";
break;
case IClaimAttachmentsViewConstants.MEDICAL_RECORD_NUMBER:
validSort = "medicalRecordNumber";
break;
case IClaimAttachmentsViewConstants.PAYER_CONTROL_NUMBER:
validSort = "payerClaimControlNumber";
break;
case IClaimAttachmentsViewConstants.REPORT_CODE:
validSort = "reportCode";
break;
case IClaimAttachmentsViewConstants.CLAIM_SERVICE_START_DATE:
validSort = "claimServiceStartDate";
break;
case IClaimAttachmentsViewConstants.CLAIM_SERVICE_END_DATE:
validSort = "claimServiceEndDate";
break;
case IClaimAttachmentsViewConstants.ATTACHMENT_TYPE:
validSort = "attachmentType";
break;
default:
validSort = "attachmentId,lx01";
}
logger.info("The requested Sort Column is \"" + sortColumn + "\" => \"" + validSort + "\"");
return validSort;
}

private boolean checkRequestNullOrEmpty(SearchClaimAttachments275Request req) {
return Stream
.of(req.getAttachId(), req.getAttachIdLx(), req.getAttachCtrNumber(), req.getClaimId(), req.getStatus(),
req.getPatientLastName(), req.getPatientFirstName(), req.getPatientCtrNumber(),
req.getPatientIdentifier(), req.getProviderName(), req.getProviderNpi(),
req.getMedicalRecordNumber(), req.getAttachType(), req.getPayerControlNumber(),
req.getReportTypeCode(), req.getClaimServiceStartDate(), req.getClaimServiceEndDate())
.filter(t -> isNotNullish(t)).findAny().isPresent();
}

private void getQueryData(SearchClaimAttachments275Request search275Request, Root<ClaimattachmentsView> root,
CriteriaBuilder cb, List<Predicate> predicates) {

if (isNotNullish(search275Request.getAttachIdLx())) {
predicates.add(cb.equal(root.get("attachIdLx"), search275Request.getAttachIdLx()));
}
if (isNotNullish(search275Request.getAttachId())) {
predicates.add(cb.equal(root.get("attachmentId"), search275Request.getAttachId()));
}
if (isNotNullish(search275Request.getAttachCtrNumber())) {
predicates.add(cb.equal(cb.lower(root.get("attachmentControlNumber")),
search275Request.getAttachCtrNumber().toLowerCase()));
}
if (isNotNullish(search275Request.getClaimId())) {
predicates.add(cb.equal(cb.lower(root.get("externalClaimId")), search275Request.getClaimId()));
}
if (isNotNullish(search275Request.getStatus())) {
predicates.add(cb.equal(cb.lower(root.get("status")), search275Request.getStatus().toLowerCase()));
}

if (isNotNullish(search275Request.getPatientLastName())) {
if (containsWildCardChar(search275Request.getPatientLastName())) {
// partial search: accepts % or _ and uses criteriaBuilder.like()
predicates.add(cb.like(cb.lower(root.get("patientLastName")),
search275Request.getPatientLastName().toLowerCase()));
} else {
predicates.add(cb.equal(cb.lower(root.get("patientLastName")),
search275Request.getPatientLastName().toLowerCase()));
}
}
if (isNotNullish(search275Request.getPatientFirstName())) {
if (containsWildCardChar(search275Request.getPatientFirstName())) {
// partial search: accepts % or _ and uses criteriaBuilder.like()
predicates.add(cb.like(cb.lower(root.get("patientFirstName")),
search275Request.getPatientFirstName().toLowerCase()));
} else {
predicates.add(cb.equal(cb.lower(root.get("patientFirstName")),
search275Request.getPatientFirstName().toLowerCase()));
}
}
if (isNotNullish(search275Request.getPatientCtrNumber())) {
predicates.add(cb.equal(cb.lower(root.get("patientControlNumber")),
search275Request.getPatientCtrNumber().toLowerCase()));
}
if (isNotNullish(search275Request.getPatientIdentifier())) {
predicates.add(cb.equal(cb.lower(root.get("patientIdentifierNumber")),
search275Request.getPatientIdentifier().toLowerCase()));
}
if (isNotNullish(search275Request.getProviderName())) {
if (containsWildCardChar(search275Request.getProviderName())) {
// partial search: accepts % or _ and uses criteriaBuilder.like()
predicates.add(
cb.like(cb.lower(root.get("providerName")), search275Request.getProviderName().toLowerCase()));
} else {
predicates.add(
cb.equal(cb.lower(root.get("providerName")), search275Request.getProviderName().toLowerCase()));
}
}
if (isNotNullish(search275Request.getProviderNpi())) {
predicates
.add(cb.equal(cb.lower(root.get("providerNpi")), search275Request.getProviderNpi().toLowerCase()));
}
if (isNotNullish(search275Request.getMedicalRecordNumber())) {
predicates.add(cb.equal(cb.lower(root.get("medicalRecordNumber")),
search275Request.getMedicalRecordNumber().toLowerCase()));
}
if (isNotNullish(search275Request.getPayerControlNumber())) {
predicates.add(cb.equal(cb.lower(root.get("payerClaimControlNumber")),
search275Request.getPayerControlNumber().toLowerCase()));
}
if (isNotNullish(search275Request.getReportTypeCode())) {
if (search275Request.getReportTypeCode().trim().equalsIgnoreCase("all")) {
// no predicate is added since report type code is 'all'
} else {
predicates.add(
cb.equal(cb.lower(root.get("reportCode")), search275Request.getReportTypeCode().toLowerCase()));
}
}
if (isNotNullish(search275Request.getClaimServiceStartDate())) {
String dbClaimServiceStartDate = backendDateString(search275Request.getClaimServiceStartDate());
predicates.add(cb.greaterThanOrEqualTo(root.get("claimServiceStartDate"), dbClaimServiceStartDate));
}
if (isNotNullish(search275Request.getClaimServiceEndDate())) {
String dbClaimServiceEndDate = backendDateString(search275Request.getClaimServiceEndDate());
predicates.add(cb.lessThanOrEqualTo(root.get("claimServiceEndDate"), dbClaimServiceEndDate));
}

}

private boolean containsWildCardChar(String searchParam) {
return searchParam.contains("%") || searchParam.contains("_");
}

private List<SearchClaimAttachments275Response> querySpecification(//
SearchClaimAttachments275Request search275Request, PageRequest pageable) {
Page<ClaimattachmentsView> cm = (Page<ClaimattachmentsView>) claimAttachmentsViewRepository
.findAll(new Specification<ClaimattachmentsView>() {

@Override
public Predicate toPredicate(Root<ClaimattachmentsView> root, CriteriaQuery<?> query,
CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();

getQueryData(search275Request, root, cb, predicates);

return cb.and(predicates.toArray(new Predicate[0]));
}

}, pageable);

return assignData(cm);
}

private List<SearchClaimAttachments275Response> assignData(Page<ClaimattachmentsView> cm) {
List<SearchClaimAttachments275Response> responseList = new ArrayList<>();
for (ClaimattachmentsView cs : cm) {
responseList.add(getClean275Response(cs));
}
return responseList;
}

private static boolean isNotNullish(String s) {
return s != null && !s.trim().isEmpty();
}

private SearchClaimAttachments275Response getClean275Response(ClaimattachmentsView cs) {
SearchClaimAttachments275Response response = new SearchClaimAttachments275Response();

response.setAttachIdLx(cs.getAttachIdLx());
response.setAttachId(cs.getAttachmentId());
response.setAttachCtrNumber(cs.getAttachmentControlNumber());
String externalClaimId = clean(cs.getExternalClaimId());
response.setExternalClaimId(externalClaimId);
response.setClaimId(externalClaimId);
response.setPatientIdentifier(clean(cs.getPatientIdentifierNumber()));
response.setProviderNpi(clean(cs.getProviderNpi()));
response.setStatus(cs.getStatus());
response.setPatientName(cs.getPatientLastName() + ", " + cs.getPatientFirstName());

response.setPatientCtrNumber(cs.getPatientControlNumber());
response.setProviderName(cs.getProviderName());
response.setMedicalRecordNumber(cs.getMedicalRecordNumber());
response.setPayerControlNumber(cs.getPayerClaimControlNumber());
response.setReportTypeCode(cs.getReportCode());
response.setAttachType(cs.getAttachmentType());
response.setClaimServiceStartDate(frontendDateString(cs.getClaimServiceStartDate()));
response.setClaimServiceEndDate(frontendDateString(cs.getClaimServiceEndDate()));
return response;
}

private String clean(String s) {
return (StringUtils.isNotBlank(s)) ? s.replaceAll("\\s", "") : "";
}

// reformat string from backend to frontend date style
private static String frontendDateString(String backend) {
String frontendDateStr = ""; // Default value in case it throws
if (backend != null) {
try {
Date date = backend_dateFormat.parse(backend);
// If parse throws, we do not setClaimServiceStartDate()
frontendDateStr = frontend_dateFormat.format(date);
} catch (ParseException e) {
logger.info("Error in backend Date Format: " + backend);
e.printStackTrace();
}
}
return frontendDateStr;
}

// reformat string from frontend to backend date style
private static String backendDateString(String frontend) {
String backend = ""; // Default value in case it throws
if (frontend != null) {
try {
Date date = frontend_dateFormat.parse(frontend);
// If parse throws, we do not setClaimServiceStartDate()
backend = backend_dateFormat.format(date);
} catch (ParseException e) {
logger.info("Error in backend Date Format: " + frontend);
e.printStackTrace();
}
}
return backend;
}

}