using framework_library; using scheduler; using scheduler.MediswitchWebService; using System; using System.Collections; using System.Configuration; using System.Data; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Text; /// /// Summary description for MediSwitch /// public class MediSwitch { MediswitchGatewayV2Service medClient; oMSSetup mainSetup; string connectionString; static string staticConnectionString; ArrayList mod0008IdList, mod0009IdList, mod0018IdList, mod0014IdList; /// /// Constructor /// public MediSwitch(string dbName) { string conn = framework_business.handler.ReturnConfigAppSetting("conn"); connectionString = conn.Replace("{catalog}", dbName); staticConnectionString = connectionString; InstantiateClass(); } private void InstantiateClass() { try { medClient = new scheduler.MediswitchWebService.MediswitchGatewayV2Service(); medClient.Url = ConfigurationManager.AppSettings["Mediswitch.Gateway"]; if (!isOnline()) { medClient.Url = ConfigurationManager.AppSettings["Mediswitch.Gateway1"]; if (!isOnline()) { medClient.Url = ConfigurationManager.AppSettings["Mediswitch.Gateway2"]; } } foreach (oMSSetup setup in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSSetup), "", "", "", "pal_", false, connectionString)) { mainSetup = setup; } } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0, false); } } /// /// check if online /// /// public bool isOnline() { return medClient.echoOperation() == "Mediswitch Gateway OK"; } ///// ///// echo operation ///// ///// //public string echoOperation() //{ // try // { // return medClient.echoOperation(); // } // catch (Exception ex) // { // exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); // return ex.Message.ToString(); // } //} /// /// single MSV call /// /// /// /// public string MSVPatientDataSingle(string destinationCode, string memberNo, string patientDOB = "") { try { string txType = enumMSTransactionType.SwitchOnMembershipStatusValidation.GetHashCode().ToString(), mode = "realtime", txVersion = "119", transmissionNo; int mCounter = 1;//counter for all m records int lastLogId = 0; if (patientDOB != "" && patientDOB != "19000101") { foreach (oMSMsvResponse lastMSVResponse in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSMsvResponse), "membershipNumber,msDestinationCode", memberNo + "," + destinationCode, "recId DESC", "pal_", false, connectionString)) { foreach (oMSMsvResponsePatient lastMSVResponsePatient in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSMsvResponsePatient), "msvResponseId,patientDOB", lastMSVResponse.recId.ToString() + "," + patientDOB, "recId DESC", "pal_", false, connectionString)) { lastLogId = lastMSVResponse.msvLogId; break; } break; } } oMSLog logMSV = new oMSLog(); if (lastLogId > 0) { foreach (oMSLog log in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSLog), "recId", lastLogId.ToString(), "", "pal_", false, connectionString)) { logMSV = log; } } else { if (patientDOB == "")//never do MSV when patientDOB is specified - only use last result { logMSV.operationType = framework_business.pNums.MediswitchOperationType.MSV.GetHashCode(); logMSV.requestDate = DateTime.Now; logMSV.recId = xData.SaveTyped("recId", typeof(oMSLog), logMSV, "pal_", false, connectionString); transmissionNo = logMSV.recId.ToString(); //transactionNumber - get new trans number from raw table logMSV.request = SetupPayloadMSV(txVersion, transmissionNo, mCounter, destinationCode, memberNo, patientDOB); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); submitResponse sResponse = medClient.submitOperation(mainSetup.user, mainSetup.passwd, mainSetup.package, destinationCode, txType, mode, txVersion, transmissionNo, logMSV.request); stopwatch.Stop(); logMSV.roundTripElapsed = Convert.ToInt32(stopwatch.ElapsedMilliseconds); logMSV.response = sResponse.responsePayload; logMSV.status = sResponse.status; logMSV.swref = sResponse.swref; logMSV.retry = sResponse.retry; if (sResponse.responsePayload == "XML Validation error") { Exception ex = new Exception("Custom Exception: XML Validation error"); exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } else ProcessMSVResponse(logMSV); logMSV.responseDate = DateTime.Now; xData.UpdateTyped("recId", logMSV.recId.ToString(), typeof(oMSLog), logMSV, "pal_", false, connectionString); } } return logMSV.response; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } private void ProcessMSVResponse(oMSLog logMSV) { try { string responsePayload = logMSV.response; oMSMsvResponse msvResponse = new oMSMsvResponse(); msvResponse.msvLogId = logMSV.recId; msvResponse.recId = xData.SaveTyped("recId", typeof(oMSMsvResponse), msvResponse); using (System.IO.StringReader reader = new System.IO.StringReader(responsePayload.ToString())) { string line; while ((line = reader.ReadLine()) != null) { string[] splitLine = line.Split('|'); switch (splitLine[0]) { case "H": break; case "S": break; case "M": msvResponse.msvLevel = Convert.ToInt32(splitLine[1]); msvResponse.memberSurname = splitLine[2]; msvResponse.memberFullNames = splitLine[3]; msvResponse.membershipNumber = splitLine[4]; msvResponse.memberIdNumber = splitLine[5]; msvResponse.memberAccountNo = splitLine[6]; msvResponse.address1 = splitLine[7]; msvResponse.address2 = splitLine[8]; msvResponse.town = splitLine[9]; msvResponse.postalCode = splitLine[10]; msvResponse.mobileNo = splitLine[11]; msvResponse.medSchemeName = splitLine[12]; msvResponse.medSchemeRegNo = splitLine[13]; msvResponse.medSchemeRegTypeInd = splitLine[14]; msvResponse.medSchemePlanName = splitLine[15]; msvResponse.medSchemePlanRefNo = splitLine[16]; msvResponse.msDestinationCode = splitLine[17]; msvResponse.medSchemeContactNo = splitLine[18]; xData.UpdateTyped("recId", msvResponse.recId.ToString(), typeof(oMSMsvResponse), msvResponse); break; case "P": oMSMsvResponsePatient msvResponsePatient = new oMSMsvResponsePatient(); msvResponsePatient.msvResponseId = msvResponse.recId; msvResponsePatient.dependantCode = splitLine[1]; msvResponsePatient.patientSurname = splitLine[2]; msvResponsePatient.patientInitials = splitLine[3]; msvResponsePatient.patientFullName = splitLine[4]; msvResponsePatient.patientDOB = DateTime.ParseExact(splitLine[5] == "" ? "19000101" : splitLine[5], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); msvResponsePatient.patientIdNumber = splitLine[6]; msvResponsePatient.patientGender = splitLine[7]; msvResponsePatient.medSchemeEffectiveDate = DateTime.ParseExact(splitLine[8] == "" ? "19000101" : splitLine[8], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); msvResponsePatient.medSchemeTerminationDate = DateTime.ParseExact(splitLine[9] == "" ? "19000101" : splitLine[9], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); msvResponsePatient.medSchemeStatus = splitLine[10]; xData.SaveTyped("recId", typeof(oMSMsvResponsePatient), msvResponsePatient); break; case "RV": oMSMsvResponseLine msvResponseLine = new oMSMsvResponseLine(); msvResponseLine.msvResponseId = msvResponse.recId; break; case "E": break; default: break; } } } } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// MSV Request Payload /// /// /// /// /// /// /// public string SetupPayloadMSV(string txVersion, string transmissionNo, int mCounter, string destinationCode, string memberNo, string patientDOB) { try { oMSMsv msv = new oMSMsv(); msv.msvLogId = Convert.ToInt32(transmissionNo); StringBuilder payloadBuilder = new StringBuilder(); payloadBuilder.AppendLine("H|" + transmissionNo + "|" + txVersion + "|" + mainSetup.softwareName + "|"); //S string PMADatasetID = "1"; //??? payloadBuilder.AppendLine("S|" + DateTime.Now.ToString("yyyyMMddhhmm") + "|" + mainSetup.bpPCNS + "|" + mainSetup.bpName + "|" + PMADatasetID + "|"); //M msv.msvLevel = 1; msv.memberIdNumber = ""; msv.memberTitle = ""; msv.memberInitials = ""; msv.memberSurname = ""; msv.memberFullNames = ""; msv.membershipNumber = memberNo; msv.cardSwipeInd = false; msv.memberAccountNo = "1"; msv.msDestinationCode = destinationCode; payloadBuilder.AppendLine("M|" + msv.msvLevel + "|" + msv.memberIdNumber + "|" + msv.memberTitle + "|" + msv.memberInitials + "|" + msv.memberSurname + "|" + msv.memberFullNames + "|" + msv.membershipNumber + "|" + (msv.cardSwipeInd ? "Y" : "N") + "|" + msv.memberAccountNo + "|" + msv.msDestinationCode + "|"); msv.recId = xData.SaveTyped("recId", typeof(oMSMsv), msv, "pal_", false, connectionString); //P oMSMsvPatient msvPatient = new oMSMsvPatient(); msvPatient.msvId = msv.recId; msvPatient.dependantCode = ""; msvPatient.patientSurname = ""; msvPatient.patientInitials = ""; msvPatient.patientDOB = DateTime.ParseExact(patientDOB == "" ? "19000101" : patientDOB, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); msvPatient.patientGender = ""; msvPatient.patientRelationCode = ""; msvPatient.patientIdNumber = ""; payloadBuilder.AppendLine("P|" + msvPatient.dependantCode + "|" + msvPatient.patientSurname + "|" + msvPatient.patientInitials + "|" + msvPatient.patientFullName + "|" + (msvPatient.patientDOB.ToString("yyyyMMdd") == "19000101" ? "" : msvPatient.patientDOB.ToString("yyyyMMdd")) + "|" + msvPatient.patientGender + "|" + msvPatient.patientRelationCode + "|" + msvPatient.patientIdNumber + "|"); xData.SaveTyped("recId", typeof(oMSMsvPatient), msvPatient, "pal_", false, connectionString); payloadBuilder.AppendLine("E|" + transmissionNo + "|" + mCounter.ToString() + "|"); return payloadBuilder.ToString(); } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// 509 check /// /// public string GetSchemes() { /* TEST2874 test7139 SWITCHON 509 1 */ try { fetchResponse fResponse = medClient.fetchOperation(mainSetup.user, mainSetup.passwd, mainSetup.package, "509", "", "1"); logFetchResponse(fResponse); Process509(fResponse); return fResponse.responsePayload.ToString(); } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Get summarized list of Era Claim Items for the given Era Member record. Need to summarize in case there are Era reversals in a single batch, only show resulting values /// private ArrayList GetSummarizedEraClaimItems(oMSEraMember member) { try { string query = "select MAX(recId) recId, eraMemberId, claimAccountId, claimResponseResultCode, SUM(itemClaimAmount) itemClaimAmount, SUM(totalItemPaidAmount) totalItemPaidAmount, treatmentStartDate, procedureCode, nappiCode " + "from pal_MSEraClaimItem " + "where eraMemberId = " + member.recId + " " + "group by eraMemberId, claimAccountId, claimResponseResultCode, treatmentStartDate, procedureCode, nappiCode"; ArrayList eras = new ArrayList(); eras = xData.GetCustomCollection("recId", typeof(oMSEraClaimItem), query, "", "pal_", false, connectionString); return eras; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); throw ex; } } /// /// Process 307 ERA /// /// /// private void Process307ERA(fetchResponse fResponse, int fetchResponseId) { /* Type H Type S { Type EB } { Type M Type P { Type I Type EY { [Type R] } { [Type EA] } { [Type AF] } { [Type G] } } Type EZ } { [Type EJ] } { [Type G] } [Type DS] Type EF */ try { //process file using (System.IO.StringReader reader = new System.IO.StringReader(fResponse.responsePayload.ToString())) { string line; oMSEra era = new oMSEra(); oMSEraBankDeposit bank = new oMSEraBankDeposit(); oMSEraClaimItem claimItem = new oMSEraClaimItem(); oMSEraClaimItemGeneralComments comments = new oMSEraClaimItemGeneralComments(); oMSEraClaimItemResponse response = new oMSEraClaimItemResponse(); oMSEraJournal journal = new oMSEraJournal(); oMSEraMember member = new oMSEraMember(); while ((line = reader.ReadLine()) != null) { string[] splitLine = line.Split('|'); switch (splitLine[0]) { case "H": //header era = new oMSEra(); era.fetchResponseId = fetchResponseId; era.medicalSchemeName = splitLine[1]; era.medicalSchemeAdministrator = splitLine[2]; era.medicalSchemeRegistrationNumber = splitLine[3]; era.eraReferenceNumber = splitLine[9]; era.eraIssueDate = DateTime.ParseExact(splitLine[10] == "" ? "19000101" : splitLine[10], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); decimal openingBalance = 0, closingBalance = 0; decimal.TryParse(splitLine[11], out openingBalance); if (openingBalance != 0m) openingBalance = openingBalance / 100m; era.openingBalance = openingBalance; decimal.TryParse(splitLine[12], out closingBalance); if (closingBalance != 0m) closingBalance = closingBalance / 100m; era.closingBalance = closingBalance; era.recId = xData.SaveTyped("recId", typeof(oMSEra), era, "pal_", false, connectionString); break; case "S": //service provider break; case "EB": //bank deposit record decimal paymentAmountBank = 0; bank = new oMSEraBankDeposit(); bank.eraId = era.recId; bank.paidToAccountNumber = splitLine[1]; bank.paidToBranchCode = splitLine[2]; bank.paidToBankName = splitLine[3]; bank.paymentDate = DateTime.ParseExact(splitLine[4] == "" ? "19000101" : splitLine[4], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); bank.paymentMethod = splitLine[5]; bank.paymentReferenceNumber = splitLine[6]; decimal.TryParse(splitLine[7], out paymentAmountBank); if (paymentAmountBank != 0m) paymentAmountBank = paymentAmountBank / 100m; bank.paymentAmount = paymentAmountBank; bank.recId = xData.SaveTyped("recId", typeof(oMSEraBankDeposit), bank, "pal_", false, connectionString); break; case "M": //member record member = new oMSEraMember(); member.eraId = era.recId; member.memberSurname = splitLine[1]; member.memberFullName = splitLine[2]; member.membershipNo = splitLine[3]; member.recId = xData.SaveTyped("recId", typeof(oMSEraMember), member, "pal_", false, connectionString); break; case "P": //patient record if (member.eraId == 0) member.eraId = era.recId; member.dependantCode = splitLine[1]; member.patientSurname = splitLine[2]; member.patientInitials = splitLine[3]; member.patientFullName = splitLine[4]; member.patientDOB = DateTime.ParseExact(splitLine[5] == "" ? "19000101" : splitLine[5], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); member.patientIdNumber = splitLine[6]; member.patientAccountNo = splitLine[7]; if (member.recId > 0) xData.UpdateTyped("recId", member.recId.ToString(), typeof(oMSEraMember), member, "pal_", false, connectionString); else member.recId = xData.SaveTyped("recId", typeof(oMSEraMember), member, "pal_", false, connectionString); break; case "I": //claim item record claimItem = new oMSEraClaimItem(); claimItem.eraMemberId = member.recId; claimItem.claimAccountId = splitLine[2]; claimItem.treatmentStartDate = DateTime.ParseExact(splitLine[6] == "" ? "19000101" : splitLine[6].Length > 8 ? splitLine[6].Substring(0, 8) : splitLine[6], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); claimItem.procedureCode = splitLine[8]; claimItem.nappiCode = splitLine[9]; claimItem.claimResponseResultCode = splitLine[11]; claimItem.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItem), claimItem, "pal_", false, connectionString); break; case "EY": //item financial record if (claimItem.eraMemberId == 0) claimItem.eraMemberId = member.recId; decimal itemClaimAmount = 0, totalItemPaidAmount = 0; decimal.TryParse(splitLine[1], out itemClaimAmount); if (itemClaimAmount != 0m) itemClaimAmount = itemClaimAmount / 100m; claimItem.itemClaimAmount = itemClaimAmount; decimal.TryParse(splitLine[2], out totalItemPaidAmount); if (totalItemPaidAmount != 0m) totalItemPaidAmount = totalItemPaidAmount / 100m; claimItem.totalItemPaidAmount = totalItemPaidAmount; if (claimItem.recId > 0) xData.UpdateTyped("recId", claimItem.recId.ToString(), typeof(oMSEraClaimItem), claimItem, "pal_", false, connectionString); else claimItem.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItem), claimItem, "pal_", false, connectionString); break; case "R": //response record response = new oMSEraClaimItemResponse(); response.eraClaimItemId = claimItem.recId; response.responseCode = splitLine[1]; response.responseDescription = splitLine[2]; response.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemResponse), response, "pal_", false, connectionString); break; case "EZ": //member totals record if (member.eraId == 0) member.eraId = era.recId; decimal memberTotalClaimAmount = 0, memberTotalItemPaidAmount = 0, totalPaidToMember = 0, totalPatientLiablePortion = 0; decimal.TryParse(splitLine[1], out memberTotalClaimAmount); if (memberTotalClaimAmount != 0m) memberTotalClaimAmount = memberTotalClaimAmount / 100m; member.totalClaimedAmount = memberTotalClaimAmount; decimal.TryParse(splitLine[2], out memberTotalItemPaidAmount); if (memberTotalItemPaidAmount != 0m) memberTotalItemPaidAmount = memberTotalItemPaidAmount / 100m; member.totalItemPaidAmount = memberTotalItemPaidAmount; decimal.TryParse(splitLine[3], out totalPaidToMember); if (totalPaidToMember != 0m) totalPaidToMember = totalPaidToMember / 100m; member.totalPaidToMember = totalPaidToMember; decimal.TryParse(splitLine[4], out totalPatientLiablePortion); if (totalPatientLiablePortion != 0m) totalPatientLiablePortion = totalPatientLiablePortion / 100m; member.totalPatientLiablePortion = totalPatientLiablePortion; if (member.recId > 0) xData.UpdateTyped("recId", member.recId.ToString(), typeof(oMSEraMember), member, "pal_", false, connectionString); else member.recId = xData.SaveTyped("recId", typeof(oMSEraMember), member, "pal_", false, connectionString); break; case "EJ": //journal record journal = new oMSEraJournal(); journal.eraId = era.recId; decimal journalAmount = 0; decimal.TryParse(splitLine[1], out journalAmount); if (journalAmount != 0m) journalAmount = journalAmount / 100m; journal.journalAmount = journalAmount; journal.journalDescription = splitLine[2]; journal.journalDate = DateTime.ParseExact(splitLine[3] == "" ? "19000101" : splitLine[3], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); journal.recId = xData.SaveTyped("recId", typeof(oMSEraJournal), journal, "pal_", false, connectionString); break; case "G": //general comments record comments = new oMSEraClaimItemGeneralComments(); comments.eraClaimItemId = claimItem.recId; comments.generalComments = splitLine[1]; comments.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemGeneralComments), comments, "pal_", false, connectionString); break; case "DS": //disclaimer record if (era.fetchResponseId == 0) era.fetchResponseId = fetchResponseId; era.disclaimer = splitLine[1]; if (era.recId > 0) xData.UpdateTyped("recId", era.recId.ToString(), typeof(oMSEra), era, "pal_", false, connectionString); else era.recId = xData.SaveTyped("recId", typeof(oMSEra), era, "pal_", false, connectionString); break; case "EF": //financial totals record if (era.fetchResponseId == 0) era.fetchResponseId = fetchResponseId; decimal totalEraClaimedAmount = 0, totalEraPaidAmount = 0, totalEraJournalAmount = 0; decimal.TryParse(splitLine[1], out totalEraClaimedAmount); if (totalEraClaimedAmount != 0m) totalEraClaimedAmount = totalEraClaimedAmount / 100m; era.totalEraClaimedAmount = totalEraClaimedAmount; decimal.TryParse(splitLine[2], out totalEraPaidAmount); if (totalEraPaidAmount != 0m) totalEraPaidAmount = totalEraPaidAmount / 100m; era.totalEraPaidAmount = totalEraPaidAmount; decimal.TryParse(splitLine[3], out totalEraJournalAmount); if (totalEraJournalAmount != 0m) totalEraJournalAmount = totalEraJournalAmount / 100m; era.totalEraJournalAmount = totalEraJournalAmount; if (era.recId > 0) xData.UpdateTyped("recId", era.recId.ToString(), typeof(oMSEra), era, "pal_", false, connectionString); else era.recId = xData.SaveTyped("recId", typeof(oMSEra), era, "pal_", false, connectionString); break; } } } int noteFieldId = 0; //post payments foreach (oMSEra era in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSEra), "fetchResponseId", fetchResponseId.ToString(), "", "pal_", false, connectionString)) { //CVH 2018-03-14 Only post the payments if the era hasn't been captured and processed before ArrayList duplicateEra = xData.GetTypedByCriteriaSpecific("recId", typeof(oMSEra), "medicalSchemeName,medicalSchemeAdministrator,eraReferenceNumber,totalEraClaimedAmount,totalEraPaidAmount,recId", era.medicalSchemeName + "," + era.medicalSchemeAdministrator + "," + era.eraReferenceNumber + "," + era.totalEraClaimedAmount + "," + era.totalEraPaidAmount + ",~<>" + era.recId, "", "pal_", false, connectionString); if (duplicateEra != null && duplicateEra.Count <= 0) { foreach (oMSEraMember member in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSEraMember), "eraId", era.recId.ToString(), "", "pal_", false, connectionString)) { //CVH 2018-02-27 Create one payment per patient oAccount accAllocatedPayment = new oAccount(); oAccount accUnallocatedPayment = new oAccount(); oMSEraClaimItemAccount linkMatched = new oMSEraClaimItemAccount(); oMSEraClaimItemAccount linkUnalloc = new oMSEraClaimItemAccount(); oMedicalPractice practice = new oMedicalPractice(); //foreach (oMSEraClaimItem claim in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSEraClaimItem), "eraMemberId", member.recId.ToString(), "", "pal_", false, connectionString)) foreach (oMSEraClaimItem claim in GetSummarizedEraClaimItems(member)) { /* * 03 = Claim Rejected * 08 = Claim Adjusted * 09 = Claim Paid in Full * 10 = Claim Part Paid */ //if claim isn't rejected, and the paid amount is not zero, post payment if (claim.claimResponseResultCode != "03" && claim.totalItemPaidAmount != 0m) { //get billing lines (because of modifier, could be multiple ArrayList billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", claim.claimAccountId, "", "pal_", false, connectionString); //CVH 2018-03-02 If no line number, get patient. If negative payment, save as unprocessed. //CVH 2018-03-22 If account number given on line, but it's for a modifier, get all modifiers, medaid groups them together but gives single account id string dateOfService = claim.treatmentStartDate.ToString("yyyy-MM-dd"); if ((billings.Count <= 0 || claim.procedureCode == "0005" || claim.procedureCode == "0008" || claim.procedureCode == "0009" || claim.procedureCode == "0011" || claim.procedureCode == "0014" || claim.procedureCode == "0018") && claim.totalItemPaidAmount > 0) { string patientNum = member.patientAccountNo; int patientNumTmp = 0; if (int.TryParse(patientNum, out patientNumTmp) && patientNumTmp > 0) { //if procedure is modifier, need to find multiple modifier lines in data (don't look at procedurecode) if (claim.procedureCode == "0005" || claim.procedureCode == "0008" || claim.procedureCode == "0009" || claim.procedureCode == "0011" || claim.procedureCode == "0014" || claim.procedureCode == "0018") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber,dateOfService,isVisible,modifier1", patientNumTmp + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.procedureCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber,dateOfService,isVisible,procedureCode", patientNumTmp + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.nappiCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber,dateOfService,isVisible,procedureNAPPI", patientNumTmp + "," + dateOfService + ",1," + claim.nappiCode, "recId ASC", "pal_", false, connectionString); } } //CVH 2018-03-02 If couldn't get patient on patient Number, use membership number and patient name. If negative payment, save as unprocessed. if ((billings.Count <= 0 || claim.procedureCode == "0005" || claim.procedureCode == "0008" || claim.procedureCode == "0009" || claim.procedureCode == "0011" || claim.procedureCode == "0014" || claim.procedureCode == "0018") && claim.totalItemPaidAmount > 0) { //if procedure is modifier, need to find multiple modifier lines in data (don't look at procedurecode) if (claim.procedureCode == "0005" || claim.procedureCode == "0008" || claim.procedureCode == "0009" || claim.procedureCode == "0011" || claim.procedureCode == "0014" || claim.procedureCode == "0018") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "medAidNumber,patientName,dateOfService,isVisible,modifier1", member.membershipNo + "," + member.patientFullName + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.procedureCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "medAidNumber,patientName,dateOfService,isVisible,procedureCode", member.membershipNo + "," + member.patientFullName + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.nappiCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "medAidNumber,patientName,dateOfService,isVisible,procedureNAPPI", member.membershipNo + "," + member.patientFullName + "," + dateOfService + ",1," + claim.nappiCode, "recId ASC", "pal_", false, connectionString); } //billing lines linked to era found if (billings.Count > 0 && claim.totalItemPaidAmount > 0) { //don't loop through billing to create payment, just need one to get account details, then use claim details for amount. If loop, it adds the claim amount multiple times incorrectly oAccount billingAcc = (oAccount)billings[0]; decimal amount = 0; if (noteFieldId == 0) { //find note field foreach (oSurfaceItem surfaceItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceItem), "recId", billingAcc.surfaceItemId.ToString(), "", "pal_", false, connectionString)) { foreach (oSurfaceField field in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceField), "surfaceId,surfaceFieldTypeId,isActive", surfaceItem.surfaceId + ",21,1", "", "pal_", false, connectionString)) { noteFieldId = field.recId; break; } } } if (accAllocatedPayment.recId <= 0) { accAllocatedPayment.surfaceItemId = billingAcc.surfaceItemId; accAllocatedPayment.name = billingAcc.name; accAllocatedPayment.surname = billingAcc.surname; accAllocatedPayment.title = billingAcc.title; accAllocatedPayment.initials = billingAcc.initials; accAllocatedPayment.idNumber = billingAcc.idNumber; accAllocatedPayment.birthDate = billingAcc.birthDate; accAllocatedPayment.patientCode = billingAcc.patientCode; accAllocatedPayment.gender = billingAcc.gender; accAllocatedPayment.planCode = billingAcc.planCode; accAllocatedPayment.medCode = billingAcc.medCode; accAllocatedPayment.claimSend = false; accAllocatedPayment.claimSent = false; accAllocatedPayment.doctorNo = billingAcc.doctorNo; accAllocatedPayment.doctor = billingAcc.doctor; accAllocatedPayment.practiceNo = billingAcc.practiceNo; accAllocatedPayment.vatRate = billingAcc.vatRate; accAllocatedPayment.postalAddress = billingAcc.postalAddress; accAllocatedPayment.patientNumber = billingAcc.patientNumber; accAllocatedPayment.medAidNumber = billingAcc.medAidNumber; accAllocatedPayment.medAidName = billingAcc.medAidName; accAllocatedPayment.patientTitle = billingAcc.patientTitle; accAllocatedPayment.patientInitials = billingAcc.patientInitials; accAllocatedPayment.patientName = billingAcc.patientName; accAllocatedPayment.patientSurname = billingAcc.patientSurname; accAllocatedPayment.email = billingAcc.email; accAllocatedPayment.isLocked = false; //practice if (practice.recId <= 0) { foreach (oMedicalPractice prac in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalPractice), "recId", billingAcc.practiceNo.ToString(), "", "pal_", false, connectionString)) { practice = prac; break; } } //unit fee amount = claim.totalItemPaidAmount * -1; //procedure info - medical aid transfer accAllocatedPayment.procedureCode = "M-EFT"; accAllocatedPayment.procedureDescription = "Payment - Medical Aid Transfer"; accAllocatedPayment.procedureType = "PM"; //amounts accAllocatedPayment.amount = amount; //receipt number accAllocatedPayment.receiptNo = xData.GetNextRecNo(false, connectionString); accAllocatedPayment.qty = 1; //service date accAllocatedPayment.dateOfService = System.DateTime.Now; //CVH 2018-03-23 //accAllocatedPayment.vatRate = 14; accAllocatedPayment.vatRate = practice.vatRate; accAllocatedPayment.serviceType = "T"; accAllocatedPayment.placeOfService = 11; accAllocatedPayment.inHospital = false; accAllocatedPayment.category = 0; accAllocatedPayment.authorisationNo = ""; accAllocatedPayment.referringDocNo = ""; accAllocatedPayment.referringDoctor = ""; //date of capture accAllocatedPayment.dateOfCapture = DateTime.Now; //JR 2017-03-03 date of transaction accAllocatedPayment.dateOfTransaction = accAllocatedPayment.dateOfService; //liabilities accAllocatedPayment.liablePat = 0; accAllocatedPayment.liableMed = 0; //visible on statement accAllocatedPayment.isVisible = true; //plan code accAllocatedPayment.planCode = ""; //running balance accAllocatedPayment.runningBal += accAllocatedPayment.amount; //set sequence on payment accAllocatedPayment.sequence = xData.GetNextSequence(accAllocatedPayment.dateOfService, accAllocatedPayment.surfaceItemId, false, connectionString); accAllocatedPayment.recId = xData.SaveTyped("recId", typeof(oAccount), accAllocatedPayment, "pal_", false, connectionString); //save era link account linkMatched.accountId = accAllocatedPayment.recId; linkMatched.eraClaimItemId = claim.recId.ToString(); linkMatched.originalProcessDate = System.DateTime.Now; linkMatched.manualProcessUserId = 0; linkMatched.manualProcessed = false; linkMatched.manualAllocateUserId = 0; linkMatched.manualAllocated = false; linkMatched.rejected = false; linkMatched.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), linkMatched, "pal_", false, connectionString); } else { //unit fee amount = claim.totalItemPaidAmount * -1; //amounts accAllocatedPayment.amount += amount; //running balance accAllocatedPayment.runningBal += amount; xData.UpdateTyped("recId", accAllocatedPayment.recId.ToString(), typeof(oAccount), accAllocatedPayment, "pal_", false, connectionString); linkMatched.eraClaimItemId += "," + claim.recId; xData.UpdateTyped("recId", linkMatched.recId.ToString(), typeof(oMSEraClaimItemAccount), linkMatched, "pal_", false, connectionString); } if (accAllocatedPayment.recId > 0) { bool billingsAllocated = false; decimal ToAllocate = Math.Abs(claim.totalItemPaidAmount); foreach (oAccount allBillAcc in billings) { //apply allocations if (ToAllocate > 0) { decimal availToAlloc = allBillAcc.amount - allBillAcc.allocated; if (availToAlloc > 0) { accAllocatedPayment.procedureDescription += " -" + allBillAcc.procedureCode; if (availToAlloc == ToAllocate)//the amount is the same { allBillAcc.allocated = allBillAcc.amount; allBillAcc.liableMed = 0; allBillAcc.liablePat = 0; if (allBillAcc.allocatedReference == String.Empty) { allBillAcc.allocatedReference = accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } else { allBillAcc.allocatedReference += "," + accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } if (xData.UpdateTyped("recId", allBillAcc.recId.ToString(), typeof(oAccount), allBillAcc, "pal_", false, connectionString)) { //update allocated reference to payment if (accAllocatedPayment.allocatedReference == String.Empty) { accAllocatedPayment.allocatedReference = allBillAcc.recId.ToString(); } else { accAllocatedPayment.allocatedReference += "," + allBillAcc.recId.ToString() + ":" + Convert.ToString(availToAlloc); } ToAllocate = 0; } } else if (availToAlloc > ToAllocate)//then we want to partially allocate the billing { allBillAcc.allocated += ToAllocate; allBillAcc.liableMed = 0; allBillAcc.liablePat = allBillAcc.amount - allBillAcc.allocated; if (allBillAcc.allocatedReference == String.Empty) { allBillAcc.allocatedReference = accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(ToAllocate); } else { allBillAcc.allocatedReference += "," + accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(ToAllocate); } if (xData.UpdateTyped("recId", allBillAcc.recId.ToString(), typeof(oAccount), allBillAcc, "pal_", false, connectionString)) { //update allocated reference to payment if (accAllocatedPayment.allocatedReference == String.Empty) { accAllocatedPayment.allocatedReference = allBillAcc.recId.ToString(); } else { accAllocatedPayment.allocatedReference += "," + allBillAcc.recId.ToString(); } ToAllocate = 0; } } else if (ToAllocate > availToAlloc)//we have more to allcoate so will allocate in full and use left over for next billing { allBillAcc.allocated = allBillAcc.amount; allBillAcc.liableMed = 0; allBillAcc.liablePat = 0; if (allBillAcc.allocatedReference == String.Empty) { allBillAcc.allocatedReference = accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } else { allBillAcc.allocatedReference += "," + accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } if (xData.UpdateTyped("recId", allBillAcc.recId.ToString(), typeof(oAccount), allBillAcc, "pal_", false, connectionString)) { //update allocated reference to payment if (accAllocatedPayment.allocatedReference == String.Empty) { accAllocatedPayment.allocatedReference = allBillAcc.recId.ToString(); } else { accAllocatedPayment.allocatedReference += "," + allBillAcc.recId.ToString(); } ToAllocate -= availToAlloc;//deduct from whats availabel to allocate } } billingsAllocated = true; xData.UpdateTyped("recId", accAllocatedPayment.recId.ToString(), typeof(oAccount), accAllocatedPayment, "pal_", false, connectionString); } } else { //CVH 2018-03-05 If none left to allocate, move amount to Patient Liable allBillAcc.liablePat += allBillAcc.liableMed; allBillAcc.liableMed = 0; xData.UpdateTyped("recId", allBillAcc.recId.ToString(), typeof(oAccount), allBillAcc, "pal_", false, connectionString); } } if (ToAllocate > 0)//then split payment to allow for allocation later { accAllocatedPayment.amount = (Math.Abs(accAllocatedPayment.amount) - ToAllocate) * -1; //if couldn't allocate anything, and payment is now 0, delete payment if (accAllocatedPayment.amount == 0) { xData.DeleteTyped("recId", accAllocatedPayment.recId.ToString(), typeof(oAccount), "pal_", false, connectionString); accAllocatedPayment = new oAccount(); xData.DeleteTyped("recId", linkMatched.recId.ToString(), typeof(oMSEraClaimItemAccount), "pal_", false, connectionString); linkMatched = new oMSEraClaimItemAccount(); } else { xData.UpdateTyped("recId", accAllocatedPayment.recId.ToString(), typeof(oAccount), accAllocatedPayment, "pal_", false, connectionString); //if no billings allocated for the era line, remove era line from link if (!billingsAllocated) { if (linkMatched.eraClaimItemId.StartsWith(claim.recId + ",")) linkMatched.eraClaimItemId = linkMatched.eraClaimItemId.Substring(claim.recId.ToString().Length + 1); else if (linkMatched.eraClaimItemId.Contains("," + claim.recId + ",")) linkMatched.eraClaimItemId = linkMatched.eraClaimItemId.Replace("," + claim.recId + ",", ","); else if (linkMatched.eraClaimItemId.EndsWith("," + claim.recId)) linkMatched.eraClaimItemId = linkMatched.eraClaimItemId.Substring(0, linkMatched.eraClaimItemId.LastIndexOf(",")); } } //create only one unAllocated payment per patient if (accUnallocatedPayment.recId <= 0) { accUnallocatedPayment.surfaceItemId = billingAcc.surfaceItemId; accUnallocatedPayment.name = billingAcc.name; accUnallocatedPayment.surname = billingAcc.surname; accUnallocatedPayment.title = billingAcc.title; accUnallocatedPayment.initials = billingAcc.initials; accUnallocatedPayment.idNumber = billingAcc.idNumber; accUnallocatedPayment.birthDate = billingAcc.birthDate; accUnallocatedPayment.patientCode = billingAcc.patientCode; accUnallocatedPayment.gender = billingAcc.gender; accUnallocatedPayment.planCode = billingAcc.planCode; accUnallocatedPayment.medCode = billingAcc.medCode; accUnallocatedPayment.claimSend = false; accUnallocatedPayment.claimSent = false; accUnallocatedPayment.doctorNo = billingAcc.doctorNo; accUnallocatedPayment.doctor = billingAcc.doctor; accUnallocatedPayment.practiceNo = billingAcc.practiceNo; accUnallocatedPayment.vatRate = billingAcc.vatRate; accUnallocatedPayment.postalAddress = billingAcc.postalAddress; accUnallocatedPayment.patientNumber = billingAcc.patientNumber; accUnallocatedPayment.medAidNumber = billingAcc.medAidNumber; accUnallocatedPayment.medAidName = billingAcc.medAidName; accUnallocatedPayment.patientTitle = billingAcc.patientTitle; accUnallocatedPayment.patientInitials = billingAcc.patientInitials; accUnallocatedPayment.patientName = billingAcc.patientName; accUnallocatedPayment.patientSurname = billingAcc.patientSurname; accUnallocatedPayment.email = billingAcc.email; accUnallocatedPayment.isLocked = false; //practice if (practice.recId <= 0) { foreach (oMedicalPractice prac in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalPractice), "recId", billingAcc.practiceNo.ToString(), "", "pal_", false, connectionString)) { practice = prac; break; } } accUnallocatedPayment.allocatedReference = ""; accUnallocatedPayment.amount = ToAllocate * -1; //procedure info - medical aid transfer accUnallocatedPayment.procedureCode = "M-EFT"; accUnallocatedPayment.procedureDescription = "Payment - Medical Aid Transfer"; accUnallocatedPayment.procedureType = "PM"; //receipt number accUnallocatedPayment.receiptNo = xData.GetNextRecNo(false, connectionString); accUnallocatedPayment.qty = 1; //service date accUnallocatedPayment.dateOfService = System.DateTime.Now; //CVH 2018-03-23 accUnallocatedPayment.vatRate = practice.vatRate; accUnallocatedPayment.serviceType = "T"; accUnallocatedPayment.placeOfService = 11; accUnallocatedPayment.inHospital = false; accUnallocatedPayment.category = 0; accUnallocatedPayment.authorisationNo = ""; accUnallocatedPayment.referringDocNo = ""; accUnallocatedPayment.referringDoctor = ""; //date of capture accUnallocatedPayment.dateOfCapture = DateTime.Now; //JR 2017-03-03 date of transaction accUnallocatedPayment.dateOfTransaction = accUnallocatedPayment.dateOfService; //liabilities accUnallocatedPayment.liablePat = 0; accUnallocatedPayment.liableMed = 0; //visible on statement accUnallocatedPayment.isVisible = true; //plan code accUnallocatedPayment.planCode = ""; //running balance accUnallocatedPayment.runningBal += (ToAllocate * -1); //set sequence on payment accUnallocatedPayment.sequence = xData.GetNextSequence(accUnallocatedPayment.dateOfService, accUnallocatedPayment.surfaceItemId, false, connectionString); accUnallocatedPayment.recId = xData.SaveTyped("recId", typeof(oAccount), accUnallocatedPayment, "pal_", false, connectionString); //insert era link linkUnalloc.accountId = accUnallocatedPayment.recId; linkUnalloc.eraClaimItemId = claim.recId.ToString(); linkUnalloc.originalProcessDate = System.DateTime.Now; linkUnalloc.manualProcessed = false; linkUnalloc.manualProcessUserId = 0; linkUnalloc.manualAllocated = false; linkUnalloc.manualAllocateUserId = 0; linkUnalloc.rejected = false; linkUnalloc.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), linkUnalloc, "pal_", false, connectionString); } else { //unit fee decimal unallocAmount = ToAllocate * -1; //amounts accUnallocatedPayment.amount += unallocAmount; //running balance accUnallocatedPayment.runningBal += unallocAmount; xData.UpdateTyped("recId", accUnallocatedPayment.recId.ToString(), typeof(oAccount), accUnallocatedPayment, "pal_", false, connectionString); //update era link linkUnalloc.eraClaimItemId += "," + claim.recId; xData.UpdateTyped("recId", linkUnalloc.recId.ToString(), typeof(oMSEraClaimItemAccount), linkUnalloc, "pal_", false, connectionString); } } } } else { oAccount billingAcc = new oAccount(); //billing line linked to era not found, find patient/member string patientNumber = member.patientAccountNo; int patientNumTmp = 0; if (int.TryParse(patientNumber, out patientNumTmp) && patientNumTmp > 0) { foreach (oAccount acc in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber", patientNumTmp.ToString(), "isVisible DESC, recId DESC", "pal_", false, connectionString)) { billingAcc = acc; break; } } //patient linked to era found if (billingAcc.recId > 0 && claim.totalItemPaidAmount > 0) { //find note field foreach (oSurfaceItem surfaceItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceItem), "recId", billingAcc.surfaceItemId.ToString(), "", "pal_", false, connectionString)) { foreach (oSurfaceField field in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceField), "surfaceId,surfaceFieldTypeId,isActive", surfaceItem.surfaceId + ",21,1", "", "pal_", false, connectionString)) { noteFieldId = field.recId; break; } } if (accUnallocatedPayment.recId <= 0) { accUnallocatedPayment.surfaceItemId = billingAcc.surfaceItemId; accUnallocatedPayment.name = billingAcc.name; accUnallocatedPayment.surname = billingAcc.surname; accUnallocatedPayment.title = billingAcc.title; accUnallocatedPayment.initials = billingAcc.initials; accUnallocatedPayment.idNumber = billingAcc.idNumber; accUnallocatedPayment.birthDate = billingAcc.birthDate; accUnallocatedPayment.patientCode = billingAcc.patientCode; accUnallocatedPayment.gender = billingAcc.gender; accUnallocatedPayment.planCode = billingAcc.planCode; accUnallocatedPayment.medCode = billingAcc.medCode; accUnallocatedPayment.claimSend = false; accUnallocatedPayment.claimSent = false; accUnallocatedPayment.doctorNo = billingAcc.doctorNo; accUnallocatedPayment.doctor = billingAcc.doctor; accUnallocatedPayment.practiceNo = billingAcc.practiceNo; accUnallocatedPayment.vatRate = billingAcc.vatRate; accUnallocatedPayment.postalAddress = billingAcc.postalAddress; accUnallocatedPayment.patientNumber = billingAcc.patientNumber; accUnallocatedPayment.medAidNumber = billingAcc.medAidNumber; accUnallocatedPayment.medAidName = billingAcc.medAidName; accUnallocatedPayment.patientTitle = billingAcc.patientTitle; accUnallocatedPayment.patientInitials = billingAcc.patientInitials; accUnallocatedPayment.patientName = billingAcc.patientName; accUnallocatedPayment.patientSurname = billingAcc.patientSurname; accUnallocatedPayment.email = billingAcc.email; accUnallocatedPayment.isLocked = false; //practice if (practice.recId <= 0) { foreach (oMedicalPractice prac in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalPractice), "recId", billingAcc.practiceNo.ToString(), "", "pal_", false, connectionString)) { practice = prac; break; } } //unit fee decimal unallocAmount = claim.totalItemPaidAmount * -1; //procedure info - medical aid transfer accUnallocatedPayment.procedureCode = "M-EFT"; accUnallocatedPayment.procedureDescription = "Payment - Medical Aid Transfer"; accUnallocatedPayment.procedureType = "PM"; //amounts accUnallocatedPayment.amount = unallocAmount; //receipt number accUnallocatedPayment.receiptNo = xData.GetNextRecNo(false, connectionString); accUnallocatedPayment.qty = 1; //service date accUnallocatedPayment.dateOfService = System.DateTime.Now; //CVH 2018-03-23 accUnallocatedPayment.vatRate = practice.vatRate; accUnallocatedPayment.serviceType = "T"; accUnallocatedPayment.placeOfService = 11; accUnallocatedPayment.inHospital = false; accUnallocatedPayment.category = 0; accUnallocatedPayment.authorisationNo = ""; accUnallocatedPayment.referringDocNo = ""; accUnallocatedPayment.referringDoctor = ""; //date of capture accUnallocatedPayment.dateOfCapture = DateTime.Now; //JR 2017-03-03 date of transaction accUnallocatedPayment.dateOfTransaction = accUnallocatedPayment.dateOfService; //liabilities accUnallocatedPayment.liablePat = 0; accUnallocatedPayment.liableMed = 0; //visible on statement accUnallocatedPayment.isVisible = true; //plan code accUnallocatedPayment.planCode = ""; //running balance accUnallocatedPayment.runningBal += unallocAmount; //set sequence on payment accUnallocatedPayment.sequence = xData.GetNextSequence(accUnallocatedPayment.dateOfService, accUnallocatedPayment.surfaceItemId, false, connectionString); accUnallocatedPayment.recId = xData.SaveTyped("recId", typeof(oAccount), accUnallocatedPayment, "pal_", false, connectionString); //insert era link linkUnalloc.accountId = accUnallocatedPayment.recId; linkUnalloc.eraClaimItemId = claim.recId.ToString(); linkUnalloc.originalProcessDate = System.DateTime.Now; linkUnalloc.manualProcessed = false; linkUnalloc.manualProcessUserId = 0; linkUnalloc.manualAllocated = false; linkUnalloc.manualAllocateUserId = 0; linkUnalloc.rejected = false; linkUnalloc.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), linkUnalloc, "pal_", false, connectionString); } else { //unit fee decimal unallocAmount = claim.totalItemPaidAmount * -1; //amounts accUnallocatedPayment.amount += unallocAmount; //running balance accUnallocatedPayment.runningBal += unallocAmount; xData.UpdateTyped("recId", accUnallocatedPayment.recId.ToString(), typeof(oAccount), accUnallocatedPayment, "pal_", false, connectionString); //update era link linkUnalloc.eraClaimItemId += "," + claim.recId; xData.UpdateTyped("recId", linkUnalloc.recId.ToString(), typeof(oMSEraClaimItemAccount), linkUnalloc, "pal_", false, connectionString); } } else { //couldn't find invoice line or patient account or is negative payment, save item to log for manual allocation oMSEraClaimItemAccount link4 = new oMSEraClaimItemAccount(); link4.accountId = 0; link4.eraClaimItemId = claim.recId.ToString(); link4.originalProcessDate = System.DateTime.Now; link4.manualProcessed = false; link4.manualProcessUserId = 0; link4.manualAllocated = false; link4.manualAllocateUserId = 0; link4.rejected = false; link4.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), link4, "pal_", false, connectionString); } } } else if (claim.claimResponseResultCode == "03") { //get billing lines (because of modifier, could be multiple ArrayList billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", claim.claimAccountId, "", "pal_", false, connectionString); //CVH 2018-03-02 If no line number, get patient. If negative payment, save as unprocessed. string dateOfService = claim.treatmentStartDate.ToString("yyyy-MM-dd"); if (billings.Count <= 0) { string patientNum = member.patientAccountNo; int patientNumTmp = 0; if (int.TryParse(patientNum, out patientNumTmp) && patientNumTmp > 0) { //if procedure is modifier, need to find multiple modifier lines in data (don't look at procedurecode) if (claim.procedureCode == "0005" || claim.procedureCode == "0008" || claim.procedureCode == "0009" || claim.procedureCode == "0011" || claim.procedureCode == "0014" || claim.procedureCode == "0018") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber,dateOfService,isVisible,modifier1", patientNumTmp + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.procedureCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber,dateOfService,isVisible,procedureCode", patientNumTmp + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.nappiCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber,dateOfService,isVisible,procedureNAPPI", patientNumTmp + "," + dateOfService + ",1," + claim.nappiCode, "recId ASC", "pal_", false, connectionString); } } //CVH 2018-03-02 If couldn't get patient on patient Number, use membership number and patient name. If negative payment, save as unprocessed. if (billings.Count <= 0) { //if procedure is modifier, need to find multiple modifier lines in data (don't look at procedurecode) if (claim.procedureCode == "0005" || claim.procedureCode == "0008" || claim.procedureCode == "0009" || claim.procedureCode == "0011" || claim.procedureCode == "0014" || claim.procedureCode == "0018") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "medAidNumber,patientName,dateOfService,isVisible,modifier1", member.membershipNo + "," + member.patientFullName + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.procedureCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "medAidNumber,patientName,dateOfService,isVisible,procedureCode", member.membershipNo + "," + member.patientFullName + "," + dateOfService + ",1," + claim.procedureCode, "recId ASC", "pal_", false, connectionString); else if (claim.nappiCode != "") billings = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "medAidNumber,patientName,dateOfService,isVisible,procedureNAPPI", member.membershipNo + "," + member.patientFullName + "," + dateOfService + ",1," + claim.nappiCode, "recId ASC", "pal_", false, connectionString); } oMSEraClaimItemAccount link5 = new oMSEraClaimItemAccount(); link5.accountId = 0; link5.eraClaimItemId = claim.recId.ToString(); link5.originalProcessDate = System.DateTime.Now; link5.manualProcessed = false; link5.manualProcessUserId = 0; link5.manualAllocated = false; link5.manualAllocateUserId = 0; link5.rejected = true; link5.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), link5, "pal_", false, connectionString); //if era sends back claim is rejected, update liable values of account if it could be found foreach (oAccount billingAcc in billings) { billingAcc.liablePat = billingAcc.liablePat + billingAcc.liableMed; billingAcc.liableMed = 0; xData.UpdateTyped("recId", billingAcc.recId.ToString(), typeof(oAccount), billingAcc, "pal_", false, connectionString); } } } string noteCaption = "A payment was receipted via eRA to the value of R " + utils.returnFormattedDecimal((accAllocatedPayment.amount).ToString()) + "
Procedures " + accAllocatedPayment.procedureDescription.Replace("Payment - Medical Aid Transfer", ""); //Add new note of type "Payment" oNote note = new oNote(); note.moduleId = 10; //surface note.typeId = 7; //note type Payment note.entityId = accAllocatedPayment.surfaceItemId; //note.title = accAllocatedPayment.procedureDescription; note.title = accAllocatedPayment.procedureDescription.Length > 200 ? accAllocatedPayment.procedureDescription.Substring(0, 200) : accAllocatedPayment.procedureDescription; note.caption = noteCaption; note.dateSaved = DateTime.Now; note.userIdSaved = 0; note.isActive = true; note.fieldName = noteFieldId.ToString(); note.recId = xData.SaveTyped("recId", typeof(oNote), note, "pal_", false, connectionString); //Add new note of type "Payment" oNote noteUnalloc = new oNote(); noteUnalloc.moduleId = 10; //surface noteUnalloc.typeId = 7; //note type Payment noteUnalloc.entityId = accUnallocatedPayment.surfaceItemId; //noteUnalloc.title = accUnallocatedPayment.procedureDescription; noteUnalloc.title = accUnallocatedPayment.procedureDescription.Length > 200 ? accUnallocatedPayment.procedureDescription.Substring(0, 200) : accUnallocatedPayment.procedureDescription; noteUnalloc.caption = "A payment was receipted via eRA to the value of R " + utils.returnFormattedDecimal((accUnallocatedPayment.amount * -1).ToString()); noteUnalloc.dateSaved = DateTime.Now; noteUnalloc.userIdSaved = 0; noteUnalloc.isActive = true; noteUnalloc.fieldName = noteFieldId.ToString(); noteUnalloc.recId = xData.SaveTyped("recId", typeof(oNote), noteUnalloc, "pal_", false, connectionString); } } } #region backup /* //post payments foreach (oMSEra era in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSEra), "fetchResponseId", fetchResponseId.ToString(), "", "pal_", false, connectionString)) { foreach (oMSEraMember member in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSEraMember), "eraId", era.recId.ToString(), "", "pal_", false, connectionString)) { foreach (oMSEraClaimItem claim in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSEraClaimItem), "eraMemberId", member.recId.ToString(), "", "pal_", false, connectionString)) { * 03 = Claim Rejected * 08 = Claim Adjusted * 09 = Claim Paid in Full * 10 = Claim Part Paid //if claim isn't rejected, and the paid amount is not zero, post payment if (claim.claimResponseResultCode != "03" && claim.totalItemPaidAmount != 0m) { int noteFieldId = 0; //get billing line oAccount billingAcc = new oAccount(); foreach (oAccount acc in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", claim.claimAccountId, "", "pal_", false, connectionString)) { billingAcc = acc; } //billing line linked to era found if (billingAcc.recId > 0) { //find note field foreach (oSurfaceItem surfaceItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceItem), "recId", billingAcc.surfaceItemId.ToString(), "", "pal_", false, connectionString)) { foreach (oSurfaceField field in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceField), "surfaceId,surfaceFieldTypeId,isActive", surfaceItem.surfaceId + ",21,1", "", "pal_", false, connectionString)) { noteFieldId = field.recId; break; } } oAccount accAllocatedPayment = new oAccount(); accAllocatedPayment.surfaceItemId = billingAcc.surfaceItemId; accAllocatedPayment.name = billingAcc.name; accAllocatedPayment.surname = billingAcc.surname; accAllocatedPayment.title = billingAcc.title; accAllocatedPayment.initials = billingAcc.initials; accAllocatedPayment.idNumber = billingAcc.idNumber; accAllocatedPayment.birthDate = billingAcc.birthDate; accAllocatedPayment.patientCode = billingAcc.patientCode; accAllocatedPayment.gender = billingAcc.gender; accAllocatedPayment.planCode = billingAcc.planCode; accAllocatedPayment.medCode = billingAcc.medCode; accAllocatedPayment.claimSend = false; accAllocatedPayment.claimSent = false; accAllocatedPayment.doctorNo = billingAcc.doctorNo; accAllocatedPayment.doctor = billingAcc.doctor; accAllocatedPayment.practiceNo = billingAcc.practiceNo; accAllocatedPayment.vatRate = billingAcc.vatRate; accAllocatedPayment.postalAddress = billingAcc.postalAddress; accAllocatedPayment.patientNumber = billingAcc.patientNumber; accAllocatedPayment.medAidNumber = billingAcc.medAidNumber; accAllocatedPayment.medAidName = billingAcc.medAidName; accAllocatedPayment.patientTitle = billingAcc.patientTitle; accAllocatedPayment.patientInitials = billingAcc.patientInitials; accAllocatedPayment.patientName = billingAcc.patientName; accAllocatedPayment.patientSurname = billingAcc.patientSurname; accAllocatedPayment.email = billingAcc.email; accAllocatedPayment.isLocked = false; //unit fee decimal unitFee = claim.totalItemPaidAmount; //procedure info - medical aid transfer accAllocatedPayment.procedureCode = "M-EFT"; string noteCaption = "A payment was receipted via eRA to the value of R " + utils.returnFormattedDecimal((unitFee * -1).ToString()); accAllocatedPayment.procedureDescription = "Payment - Medical Aid Transfer"; accAllocatedPayment.procedureType = "PM"; //amounts accAllocatedPayment.amount = unitFee * -1; //receipt number accAllocatedPayment.receiptNo = xData.GetNextRecNo(false, connectionString); accAllocatedPayment.qty = 1; //service date accAllocatedPayment.dateOfService = System.DateTime.Now; //TO DO Theses will be selectable from setup and billing screen accAllocatedPayment.vatRate = 14; accAllocatedPayment.serviceType = "T"; accAllocatedPayment.placeOfService = 11; accAllocatedPayment.inHospital = false; accAllocatedPayment.category = 0; accAllocatedPayment.authorisationNo = ""; accAllocatedPayment.referringDocNo = ""; accAllocatedPayment.referringDoctor = ""; //date of capture accAllocatedPayment.dateOfCapture = DateTime.Now; //JR 2017-03-03 date of transaction accAllocatedPayment.dateOfTransaction = accAllocatedPayment.dateOfService; //liabilities accAllocatedPayment.liablePat = 0; accAllocatedPayment.liableMed = 0; //visible on statement accAllocatedPayment.isVisible = true; //plan code accAllocatedPayment.planCode = ""; //running balance accAllocatedPayment.runningBal += accAllocatedPayment.amount; //set sequence on payment accAllocatedPayment.sequence = xData.GetNextSequence(accAllocatedPayment.dateOfService, accAllocatedPayment.surfaceItemId, false, connectionString); accAllocatedPayment.recId = xData.SaveTyped("recId", typeof(oAccount), accAllocatedPayment, "pal_", false, connectionString); oMSEraClaimItemAccount link1 = new oMSEraClaimItemAccount(); link1.accountId = accAllocatedPayment.recId; link1.eraClaimItemId = claim.recId; link1.originalProcessDate = System.DateTime.Now; link1.manualProcessUserId = 0; link1.manualProcessed = false; link1.manualAllocateUserId = 0; link1.manualAllocated = false; link1.rejected = false; link1.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), link1, "pal_", false, connectionString); if (accAllocatedPayment.recId > 0) { bool billingsAllocated = false; decimal ToAllocate = Math.Abs(accAllocatedPayment.amount); //apply allocations if (ToAllocate > 0) { accAllocatedPayment.procedureDescription += " -" + billingAcc.procedureCode; decimal availToAlloc = billingAcc.amount - billingAcc.allocated; if (availToAlloc == ToAllocate)//the amount is the same { billingAcc.allocated = billingAcc.amount; billingAcc.liableMed = 0; billingAcc.liablePat = 0; if (billingAcc.allocatedReference == String.Empty) { billingAcc.allocatedReference = accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } else { billingAcc.allocatedReference += "," + accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } if (xData.UpdateTyped("recId", billingAcc.recId.ToString(), typeof(oAccount), billingAcc, "pal_", false, connectionString)) { //update allocated reference to payment if (accAllocatedPayment.allocatedReference == String.Empty) { accAllocatedPayment.allocatedReference = billingAcc.recId.ToString(); } else { accAllocatedPayment.allocatedReference += "," + billingAcc.recId.ToString() + ":" + Convert.ToString(availToAlloc); } ToAllocate = 0; } } else if (availToAlloc > ToAllocate)//then we want to partially allocate the billing { billingAcc.allocated += ToAllocate; billingAcc.liableMed = 0; billingAcc.liablePat = billingAcc.amount - billingAcc.allocated; if (billingAcc.allocatedReference == String.Empty) { billingAcc.allocatedReference = accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(ToAllocate); } else { billingAcc.allocatedReference += "," + accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(ToAllocate); } if (xData.UpdateTyped("recId", billingAcc.recId.ToString(), typeof(oAccount), billingAcc, "pal_", false, connectionString)) { //update allocated reference to payment if (accAllocatedPayment.allocatedReference == String.Empty) { accAllocatedPayment.allocatedReference = billingAcc.recId.ToString(); } else { accAllocatedPayment.allocatedReference += "," + billingAcc.recId.ToString(); } ToAllocate = 0; } } else if (ToAllocate > availToAlloc)//we have more to allcoate so will allocate in full and use left over for next billing { billingAcc.allocated = billingAcc.amount; billingAcc.liableMed = 0; billingAcc.liablePat = 0; if (billingAcc.allocatedReference == String.Empty) { billingAcc.allocatedReference = accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } else { billingAcc.allocatedReference += "," + accAllocatedPayment.recId.ToString() + ":" + Convert.ToString(availToAlloc); } if (xData.UpdateTyped("recId", billingAcc.recId.ToString(), typeof(oAccount), billingAcc, "pal_", false, connectionString)) { //update allocated reference to payment if (accAllocatedPayment.allocatedReference == String.Empty) { accAllocatedPayment.allocatedReference = billingAcc.recId.ToString(); } else { accAllocatedPayment.allocatedReference += "," + billingAcc.recId.ToString(); } ToAllocate -= availToAlloc;//deduct from whats availabel to allocate } } billingsAllocated = true; xData.UpdateTyped("recId", accAllocatedPayment.recId.ToString(), typeof(oAccount), accAllocatedPayment, "pal_", false, connectionString); noteCaption = noteCaption + "
Procedures " + accAllocatedPayment.procedureDescription.Replace("Payment - Medical Aid Transfer", ""); } //Add new note of type "Payment" oNote note = new oNote(); note.moduleId = 10; //surface note.typeId = 7; //note type Payment note.entityId = accAllocatedPayment.surfaceItemId; note.title = accAllocatedPayment.procedureDescription; note.caption = noteCaption; note.dateSaved = DateTime.Now; note.userIdSaved = 0; note.isActive = true; note.fieldName = noteFieldId.ToString(); note.recId = xData.SaveTyped("recId", typeof(oNote), note, "pal_", false, connectionString); if (ToAllocate > 0 && billingsAllocated)//then split payment to allow for allocation later { accAllocatedPayment.amount = (Math.Abs(accAllocatedPayment.amount) - ToAllocate) * -1; if (xData.UpdateTyped("recId", accAllocatedPayment.recId.ToString(), typeof(oAccount), accAllocatedPayment, "pal_", false, connectionString)) { //create a new payment oAccount accPaymentNew = (oAccount)utils.CloneObject(accAllocatedPayment); accPaymentNew.isLocked = false; accPaymentNew.recId = 0; accPaymentNew.allocatedReference = ""; accPaymentNew.amount = ToAllocate * -1; accAllocatedPayment.sequence += 1; accPaymentNew.recId = xData.SaveTyped("recId", typeof(oAccount), accPaymentNew, "pal_", false, connectionString); oMSEraClaimItemAccount link2 = new oMSEraClaimItemAccount(); link2.accountId = accPaymentNew.recId; link2.eraClaimItemId = claim.recId; link2.originalProcessDate = System.DateTime.Now; link2.manualProcessed = false; link2.manualProcessUserId = 0; link2.manualAllocated = false; link2.manualAllocateUserId = 0; link2.rejected = false; link2.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), link2, "pal_", false, connectionString); //Add new note of type "Payment" oNote noteNew = new oNote(); noteNew.moduleId = 10; //surface noteNew.typeId = 7; //note type Payment noteNew.entityId = accPaymentNew.surfaceItemId; noteNew.title = accAllocatedPayment.procedureDescription; noteNew.caption = "A payment was receipted via eRA to the value of R " + utils.returnFormattedDecimal((accAllocatedPayment.amount * -1).ToString()); noteNew.dateSaved = DateTime.Now; noteNew.userIdSaved = 0; noteNew.isActive = true; noteNew.fieldName = noteFieldId.ToString(); noteNew.recId = xData.SaveTyped("recId", typeof(oNote), noteNew, "pal_", false, connectionString); } } } } else { //billing line linked to era not found, find patient/member string patientNumber = member.patientAccountNo; foreach (oAccount acc in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "patientNumber", patientNumber, "isVisible DESC, recId DESC", "pal_", false, connectionString)) { billingAcc = acc; break; } //patient linked to era found if (billingAcc.recId > 0) { //find note field foreach (oSurfaceItem surfaceItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceItem), "recId", billingAcc.surfaceItemId.ToString(), "", "pal_", false, connectionString)) { foreach (oSurfaceField field in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceField), "surfaceId,surfaceFieldTypeId,isActive", surfaceItem.surfaceId + ",21,1", "", "pal_", false, connectionString)) { noteFieldId = field.recId; break; } } oAccount accUnllocatedPayment = new oAccount(); accUnllocatedPayment.surfaceItemId = billingAcc.surfaceItemId; accUnllocatedPayment.name = billingAcc.name; accUnllocatedPayment.surname = billingAcc.surname; accUnllocatedPayment.title = billingAcc.title; accUnllocatedPayment.initials = billingAcc.initials; accUnllocatedPayment.idNumber = billingAcc.idNumber; accUnllocatedPayment.birthDate = billingAcc.birthDate; accUnllocatedPayment.patientCode = billingAcc.patientCode; accUnllocatedPayment.gender = billingAcc.gender; accUnllocatedPayment.planCode = billingAcc.planCode; accUnllocatedPayment.medCode = billingAcc.medCode; accUnllocatedPayment.claimSend = false; accUnllocatedPayment.claimSent = false; accUnllocatedPayment.doctorNo = billingAcc.doctorNo; accUnllocatedPayment.doctor = billingAcc.doctor; accUnllocatedPayment.practiceNo = billingAcc.practiceNo; accUnllocatedPayment.vatRate = billingAcc.vatRate; accUnllocatedPayment.postalAddress = billingAcc.postalAddress; accUnllocatedPayment.patientNumber = billingAcc.patientNumber; accUnllocatedPayment.medAidNumber = billingAcc.medAidNumber; accUnllocatedPayment.medAidName = billingAcc.medAidName; accUnllocatedPayment.patientTitle = billingAcc.patientTitle; accUnllocatedPayment.patientInitials = billingAcc.patientInitials; accUnllocatedPayment.patientName = billingAcc.patientName; accUnllocatedPayment.patientSurname = billingAcc.patientSurname; accUnllocatedPayment.email = billingAcc.email; accUnllocatedPayment.isLocked = false; //unit fee decimal unitFee = claim.totalItemPaidAmount; //procedure info - medical aid transfer accUnllocatedPayment.procedureCode = "M-EFT"; string noteCaption = "A payment was receipted via eRA to the value of R " + utils.returnFormattedDecimal((unitFee * -1).ToString()); accUnllocatedPayment.procedureDescription = "Payment - Medical Aid Transfer"; accUnllocatedPayment.procedureType = "PM"; //amounts accUnllocatedPayment.amount = unitFee * -1; //receipt number accUnllocatedPayment.receiptNo = xData.GetNextRecNo(false, connectionString); accUnllocatedPayment.qty = 1; //service date accUnllocatedPayment.dateOfService = System.DateTime.Now; //TO DO Theses will be selectable from setup and billing screen accUnllocatedPayment.vatRate = 14; accUnllocatedPayment.serviceType = "T"; accUnllocatedPayment.placeOfService = 11; accUnllocatedPayment.inHospital = false; accUnllocatedPayment.category = 0; accUnllocatedPayment.authorisationNo = ""; accUnllocatedPayment.referringDocNo = ""; accUnllocatedPayment.referringDoctor = ""; //date of capture accUnllocatedPayment.dateOfCapture = DateTime.Now; //JR 2017-03-03 date of transaction accUnllocatedPayment.dateOfTransaction = accUnllocatedPayment.dateOfService; //liabilities accUnllocatedPayment.liablePat = 0; accUnllocatedPayment.liableMed = 0; //visible on statement accUnllocatedPayment.isVisible = true; //plan code accUnllocatedPayment.planCode = ""; //running balance accUnllocatedPayment.runningBal += accUnllocatedPayment.amount; //set sequence on payment accUnllocatedPayment.sequence = xData.GetNextSequence(accUnllocatedPayment.dateOfService, accUnllocatedPayment.surfaceItemId, false, connectionString); accUnllocatedPayment.recId = xData.SaveTyped("recId", typeof(oAccount), accUnllocatedPayment, "pal_", false, connectionString); oMSEraClaimItemAccount link3 = new oMSEraClaimItemAccount(); link3.accountId = accUnllocatedPayment.recId; link3.eraClaimItemId = claim.recId; link3.originalProcessDate = System.DateTime.Now; link3.manualProcessed = false; link3.manualProcessUserId = 0; link3.manualAllocated = false; link3.manualAllocateUserId = 0; link3.rejected = false; link3.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), link3, "pal_", false, connectionString); //Add new note of type "Payment" oNote noteNew = new oNote(); noteNew.moduleId = 10; //surface noteNew.typeId = 7; //note type Payment noteNew.entityId = accUnllocatedPayment.surfaceItemId; noteNew.title = accUnllocatedPayment.procedureDescription; noteNew.caption = "A payment was receipted via eRA to the value of R " + utils.returnFormattedDecimal((accUnllocatedPayment.amount * -1).ToString()); noteNew.dateSaved = DateTime.Now; noteNew.userIdSaved = 0; noteNew.isActive = true; noteNew.fieldName = noteFieldId.ToString(); noteNew.recId = xData.SaveTyped("recId", typeof(oNote), noteNew, "pal_", false, connectionString); } else { //save item to log for manual allocation oMSEraClaimItemAccount link4 = new oMSEraClaimItemAccount(); link4.accountId = 0; link4.eraClaimItemId = claim.recId; link4.originalProcessDate = System.DateTime.Now; link4.manualProcessed = false; link4.manualProcessUserId = 0; link4.manualAllocated = false; link4.manualAllocateUserId = 0; link4.rejected = false; link4.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), link4, "pal_", false, connectionString); } } } else if (claim.claimResponseResultCode == "03") { //get billing line oAccount billingAcc = new oAccount(); foreach (oAccount acc in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", claim.claimAccountId, "", "pal_", false, connectionString)) { billingAcc = acc; } oMSEraClaimItemAccount link5 = new oMSEraClaimItemAccount(); link5.accountId = 0; link5.eraClaimItemId = claim.recId; link5.originalProcessDate = System.DateTime.Now; link5.manualProcessed = false; link5.manualProcessUserId = 0; link5.manualAllocated = false; link5.manualAllocateUserId = 0; link5.rejected = true; link5.recId = xData.SaveTyped("recId", typeof(oMSEraClaimItemAccount), link5, "pal_", false, connectionString); //if era sends back claim is rejected, update liable values of account if it could be found if (billingAcc.recId > 0) { billingAcc.liablePat = billingAcc.liablePat + billingAcc.liableMed; billingAcc.liableMed = 0; xData.UpdateTyped("recId", billingAcc.recId.ToString(), typeof(oAccount), billingAcc, "pal_", false, connectionString); } } } } } */ #endregion } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } private static void Process509(fetchResponse fResponse) { try { StringBuilder changeTable = new StringBuilder(); bool hasChanges = false; changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); using (System.IO.StringReader reader = new System.IO.StringReader(fResponse.responsePayload.ToString())) { string line; //DC string sDCCode = "", sDCQEDICode = "", sDCMedSchemeName = "", sDCAdminName = "", sDCMSVAllowed = "", sDCReversalAllowed = "", sDCMSEndDate = ""; while ((line = reader.ReadLine()) != null) { string[] splitLine = line.Split('|'); switch (splitLine[0]) { case "DC": sDCCode = splitLine[1]; sDCQEDICode = splitLine[2]; sDCMedSchemeName = splitLine[3]; sDCAdminName = splitLine[6]; sDCMSEndDate = splitLine[16]; sDCMSVAllowed = splitLine[17]; sDCReversalAllowed = splitLine[18]; //saveDC oMedicalAdministrator medAdmin = new oMedicalAdministrator(); medAdmin.msDestinationCode = sDCCode; medAdmin.msQEDICode = sDCQEDICode; medAdmin.medSchemeName = sDCMedSchemeName; medAdmin.administratorName = sDCAdminName; medAdmin.msMSVAllowed = sDCMSVAllowed == "Y"; medAdmin.msReversalAllowed = sDCReversalAllowed == "Y"; medAdmin.msEndDate = DateTime.ParseExact(sDCMSEndDate == "" ? "19000101" : sDCMSEndDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); medAdmin.recId = 0; foreach (oMedicalAdministrator admin in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalAdministrator), "msDestinationCode", sDCCode.ToString(), "", "pal_", false, staticConnectionString)) { medAdmin.recId = admin.recId; medAdmin.dateAdded = admin.dateAdded; medAdmin.dateUpdated = admin.dateUpdated; if (!(admin.medSchemeName == medAdmin.medSchemeName && admin.administratorName == medAdmin.administratorName && admin.msQEDICode == medAdmin.msQEDICode && admin.msMSVAllowed == medAdmin.msMSVAllowed && admin.msReversalAllowed == medAdmin.msReversalAllowed && admin.msEndDate == medAdmin.msEndDate)) { medAdmin.dateUpdated = DateTime.Now; hasChanges = true; //email admins change log changeTable.AppendLine(""); changeTable.AppendLine("" + medAdmin.medSchemeName + "
(was: " + admin.medSchemeName + ")" : ">" + medAdmin.medSchemeName) + ""); changeTable.AppendLine("" + medAdmin.administratorName + "
(was: " + admin.administratorName + ")" : ">" + medAdmin.administratorName) + ""); changeTable.AppendLine("" + medAdmin.msQEDICode + "
(was: " + admin.msQEDICode + ")" : ">" + medAdmin.msQEDICode) + ""); changeTable.AppendLine("" + medAdmin.msDestinationCode + "
(was: " + admin.msDestinationCode + ")" : ">" + medAdmin.msDestinationCode) + ""); changeTable.AppendLine("" + medAdmin.msMSVAllowed + "
(was: " + admin.msMSVAllowed + ")" : ">" + medAdmin.msMSVAllowed) + ""); changeTable.AppendLine("" + medAdmin.msReversalAllowed + "
(was: " + admin.msReversalAllowed + ")" : ">" + medAdmin.msReversalAllowed) + ""); changeTable.AppendLine("" + medAdmin.msEndDate + "
(was: " + admin.msEndDate + ")" : ">" + medAdmin.msEndDate) + ""); changeTable.AppendLine("
"); changeTable.AppendLine(""); } } if (medAdmin.recId == 0) { medAdmin.dateAdded = DateTime.Now; hasChanges = true; changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); changeTable.AppendLine(""); xData.SaveTyped("recId", typeof(oMedicalAdministrator), medAdmin, "pal_", false, staticConnectionString); } else xData.UpdateTyped("recId", medAdmin.recId.ToString(), typeof(oMedicalAdministrator), medAdmin, "pal_", false, staticConnectionString); break; default: break; } } changeTable.AppendLine("
Medical Scheme NameAdministratorQEDI CodeDestination CodeAllow MSVAllow ReversalMediswitch End DateNew Entry
No
" + medAdmin.medSchemeName + "" + medAdmin.administratorName + "" + medAdmin.msQEDICode + "" + medAdmin.msDestinationCode + "" + medAdmin.msMSVAllowed + "" + medAdmin.msReversalAllowed + "" + medAdmin.msEndDate + "Yes
"); if (hasChanges) { string emailTemplate = string.Empty; //get templates foreach (oTemplate template in xData.GetTypedByCriteriaSpecific("recId", typeof(oTemplate), "templateTypeId", framework_business.pNums.TemplateType.OutboundResponse.GetHashCode().ToString(), "templateName", "pal_", false, staticConnectionString)) { if (template.templateName.ToLower().Contains("509")) { emailTemplate = template.templateContent; } } emailTemplate = emailTemplate.Replace("{changeTable}", changeTable.ToString()); oEmail mail = new oEmail(); mail.Body = emailTemplate; mail.Subject = "Medical Adminstrator Update"; mail.fromAddress = ConfigurationManager.AppSettings["from"]; mail.toAddress = ConfigurationManager.AppSettings["admin"]; communication.SendAnEmail(mail); } } } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } public string ClaimPatientDataSingle(oAccount account, bool send = false) { try { //JasR 2016-04-12 no need to do this check as mediswitch verifies it anyway //if (!account.isIOD) //{ // string msvResult = ValidateMSVPatientData(ref account); // if (msvResult != string.Empty) // { // return "MSV Failed: " + msvResult; // } //} string txType = enumMSTransactionType.SwitchClaim_GeneralMedical.GetHashCode().ToString(), mode = "realtime", txVersion = "120", transmissionNo; string msDestinationCode = ""; bool splitMods = false; foreach (oMedicalScheme medScheme in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", account.medCode, "", "pal_", false, connectionString)) { msDestinationCode = medScheme.msDestinationCode; foreach (oMedicalAdministrator medAdmin in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalAdministrator), "msDestinationCode", msDestinationCode, "", "pal_", false, connectionString)) { splitMods = medAdmin.splitModifiers; } } int mCounter = 1;//counter for all m records oMSLog logClaim = new oMSLog(); logClaim.operationType = framework_business.pNums.MediswitchOperationType.Claim.GetHashCode(); logClaim.requestDate = DateTime.Now; logClaim.recId = xData.SaveTyped("recId", typeof(oMSLog), logClaim, "pal_", false, connectionString); transmissionNo = logClaim.recId.ToString(); //transactionNumber - get new trans number from raw table logClaim.request = SetupPayloadClaim(txVersion, transmissionNo, mCounter, account, "", splitMods); if (logClaim.request == "No Valid Destination Code") return "No Valid Destination Code"; if (logClaim.request == "No Valid Transactions") return "No Valid Transactions"; if (send) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); submitResponse sResponse = medClient.submitOperation(mainSetup.user, mainSetup.passwd, mainSetup.package, msDestinationCode, txType, mode, txVersion, transmissionNo, logClaim.request); stopwatch.Stop(); logClaim.roundTripElapsed = Convert.ToInt32(stopwatch.ElapsedMilliseconds); logClaim.response = sResponse.responsePayload; logClaim.status = sResponse.status; logClaim.swref = sResponse.swref; logClaim.retry = sResponse.retry; if (sResponse.responsePayload == "XML Validation error") { Exception ex = new Exception("Custom Exception: XML Validation error"); exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } else { if (logClaim.response.Contains("|"))//no pipes == error { ProcessClaimResponse(logClaim); } } } logClaim.responseDate = DateTime.Now; xData.UpdateTyped("recId", logClaim.recId.ToString(), typeof(oMSLog), logClaim, "pal_", false, connectionString); if (send) return logClaim.response; else return logClaim.request; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } public string ReverseClaim(string claimLogId) { try { oAccount account = new oAccount(); foreach (oMSClaimResponse msClaimResponse in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSClaimResponse), "claimLogId", claimLogId, "", "pal_", false, connectionString)) { foreach (oAccount acc in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "invoiceNo,isVisible", msClaimResponse.claimRefNo.ToString() + ",1", "", "pal_", false, connectionString)) { account = acc; } } ValidateMSVPatientData(ref account); string txType = enumMSTransactionType.SwitchClaim_Reversal.GetHashCode().ToString(), mode = "realtime", txVersion = "120", transmissionNo = claimLogId; string msDestinationCode = ""; foreach (oMedicalScheme medScheme in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", account.medCode, "", "pal_", false, connectionString)) { msDestinationCode = medScheme.msDestinationCode; } int mCounter = 1;//counter for all m records oMSLog logClaim = new oMSLog(); logClaim.operationType = framework_business.pNums.MediswitchOperationType.Reversal.GetHashCode(); logClaim.requestDate = DateTime.Now; logClaim.recId = xData.SaveTyped("recId", typeof(oMSLog), logClaim, "pal_", false, connectionString); transmissionNo = logClaim.recId.ToString(); //transactionNumber - get new trans number from raw table logClaim.request = SetupPayloadClaim(txVersion, transmissionNo, mCounter, account, claimLogId); if (logClaim.request == "No Valid Destination Code") return "No Valid Destination Code"; if (logClaim.request == "No Valid Transactions") return "No Valid Transactions"; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); submitResponse sResponse = medClient.submitOperation(mainSetup.user, mainSetup.passwd, mainSetup.package, msDestinationCode, txType, mode, txVersion, claimLogId, logClaim.request); stopwatch.Stop(); logClaim.roundTripElapsed = Convert.ToInt32(stopwatch.ElapsedMilliseconds); logClaim.responseDate = DateTime.Now; logClaim.response = sResponse.responsePayload; logClaim.retry = sResponse.retry; logClaim.status = sResponse.status; logClaim.swref = sResponse.swref; xData.UpdateTyped("recId", logClaim.recId.ToString(), typeof(oMSLog), logClaim, "pal_", false, connectionString); if (sResponse.responsePayload == "XML Validation error") { Exception ex = new Exception("Custom Exception: XML Validation error"); exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } else if (sResponse.status == "ERROR") return sResponse.responsePayload; else ProcessClaimResponse(logClaim, true); return ""; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } public void ProcessDelayed(StreamWriter logWriter) { try { bool moreFiles = false; do { fetchResponse fResponse = GetDelayedResponses(logWriter); #region Testing //fetchResponse fResponse = null; //if (fResponse == null) //{ // fResponse = new scheduler.MediswitchWebService.fetchResponse(); // fResponse.feedbackType = "307"; // fResponse.feedbackVersion = "120"; // fResponse.fileDate = ""; // fResponse.fileName = "Discovery Health Administrators.20190123063424.era"; // fResponse.moreFiles = "0"; // fResponse.originalDataSetId = "1"; // fResponse.originalSwref = "0-3-d391178000"; // fResponse.originalUserRef = "907022064"; // fResponse.status = "OK"; // StringBuilder responsePayload = new StringBuilder(); // responsePayload.AppendLine("H|BANKMED MEDICAL SCHE|Discovery Health Adm||BKAC0000|||||907022064|20190122|||"); // responsePayload.AppendLine("S|0573159|The Shoulder Practice|"); // responsePayload.AppendLine("EB|1|00|UNKNOWN|20190122||159016694|246065|"); // responsePayload.AppendLine("M|Mac millan|Cherryl|516237750|"); // responsePayload.AppendLine("P|1|MAC MILLAN||CHERRYL|19540221||2714|"); // responsePayload.AppendLine("I|1|29841|||6kw5xl|20181123||0190||Specialist Consultation|10|"); // responsePayload.AppendLine("R|729|We have paid claims at 80% of the contracted or scheme rate |"); // responsePayload.AppendLine("G|We have paid claims at 80% of the contracted or scheme rate because there was no prior authorisation obtained.|"); // responsePayload.AppendLine("EY|59306|44448|0|11112|"); // responsePayload.AppendLine("I|1|29842|||6kw5xl|20181123||0661||Joint Injection|10|"); // responsePayload.AppendLine("R|547|We have paid the claim from the member's Medical Savings Acc|"); // responsePayload.AppendLine("G|We have paid the claim from the member's Medical Savings Account.|"); // responsePayload.AppendLine("EY|17099|10002|0|7097|"); // responsePayload.AppendLine("I|1|29843|||6kw5xl|20181123|||711231002|Cortisone Vial x 5ml|10|"); // responsePayload.AppendLine("R|190|The amount claimed on this line is more than the maximum amo|"); // responsePayload.AppendLine("G|The amount claimed on this line is more than the maximum amount the Scheme pays.|"); // responsePayload.AppendLine("EY|40836|13195|0|0|"); // responsePayload.AppendLine("EZ|117241|67645|0|18209|"); // responsePayload.AppendLine("M|Carstens|Gertina|510573540|"); // responsePayload.AppendLine("P|1|CARSTENS||GERTINA|19691010||2831|"); // responsePayload.AppendLine("I|1|30905|||6l2lp8|20190116||0190||Specialist Consultation|10|"); // responsePayload.AppendLine("R|391|We paid the amount on this line according to the agreed paym|"); // responsePayload.AppendLine("G|We paid the amount on this line according to the agreed payment arrangement. The member does not have to pay the difference between the claimed amount and the amount we paid.|"); // responsePayload.AppendLine("EY|62271|55020|0|0|"); // responsePayload.AppendLine("I|1|30906|||6l2lp8|20190116||0661||Joint Injection|09|"); // responsePayload.AppendLine("EY|17950|17950|0|0|"); // responsePayload.AppendLine("I|1|30908|||6l2lp8|20190116||5102||Ultrasound|09|"); // responsePayload.AppendLine("EY|95060|95060|0|0|"); // responsePayload.AppendLine("I|1|30922|||6l2lp8|20190116|||711231002|Cortisone Vial 1ml|09|"); // responsePayload.AppendLine("R|541|We have accepted your submitted price as it is lower than th|"); // responsePayload.AppendLine("G|We have accepted your submitted price as it is lower than the calculated amount.|"); // responsePayload.AppendLine("EY|10390|10390|0|0|"); // responsePayload.AppendLine("I|1|30923|||6l2lp8|20190116|||711231002|Cortisone Vial 1ml|03|"); // responsePayload.AppendLine("R|54|Please check your statement records as we have processed thi|"); // responsePayload.AppendLine("G|Please check your statement records as we have processed this amount before.|"); // responsePayload.AppendLine("EY|10390|0|0|0|"); // responsePayload.AppendLine("I|1|30924|||6l2lp8|20190116|||711231002|Cortisone Vial 1ml|03|"); // responsePayload.AppendLine("R|54|Please check your statement records as we have processed thi|"); // responsePayload.AppendLine("G|Please check your statement records as we have processed this amount before.|"); // responsePayload.AppendLine("EY|10390|0|0|0|"); // responsePayload.AppendLine("I|1|30925|||6l2lp8|20190116|||711231002|Cortisone Vial 1ml|03|"); // responsePayload.AppendLine("R|54|Please check your statement records as we have processed thi|"); // responsePayload.AppendLine("G|Please check your statement records as we have processed this amount before.|"); // responsePayload.AppendLine("EY|10390|0|0|0|"); // responsePayload.AppendLine("I|1|30926|||6l2lp8|20190116|||711231002|Cortisone Vial 1ml|03|"); // responsePayload.AppendLine("R|54|Please check your statement records as we have processed thi|"); // responsePayload.AppendLine("G|Please check your statement records as we have processed this amount before.|"); // responsePayload.AppendLine("EY|10390|0|0|0|"); // responsePayload.AppendLine("I|1|30905|||6kvcP6|20190116||0190||Specialist Consultation|10|"); // responsePayload.AppendLine("R|391|We paid the amount on this line according to the agreed paym|"); // responsePayload.AppendLine("G|We paid the amount on this line according to the agreed payment arrangement. The member does not have to pay the difference between the claimed amount and the amount we paid.|"); // responsePayload.AppendLine("EY|62271|55020|0|0|"); // responsePayload.AppendLine("I|1|30906|||6kvcP6|20190116||0661||Joint Injection|09|"); // responsePayload.AppendLine("EY|17950|17950|0|0|"); // responsePayload.AppendLine("I|1|30907|||6kvcP6|20190116|||711231002|5 x Cortisone Vial 1ml @ R103.90|10|"); // responsePayload.AppendLine("R|190|The amount claimed on this line is more than the maximum amo|"); // responsePayload.AppendLine("G|The amount claimed on this line is more than the maximum amount the Scheme pays.|"); // responsePayload.AppendLine("EY|51950|13195|0|0|"); // responsePayload.AppendLine("I|1|30908|||6kvcP6|20190116||5102||Ultrasound|09|"); // responsePayload.AppendLine("EY|95060|95060|0|0|"); // responsePayload.AppendLine("I|1||||6kvcP6|20190116||0190|||10|"); // responsePayload.AppendLine("R|36|This is an adjustment of a claim that we have processed befo|"); // responsePayload.AppendLine("G|This is an adjustment of a claim that we have processed before.|"); // responsePayload.AppendLine("EY|-62271|-55020|0|0|"); // responsePayload.AppendLine("I|1||||6kvcP6|20190116||0661|||09|"); // responsePayload.AppendLine("R|36|This is an adjustment of a claim that we have processed befo|"); // responsePayload.AppendLine("G|This is an adjustment of a claim that we have processed before.|"); // responsePayload.AppendLine("EY|-17950|-17950|0|0|"); // responsePayload.AppendLine("I|1||||6kvcP6|20190116|||711231002||10|"); // responsePayload.AppendLine("R|36|This is an adjustment of a claim that we have processed befo|"); // responsePayload.AppendLine("G|This is an adjustment of a claim that we have processed before.|"); // responsePayload.AppendLine("EY|-51950|-13195|0|0|"); // responsePayload.AppendLine("I|1||||6kvcP6|20190116||5102|||09|"); // responsePayload.AppendLine("R|36|This is an adjustment of a claim that we have processed befo|"); // responsePayload.AppendLine("G|This is an adjustment of a claim that we have processed before.|"); // responsePayload.AppendLine("EY|-95060|-95060|0|0|"); // responsePayload.AppendLine("EZ|227231|178420|0|0|"); // responsePayload.AppendLine("EF|344472|246065|0|0|18209|"); // fResponse.responsePayload = responsePayload.ToString(); //} #endregion if (fResponse != null) { logWriter.Write("Response feedback type " + fResponse.feedbackType + "." + Environment.NewLine); if (fResponse.feedbackType != string.Empty) { oMSFetchResponseLog fetchResponseLog = logFetchResponse(fResponse, logWriter); //check switch (fResponse.feedbackType) { case "509"://destination codes Process509(fResponse); break; case "302"://claim GetRelatedClaimAndProcess(fResponse); break; case "303"://reversal GetRelatedClaimAndProcess(fResponse); break; case "307"://ERA //CVH 2019-01-10 For Momentum files this recId is 0 for some reason, which causes duplicates when processing ERAs. Check if 0, if yes get fetchId from table int fetchId = fetchResponseLog.recId; if (fetchId == 0) { logWriter.Write("ERROR! Fetch response ID is 0. " + Environment.NewLine); logWriter.Write("Feedback Version: " + fResponse.feedbackVersion + Environment.NewLine); logWriter.Write("File Name: " + fResponse.fileName + Environment.NewLine); logWriter.Write("Original Swref: " + fResponse.originalSwref + Environment.NewLine); logWriter.Write("Original User Ref: " + fResponse.originalUserRef + Environment.NewLine); logWriter.Write("Payload: " + Environment.NewLine + fResponse.responsePayload + Environment.NewLine); } Process307ERA(fResponse, fetchId); break; default: LogUnknownFeedback(fResponse); break; } //cater for all known - if not known - log and sent notify } moreFiles = (fResponse.moreFiles == "1"); } } while (moreFiles); } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, null); } } private void LogUnknownFeedback(fetchResponse fResponse) { logFetchResponse(fResponse); Exception ex = new Exception("Custom Exception: Unknown Response Downloaded"); exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } private void GetRelatedClaimAndProcess(fetchResponse fResponse) { try { foreach (oMSLog logClaim in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSLog), "recId", fResponse.originalUserRef, "", "pal_", false, connectionString)) { logClaim.response = fResponse.responsePayload; logClaim.responseDate = DateTime.Now; xData.UpdateTyped("recId", logClaim.recId.ToString(), typeof(oMSLog), logClaim, "pal_", false, connectionString); string invoiceNo = ProcessClaimResponse(logClaim); //send mail notify string patientName = "", patientSurname = ""; foreach (oAccount accountItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "invoiceNo", invoiceNo, "", "pal_", false, connectionString)) { patientName = accountItem.patientName; patientSurname = accountItem.patientSurname; break; } string emailTemplate = string.Empty; //get templates foreach (oTemplate template in xData.GetTypedByCriteriaSpecific("recId", typeof(oTemplate), "templateTypeId", framework_business.pNums.TemplateType.OutboundResponse.GetHashCode().ToString(), "templateName", "pal_", false, connectionString)) { if (template.templateName.ToLower().Contains("Email Queued Response")) { emailTemplate = template.templateContent; } } emailTemplate = emailTemplate.Replace("{patientName}", patientName); emailTemplate = emailTemplate.Replace("{patientSurname}", patientSurname); emailTemplate = emailTemplate.Replace("{invoiceNo}", invoiceNo); oEmail mail = new oEmail(); mail.Body = emailTemplate; mail.Subject = "Queued Transaction Processed"; mail.fromAddress = ConfigurationManager.AppSettings["from"]; mail.toAddress = ConfigurationManager.AppSettings["admin"]; communication.SendAnEmail(mail); } } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } private fetchResponse GetDelayedResponses(StreamWriter logWriter) { try { if (medClient == null) InstantiateClass(); logWriter.Write("User " + mainSetup.user + ". Password " + mainSetup.passwd + ". Package " + mainSetup.package + "." + Environment.NewLine); fetchResponse fResponse = medClient.fetchOperation(mainSetup.user, mainSetup.passwd, mainSetup.package, "", "", "0"); return fResponse; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return null; } } private oMSFetchResponseLog logFetchResponse(fetchResponse fResponse, int payloadLogId = 0) { oMSFetchResponseLog fetchResponseLog = new oMSFetchResponseLog(); try { //CVH 2019-01-22 Need to make this safe for SQL insert, otherwise we get a 0 fetch response Id which causes duplicate ERA's to be processed string fileName = fResponse.fileName.Replace("'", "''"); if (fileName.Length > 50) fileName = fileName.Substring(0, 50); string originalSwref = fResponse.originalSwref.Replace("'", "''"); if (originalSwref.Length > 50) originalSwref = originalSwref.Substring(0, 50); string originalUserRef = fResponse.originalUserRef.Replace("'", "''"); if (originalUserRef.Length > 50) originalUserRef = originalUserRef.Substring(0, 50); fetchResponseLog.feedbackType = fResponse.feedbackType; fetchResponseLog.feedbackVersion = fResponse.feedbackVersion; fetchResponseLog.fileDate = fResponse.fileDate; fetchResponseLog.fileName = fileName; fetchResponseLog.moreFiles = fResponse.moreFiles; fetchResponseLog.originalDataSetId = fResponse.originalDataSetId; fetchResponseLog.originalSwref = originalSwref; fetchResponseLog.originalUserRef = originalUserRef; fetchResponseLog.status = fResponse.status; fetchResponseLog.responsePayloadId = payloadLogId; fetchResponseLog.responsePayload = fResponse.responsePayload.Replace("'", "''"); fetchResponseLog.processDate = System.DateTime.Now; fetchResponseLog.recId = xData.SaveTyped("recId", typeof(oMSFetchResponseLog), fetchResponseLog, "pal_", false, connectionString); return fetchResponseLog; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return fetchResponseLog; } } //overloaded private oMSFetchResponseLog logFetchResponse(fetchResponse fResponse, StreamWriter logWriter, int payloadLogId = 0) { oMSFetchResponseLog fetchResponseLog = new oMSFetchResponseLog(); try { //CVH 2019-01-23 Save blank item then do an update, just to be sure to get an ID, save still failing fetchResponseLog.processDate = System.DateTime.Now; fetchResponseLog.recId = xData.SaveTyped("recId", typeof(oMSFetchResponseLog), fetchResponseLog, "pal_", false, connectionString); //CVH 2019-01-22 Need to make this safe for SQL insert, otherwise we get a 0 fetch response Id which causes duplicate ERA's to be processed string fileName = fResponse.fileName.Replace("'","''"); if (fileName.Length > 50) fileName = fileName.Substring(0, 50); string originalSwref = fResponse.originalSwref.Replace("'", "''"); if (originalSwref.Length > 50) originalSwref = originalSwref.Substring(0, 50); string originalUserRef = fResponse.originalUserRef.Replace("'", "''"); if (originalUserRef.Length > 50) originalUserRef = originalUserRef.Substring(0, 50); fetchResponseLog.feedbackType = fResponse.feedbackType; fetchResponseLog.feedbackVersion = fResponse.feedbackVersion; fetchResponseLog.fileDate = fResponse.fileDate; fetchResponseLog.fileName = fileName; fetchResponseLog.moreFiles = fResponse.moreFiles; fetchResponseLog.originalDataSetId = fResponse.originalDataSetId; fetchResponseLog.originalSwref = originalSwref; fetchResponseLog.originalUserRef = originalUserRef; fetchResponseLog.status = fResponse.status; fetchResponseLog.responsePayloadId = payloadLogId; fetchResponseLog.responsePayload = fResponse.responsePayload.Replace("'", "''"); //fetchResponseLog.processDate = System.DateTime.Now; //fetchResponseLog.recId = xData.SaveTyped("recId", typeof(oMSFetchResponseLog), fetchResponseLog, "pal_", false, connectionString); xData.UpdateTyped("recId", fetchResponseLog.recId.ToString(), typeof(oMSFetchResponseLog), fetchResponseLog, "pal_", false, connectionString); return fetchResponseLog; } catch (Exception ex) { logWriter.Write("EXCEPTION! " + Environment.NewLine); logWriter.Write("Message: " + ex.Message + " | StackTrace: " + ex.StackTrace + Environment.NewLine); logWriter.Write("Feedback Version: " + fResponse.feedbackVersion + Environment.NewLine); logWriter.Write("File Name: " + fResponse.fileName + Environment.NewLine); logWriter.Write("Original Swref: " + fResponse.originalSwref + Environment.NewLine); logWriter.Write("Original User Ref: " + fResponse.originalUserRef + Environment.NewLine); logWriter.Write("Payload: " + Environment.NewLine + fResponse.responsePayload + Environment.NewLine); exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return fetchResponseLog; } } private string ValidateMSVPatientData(ref oAccount account) { try { string msDestinationCode = ""; foreach (oMedicalScheme medScheme in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", account.medCode, "", "pal_", false, connectionString)) { msDestinationCode = medScheme.msDestinationCode; } //if (msDestinationCode == "") - ne need for this check - the vClaimables view already checks // return "No SwithClaim Destination Code Found"; string memberNo = account.medAidNumber; string patientDOB; DataTable surfaceData = xData.GetSurfaceItemData(0, account.surfaceItemId, false, connectionString); patientDOB = Convert.ToDateTime(surfaceData.Rows[0]["PatientInformation_PatientDetails_DateofBirth"]).ToString("yyyyMMdd"); string msvResponse = MSVPatientDataSingle(msDestinationCode, memberNo, patientDOB); if (!msvResponse.Contains("|")) // no pipes == no payload { return msvResponse; } string pPatientDOB = string.Empty, pMedSchemeEffectiveDate = string.Empty, pMedSchemeTerminationDate = string.Empty, pMedSchemeStatusCode = string.Empty; string rvDecsription = string.Empty; bool isValid = false; using (System.IO.StringReader reader = new System.IO.StringReader(msvResponse.ToString())) { string line; while ((line = reader.ReadLine()) != null) { string[] splitLine = line.Split('|'); switch (splitLine[0]) { case "H": break; case "S": break; case "M": break; case "P": if (patientDOB == "" || patientDOB == splitLine[5]) { account.patientCode = splitLine[1] != "" ? splitLine[1] : account.patientCode; account.patientSurname = splitLine[2] != "" ? splitLine[2] : account.patientSurname; account.surname = splitLine[2] != "" ? splitLine[2] : account.surname; account.patientInitials = splitLine[3] != "" ? splitLine[3] : account.patientInitials; account.initials = splitLine[3] != "" ? splitLine[3] : account.initials; account.patientName = splitLine[4] != "" ? splitLine[4] : account.patientName; account.name = splitLine[4] != "" ? splitLine[4] : account.name; pPatientDOB = splitLine[5]; account.birthDate = DateTime.ParseExact(splitLine[5] == "" ? "19000101" : splitLine[5], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); account.idNumber = splitLine[6] != "" ? splitLine[6] : account.idNumber; switch (splitLine[7]) { case "M": account.gender = "Male"; break; case "F": account.gender = "Female"; break; default: account.gender = account.gender; break; } pMedSchemeEffectiveDate = splitLine[8]; pMedSchemeTerminationDate = splitLine[9]; pMedSchemeStatusCode = splitLine[10]; } break; case "RV": isValid = splitLine[1] == "02"; if (!isValid) rvDecsription = splitLine[5]; break; case "E": break; default: break; } } } return rvDecsription; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } public string SetupPayloadClaim(string txVersion, string transmissionNo, int mCounter, oAccount account, string reversalRef = "", bool splitMods = false) { try { decimal fClaimNetAmount = 0, fClaimGrossAmount = 0, fTotalClaimAmount = 0, fClaimDiscountAmount = 0, fClaimLevyAmount = 0, fClaimMMAPSurcharge = 0, fClaimCoPaymentAmount = 0, fClaimPatientLiablePortion = 0, fClaimMedicalFundLiableAmount = 0, fMemberReimbursementAmount = 0; oMSClaim msClaim = new oMSClaim(); msClaim.claimLogId = Convert.ToInt32(transmissionNo); StringBuilder payloadBuilder = new StringBuilder(); payloadBuilder.AppendLine(GetPayloadClaimH(reversalRef == "" ? transmissionNo : reversalRef, txVersion)); payloadBuilder.AppendLine(GetPayloadClaimS()); string msDestinationCode = string.Empty; payloadBuilder.AppendLine(GetPayloadClaimM(account, ref msClaim, ref msDestinationCode)); if (msDestinationCode == string.Empty) return "No Valid Destination Code"; payloadBuilder.AppendLine(GetPayloadClaimP(account, ref msClaim)); msClaim.recId = xData.SaveTyped("recId", typeof(oMSClaim), msClaim); //refering dr number on account table - if > 0 if (account.referringDocNo != string.Empty && account.referringDocNo != "0") payloadBuilder.AppendLine(GetPayloadClaimDR(account, enumDrTypeCode_DR.Referring_Doctor.GetHashCode(), msClaim.recId, 0)); int treatmentNumber = 0; ArrayList accountsToClaim = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "invoiceNo,isVisible,claimSend,liableMed", account.invoiceNo.ToString() + ",1,1,~>0", "sequence", "pal_", false, connectionString); int claimCount = 0; oAccount modAccount0008 = new oAccount(); //modAccount0008.amount = 0; //mod0008IdList = new ArrayList(); oAccount modAccount0009 = new oAccount(); //modAccount0009.amount = 0; //mod0009IdList = new ArrayList(); oAccount modAccount0018 = new oAccount(); //modAccount0018.amount = 0; //mod0018IdList = new ArrayList(); oAccount modAccount0014 = new oAccount(); //loop through all treatments for patient - all invoice lines foreach (oAccount accountItem in accountsToClaim) { claimCount++; //if (accountItem.liableMed > 0) //{ if (accountItem.modifier1 != string.Empty)//is Modifier { if (claimCount > 1) { if (((oAccount)accountsToClaim[claimCount - 1]).procedureCode != accountItem.procedureCode) { continue; } } else { continue; } } oMSClaimTreatment msTreatment = new oMSClaimTreatment(); if (splitMods) { treatmentNumber++; msTreatment.claimId = msClaim.recId; msTreatment.treatmentNo = treatmentNumber; payloadBuilder.AppendLine(GetPayloadClaimT(accountItem, ref msTreatment, reversalRef)); msTreatment.recId = xData.SaveTyped("recId", typeof(oMSClaimTreatment), msTreatment, "pal_", false, connectionString); //DR - attending payloadBuilder.AppendLine(GetPayloadClaimDR(accountItem, enumDrTypeCode_DR.Attending_Treating_Prescribing_Doctor.GetHashCode(), 0, msTreatment.recId)); //if assistant - dr if ((accountItem.modifier1 == "0008" || accountItem.modifier1 == "0009") && accountItem.modifier2 != string.Empty) { payloadBuilder.AppendLine(GetPayloadClaimDR(accountItem, enumDrTypeCode_DR.Assisting_Doctor.GetHashCode(), 0, msTreatment.recId)); } //MD - if inline if (accountItem.modifier4 != string.Empty) payloadBuilder.AppendLine(GetPayloadClaimMD(accountItem, msTreatment.recId)); //D - multi //D primary payloadBuilder.AppendLine(GetPayloadClaimD(accountItem, true, msTreatment.recId)); //D other string icd10List = string.Empty; if (accountItem.icd2 != string.Empty) icd10List += accountItem.icd2 + ","; if (accountItem.icd3 != string.Empty) icd10List += accountItem.icd3 + ","; if (accountItem.icd4 != string.Empty) icd10List += accountItem.icd4 + ","; if (accountItem.icd5 != string.Empty) icd10List += accountItem.icd5 + ","; //GR - Added external Cause code if (accountItem.externalCause != String.Empty) icd10List += accountItem.externalCause + ","; if (icd10List != string.Empty) { foreach (string icd10Item in icd10List.Split(',')) { if (icd10Item != string.Empty) payloadBuilder.AppendLine(GetPayloadClaimD(accountItem, false, msTreatment.recId, icd10Item)); } } //Z payloadBuilder.AppendLine(GetPayLoadClaimZ(accountItem, ref fClaimNetAmount, ref fClaimGrossAmount, ref fTotalClaimAmount, ref fClaimDiscountAmount, ref fClaimLevyAmount, ref fClaimMMAPSurcharge, ref fClaimCoPaymentAmount, ref fClaimPatientLiablePortion, ref fClaimMedicalFundLiableAmount, ref fMemberReimbursementAmount, ref msTreatment)); xData.UpdateTyped("recId", msTreatment.recId.ToString(), typeof(oMSClaimTreatment), msTreatment, "pal_", false, connectionString); //} } else { if (accountItem.modifier1 != string.Empty)//is Modifier { switch (accountItem.modifier1) { case "0008": if (modAccount0008.recId == 0) { mod0008IdList = new ArrayList(); modAccount0008 = accountItem; } else { if (mod0008IdList == null) { mod0008IdList = new ArrayList(); modAccount0008 = accountItem; } modAccount0008.amount = modAccount0008.amount + accountItem.amount; } mod0008IdList.Add(accountItem.recId); break; case "0009": if (modAccount0009.recId == 0) { mod0009IdList = new ArrayList(); modAccount0009 = accountItem; } else { if (mod0009IdList == null) { mod0009IdList = new ArrayList(); modAccount0009 = accountItem; } modAccount0009.amount = modAccount0009.amount + accountItem.amount; } mod0009IdList.Add(accountItem.recId); break; case "0018": if (modAccount0018.recId == 0) { mod0018IdList = new ArrayList(); modAccount0018 = accountItem; } else { if (mod0018IdList == null) { mod0018IdList = new ArrayList(); modAccount0018 = accountItem; } modAccount0018.amount = modAccount0018.amount + accountItem.amount; } mod0018IdList.Add(accountItem.recId); break; case "0014": if (modAccount0014.recId == 0) { mod0014IdList = new ArrayList(); modAccount0014 = accountItem; } else { if (mod0014IdList == null) { mod0014IdList = new ArrayList(); modAccount0014 = accountItem; } modAccount0014.amount = modAccount0014.amount + accountItem.amount; } mod0014IdList.Add(accountItem.recId); break; default: break; } } else { treatmentNumber++; msTreatment.claimId = msClaim.recId; msTreatment.treatmentNo = treatmentNumber; payloadBuilder.AppendLine(GetPayloadClaimT(accountItem, ref msTreatment, reversalRef)); msTreatment.recId = xData.SaveTyped("recId", typeof(oMSClaimTreatment), msTreatment, "pal_", false, connectionString); //DR - attending payloadBuilder.AppendLine(GetPayloadClaimDR(accountItem, enumDrTypeCode_DR.Attending_Treating_Prescribing_Doctor.GetHashCode(), 0, msTreatment.recId)); //if assistant - dr if ((accountItem.modifier1 == "0008" || accountItem.modifier1 == "0009") && accountItem.modifier2 != string.Empty) { payloadBuilder.AppendLine(GetPayloadClaimDR(accountItem, enumDrTypeCode_DR.Assisting_Doctor.GetHashCode(), 0, msTreatment.recId)); } //MD - if inline if (accountItem.modifier4 != string.Empty) payloadBuilder.AppendLine(GetPayloadClaimMD(accountItem, msTreatment.recId)); //D - multi //D primary payloadBuilder.AppendLine(GetPayloadClaimD(accountItem, true, msTreatment.recId)); //D other string icd10List = string.Empty; if (accountItem.icd2 != string.Empty) icd10List += accountItem.icd2 + ","; if (accountItem.icd3 != string.Empty) icd10List += accountItem.icd3 + ","; if (accountItem.icd4 != string.Empty) icd10List += accountItem.icd4 + ","; if (accountItem.icd5 != string.Empty) icd10List += accountItem.icd5 + ","; //GR - Added external Cause code if (accountItem.externalCause != String.Empty) icd10List += accountItem.externalCause + ","; if (icd10List != string.Empty) { foreach (string icd10Item in icd10List.Split(',')) { if (icd10Item != string.Empty) payloadBuilder.AppendLine(GetPayloadClaimD(accountItem, false, msTreatment.recId, icd10Item)); } } //Z payloadBuilder.AppendLine(GetPayLoadClaimZ(accountItem, ref fClaimNetAmount, ref fClaimGrossAmount, ref fTotalClaimAmount, ref fClaimDiscountAmount, ref fClaimLevyAmount, ref fClaimMMAPSurcharge, ref fClaimCoPaymentAmount, ref fClaimPatientLiablePortion, ref fClaimMedicalFundLiableAmount, ref fMemberReimbursementAmount, ref msTreatment)); xData.UpdateTyped("recId", msTreatment.recId.ToString(), typeof(oMSClaimTreatment), msTreatment, "pal_", false, connectionString); //} } } } if (modAccount0008.amount > 0) { AppendModifierLines(reversalRef, ref fClaimNetAmount, ref fClaimGrossAmount, ref fTotalClaimAmount, ref fClaimDiscountAmount, ref fClaimLevyAmount, ref fClaimMMAPSurcharge, ref fClaimCoPaymentAmount, ref fClaimPatientLiablePortion, ref fClaimMedicalFundLiableAmount, ref fMemberReimbursementAmount, msClaim, ref payloadBuilder, ref treatmentNumber, modAccount0008); } if (modAccount0009.amount > 0) { AppendModifierLines(reversalRef, ref fClaimNetAmount, ref fClaimGrossAmount, ref fTotalClaimAmount, ref fClaimDiscountAmount, ref fClaimLevyAmount, ref fClaimMMAPSurcharge, ref fClaimCoPaymentAmount, ref fClaimPatientLiablePortion, ref fClaimMedicalFundLiableAmount, ref fMemberReimbursementAmount, msClaim, ref payloadBuilder, ref treatmentNumber, modAccount0009); } if (modAccount0018.amount > 0) { AppendModifierLines(reversalRef, ref fClaimNetAmount, ref fClaimGrossAmount, ref fTotalClaimAmount, ref fClaimDiscountAmount, ref fClaimLevyAmount, ref fClaimMMAPSurcharge, ref fClaimCoPaymentAmount, ref fClaimPatientLiablePortion, ref fClaimMedicalFundLiableAmount, ref fMemberReimbursementAmount, msClaim, ref payloadBuilder, ref treatmentNumber, modAccount0018); } if (modAccount0014.amount > 0) { AppendModifierLines(reversalRef, ref fClaimNetAmount, ref fClaimGrossAmount, ref fTotalClaimAmount, ref fClaimDiscountAmount, ref fClaimLevyAmount, ref fClaimMMAPSurcharge, ref fClaimCoPaymentAmount, ref fClaimPatientLiablePortion, ref fClaimMedicalFundLiableAmount, ref fMemberReimbursementAmount, msClaim, ref payloadBuilder, ref treatmentNumber, modAccount0014); } if (treatmentNumber == 0) return "No Valid Transactions"; //F payloadBuilder.AppendLine(GetPayloadClaimF(account, fClaimNetAmount, fClaimGrossAmount, fTotalClaimAmount, fClaimDiscountAmount, fClaimLevyAmount, fClaimMMAPSurcharge, fClaimCoPaymentAmount, fClaimPatientLiablePortion, fClaimMedicalFundLiableAmount, fMemberReimbursementAmount, ref msClaim)); xData.UpdateTyped("recId", msClaim.recId.ToString(), typeof(oMSClaim), msClaim, "pal_", false, connectionString); //E payloadBuilder.AppendLine(GetPayloadClaimE(reversalRef == "" ? transmissionNo : reversalRef, 1, fTotalClaimAmount)); return payloadBuilder.ToString(); } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } private void AppendModifierLines(string reversalRef, ref decimal fClaimNetAmount, ref decimal fClaimGrossAmount, ref decimal fTotalClaimAmount, ref decimal fClaimDiscountAmount, ref decimal fClaimLevyAmount, ref decimal fClaimMMAPSurcharge, ref decimal fClaimCoPaymentAmount, ref decimal fClaimPatientLiablePortion, ref decimal fClaimMedicalFundLiableAmount, ref decimal fMemberReimbursementAmount, oMSClaim msClaim, ref StringBuilder payloadBuilder, ref int treatmentNumber, oAccount modAccount) { oMSClaimTreatment msTreatment = new oMSClaimTreatment(); treatmentNumber++; msTreatment.claimId = msClaim.recId; msTreatment.treatmentNo = treatmentNumber; payloadBuilder.AppendLine(GetPayloadClaimT(modAccount, ref msTreatment, reversalRef)); msTreatment.recId = xData.SaveTyped("recId", typeof(oMSClaimTreatment), msTreatment, "pal_", false, connectionString); //DR - attending payloadBuilder.AppendLine(GetPayloadClaimDR(modAccount, enumDrTypeCode_DR.Attending_Treating_Prescribing_Doctor.GetHashCode(), 0, msTreatment.recId)); //if assistant - dr if ((modAccount.modifier1 == "0008" || modAccount.modifier1 == "0009") && modAccount.modifier2 != string.Empty) { payloadBuilder.AppendLine(GetPayloadClaimDR(modAccount, enumDrTypeCode_DR.Assisting_Doctor.GetHashCode(), 0, msTreatment.recId)); } //D - multi //D primary payloadBuilder.AppendLine(GetPayloadClaimD(modAccount, true, msTreatment.recId)); //D other string icd10List = string.Empty; if (modAccount.icd2 != string.Empty) icd10List += modAccount.icd2 + ","; if (modAccount.icd3 != string.Empty) icd10List += modAccount.icd3 + ","; if (modAccount.icd4 != string.Empty) icd10List += modAccount.icd4 + ","; if (modAccount.icd5 != string.Empty) icd10List += modAccount.icd5 + ","; //GR - Added external Cause code if (modAccount.externalCause != String.Empty) icd10List += modAccount.externalCause + ","; if (icd10List != string.Empty) { foreach (string icd10Item in icd10List.Split(',')) { if (icd10Item != string.Empty) payloadBuilder.AppendLine(GetPayloadClaimD(modAccount, false, msTreatment.recId, icd10Item)); } } //Z payloadBuilder.AppendLine(GetPayLoadClaimZ(modAccount, ref fClaimNetAmount, ref fClaimGrossAmount, ref fTotalClaimAmount, ref fClaimDiscountAmount, ref fClaimLevyAmount, ref fClaimMMAPSurcharge, ref fClaimCoPaymentAmount, ref fClaimPatientLiablePortion, ref fClaimMedicalFundLiableAmount, ref fMemberReimbursementAmount, ref msTreatment)); xData.UpdateTyped("recId", msTreatment.recId.ToString(), typeof(oMSClaimTreatment), msTreatment, "pal_", false, connectionString); } #region Claim Request Lines /// /// Header (Start of Message) Record /// /// /// /// private string GetPayloadClaimH(string transmissionNo, string txVersion) { return "H|" + transmissionNo.Trim() + "|" + txVersion.Trim() + "|" + mainSetup.softwareName.Trim() + "||"; } /// /// Service Provider Record /// /// private string GetPayloadClaimS() { try { string PMADatasetID = "1", BPVatRegNo = ""; foreach (oMedicalPractice practice in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalPractice), "practiceNo", mainSetup.bpPCNS, "", "pal_", false, connectionString)) { BPVatRegNo = practice.vatNum; } return "S|" + DateTime.Now.ToString("yyyMMddhhmm").Trim() + "|" + mainSetup.bpPCNS.Trim() + "|" + mainSetup.bpName.Trim() + "|" + PMADatasetID.Trim() + "|" + BPVatRegNo.Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Member Record /// /// /// private string GetPayloadClaimM(oAccount account, ref oMSClaim msClaim, ref string msDestinationCode) { try { DataTable surfaceData = xData.GetSurfaceItemData(0, account.surfaceItemId, false, connectionString); msClaim.memberCellphone = surfaceData.Rows[0]["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_MobileNumber"].ToString(); foreach (oMedicalScheme medScheme in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", account.medCode, "", "pal_", false, connectionString)) { msClaim.msDestinationCode = medScheme.msDestinationCode; msDestinationCode = medScheme.msDestinationCode; } foreach (oMedicalAdministrator medAdmin in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalAdministrator), "msDestinationCode", msClaim.msDestinationCode, "", "pal_", false, connectionString)) { if (medAdmin.medSchemeName.Length > 20) msClaim.medSchemeName = medAdmin.medSchemeName.Substring(0, 20); else msClaim.medSchemeName = medAdmin.medSchemeName; } msClaim.memberIdNumber = account.idNumber; msClaim.memberTitle = account.title; msClaim.memberInitials = account.initials; msClaim.memberSurname = account.surname; msClaim.memberFullNames = account.name; string memberNumber = account.medAidNumber; if (account.isIOD) memberNumber = account.iodRefNo.Length > 20 ? account.iodRefNo.Substring(0, 20) : account.iodRefNo; msClaim.membershipNumber = memberNumber; msClaim.cardSwipeInd = false; msClaim.memberAccountNo = account.patientNumber.ToString(); msClaim.address1 = ""; msClaim.address2 = ""; msClaim.town = ""; msClaim.postalCode = ""; msClaim.medSchemePlanName = ""; msClaim.medSchemePlanNo = ""; msClaim.medSchemeRegNo = ""; msClaim.medSchemeRegType = ""; msClaim.medSchemeClaimOption = ""; return "M|" + msClaim.memberIdNumber.Trim() + "|" + msClaim.memberTitle.Trim() + "|" + msClaim.memberInitials.Trim() + "|" + msClaim.memberSurname.Trim() + "|" + msClaim.memberFullNames.Trim() + "|" + msClaim.membershipNumber.Trim() + "|" + (msClaim.cardSwipeInd ? "Y" : "N") + "|" + msClaim.memberAccountNo.Trim() + "|" + msClaim.address1.Trim() + "|" + msClaim.address2.Trim() + "|" + msClaim.town.Trim() + "|" + msClaim.postalCode.Trim() + "|" + msClaim.memberCellphone.Trim() + "|" + msClaim.medSchemePlanName.Trim() + "|" + msClaim.medSchemePlanNo.Trim() + "|" + msClaim.medSchemeName.Trim() + "|" + msClaim.medSchemeRegNo.Trim() + "|" + msClaim.medSchemeRegType.Trim() + "|" + msClaim.medSchemeClaimOption.Trim() + "|" + msClaim.msDestinationCode.Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Patient Record /// /// /// private string GetPayloadClaimP(oAccount account, ref oMSClaim msClaim) { try { DataTable surfaceData = xData.GetSurfaceItemData(0, account.surfaceItemId); msClaim.patientDOB = Convert.ToDateTime(surfaceData.Rows[0]["PatientInformation_PatientDetails_DateofBirth"]); msClaim.patientGender = surfaceData.Rows[0]["PatientInformation_PatientDetails_Gender"].ToString().Substring(0, 1); msClaim.patientIdNumber = surfaceData.Rows[0]["PatientInformation_PatientDetails_IDPassportNumber"].ToString(); foreach (oPlaceOfService place in xData.GetTypedByCriteriaSpecific("recId", typeof(oPlaceOfService), "indicator,isActive", account.placeOfService.ToString() + ",1", "", "pal_", false, connectionString)) { msClaim.inOutHospitalInd = GetInOrOutOfHopsital(place.rateType); } msClaim.dependantCode = account.patientCode; msClaim.patientSurname = account.patientSurname; msClaim.patientInitials = account.patientInitials; msClaim.patientFullName = account.patientName; msClaim.patientAccountNo = account.patientNumber.ToString(); msClaim.claimRefNo = account.invoiceNo.ToString(); msClaim.medSchemeAuthNo = account.authorisationNo; msClaim.patientRelationCode = "";// not required msClaim.recallDate = new DateTime(1900, 1, 1); //Dentists Only int patientHeight = 0, patientWeight = 0; foreach (oAccount accountItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "invoiceNo,isVisible,claimSend", account.invoiceNo.ToString() + ",1,1", "", "pal_", false, connectionString)) { if (accountItem.modifier1 == "0018")//BMI>50 { Int32.TryParse(accountItem.modifier2, out patientHeight); Int32.TryParse(accountItem.modifier3, out patientWeight); patientWeight = patientWeight * 1000;//take from kg to g break; } } msClaim.patientHeight = patientHeight; msClaim.patientWeight = patientWeight; //Injury on Duty msClaim.COIDInd = account.isIOD ? "01" : ""; msClaim.dateOfInjury = account.isIOD ? account.iodDate : new DateTime(1900, 1, 1); msClaim.employerName = account.isIOD ? account.iodEmployerName : ""; msClaim.employerRegNo = account.isIOD ? account.iodEmployerRegNo : ""; msClaim.employeeNo = account.isIOD ? account.iodEmployeeNo : ""; msClaim.COIDRefNo = account.isIOD ? account.iodRefNo : ""; return "P|" + msClaim.dependantCode.Trim() + "|" + msClaim.patientSurname.Trim() + "|" + msClaim.patientInitials.Trim() + "|" + msClaim.patientFullName.Trim() + "|" + utils.stripCharacters(msClaim.patientDOB.ToString("yyyyMMdd")) + "|" + msClaim.patientGender.Trim() + "|" + msClaim.patientRelationCode.Trim() + "|" + msClaim.patientIdNumber.Trim() + "|" + (msClaim.recallDate.ToString("yyyyMMdd") == "19000101" ? "" : msClaim.recallDate.ToString("yyyyMMdd")) + "|" + msClaim.COIDInd.Trim() + "|" + (msClaim.dateOfInjury.ToString("yyyyMMdd") == "19000101" ? "" : msClaim.dateOfInjury.ToString("yyyyMMdd")) + "|" + msClaim.employerName.Trim() + "|" + msClaim.employerRegNo.Trim() + "|" + msClaim.employeeNo.Trim() + "|" + msClaim.COIDRefNo.Trim() + "|" + msClaim.medSchemeAuthNo.Trim() + "|" + msClaim.medSchemeAuthNo.Trim() + "|" + msClaim.patientAccountNo.Trim() + "|" + msClaim.inOutHospitalInd.Trim() + "|" + (msClaim.patientHeight == 0 ? "" : msClaim.patientHeight.ToString().Trim()) + "|" + (msClaim.patientWeight == 0 ? "" : msClaim.patientWeight.ToString().Trim()) + "|" + msClaim.claimRefNo.Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Doctor Record /// /// /// private string GetPayloadClaimDR(oAccount account, int drType, int claimId, int treatmentId) { try { oMSClaimDoctor msDoctor = new oMSClaimDoctor(); msDoctor.claimId = claimId; msDoctor.treatmentId = treatmentId; msDoctor.doctorTypeCode = ((enumDrTypeCode_DR)drType).GetHashCode().ToString().PadLeft(2, '0'); msDoctor.doctorCMSTypeInd = enumCMSDrType.HPCSA.GetHashCode().ToString().PadLeft(2, '0'); msDoctor.dispensingDocLicenseNo = ""; msDoctor.designatedServiceProviderInd = false; msDoctor.doctorTrackingNo = ""; switch (drType) { case 1://attending foreach (oMedicalDoctor doc in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalDoctor), "recId", account.doctorNo.ToString(), "", "pal_", false, connectionString)) { msDoctor.doctorPCNSNumber = doc.BHFRegNo; msDoctor.doctorName = doc.name + " " + doc.surname; msDoctor.doctorCMSRegNo = doc.HPCSARegNo == "" ? "999999" : doc.HPCSARegNo; } break; case 2://assisting msDoctor.doctorPCNSNumber = account.modifier2; msDoctor.doctorName = account.modifier3; msDoctor.doctorCMSRegNo = ""; msDoctor.doctorCMSTypeInd = ""; break; case 5://referring msDoctor.doctorPCNSNumber = account.referringDocNo; msDoctor.doctorName = account.referringDoctor; msDoctor.doctorCMSRegNo = ""; msDoctor.doctorCMSTypeInd = ""; break; default: break; } xData.SaveTyped("recId", typeof(oMSClaimDoctor), msDoctor, "pal_", false, connectionString); return "DR|" + msDoctor.doctorPCNSNumber.Trim() + "|" + msDoctor.doctorName.Trim() + "|" + msDoctor.doctorTypeCode.Trim() + "|" + msDoctor.doctorCMSRegNo.Trim() + "|" + msDoctor.doctorCMSTypeInd.Trim() + "|" + msDoctor.dispensingDocLicenseNo.Trim() + "|" + (msDoctor.designatedServiceProviderInd ? "Y" : "N") + "|" + msDoctor.doctorTrackingNo.Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Doctor Diagnosis Record /// /// /// private string GetPayloadClaimD(oAccount account, bool isPrimary, int treatmentId, string icd10Item = "") { try { oMSClaimDiagnosis msDiagnosis = new oMSClaimDiagnosis(); msDiagnosis.treatmentID = treatmentId; msDiagnosis.doctorTypeCode = enumDrTypeCode_D.Attending_Doctor_Prescribing.GetHashCode().ToString().PadLeft(2, '0'); msDiagnosis.diagnosisCodeType = enumDiagnosisCodeType.ICD10.GetHashCode().ToString().PadLeft(2, '0'); msDiagnosis.diagnosisCode = icd10Item != "" ? icd10Item : account.icd1; msDiagnosis.extendedDiagnosis = icd10Item != "" ? enumExterdedDiagnosis.Secondary.GetHashCode().ToString().PadLeft(2, '0') : enumExterdedDiagnosis.Primary.GetHashCode().ToString().PadLeft(2, '0'); foreach (oMedicalICD10 icd10 in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalICD10), "icdCode", msDiagnosis.diagnosisCode, "", "pal_", false, connectionString)) { msDiagnosis.diagnosisDescription = icd10.icdDescription; } xData.SaveTyped("recId", typeof(oMSClaimDiagnosis), msDiagnosis, "pal_", false, connectionString); return "D|" + msDiagnosis.doctorTypeCode.Trim() + "|" + msDiagnosis.diagnosisCodeType.Trim() + "|" + msDiagnosis.diagnosisCode.Trim() + "|" + msDiagnosis.diagnosisDescription.Trim() + "|" + msDiagnosis.extendedDiagnosis.Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Treatment Record /// /// /// /// private string GetPayloadClaimT(oAccount account, ref oMSClaimTreatment msTreatment, string reversalRef = "") { try { string authNo = ""; if (reversalRef == "") authNo = account.authorisationNo; else { foreach (oMSClaimResponse msClaimResponse in xData.GetTypedByCriteriaSpecific("recId", typeof(oMSClaimResponse), "claimLogId", reversalRef, "", "pal_", false, connectionString)) { authNo = msClaimResponse.authorizationNo; } } msTreatment.treatmentStartDate = account.dateOfService; // .ToString("yyyyMMdd"); msTreatment.treatmentEndDate = new DateTime(1900, 1, 1); msTreatment.authorizationNo = authNo; msTreatment.invoiceNo = ""; // ??? msTreatment.claimLineNo = account.recId.ToString(); msTreatment.treatmentTypeInd = enumTreatmentTypeInd.Tariff.GetHashCode().ToString().PadLeft(2, '0'); msTreatment.qty = account.qty; // .ToString().Replace(".", ""); msTreatment.qtyTypeInd = enumQtyUnitTypeInd.Unit.GetHashCode().ToString().PadLeft(2, '0'); msTreatment.code = account.consumableCode != string.Empty ? account.consumableCode : account.procedureCode; msTreatment.codeType = enumTariffTypeCode.NHRPL.GetHashCode().ToString().PadLeft(2, '0'); // ??? is it always NHRPL? msTreatment.modifierType = ""; msTreatment.nappiCode = account.procedureNAPPI; msTreatment.traiffInd = enumServiceRateInd.NHRPL.GetHashCode().ToString().PadLeft(2, '0'); // ??? is it always NHRPL? - can be COID msTreatment.description = account.procedureDescription; msTreatment.registeredPMB = false; // "N"; msTreatment.scriptWrittenDate = new DateTime(1900, 1, 1); //not applicable msTreatment.benefitTypeInd = enumBenefitTypeInd.Acute.GetHashCode().ToString().PadLeft(2, '0'); msTreatment.hospitalTariffType = ""; //hospital only msTreatment.labPCNS = ""; //dentists only msTreatment.labRefNo = ""; //dentists only msTreatment.labName = ""; //dentists only msTreatment.resubmitReasonCode = ""; //get from enum - only if re-submitted msTreatment.originalClaimNo = ""; // - only if re-submitted msTreatment.originalClaimDate = new DateTime(1900, 1, 1); //CCYYMMDDhhmm - only if re-submitted msTreatment.placeOfServiceCode = account.placeOfService.ToString(); if (account.modifier1.Length > 0) { msTreatment.treatmentTypeInd = enumTreatmentTypeInd.Modifier.GetHashCode().ToString().PadLeft(2, '0'); msTreatment.code = account.modifier1; msTreatment.modifierType = enumModifierType.AddModifier.GetHashCode().ToString().PadLeft(2, '0'); foreach (oMedicalProcedure proc in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalProcedure), "code", account.modifier1, "", "pal_", false, connectionString)) { msTreatment.description = proc.description; } } return "T|" + msTreatment.treatmentNo.ToString().Trim() + "|" + msTreatment.treatmentStartDate.ToString("yyyyMMdd") + "|" + (msTreatment.treatmentEndDate.ToString("yyyyMMdd") == "19000101" ? "" : msTreatment.treatmentEndDate.ToString("yyyyMMdd")) + "|" + msTreatment.authorizationNo.Trim() + "|" + msTreatment.invoiceNo.Trim() + "|" + msTreatment.claimLineNo.Trim() + "|" + msTreatment.treatmentTypeInd.Trim() + "|" + msTreatment.qty.ToString().Replace(".", "").Trim() + "|" + msTreatment.qtyTypeInd.Trim() + "|" + msTreatment.code.Trim() + "|" + msTreatment.codeType.Trim() + "|" + msTreatment.modifierType.Trim() + "|" + msTreatment.nappiCode.Trim() + "|" + msTreatment.traiffInd.Trim() + "|" + msTreatment.description.Trim() + "|" + (msTreatment.registeredPMB ? "Y" : "N") + "|" + (msTreatment.scriptWrittenDate.ToString("yyyyMMdd") == "19000101" ? "" : msTreatment.scriptWrittenDate.ToString("yyyyMMdd")) + "|" + msTreatment.benefitTypeInd.Trim() + "|" + msTreatment.hospitalTariffType.Trim() + "|" + msTreatment.labPCNS.Trim() + "|" + msTreatment.labRefNo.Trim() + "|" + msTreatment.labName.Trim() + "|" + msTreatment.resubmitReasonCode.Trim() + "|" + msTreatment.originalClaimNo.Trim() + "|" + (msTreatment.originalClaimDate.ToString("yyyyMMdd") == "19000101" ? "" : msTreatment.originalClaimDate.ToString("yyyyMMdd")) + "|" + msTreatment.placeOfServiceCode.Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Modifier Record /// /// /// private string GetPayloadClaimMD(oAccount account, int treatmentId) { try { oMSClaimModifier modifier = new oMSClaimModifier(); modifier.treatmentId = treatmentId; if (account.modifier4 == "0005") modifier.modifierType = enumModifierType.ReductionModifier.GetHashCode().ToString().PadLeft(2, '0'); modifier.modifierCode = account.modifier4; xData.SaveTyped("recId", typeof(oMSClaimModifier), modifier, "pal_", false, connectionString); return "MD|" + modifier.modifierCode.Trim() + "|" + modifier.modifierType.Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// General Comments Record /// /// private string GetPayLoadClaimG() { try { string generalComments = ""; return "G|" + generalComments + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Treatment Financial Record /// /// /// private string GetPayLoadClaimZ(oAccount account, ref decimal fClaimNetAmount, ref decimal fClaimGrossAmount, ref decimal fTotalClaimAmount, ref decimal fClaimDiscountAmount, ref decimal fClaimLevyAmount, ref decimal fClaimMMAPSurcharge, ref decimal fClaimCoPaymentAmount, ref decimal fClaimPatientLiablePortion, ref decimal fClaimMedicalFundLiableAmount, ref decimal fMemberReimbursementAmount, ref oMSClaimTreatment msTreatment) { try { msTreatment.treatmentNetAmount = account.amount;//.ToString().Replace(".", ""); msTreatment.treatmentGrossAmount = account.amount;//.ToString().Replace(".", ""); msTreatment.dispensingFee = 0; //Pharmacy Only msTreatment.containerFee = 0; //Pharmacy Only msTreatment.excessTimeFee = 0; //Pharmacy Only msTreatment.callOutFee = 0; //Pharmacy Only msTreatment.copyFee = 0; //Pharmacy Only msTreatment.deliveryFee = 0; //Pharmacy Only msTreatment.contractFee = 0; //Pharmacy Only msTreatment.treatmentClaimedAmount = account.amount;//.ToString().Replace(".", ""); msTreatment.discountAmount = 0; msTreatment.patientLevyAmount = 0; msTreatment.mmapSurcharge = 0; msTreatment.patientCoPaymentAmount = 0; msTreatment.patientLiableAmount = account.liablePat; msTreatment.medicalFundLiableAmount = account.liableMed;//.ToString().Replace(".", ""); msTreatment.memberReimbursementAmount = 0; fClaimNetAmount += account.amount; fClaimGrossAmount += account.amount; fTotalClaimAmount += account.amount; fClaimDiscountAmount += 0; fClaimLevyAmount += 0; fClaimMMAPSurcharge += 0; fClaimCoPaymentAmount += 0; fClaimPatientLiablePortion += account.liablePat; fClaimMedicalFundLiableAmount += account.liableMed; fMemberReimbursementAmount += 0; return "Z|" + msTreatment.treatmentNetAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.treatmentGrossAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.dispensingFee.ToString().Replace(".", "").Trim() + "|" + msTreatment.containerFee.ToString().Replace(".", "").Trim() + "|" + msTreatment.excessTimeFee.ToString().Replace(".", "").Trim() + "|" + msTreatment.callOutFee.ToString().Replace(".", "").Trim() + "|" + msTreatment.copyFee.ToString().Replace(".", "").Trim() + "|" + msTreatment.deliveryFee.ToString().Replace(".", "").Trim() + "|" + msTreatment.contractFee.ToString().Replace(".", "").Trim() + "|" + msTreatment.treatmentClaimedAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.discountAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.patientLevyAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.mmapSurcharge.ToString().Replace(".", "").Trim() + "|" + msTreatment.patientCoPaymentAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.patientLiableAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.medicalFundLiableAmount.ToString().Replace(".", "").Trim() + "|" + msTreatment.memberReimbursementAmount.ToString().Replace(".", "").Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Claim Financial Record /// /// /// private string GetPayloadClaimF(oAccount account, decimal fClaimNetAmount, decimal fClaimGrossAmount, decimal fTotalClaimAmount, decimal fClaimDiscountAmount, decimal fClaimLevyAmount, decimal fClaimMMAPSurcharge, decimal fClaimCoPaymentAmount, decimal fClaimPatientLiablePortion, decimal fClaimMedicalFundLiableAmount, decimal fMemberReimbursementAmount, ref oMSClaim msClaim) { try { msClaim.claimNetAmount = fClaimNetAmount;//.ToString().Replace(".", ""); msClaim.claimGrossAmount = fClaimGrossAmount;//.ToString().Replace(".", ""); msClaim.totalClaimedAmount = fTotalClaimAmount;//.ToString().Replace(".", ""); msClaim.claimDiscountAmount = fClaimDiscountAmount; msClaim.claimDeductableLevyAmount = fClaimLevyAmount; msClaim.claimMMAPSurcharge = fClaimMMAPSurcharge; msClaim.claimCoPaymentAmount = fClaimCoPaymentAmount; msClaim.receiptNo = ""; msClaim.claimPatientLiableAmount = fClaimPatientLiablePortion; msClaim.claimMedicalFundLiableAmount = fClaimMedicalFundLiableAmount;//.ToString().Replace(".", ""); msClaim.memberReimbursementAmount = fMemberReimbursementAmount; return "F|" + msClaim.claimNetAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.claimGrossAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.totalClaimedAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.claimDiscountAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.claimDeductableLevyAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.claimMMAPSurcharge.ToString().Replace(".", "").Trim() + "|" + msClaim.claimCoPaymentAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.receiptNo.Trim() + "|" + msClaim.claimPatientLiableAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.claimMedicalFundLiableAmount.ToString().Replace(".", "").Trim() + "|" + msClaim.memberReimbursementAmount.ToString().Replace(".", "").Trim() + "|"; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } /// /// Footer (End of Message) Record /// /// private string GetPayloadClaimE(string transmissionNo, int numberOfClaims, decimal valueOfClaims) { return "E|" + transmissionNo.Trim() + "|" + numberOfClaims.ToString().Trim() + "|" + valueOfClaims.ToString().Replace(".", "").Trim() + "|"; } #endregion #region Claim Response Lines /// /// process response payload /// /// private string ProcessClaimResponse(oMSLog logClaim, bool isReversal = false) { try { string invoiceNo = ""; string responsePayload = logClaim.response; oMSClaimResponse msResponse = new oMSClaimResponse(); oMSClaimResponseTreatment msResponseTreatment = new oMSClaimResponseTreatment(); msResponse.claimLogId = logClaim.recId; msResponse.recId = xData.SaveTyped("recId", typeof(oMSClaimResponse), msResponse, "pal_", false, connectionString); using (System.IO.StringReader reader = new System.IO.StringReader(responsePayload)) { string line; while ((line = reader.ReadLine()) != null) { string[] splitLine = line.Split('|'); switch (splitLine[0]) { case "H": ProcessClaimResponseH(line); break; case "S": ProcessClaimResponseS(line); break; case "M": ProcessClaimResponseM(line, ref msResponse); xData.UpdateTyped("recId", msResponse.recId.ToString(), typeof(oMSClaimResponse), msResponse, "pal_", false, connectionString); break; case "P": ProcessClaimResponseP(line, ref msResponse); xData.UpdateTyped("recId", msResponse.recId.ToString(), typeof(oMSClaimResponse), msResponse, "pal_", false, connectionString); break; case "T": msResponseTreatment = new oMSClaimResponseTreatment(); msResponseTreatment.claimResponseId = msResponse.recId; msResponseTreatment.recId = xData.SaveTyped("recId", typeof(oMSClaimResponseTreatment), msResponseTreatment, "pal_", false, connectionString); ProcessClaimResponseT(line, ref msResponseTreatment); xData.UpdateTyped("recId", msResponseTreatment.recId.ToString(), typeof(oMSClaimResponseTreatment), msResponseTreatment, "pal_", false, connectionString); foreach (oAccount accountItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", msResponseTreatment.claimLineNo, "", "pal_", false, connectionString)) { switch (accountItem.modifier1) { case "0008": foreach (int modId in mod0008IdList) { foreach (oAccount modItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", modId.ToString(), "", "pal_", false, connectionString)) { invoiceNo = UpdateTreatmentAccountItem(isReversal, msResponse, modItem); } } break; case "0009": foreach (int modId in mod0009IdList) { foreach (oAccount modItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", modId.ToString(), "", "pal_", false, connectionString)) { invoiceNo = UpdateTreatmentAccountItem(isReversal, msResponse, modItem); } } break; case "0018": foreach (int modId in mod0018IdList) { foreach (oAccount modItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "recId", modId.ToString(), "", "pal_", false, connectionString)) { invoiceNo = UpdateTreatmentAccountItem(isReversal, msResponse, modItem); } } break; default://assume string.Empty ie no modifiers invoiceNo = UpdateTreatmentAccountItem(isReversal, msResponse, accountItem); break; } } break; case "R": ProcessClaimResponseR(line, ref msResponseTreatment); break; case "G": ProcessClaimResponseG(line, ref msResponseTreatment, ref msResponse); break; //case "FR"://ToDo // ProcessClaimResponseFR(line); // break; case "Z": ProcessClaimResponseZ(line, ref msResponseTreatment); xData.UpdateTyped("recId", msResponseTreatment.recId.ToString(), typeof(oMSClaimResponseTreatment), msResponseTreatment, "pal_", false, connectionString); break; case "F": ProcessClaimResponseF(line, ref msResponse); xData.UpdateTyped("recId", msResponse.recId.ToString(), typeof(oMSClaimResponse), msResponse, "pal_", false, connectionString); break; case "E": ProcessClaimResponseE(line); break; default: break; } } } return invoiceNo; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } private static string UpdateTreatmentAccountItem(bool isReversal, oMSClaimResponse msResponse, oAccount accountItem) { string invoiceNo; if (isReversal) { accountItem.claimSent = false; } else { accountItem.claimSent = true; accountItem.claimDate = DateTime.Now; accountItem.claimNumber = msResponse.claimLogId; } xData.UpdateTyped("recId", accountItem.recId.ToString(), typeof(oAccount), accountItem, "pal_", false, staticConnectionString); invoiceNo = accountItem.invoiceNo.ToString(); return invoiceNo; } /// /// Header (Start of Message) Record – Type ‘H’ /// /// private void ProcessClaimResponseH(string line) { string[] splitLine = line.Split('|'); string transmissionNo = splitLine[1]; } /// /// Service Provider Record – Type ‘S’ /// /// private void ProcessClaimResponseS(string line) { string[] splitLine = line.Split('|'); string responseFileCreationDateTime = splitLine[1], bpPCNSNo = splitLine[2], bpName = splitLine[3], datasetId = splitLine[4], rejectCount = splitLine[5]; } /// /// Member Record – Type ‘M’ /// /// private void ProcessClaimResponseM(string line, ref oMSClaimResponse msResponse) { try { string[] splitLine = line.Split('|'); msResponse.memberSurname = splitLine[1]; msResponse.memberFullName = splitLine[2]; msResponse.membershipNo = splitLine[3]; msResponse.memberAccountNo = splitLine[4]; msResponse.medSchemeName = splitLine[5]; msResponse.medSchemeRegNo = splitLine[6]; msResponse.msDestinationCode = splitLine[7]; msResponse.msDestinationContactNo = splitLine[8]; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// Patient Record – Type ‘P’ /// /// private void ProcessClaimResponseP(string line, ref oMSClaimResponse msResponse) { try { string[] splitLine = line.Split('|'); msResponse.dependantCode = splitLine[1]; msResponse.patientSurname = splitLine[2]; msResponse.patientInitials = splitLine[3]; msResponse.patientFullName = splitLine[4]; msResponse.patientDOB = DateTime.ParseExact(splitLine[5] == "" ? "19000101" : splitLine[5], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); msResponse.patientIdNumber = splitLine[6]; msResponse.authorizationNo = splitLine[7]; msResponse.confirmationNo = splitLine[8]; msResponse.patientAccountNo = splitLine[9]; msResponse.inOutHospitalInd = splitLine[10]; msResponse.claimRefNo = splitLine[11]; msResponse.responseLevelInd = splitLine[12]; msResponse.responseResultCode = splitLine[13]; msResponse.respondingParty = splitLine[14]; msResponse.msDeliveryTypeInd = splitLine[15]; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// Treatment Record – Type ‘T’ /// /// private void ProcessClaimResponseT(string line, ref oMSClaimResponseTreatment msResponseTreatment) { try { string[] splitLine = line.Split('|'); switch (splitLine[1].Length) { case 8: msResponseTreatment.treatmentStartDate = DateTime.ParseExact(splitLine[1], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); break; case 12: msResponseTreatment.treatmentStartDate = DateTime.ParseExact(splitLine[1], "yyyyMMddhhmm", CultureInfo.InvariantCulture, DateTimeStyles.None); break; default: msResponseTreatment.treatmentStartDate = new DateTime(1900, 1, 1); break; } switch (splitLine[2].Length) { case 8: msResponseTreatment.treatmentEndDate = DateTime.ParseExact(splitLine[2], "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); break; case 12: msResponseTreatment.treatmentEndDate = DateTime.ParseExact(splitLine[2], "yyyyMMddhhmm", CultureInfo.InvariantCulture, DateTimeStyles.None); break; default: msResponseTreatment.treatmentEndDate = new DateTime(1900, 1, 1); break; } msResponseTreatment.authorizationNo = splitLine[3]; msResponseTreatment.invoiceNo = splitLine[4]; msResponseTreatment.claimLineNo = splitLine[5]; msResponseTreatment.claimRefTrackingNo = splitLine[6]; msResponseTreatment.treatmentTypeInd = splitLine[7]; decimal dVal = 0; Decimal.TryParse(splitLine[8], out dVal); msResponseTreatment.qty = dVal; msResponseTreatment.code = splitLine[9]; msResponseTreatment.nappiCode = splitLine[10]; msResponseTreatment.description = splitLine[11]; msResponseTreatment.benefitTypeInd = splitLine[12]; msResponseTreatment.labRefNo = splitLine[13]; msResponseTreatment.responseResultCode = splitLine[14]; msResponseTreatment.respondingParty = splitLine[15]; msResponseTreatment.msDeliveryTypeInd = splitLine[16]; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// Response Record – Type ‘R’ /// /// private void ProcessClaimResponseR(string line, ref oMSClaimResponseTreatment msResponseTreatment) { try { oMSClaimResponseLine msResponseLine = new oMSClaimResponseLine(); msResponseLine.responseTreatmentId = msResponseTreatment.recId; string[] splitLine = line.Split('|'); msResponseLine.Code = splitLine[1]; msResponseLine.Description = splitLine[2]; xData.SaveTyped("recId", typeof(oMSClaimResponseLine), msResponseLine, "pal_", false, connectionString); } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// General Comments Record – Type ‘G’ /// /// private void ProcessClaimResponseG(string line, ref oMSClaimResponseTreatment msResponseTreatment, ref oMSClaimResponse msResponse) { try { oMSClaimResponseComment msResponseComment = new oMSClaimResponseComment(); msResponseComment.responseTreatmentId = msResponseTreatment.recId; msResponseComment.claimResponseId = msResponse.recId; string[] splitLine = line.Split('|'); msResponseComment.comment = splitLine[1]; xData.SaveTyped("recId", typeof(oMSClaimResponseComment), msResponseComment, "pal_", false, connectionString); } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// Failure Response Record – Type ‘FR’ /// /// private void ProcessClaimResponseFR(string line) { try { string[] splitLine = line.Split('|'); string failureResponseMssage = splitLine[1]; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// Treatment Financial Record – Type ‘Z’ /// /// private void ProcessClaimResponseZ(string line, ref oMSClaimResponseTreatment msResponseTreatment) { try { string[] splitLine = line.Split('|'); decimal dVal = 0; Decimal.TryParse(splitLine[1], out dVal); msResponseTreatment.treatmentNetAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[2], out dVal); msResponseTreatment.treatmentGrossAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[3], out dVal); msResponseTreatment.dispensingFee = dVal; dVal = 0; Decimal.TryParse(splitLine[4], out dVal); msResponseTreatment.containerFee = dVal; dVal = 0; Decimal.TryParse(splitLine[5], out dVal); msResponseTreatment.excessTimeFee = dVal; dVal = 0; Decimal.TryParse(splitLine[6], out dVal); msResponseTreatment.callOutFee = dVal; dVal = 0; Decimal.TryParse(splitLine[7], out dVal); msResponseTreatment.copyFee = dVal; dVal = 0; Decimal.TryParse(splitLine[8], out dVal); msResponseTreatment.deliveryFee = dVal; dVal = 0; Decimal.TryParse(splitLine[9], out dVal); msResponseTreatment.contractFee = dVal; dVal = 0; Decimal.TryParse(splitLine[10], out dVal); msResponseTreatment.treatmentClaimedAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[11], out dVal); msResponseTreatment.discountAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[12], out dVal); msResponseTreatment.overchargedAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[13], out dVal); msResponseTreatment.patientLevyAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[14], out dVal); msResponseTreatment.mmapSurcharge = dVal; dVal = 0; Decimal.TryParse(splitLine[15], out dVal); msResponseTreatment.patientCoPaymentAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[16], out dVal); msResponseTreatment.patientLiableAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[17], out dVal); msResponseTreatment.medicalFundLiableAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[18], out dVal); msResponseTreatment.authAmountToProvider = dVal; dVal = 0; Decimal.TryParse(splitLine[19], out dVal); msResponseTreatment.memberReimbursementAmount = dVal; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// Claim Financial Record – Type ‘F’ /// /// private void ProcessClaimResponseF(string line, ref oMSClaimResponse msResponse) { try { string[] splitLine = line.Split('|'); decimal dVal = 0; Decimal.TryParse(splitLine[1], out dVal); msResponse.claimNetAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[2], out dVal); msResponse.claimGrossAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[3], out dVal); msResponse.totalClaimedAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[4], out dVal); msResponse.claimDiscountAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[5], out dVal); msResponse.claimOverchargeAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[6], out dVal); msResponse.claimDeductableLevyAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[7], out dVal); msResponse.claimMMAPSurcharge = dVal; dVal = 0; Decimal.TryParse(splitLine[8], out dVal); msResponse.claimCoPaymentAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[9], out dVal); msResponse.claimPatientLiableAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[10], out dVal); msResponse.claimMedicalFundLiableAmount = dVal; dVal = 0; Decimal.TryParse(splitLine[11], out dVal); msResponse.authAmountToProvider = dVal; dVal = 0; Decimal.TryParse(splitLine[12], out dVal); msResponse.memberReimbursementAmount = dVal; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); } } /// /// Footer (End of Message) Record – Type ‘E’ /// /// private void ProcessClaimResponseE(string line) { string[] splitLine = line.Split('|'); string transmissionNo = splitLine[1], numberOfClaims = splitLine[2], valueOfClaims = splitLine[3]; } #endregion #region Code methods /// /// Get In or Out of Hopital Code /// /// /// private string GetInOrOutOfHopsital(string rateType) { try { string returnCode = ""; switch (rateType) { case "IH": returnCode = "01"; break; case "OH": returnCode = "02"; break; default: break; } return returnCode; } catch (Exception ex) { exception.HandleException("mediswitch class:", MethodBase.GetCurrentMethod().Name, ex, 0); return ex.Message; } } #endregion #region enums enum enumMSTransactionType { SwitchOnMembershipStatusValidation = 301, SwitchClaim_GeneralMedical = 302, SwitchClaim_Reversal = 303, SwitchClaim_Hospital = 304 } enum enumPatientRelationCode { MainMember = 01, Son = 02, Spouce = 03, Daughter = 04, Mother = 05, Father = 06, Other = 07 } enum enumDrTypeCode_DR { Attending_Treating_Prescribing_Doctor = 01, Assisting_Doctor = 02, Anaesthetist = 03, Admitting_Doctor = 04, Referring_Doctor = 05, Referred_to_Doctor = 06, Discharging_Doctor = 07 } enum enumCMSDrType { HPCSA = 01, A_HPCSA = 02, SACSSP = 03, SADTC = 04, SANC = 05, SAPC = 06 } enum enumDrTypeCode_D { Attending_Doctor_Prescribing = 01, Admitting_Doctor = 02, Referring_Doctor = 03, Discharging_Doctor = 04 } enum enumDiagnosisCodeType { ICD10 = 01, ICD_DA_Dental = 02, FreeText = 03 } enum enumExterdedDiagnosis { Primary = 01, Secondary = 02, Co_Morbidity = 03, Complication = 04, Allergy = 05 } enum enumTreatmentTypeInd { DispensedMedicine = 01, Tariff = 02, Modifier = 03 } enum enumQtyUnitTypeInd { Day = 01, Hour = 02, Minute = 03, Second = 04, Kilometer = 05, Unit = 06, Item = 07, TheatreTime = 08 } enum enumTariffTypeCode { NHRPL = 01, NAPPI = 02, CPT_CCSA = 03, CDT = 04, SAOA = 05, Orthotist = 06, UPFS = 07 } enum enumModifierType { InformationalModifier = 01, ReductionModifier = 02, AddModifier = 03, CompoundModifier = 04 } enum enumServiceRateInd { NHRPL = 01, COID = 02, FundTariff = 03, ManagedFeeForService = 04, GroupCapitation = 05, IndividualCapitation = 06, EthicalTariffRates_HPCSA = 07, SAMA = 08, SADA = 09, SAOA = 10, HASA = 11, FixedFee_Hospital = 12, PerDiem_Hospital = 13, UPFS = 14 } enum enumBenefitTypeInd { Acute = 01, Chronic = 02, OverTheCounter_PAT = 03, Chemotherapy = 04 } enum enumHospitalTariffType { WardFees = 01, TheatreFees = 02, TTO = 03, WardExtra = 04, Gas = 05, DispensedDrugs = 06, Exclusions = 07, WardDrugs = 08, TheatreDrugs = 09, Miscellaneous = 10, TheatreExtra = 11, DispensaryFees = 12, ManagementFees = 13 } enum enumReSubmissionReasonCode { Unpaid = 01, DetailsChanged = 02 } enum enumProcCodeType { NHRPL = 01, CPT_CCSA = 02, CDT = 03 } enum enumBasisOfDOT { NotSpecified = 01, OnScript_ImplicitUsage = 02, DispensersEstimation = 03, DoctorsDirections = 04 } enum enumDAW { NoDAW = 01,//default DrDAW = 02, PatDAW = 03, RphDAW = 04, NoGenericAvailable = 05, BrandDispensedAsGeneric = 06 } #endregion }