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.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import gov.va.med.ars.constants.ClaimSubmissionConstants;
import gov.va.med.ars.dao.ars.ClaimContactRepository;
import gov.va.med.ars.dao.ars.EmailTemplateRepository;
import gov.va.med.ars.dao.ars.IArsUserRepository;
import gov.va.med.ars.dao.ars.IClaimSubmissionRepository;
import gov.va.med.ars.dao.ars.IPayerInfoRepository;
import gov.va.med.ars.exceptions.GenericException;
import gov.va.med.ars.model.response.CodeAndLevel;
import gov.va.med.ars.model.response.RfaiLineItemResponse;
import gov.va.med.ars.model.response.RfaiResponse;
import gov.va.med.ars.service.IRfaiRequestSubmitService;
import gov.va.med.ars.util.Email;
import gov.va.med.ars.util.EmailInfo;
import gov.va.med.domain.ars.ArsUser;
import gov.va.med.domain.ars.ClaimCodeBridge;
import gov.va.med.domain.ars.ClaimCodeBridgeId;
import gov.va.med.domain.ars.ClaimContact;
import gov.va.med.domain.ars.ClaimSubmission;
import gov.va.med.domain.ars.ClaimSvcLines;
import gov.va.med.domain.ars.EmailTemplate;
import gov.va.med.domain.ars.PayerConfig;
@Service
public class RfaiRequestSubmitServiceImpl implements IRfaiRequestSubmitService {
private static final Logger logger = LogManager.getLogger(RfaiRequestSubmitServiceImpl.class);
@Autowired
private IClaimSubmissionRepository claimSubmissionRepo;
@Autowired
private ClaimContactRepository claimContactRepo;
@Autowired
IArsUserRepository arsUserRepo;
@Autowired
IPayerInfoRepository payerInfoRepo;
@Autowired
EmailInfo info;
@Autowired
EmailTemplateRepository emailRepo;
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
@Override
public boolean submitAdditionalInfoRequest(RfaiResponse request) throws GenericException {
logger.info("In AdditionalInfoRequestServiceImpl");
boolean isCreated = false;
Date dateCreatedAndModified = new Date(System.currentTimeMillis());
ClaimSubmission claimSubmission = new ClaimSubmission();
Set<CodeAndLevel> codeAndLevelFromRequest = request.getCodeAndLevelList();
Set<ClaimCodeBridge> ccbSet = new HashSet<>();
List<RfaiLineItemResponse> lineItemFromRequest = request.getRfaiLineItemResponse();
validateRequestForBusinessRules(lineItemFromRequest, codeAndLevelFromRequest);
rearrangeOrderOfLoincModIds(codeAndLevelFromRequest);
// if line item is empty
if (lineItemFromRequest == null || lineItemFromRequest.isEmpty()) {
Date claimSvcFromDate = null;
Date claimSvcToDate = null;
try {
if (request.getServiceFromDate() != null && request.getServiceFromDate() != "") {
claimSvcFromDate = dateFormat.parse(request.getServiceFromDate());
}
if (request.getServiceToDate() != null && request.getServiceToDate() != "") {
claimSvcToDate = dateFormat.parse(request.getServiceToDate());
} else {
//if claim service to date is null then use from date
claimSvcToDate = dateFormat.parse(request.getServiceFromDate());
}
} catch (ParseException e) {
logger.info("Error in parsing claim service from/to date from request");
throw new GenericException("ERR",
"Error in parsing claim level service from/to date. Please send it in format of MM/dd/yyyy",
HttpStatus.BAD_REQUEST);
}
if(claimSvcFromDate != null ) {
claimSubmission.setDtp103svcfrmdt(claimSvcFromDate);
}
if(claimSvcToDate != null) {
claimSubmission.setDtp103svctodt(claimSvcToDate);
} else {
//extra check if claimSvcToDate is null then user from date, should not be null here
claimSubmission.setDtp103svctodt(claimSvcFromDate);
}
addClaimLevelCodesToBridge(claimSubmission, codeAndLevelFromRequest, ccbSet);
}
Set<ClaimSvcLines> claimSvcLines = new HashSet<>();
// if at least 1 line item exists
if (request.getRfaiLineItemResponse() != null && !request.getRfaiLineItemResponse().isEmpty()) {
// 2 item exists
Date svcFromDateBegin = null;
Date svcToDateBegin = null;
for (RfaiLineItemResponse rfaiLineItem : request.getRfaiLineItemResponse()) {
Date svcFromDate = null;
Date svcToDate = null;
try {
if (rfaiLineItem.getServiceFrom() != null && rfaiLineItem.getServiceFrom() != "") {
svcFromDate = dateFormat.parse(rfaiLineItem.getServiceFrom());
}
if (rfaiLineItem.getServiceTo() != null && rfaiLineItem.getServiceTo() != "") {
svcToDate = dateFormat.parse(rfaiLineItem.getServiceTo());
}
} catch (ParseException e) {
logger.info("Error in parsing line service from or to date from request");
throw new GenericException("ERR",
"Error in parsing line level service from/to date. Please send it in format of MM/dd/yyyy",
HttpStatus.BAD_REQUEST);
}
ClaimSvcLines lineItem = new ClaimSvcLines();
lineItem.setRef02svclnnmbr(rfaiLineItem.getServiceLineId().toString());
if(svcFromDate != null) {
lineItem.setDtp03svcfrmdt(svcFromDate);
}
if(svcToDate != null) {
lineItem.setDtp03svctodt(svcToDate);
claimSubmission.setDtp103svctodt(svcToDate);
} else {
if(svcFromDateBegin == null) {
svcFromDateBegin = svcFromDate;
svcToDateBegin = svcFromDate;
} else {
if(svcFromDate != null && svcFromDate.before(svcFromDateBegin)) {
svcFromDateBegin = svcFromDate;
} else {
if(svcToDateBegin != null && svcToDateBegin.after(svcFromDate)) {
svcToDateBegin = svcFromDate;
}
}
}
}
claimSubmission.setDtp103svcfrmdt(svcFromDateBegin);
claimSubmission.setDtp103svctodt(svcToDateBegin);
lineItem.setSvc01revcd(rfaiLineItem.getRevenueCode());
lineItem.setSvc01proccd(rfaiLineItem.getProcedureCode());
lineItem.setSvc01mod(rfaiLineItem.getModifiers());
lineItem.setSvc02chrgamt(rfaiLineItem.getChargeAmount());
lineItem.setDatecreated(dateCreatedAndModified);
lineItem.setDatemodified(dateCreatedAndModified);
lineItem.setClaimSubmission(claimSubmission);
claimSvcLines.add(lineItem);
}
addClaimLevelCodesToBridge(claimSubmission, codeAndLevelFromRequest, ccbSet);
}
setDtp203ResponseDueDate(request, claimSubmission);
logger.info("claimSvcLines size() : " + claimSvcLines.size());
claimSubmission.setClaimSvcLineses(claimSvcLines);
claimSubmission.setTrn02claimIndex(request.getClaimId());
// auto pop
if(!request.getPayerName().isEmpty()&&!request.getPayerId().isEmpty()&&request.getPayerIndex()==null){
claimSubmission.setHl1nm103pyrNm(request.getPayerName());
claimSubmission.setHl1nm109pyrId(request.getPayerId());
}
// manual entry
else{
PayerConfig payerRecord=payerInfoRepo.findByPayerIndex(request.getPayerIndex());
claimSubmission.setPayerConfig(payerRecord);
claimSubmission.setHl1nm103pyrNm(request.getPayerName());
claimSubmission.setHl1nm109pyrId(request.getPayerId());
}
claimSubmission.setHl2nm103infRcvr(request.getInformationReceiver());
claimSubmission.setHl3nm109prvnpi(request.getProviderNpi());
claimSubmission.setHl2nm109svcprvtin(request.getProviderTin());
claimSubmission.setHl4nm103ptlstnm(request.getPatientLastname());
claimSubmission.setHl4nm104ptftnm(request.getPatientFirstName());
claimSubmission.setHl4nm105ptmdlnm(request.getPatientMiddleName());
claimSubmission.setHl4nm107ptsfx(request.getPatientSuffix());
claimSubmission.setHl4nm109ptid(request.getPatientIdentifier());
claimSubmission.setRef102ptctrlnmbr(request.getPatientcontrolNumber());
claimSubmission.setTrn02pyrclmctrlnmbr(request.getPayerClaimControlNumber());
claimSubmission.setRef202billtype(request.getBillType());
claimSubmission.setRef402clrnghsid(request.getClearingHouseId());
claimSubmission.setRef302medrecnmbr(request.getMedicalRecordNumber());
claimSubmission.setHl3nm103svcbillprvnm(request.getProviderInformation());
claimSubmission.setSubmissionStatus(ClaimSubmissionConstants.SUBMISSION_SUBMITTED_STATUS);
claimSubmission.setGenerate277Status(ClaimSubmissionConstants.SUBMISSION_PENDING_STATUS);
claimSubmission.setDatecreated(dateCreatedAndModified);
claimSubmission.setDatemodified(dateCreatedAndModified);
claimSubmission.setDatesubmitted(dateCreatedAndModified);
ArsUser arsUserInfo = arsUserRepo.findByUserNameIgnoreCase(request.getSubmittedBy());
ClaimContact claimContact = null;
if (!request.getContactInformation().isEmpty() && request.getContactInformation() != null) {
claimContact = claimContactRepo.findOneByContactemailAndSubmittedbyAllIgnoreCase(
request.getContactInformation(), arsUserInfo.getEmailAddress());
}
if (claimContact == null) {
ClaimContact newContact = new ClaimContact();
newContact.setContactemail(request.getContactInformation().toLowerCase());
newContact.setDatecreated(dateCreatedAndModified);
newContact.setDatemodified(dateCreatedAndModified);
newContact.setSubmittedby(arsUserInfo.getEmailAddress());
claimContact = claimContactRepo.save(newContact);
}
claimSubmission.setClaimContact(claimContact);
try {
ClaimSubmission clmSubmission = claimSubmissionRepo.save(claimSubmission);
addLineLevelCodesToBridge(codeAndLevelFromRequest, ccbSet, clmSubmission);
ccbSet.forEach(ccb -> ccb.getId().setSubmissionid(clmSubmission.getSubmissionid()));
clmSubmission.setClaimCodeBridges(ccbSet);
ClaimSubmission clmSubmissionWithCodes = claimSubmissionRepo.save(clmSubmission);
if (clmSubmission != null && clmSubmissionWithCodes != null) {
isCreated = true;
List<ClaimContact> claimContacts = claimContactRepo.findAllByclaimSubmissions(clmSubmission);
sendSubmissionEmail(clmSubmission, claimContacts);
}
} catch (Exception e) {
logger.error(
"AdditionalInfoRequestServiceImpl.submitAdditionalInfoRequest() : exception occured while submitting additional info data "
+ "claimId = " + request.getClaimId() + " " + e);
throw new GenericException("ERR",
"Could not add Codes to Database. Please contact your administrator for details",
HttpStatus.INTERNAL_SERVER_ERROR);
}
return isCreated;
}
private void setDtp203ResponseDueDate(RfaiResponse request, ClaimSubmission claimSubmission)
throws GenericException {
Date responseDate = null;
try {
responseDate = dateFormat.parse(request.getResponseDate());
} catch (ParseException e) {
logger.info("Error in parsing response date from request");
throw new GenericException("ERR", "Error in parsing response date. Please send it in format of MM/dd/yyyy",
HttpStatus.BAD_REQUEST);
}
claimSubmission.setDtp203responseduedate(responseDate);
}
private void rearrangeOrderOfLoincModIds(Set<CodeAndLevel> codeAndLevelFromRequest) {
if (codeAndLevelFromRequest.stream()
.anyMatch(c -> c.getLoincCodeModifier1() == 0 && c.getLoincCodeModifier2() != 0)) {
codeAndLevelFromRequest.stream()
.filter(c -> c.getLoincCodeModifier1() == 0 && c.getLoincCodeModifier2() != 0).forEach(c -> {
c.setLoincCodeModifier1(c.getLoincCodeModifier2());
c.setLoincCodeModifier2(0L);
});
}
}
private void validateRequestForBusinessRules(List<RfaiLineItemResponse> rfaiLineItemFromRequest,
Set<CodeAndLevel> codeAndLevelFromRequest) throws GenericException {
if (codeAndLevelFromRequest == null || codeAndLevelFromRequest.isEmpty()) {
logger.error(
"AdditionalInfoRequestServiceImpl.submitAdditionalInfoRequest() : codeAndLevel array is empty");
throw new GenericException("ERR", "Please enter in at least 1 HCCS/LOINC/LOINC_MOD Codes",
HttpStatus.BAD_REQUEST);
}
if (codeAndLevelFromRequest.size() > 6) {
logger.error(
"AdditionalInfoRequestServiceImpl.submitAdditionalInfoRequest() : codeAndLevel array size greater than 6");
throw new GenericException("ERR", "Please enter maximum of 6 HCCS/LOINC/LOINC_MOD Code Sets",
HttpStatus.BAD_REQUEST);
}
if ((rfaiLineItemFromRequest == null || rfaiLineItemFromRequest.isEmpty())
&& codeAndLevelFromRequest.stream().anyMatch(c -> !c.getLineNumber().equals("0"))) {
logger.error(
"AdditionalInfoRequestServiceImpl.submitAdditionalInfoRequest() : lineItem not present but codeLevelFromRequest contains line level codes");
throw new GenericException("ERR",
"Please enter in Service Line Information to associate with the Line Level HCCS/LOINC/LOINC_MOD_Codes",
HttpStatus.BAD_REQUEST);
}
// As per the change request the codeAndLevelFromRequest can contain claim level
// though it has the line Items, this validation is not required
/*
* if ((rfaiLineItemFromRequest != null && !rfaiLineItemFromRequest.isEmpty())
* && codeAndLevelFromRequest.stream().allMatch(c -> c.getIsClaim() == true)) {
* logger.error(
* "AdditionalInfoRequestServiceImpl.submitAdditionalInfoRequest() : lineItem present but codeLevelFromRequest does not contain any line level codes"
* ); throw new GenericException("ERR",
* "Please enter in Line Level HCCS/LOINC/LOINC_MOD_Codes to associate with the Service Line Information."
* , HttpStatus.BAD_REQUEST);
*
* }
*/
}
private void addLineLevelCodesToBridge(Set<CodeAndLevel> codeAndLevelFromRequest, Set<ClaimCodeBridge> ccbSet,
ClaimSubmission clmSubmission) {
Set<ClaimSvcLines> clmSvcLines = clmSubmission.getClaimSvcLineses();
Set<CodeAndLevel> codeAndLevelForLine = codeAndLevelFromRequest.stream()
.filter(codeAndLevel -> !codeAndLevel.getLineNumber().equals("0")).collect(Collectors.toSet());
if (clmSvcLines != null && !clmSvcLines.isEmpty()) {
for (ClaimSvcLines svcLineItem : clmSvcLines) {
for (CodeAndLevel cal : codeAndLevelForLine) {
if (svcLineItem.getRef02svclnnmbr().equals(cal.getLineNumber())) {
logger.info("Loading Claim Code Bridges for line number : " + cal.getLineNumber());
ClaimCodeBridgeId ccbId = new ClaimCodeBridgeId();
ccbId.setHccsId(cal.getClaimStatus());
ccbId.setLoincId(cal.getLoincCode());
ccbId.setLoincMod1Id(cal.getLoincCodeModifier1());
ccbId.setLoincMod2Id(cal.getLoincCodeModifier2());
ccbId.setSubmissionsvclineid(svcLineItem.getSubmissionsvclineid());
ClaimCodeBridge ccb = new ClaimCodeBridge(ccbId);
ccbSet.add(ccb);
}
}
}
clmSubmission.setClaimCodeBridges(ccbSet);
}
}
private void addClaimLevelCodesToBridge(ClaimSubmission claimSubmission, Set<CodeAndLevel> codeAndLevelFromRequest,
Set<ClaimCodeBridge> ccbSet) {
Set<CodeAndLevel> codeAndLevelForClaim = codeAndLevelFromRequest.stream()
.filter(codeAndLevel -> codeAndLevel.getLineNumber().equals("0")).collect(Collectors.toSet());
logger.info("codeAndLevelForClaim size is " + codeAndLevelForClaim.size());
for (CodeAndLevel cal : codeAndLevelForClaim) {
ClaimCodeBridgeId ccbId = new ClaimCodeBridgeId();
ccbId.setHccsId(cal.getClaimStatus());
ccbId.setLoincId(cal.getLoincCode());
ccbId.setLoincMod1Id(cal.getLoincCodeModifier1());
ccbId.setLoincMod2Id(cal.getLoincCodeModifier2());
ClaimCodeBridge ccb = new ClaimCodeBridge(ccbId);
ccb.setClaimSubmission(claimSubmission);
ccbSet.add(ccb);
}
}
private void sendSubmissionEmail(ClaimSubmission claimSubmission, List<ClaimContact> claimContacts) {
String templateType = Email.getTemplateName(claimSubmission.getSubmissionStatus());
if(!templateType.equals("Invalid Status")) {
EmailTemplate template = emailRepo.getEmailTemplateByType(templateType);
logger.info("Till here ++++++++++");
Email email = new Email();
try {
email.postMail(claimSubmission, template, info, claimContacts);
} catch (Exception e) {
logger.error(e.getMessage());
}
} else {
logger.error("Submission status is invalid");
}
}
}