using framework_library; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Web; namespace framework_business { public class xDebtors { /// /// Adds a note with an attachment after statement has been created /// /// /// /// /// /// public static void AddCreateStatementNote(int noteEntityId, string noteTitle, string noteCaption, string statementPath, string statementFile, int userId, string fieldName) { try { /* CVH 2016-04-20 Change from module Procedures to Surface, and type General to Statement */ oNote note = new oNote(); note.moduleId = pNums.Module.Surface.GetHashCode(); note.typeId = pNums.NoteType.Statement.GetHashCode(); note.entityId = noteEntityId; note.title = noteTitle; note.caption = noteCaption; note.dateSaved = DateTime.Now; note.userIdSaved = userId; note.isActive = true; note.fieldName = fieldName; note.recId = xData.SaveTyped("recId", typeof(oNote), note); //add statement as attachment to note oAttachment noteAtt = new oAttachment(); noteAtt.dateSaved = DateTime.Now; noteAtt.display = note.title; noteAtt.entityId = note.recId; noteAtt.fileName = noteAtt.entityId + "_" + utils.RandomString(9, true) + statementFile.Substring(statementFile.IndexOf("."), statementFile.Length - statementFile.IndexOf(".")); noteAtt.folderName = "note/" + note.recId; noteAtt.isActive = true; noteAtt.moduleId = pNums.Module.Notes.GetHashCode(); noteAtt.typeId = pNums.AttachmentType.Document.GetHashCode(); noteAtt.userIdSaved = note.userIdSaved; //CVH 2016-10-28 Save PDF to file folder, not straight in root of note item folder string copyTo = HttpContext.Current.Server.MapPath("~/upload/" + noteAtt.folderName + "/file/"); utils.validateFolder(copyTo); System.IO.File.Copy(statementPath + statementFile, copyTo + noteAtt.fileName); noteAtt.recId = xData.SaveTyped("recId", typeof(oAttachment), noteAtt); } catch (Exception ex) { //log don't redirect exception.HandleException("enquiry:", MethodBase.GetCurrentMethod().Name, ex, userId); } } /// /// string to build the account lines /// /// /// day brough forward /// /// /// /// /// /// private static string BuildAccountLines(oAccount accountMain, ArrayList accountList, int balforward, DateTime statementDate, bool useDateRange, DateTime statementDateFrom, DateTime statementDateTo, bool includeHidden, int lineCount, bool fromZero, bool includeInvoiceNo) { StringBuilder lineResult = new StringBuilder(); bool includeTransaction = true; decimal totalPat = 0; decimal totalMed = 0; decimal BalanceBF = 0; int BfDays = 0; DateTime BFDate = DateTime.MinValue; bool usingBF = false; int counter = 0; int accCounter = 0; int transIncludedCount = 0; string patient = String.Empty; try { if (balforward > 0) { usingBF = true; BfDays = balforward; } //set running balance based on records decimal bal = 0; foreach (oAccount accline in accountList) { if (accline.procedureType != "PA" && accline.procedureType != "CA") { bal += accline.amount; accline.runningBal = bal; } } //from zero if (fromZero) { bool firstZeroFound = false; ArrayList zeroList = new ArrayList(); //reverse the collection accountList.Reverse(); //enumerate and clear if zero balance foreach (oAccount accTemp in accountList) { if (accTemp.procedureType != "PA" && accTemp.procedureType != "CA") { bool allowInZero = true; if (decimal.Round(accTemp.runningBal) > 0) firstZeroFound = true; if (!includeHidden) { if (!accTemp.isVisible) allowInZero = false; } if (allowInZero) { if (decimal.Round(accTemp.runningBal, 2) <= 0 && decimal.Round(accTemp.amount, 2) != 0) { if (!firstZeroFound) firstZeroFound = true; else { break; } } //append transaction line zeroList.Add(accTemp); } } } zeroList.Reverse(); accountList = zeroList; } lineResult.AppendLine(""); lineResult.AppendLine(""); if (includeInvoiceNo) { lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); } else { lineResult.AppendLine(""); //lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); } lineResult.AppendLine(""); foreach (oAccount acnt in accountList) { if (acnt.procedureType != "PA" && acnt.procedureType != "CA")//ignore assistant payments and credits { counter++; includeTransaction = true;//default flag if (!useDateRange) { if (acnt.dateOfService.Date > statementDate.Date) includeTransaction = false; } //CVH 2018-07-04 Need an else here, otherwise it prints blank statements on Bulk Month End run else if (acnt.dateOfService.Date < statementDateFrom.Date || acnt.dateOfService.Date > statementDateTo.Date) includeTransaction = false; //if (trans.transServiceType == "L") // includeTransaction = false; //tally total patient and med liable if not Lab Fee //check if we must include items marked for print if (!includeHidden) { if (!acnt.isVisible) includeTransaction = false; } if (usingBF && includeTransaction)//using balance brought forward and transaction included { accCounter++; if (accCounter == 1) { //if (BfDays != 1) // BfDays += 1; //calculate the difference in days BFDate = statementDate.AddDays(-BfDays); } if (acnt.dateOfService.Date <= BFDate.Date) { BalanceBF = acnt.runningBal; includeTransaction = false; if (counter == accountList.Count) { if (decimal.Round(BalanceBF, 2) != 0) { lineResult.AppendLine(""); lineResult.AppendLine(""); if (includeInvoiceNo) lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); } } } } //CVH 2018-04-17 Medical aid and patient totals. When only printing invoices, only add included transactions in totals, otherwise include all visible lines so that the med and pat liable totals match the Total Due if (includeInvoiceNo) { if (includeTransaction) { totalPat += acnt.liablePat; totalMed += acnt.liableMed; } //else don't add } else if (acnt.isVisible) { totalPat += acnt.liablePat; totalMed += acnt.liableMed; } if (includeTransaction)//validate if transaction line must be included { transIncludedCount++; if (usingBF && transIncludedCount == 1)//include balance brought forward { if (decimal.Round(BalanceBF, 2) != 0) { lineResult.AppendLine(""); lineResult.AppendLine(""); if (includeInvoiceNo) lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); } } if (transIncludedCount == lineCount || transIncludedCount == (lineCount * 2) || transIncludedCount == (lineCount * 3) || transIncludedCount == (lineCount * 4) || transIncludedCount == (lineCount * 5))//insert page break { lineResult.AppendLine("
DateInv-NoPatientCodeICD10DescriptionP.O.SNAPPIQtyMed-LiablePnt-LiableAmountBalanceDateInv-NoPatientCodeICD10DescriptionP.O.SNAPPIQtyMed-LiablePnt-LiableAmountBalance
Balance brought forward" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(BalanceBF, 2))).Replace(" ", ",") + "
Balance brought forward" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(BalanceBF, 2))).Replace(" ", ",") + "
"); lineResult.AppendLine("
"); lineResult.AppendLine(" "); //rebuild header row lineResult.AppendLine(""); if (includeInvoiceNo) { lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); } else { lineResult.AppendLine(""); //lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); } lineResult.AppendLine(""); } lineResult.AppendLine(""); if (acnt.claimSent) { lineResult.AppendLine(""); } else { lineResult.AppendLine(""); } if (includeInvoiceNo) lineResult.AppendLine(""); patient = String.Empty; patient = accountMain.patientName;//patient name if (acnt.patientTitle != String.Empty)//patient initials patient = accountMain.patientTitle + " " + patient; if (acnt.patientCode != String.Empty)//patient code patient = accountMain.patientCode + " " + patient; if (acnt.patientSurname != String.Empty)//patient surname patient += " " + accountMain.patientSurname; if (acnt.birthDate.Year > 1901) patient += " (D.O.B: " + accountMain.birthDate.ToString("dd/MM/yyyy") + ")"; lineResult.AppendLine(""); if (acnt.modifier1 != String.Empty) { lineResult.AppendLine(""); } else { if (acnt.consumableCode.Trim() == String.Empty) if (acnt.procedureCode.Contains(" ")) lineResult.AppendLine(""); else lineResult.AppendLine(""); else { lineResult.AppendLine(""); } } lineResult.AppendLine(""); if (acnt.modifier1 != String.Empty) { if (acnt.modifier1 == "0011") { lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); } } } //include total patient/med aid liable lineResult.AppendLine(""); lineResult.AppendLine(""); if (includeInvoiceNo) lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine(""); lineResult.AppendLine("
DateInv-NoPatientCodeICD10DescriptionP.O.SNAPPIQtyMed-LiablePnt-LiableAmountBalanceDateInv-NoPatientCodeICD10DescriptionP.O.SNAPPIQtyMed-LiablePnt-LiableAmountBalance
" + acnt.dateOfService.ToString("dd-MMM-yy") + "*" + acnt.dateOfService.ToString("dd-MMM-yy") + "" + acnt.invoiceNo + "" + patient + ""); /* CVH 2016-05-06 Show assistant registration number and height/weight next to modifier code if (acnt.modifier1 != String.Empty) lineResult.AppendLine(acnt.modifier1); if (acnt.modifier2 != String.Empty) lineResult.AppendLine(" (" + acnt.modifier2 + ")"); if (acnt.modifier3 != String.Empty) lineResult.AppendLine(" " + acnt.modifier3); */ lineResult.AppendLine(acnt.modifier1); switch (acnt.modifier1) { case "0008": case "0009": case "0011": lineResult.AppendLine(" (" + acnt.modifier2 + ")"); break; case "0018": lineResult.AppendLine(" (H" + acnt.modifier2 + " W" + acnt.modifier3 + ")"); break; default: break; } lineResult.AppendLine("" + acnt.procedureCode.Remove(acnt.procedureCode.IndexOf(" ")) + "" + acnt.procedureCode + "" + acnt.consumableCode + ""); if (acnt.icd1 != String.Empty) lineResult.AppendLine(" " + acnt.icd1); if (acnt.icd2 != String.Empty) lineResult.AppendLine(" / " + acnt.icd2); if (acnt.icd3 != String.Empty) lineResult.AppendLine(" / " + acnt.icd3); if (acnt.icd4 != String.Empty) lineResult.AppendLine(" / " + acnt.icd4); if (acnt.icd5 != String.Empty) lineResult.AppendLine(" / " + acnt.icd5); if (acnt.externalCause != String.Empty) lineResult.AppendLine(" / " + acnt.externalCause); lineResult.AppendLine("" + acnt.modifier1 + "- Emergency Procedure"); } else { lineResult.AppendLine("" + acnt.procedureCode + "-" + utils.stripSpecialCharacters(acnt.procedureDescription)); } } else lineResult.AppendLine("" + utils.stripSpecialCharacters(acnt.procedureDescription)); //if (acnt.modifier1 != String.Empty) // lineResult.AppendLine("
Modifiers: " + acnt.modifier1); //if (acnt.modifier2 != String.Empty) // lineResult.AppendLine(" (" + acnt.modifier2 + ")"); //if (acnt.modifier3 != String.Empty) // lineResult.AppendLine(" " + acnt.modifier3); if (acnt.modifier4 != String.Empty) lineResult.AppendLine(" " + acnt.modifier4); lineResult.AppendLine("
"); //CVH 2018-01-24 Change POS (Place of Service) to show "Site" for GWC if (handler.ReturnSetup().code == "GLOB-1" || handler.ReturnSetup().code == "GLOB-2") { foreach (oSurfaceItem item in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceItem), "recId", acnt.surfaceItemId.ToString())) { DataTable dtPOS = xData.GetSurfaceQueryItemData(item.surfaceId, item.recId); if (dtPOS != null && dtPOS.Rows.Count > 0 && dtPOS.Columns["PatientType_PatientTypeandPracticeLocation_Site"] != null) lineResult.AppendLine(dtPOS.Rows[0]["PatientType_PatientTypeandPracticeLocation_Site"].ToString()); } } else { lineResult.AppendLine(acnt.placeOfService.ToString()); } lineResult.AppendLine(""); lineResult.AppendLine(acnt.procedureNAPPI); lineResult.AppendLine("" + acnt.qty + "" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(acnt.liableMed, 2))).Replace(" ", ",") + "" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(acnt.liablePat, 2))).Replace(" ", ",") + "" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(acnt.amount, 2))).Replace(" ", ",") + "" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(acnt.runningBal, 2))).Replace(" ", ",") + "
Total patient/med aid liable" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(totalMed, 2))).Replace(" ", ",") + "" + utils.returnFormattedDecimal(Convert.ToString(decimal.Round(totalPat, 2))).Replace(" ", ",") + "
"); } catch (Exception ex) { throw new Exception(MethodBase.GetCurrentMethod().Name + ":" + ex.Message); } return lineResult.ToString(); } /// /// Create Statement /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static bool CreateStatement(oAccount accountMain, string webAddress, string emailBodyMessage, int balforward, bool showHidden, int lineCount, bool fromZero, DateTime statementDate, bool useDateRange, DateTime statementDateFrom, DateTime statementDateTo, ref string statementPath, ref string statementFile, bool invoicesOnlyList = false) { try { bool result = false; oMedicalPractice practice = new oMedicalPractice(); string headerData = String.Empty; string bodyData = String.Empty; ArrayList accountList = new ArrayList(); //CVH 2017-07-31 Allow for only invoices to be printed if (invoicesOnlyList) accountList = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "surfaceItemId,procedureType", accountMain.surfaceItemId.ToString() + ",TI", "dateOfService,sequence"); else accountList = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "surfaceItemId", accountMain.surfaceItemId.ToString(), "dateOfService,sequence"); //get practice foreach (oAccount accnt in accountList) { foreach (oMedicalPractice prac in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalPractice), "recId", accnt.practiceNo.ToString())) { practice = prac; break; } break; } //get templates foreach (oTemplate template in xData.GetTypedByCriteriaSpecific("recId", typeof(oTemplate), "templateTypeId", pNums.TemplateType.Debtors.GetHashCode().ToString(), "templateName")) { if (template.templateName.ToLower().Contains("header") && !template.templateName.ToLower().Contains("individual")) { headerData = template.templateContent; } else if (invoicesOnlyList && template.templateName.ToLower().Contains("body invoice list")) { bodyData = template.templateContent; } else if (bodyData == String.Empty && template.templateName.ToLower().Contains("body") && !template.templateName.ToLower().Contains("individual")) { bodyData = template.templateContent; } } //JasR 2016-02-09 //replace address breaks accountMain.postalAddress = accountMain.postalAddress.Replace("\n", "
"); //replace address placeholder stuff accountMain.postalAddress = accountMain.postalAddress.Replace("~|~", ""); for (int i = 1; i < 7; i++) { accountMain.postalAddress = accountMain.postalAddress.Replace("~" + i + "~", "
"); } //merge header values if (practice.vatNum == string.Empty) practice.vatNum = "N/A"; utils.MergeHTMData(ref headerData, utils.BuildFieldCodeList(practice, true)); utils.MergeHTMData(ref headerData, utils.BuildFieldCodeList(accountMain, true)); //CVH 2017-07-31 Allow printing of invoices only headerData = headerData.Replace("{Heading}", invoicesOnlyList ? "Invoice Summary" : "Statement"); headerData = headerData.Replace("{Date}", statementDate.ToString("yyyy/MM/dd")); headerData = headerData.Replace("{WebAddress}", webAddress); //refering dr changes string referingDr = string.Empty; foreach (oAccount accountItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "surfaceItemId", accountMain.surfaceItemId.ToString(), "recId DESC")) { if (accountItem.referringDoctor != string.Empty) { accountMain.referringDoctor = accountItem.referringDoctor; accountMain.referringDocNo = accountItem.referringDocNo; break; } } if (accountMain.referringDoctor != string.Empty) { StringBuilder referBuilder = new StringBuilder(); referBuilder.AppendLine("
Referring Dr:"); referBuilder.AppendLine(accountMain.referringDoctor + "
"); referBuilder.AppendLine("Referring Dr Practice Nr: " + accountMain.referringDocNo.ToString()); referingDr = referBuilder.ToString(); } headerData = headerData.Replace("{refer}", referingDr); if (handler.ReturnSetup().code == "GLOB-1" || handler.ReturnSetup().code == "GLOB-2") { foreach (oSurfaceField memberfield in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceField), "surfaceFieldName", "PatientInformation_MedicalAidifapplicable_MainMembersName")) { foreach (oSurfaceFieldData memberdata in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceFieldData), "surfaceFieldID,surfaceItemId", memberfield.recId + "," + accountMain.surfaceItemId)) { headerData = headerData.Replace("{" + memberfield.surfaceFieldName + "}", memberdata.surfaceFieldValueChar); } } } //merge body values bool includeInvoiceNo = (invoicesOnlyList); bodyData = bodyData.Replace("{AccountLines}", BuildAccountLines(accountMain, accountList, balforward, statementDate, useDateRange, statementDateFrom, statementDateTo, showHidden, lineCount, fromZero, includeInvoiceNo)); decimal accBal = xData.GetAccountBalance(accountMain.surfaceItemId); if (bodyData.Contains("{Balance}")) { bodyData = bodyData.Replace("{Balance}", utils.returnFormattedDecimal(Convert.ToString(accBal), true)); } else { decimal exclBalance = (100.00m / (100.00m + practice.vatRate)) * accBal; decimal vatBalance = accBal - ((100.00m / (100.00m + practice.vatRate)) * accBal); bodyData = bodyData.Replace("{ExclBalance}", utils.returnFormattedDecimal(Convert.ToString(exclBalance), true)); bodyData = bodyData.Replace("{VATBalance}", utils.returnFormattedDecimal(Convert.ToString(vatBalance), true)); bodyData = bodyData.Replace("{InclBalance}", utils.returnFormattedDecimal(Convert.ToString(accBal), true)); } string patientMessage = string.Empty; if (emailBodyMessage != string.Empty) { patientMessage = "For Attention " + accountMain.patientName + " " + accountMain.patientSurname + "
"; patientMessage += emailBodyMessage; } bodyData = bodyData.Replace("{PatientMessage}", patientMessage); statementFile = "Statement_" + accountMain.surfaceItemId + "_" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm") + ".pdf"; statementPath = HttpContext.Current.Server.MapPath("~/upload/documents/"); utils.validateFolder(statementPath); result = utils.ConvertHTMLToPDFFile(bodyData, statementPath + statementFile, true, headerData, ""); return result; } catch (Exception ex) { throw new Exception(MethodBase.GetCurrentMethod().Name + ":" + ex.Message); } } /// /// Create Statement /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static bool CreateStatementIndividualInvoices(oAccount accountMain, string webAddress, string emailBodyMessage, int balforward, bool showHidden, int lineCount, bool fromZero, DateTime statementDate, bool useDateRange, DateTime statementDateFrom, DateTime statementDateTo, ref string statementPath, ref string statementFile) { try { bool result = false; oMedicalPractice practice = new oMedicalPractice(); string bodyDataTemplate = String.Empty; string fileData = String.Empty; ArrayList accountListAll = new ArrayList(); //CVH 2017-07-31 Allow for only invoices to be printed accountListAll = xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "surfaceItemId,isVisible,procedureType", accountMain.surfaceItemId.ToString() + ",1,TI", "dateOfService,sequence"); //get practice foreach (oAccount accnt in accountListAll) { foreach (oMedicalPractice prac in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalPractice), "recId", accnt.practiceNo.ToString())) { practice = prac; break; } break; } //get templates foreach (oTemplate template in xData.GetTypedByCriteriaSpecific("recId", typeof(oTemplate), "templateTypeId", pNums.TemplateType.Debtors.GetHashCode().ToString(), "templateName")) { if (template.templateName.ToLower().Contains("body") && template.templateName.ToLower().Contains("individual")) { bodyDataTemplate = template.templateContent; } else if (template.templateName.ToLower().Contains("header") && template.templateName.ToLower().Contains("individual")) { fileData = template.templateContent; } } //JasR 2016-02-09 //replace address breaks accountMain.postalAddress = accountMain.postalAddress.Replace("\n", "
"); //replace address placeholder stuff accountMain.postalAddress = accountMain.postalAddress.Replace("~|~", ""); for (int i = 1; i < 7; i++) { accountMain.postalAddress = accountMain.postalAddress.Replace("~" + i + "~", "
"); } //merge header values if (practice.vatNum == string.Empty) practice.vatNum = "N/A"; utils.MergeHTMData(ref bodyDataTemplate, utils.BuildFieldCodeList(practice, true)); utils.MergeHTMData(ref bodyDataTemplate, utils.BuildFieldCodeList(accountMain, true)); bodyDataTemplate = bodyDataTemplate.Replace("{Date}", statementDate.ToString("yyyy/MM/dd")); bodyDataTemplate = bodyDataTemplate.Replace("{WebAddress}", webAddress); //refering dr changes string referingDr = string.Empty; foreach (oAccount accountItem in xData.GetTypedByCriteriaSpecific("recId", typeof(oAccount), "surfaceItemId", accountMain.surfaceItemId.ToString(), "recId DESC")) { if (accountItem.referringDoctor != string.Empty) { accountMain.referringDoctor = accountItem.referringDoctor; accountMain.referringDocNo = accountItem.referringDocNo; break; } } if (accountMain.referringDoctor != string.Empty) { StringBuilder referBuilder = new StringBuilder(); referBuilder.AppendLine("
Referring Dr:"); referBuilder.AppendLine(accountMain.referringDoctor + "
"); referBuilder.AppendLine("Referring Dr Practice Nr: " + accountMain.referringDocNo.ToString()); referingDr = referBuilder.ToString(); } bodyDataTemplate = bodyDataTemplate.Replace("{refer}", referingDr); string patientMessage = string.Empty; if (emailBodyMessage != string.Empty) { patientMessage = "For Attention " + accountMain.patientName + " " + accountMain.patientSurname + "
"; patientMessage += emailBodyMessage; } bodyDataTemplate = bodyDataTemplate.Replace("{PatientMessage}", patientMessage); StringBuilder bodyDataAll = new StringBuilder(); foreach (var invoice in accountListAll.Cast().ToList().Select(o => o.invoiceNo).Distinct()) { string invoiceBody = bodyDataTemplate; if (bodyDataAll.ToString().Length > 0) invoiceBody = "
 
" + invoiceBody; var invAccounts = (from oAccount acc in accountListAll where acc.invoiceNo == invoice select acc).ToArray(); ArrayList accountList = new ArrayList(invAccounts); if (accountList.Count > 0) { //check if invoice date falls in date range, otherwise it adds blank invoice if (((oAccount)accountList[0]).dateOfService.Date >= statementDateFrom.Date && ((oAccount)accountList[0]).dateOfService.Date <= statementDateTo.Date) { decimal vatRate = ((oAccount)accountList[0]).vatRate; invoiceBody = invoiceBody.Replace("{Heading}", "Invoice " + xData.BuildDebtorsInvoiceNumber(((oAccount)accountList[0]).recId)); //merge body values bool includeInvoiceNo = true; invoiceBody = invoiceBody.Replace("{AccountLines}", BuildAccountLines(accountMain, accountList, balforward, statementDate, useDateRange, statementDateFrom, statementDateTo, showHidden, lineCount, fromZero, includeInvoiceNo)); //CVH 2018-07-13 Print maim member details on statements and invoices. At the moment the main member isn't being saved in pal_Account for GWC if (handler.ReturnSetup().code == "GLOB-1" || handler.ReturnSetup().code == "GLOB-2") { foreach (oSurfaceField memberfield in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceField), "surfaceFieldName", "PatientInformation_MedicalAidifapplicable_MainMembersName")) { foreach (oSurfaceFieldData memberdata in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurfaceFieldData), "surfaceFieldID,surfaceItemId", memberfield.recId + "," + accountMain.surfaceItemId)) { invoiceBody = invoiceBody.Replace("{" + memberfield.surfaceFieldName + "}", memberdata.surfaceFieldValueChar); } } } decimal accBal = accountList.Cast().ToList().Sum(o => o.amount); //CVH 2018-03-23 Use saved VAT Rate, not current VAT rate of practice decimal exclBalance = (100.00m / (100.00m + vatRate)) * accBal; decimal vatBalance = accBal - ((100.00m / (100.00m + vatRate)) * accBal); invoiceBody = invoiceBody.Replace("{ExclBalance}", utils.returnFormattedDecimal(Convert.ToString(exclBalance), true)); invoiceBody = invoiceBody.Replace("{VATBalance}", utils.returnFormattedDecimal(Convert.ToString(vatBalance), true)); invoiceBody = invoiceBody.Replace("{InclBalance}", utils.returnFormattedDecimal(Convert.ToString(accBal), true)); bodyDataAll.Append(invoiceBody); } } } fileData = fileData.Replace("{Body}", bodyDataAll.ToString()); statementFile = "Statement_" + accountMain.surfaceItemId + "_" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm") + ".pdf"; statementPath = HttpContext.Current.Server.MapPath("~/upload/documents/"); utils.validateFolder(statementPath); result = utils.ConvertHTMLToPDFFile(fileData, statementPath + statementFile, true, "", ""); return result; } catch (Exception ex) { throw new Exception(MethodBase.GetCurrentMethod().Name + ":" + ex.Message); } } /// /// Email account statement /// /// Account with patient details (email etc.) /// emailBodyMessage - optional /// admin setting from web.config /// bcc setting from web.config /// from setting from web.config /// webAddress from web.config /// balance brought forward (days) /// balance from zero /// maximum lines /// show corrections /// user Id /// statement Date /// override subject /// email medical aid /// email patient /// email practice /// medical aid email success /// patient email success /// practice email success /// Success public static bool EmailAccountStatement(oAccount account, string configFrom, string configBcc, string configAdmin, string configWebAddress, string emailBodyMessage, int balforward, bool showHidden, int lineCount, bool fromZero, int userId, DateTime statementDate, bool useDateRange, DateTime statementDateFrom, DateTime statementDateTo, string overrideSubject, bool emailPatient, bool emailPractice, bool emailMedAid, out bool validAccountEmail, out bool validPractice, out bool validMedicalEmail, string noteSurfaceFieldName, bool invoicesOnlyList = false, bool invoicesOnlyDocs = false) { try { string file = String.Empty; string path = string.Empty; validMedicalEmail = false; validAccountEmail = false; validPractice = false; bool success = false; if (invoicesOnlyDocs) success = CreateStatementIndividualInvoices(account, configWebAddress, emailBodyMessage, balforward, showHidden, lineCount, fromZero, statementDate, useDateRange, statementDateFrom, statementDateTo, ref path, ref file); else success = CreateStatement(account, configWebAddress, emailBodyMessage, balforward, showHidden, lineCount, fromZero, statementDate, useDateRange, statementDateFrom, statementDateTo, ref path, ref file, invoicesOnlyList); if (success) { string emailTemplate = string.Empty; //get templates foreach (oTemplate template in xData.GetTypedByCriteriaSpecific("recId", typeof(oTemplate), "templateTypeId", pNums.TemplateType.OutboundResponse.GetHashCode().ToString(), "templateName")) { if (template.templateName.ToLower().Contains("email statement")) { emailTemplate = template.templateContent; } } decimal balance = xData.GetAccountBalance(account.surfaceItemId); if (balance == 0) { if (emailBodyMessage == String.Empty) emailBodyMessage = "Thank you, your payment has been received and your account has been settled in full."; else emailBodyMessage += "

Thank you, your payment has been received and your account has been settled in full."; } utils.MergeHTMData(ref emailTemplate, utils.BuildFieldCodeList(account, true)); emailTemplate = emailTemplate.Replace("{Date}", statementDate.ToString("yyyy/MM/dd")); emailTemplate = emailTemplate.Replace("src=\"/images/", "src=\"" + configWebAddress + "/images/"); emailTemplate = emailTemplate.Replace("src=\"/upload/image/", "src=\"" + configWebAddress + "/upload/image/"); emailTemplate = emailTemplate.Replace("{Message}", emailBodyMessage); oEmail mail = new oEmail(); mail.Body = emailTemplate; mail.Attachments.Add(path + file); /* CVH 2016-07-08 If balance is 0, change subject of email */ string subject = "Medical Statement"; if (overrideSubject != "") subject = overrideSubject; else if (balance == 0) subject = "Thank you for the payment received"; mail.Subject = subject; mail.fromAddress = configFrom; mail.toAddress = configAdmin; if (emailMedAid) { foreach (oMedicalScheme medScheme in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", account.medCode)) { /* CVH 2016-09-05 Validate med scheme email, not mail.toAddress */ if (medScheme.email != string.Empty && utils.validateEmail(medScheme.email)) { mail.toAddress = medScheme.email; validMedicalEmail = true; } } } if (emailPatient) { if (utils.validateEmail(account.email)) { if (mail.toAddress == String.Empty) { mail.toAddress = account.email; } else { mail.toAddress += ";" + account.email; } validAccountEmail = true; } } if (emailPractice) { if (mail.toAddress == String.Empty) { mail.toAddress = configAdmin; } else { mail.toAddress += ";" + configAdmin; } validPractice = true; } //mail.ccAddress += ConfigurationManager.AppSettings["cc"]; mail.bccAddress = configBcc; if (communication.SendAnEmail(mail)) { //Add note with statement as attachment AddCreateStatementNote(account.surfaceItemId, mail.Subject, mail.Body, path, file, userId, noteSurfaceFieldName); return true; } else { return false; } } else return false; } catch (Exception ex) { throw new Exception(MethodBase.GetCurrentMethod().Name + ":" + ex.Message); } } public static oAccount SetAccountItem(int itemId, int surfaceId, oUser usr) { oAccount account = new oAccount(); try { DataTable surfaceItemData = xData.GetSurfaceItemData(surfaceId, itemId); account.surfaceItemId = itemId; if (handler.ReturnSetup().code == "SHOU-1") { foreach (DataRow row in surfaceItemData.Rows) { account.title = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_Title") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_Title"].ToString() : String.Empty; if (account.title.Length > 1) account.title = account.title.Substring(0, 1).ToUpper() + account.title.Substring(1).ToLower(); account.name = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_FirstNames") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_FirstNames"].ToString() : String.Empty; if (account.name.Length > 1) account.name = account.name.Substring(0, 1).ToUpper() + account.name.Substring(1).ToLower(); account.surname = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_Surname") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_Surname"].ToString() : String.Empty; if (account.surname.Length > 1) account.surname = account.surname.Substring(0, 1).ToUpper() + account.surname.Substring(1).ToLower(); account.initials = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_FirstNames") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_FirstNames"].ToString().Substring(0, 1).ToUpper() : String.Empty; account.idNumber = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_IDPassportNumber") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_IDPassportNumber"].ToString() : String.Empty; account.gender = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_Gender") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_Gender"].ToString() : String.Empty; account.postalAddress = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_PostalAddress") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_PostalAddress"].ToString() : String.Empty; DateTime dt = row.Table.Columns.Contains("PatientInformation_PatientDetails_DateofBirth") ? DateTime.Parse(row["PatientInformation_PatientDetails_DateofBirth"].ToString()) : DateTime.MinValue; account.birthDate = dt; account.email = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_EmailAddress") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_EmailAddress"].ToString() : String.Empty; account.patientNumber = row.Table.Columns.Contains("PatientInformation_PatientDetails_PatientNumber") ? int.Parse(row["PatientInformation_PatientDetails_PatientNumber"].ToString()) : 0; account.patientTitle = row.Table.Columns.Contains("PatientInformation_PatientDetails_Title") ? row["PatientInformation_PatientDetails_Title"].ToString().ToUpper() : String.Empty; if (account.patientTitle.Length > 1) account.patientTitle = account.patientTitle.Substring(0, 1).ToUpper() + account.patientTitle.Substring(1).ToLower(); account.patientName = row.Table.Columns.Contains("PatientInformation_PatientDetails_FirstNames") ? row["PatientInformation_PatientDetails_FirstNames"].ToString() : String.Empty; if (account.patientName.Length > 1) account.patientName = account.patientName.Substring(0, 1).ToUpper() + account.patientName.Substring(1).ToLower(); account.patientSurname = row.Table.Columns.Contains("PatientInformation_PatientDetails_Surname") ? row["PatientInformation_PatientDetails_Surname"].ToString() : String.Empty; if (account.patientSurname.Length > 1) account.patientSurname = account.patientSurname.Substring(0, 1).ToUpper() + account.patientSurname.Substring(1).ToLower(); account.patientInitials = row.Table.Columns.Contains("PatientInformation_PatientDetails_FirstNames") ? row["PatientInformation_PatientDetails_FirstNames"].ToString().Substring(0, 1).ToUpper() : String.Empty; //account.planCode = row["PatientInformation_MedicalAidIfapplicable_PlanOption"].ToString();///tariff code account.medAidNumber = row.Table.Columns.Contains("PatientInformation_MedicalAidIfapplicable_MembershipNumber") ? row["PatientInformation_MedicalAidIfapplicable_MembershipNumber"].ToString() : String.Empty; account.patientCode = row.Table.Columns.Contains("PatientInformation_MedicalAidIfapplicable_DependantCode") ? row["PatientInformation_MedicalAidIfapplicable_DependantCode"].ToString() : String.Empty; account.medCode = row.Table.Columns.Contains("PatientInformation_MedicalAidIfapplicable_MedicalAidSchemeName") ? row["PatientInformation_MedicalAidIfapplicable_MedicalAidSchemeName"].ToString() : String.Empty;///medical scheme code account.isIOD = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_InjuryonDuty") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_InjuryonDuty"].ToString() == "1" : false; account.iodEmployerName = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_EmployerName") ? row["PatientInformation_EmployerDetailsInjuryonDuty_EmployerName"].ToString() : String.Empty; account.iodEmployerRegNo = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_EmployerRegistrationNumber") ? row["PatientInformation_EmployerDetailsInjuryonDuty_EmployerRegistrationNumber"].ToString() : String.Empty; account.iodEmployeeNo = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_EmployeeNumber") ? row["PatientInformation_EmployerDetailsInjuryonDuty_EmployeeNumber"].ToString() : String.Empty; account.iodRefNo = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_ReferenceNumber") ? row["PatientInformation_EmployerDetailsInjuryonDuty_ReferenceNumber"].ToString() : String.Empty; if (row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_DateofInjury") && row["PatientInformation_EmployerDetailsInjuryonDuty_DateofInjury"].ToString() != "") { DateTime iodDate = DateTime.Parse(row["PatientInformation_EmployerDetailsInjuryonDuty_DateofInjury"].ToString()); account.iodDate = iodDate; } foreach (oMedicalScheme medScheme in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", account.medCode)) { account.medAidName = medScheme.name; } } } if (handler.ReturnSetup().code == "GLOB-1" || handler.ReturnSetup().code == "GLOB-2" || handler.ReturnSetup().code == "MEDI-1") { foreach (DataRow row in surfaceItemData.Rows) { account.title = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPayment_Title") ? row["PatientInformation_PersonResponsibleforAccountPayment_Title"].ToString() : String.Empty; if (account.title.Length > 1) account.title = account.title.Substring(0, 1).ToUpper() + account.title.Substring(1).ToLower(); account.name = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPayment_FirstNames") ? row["PatientInformation_PersonResponsibleforAccountPayment_FirstNames"].ToString() : String.Empty; if (account.name.Length > 1) account.name = account.name.Substring(0, 1).ToUpper() + account.name.Substring(1).ToLower(); account.surname = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPayment_Surname") ? row["PatientInformation_PersonResponsibleforAccountPayment_Surname"].ToString() : String.Empty; if (account.surname.Length > 1) account.surname = account.surname.Substring(0, 1).ToUpper() + account.surname.Substring(1).ToLower(); account.initials = account.name.Length < 1 ? String.Empty : account.name.Substring(0, 1).ToUpper(); account.idNumber = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPayment_IDPassportNumber") ? row["PatientInformation_PersonResponsibleforAccountPayment_IDPassportNumber"].ToString() : String.Empty; //account.gender = row.Table.Columns.Contains("") ? row[""].ToString() : String.Empty; account.postalAddress = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPayment_PostalAddress") ? row["PatientInformation_PersonResponsibleforAccountPayment_PostalAddress"].ToString() : String.Empty; //CVH 2018-01-02 This was commented out, so birth date never saved. Not sure why, so re-enabling it. DateTime dt = row.Table.Columns.Contains("PatientInformation_PatientDetails_DateofBirth") ? DateTime.Parse(row["PatientInformation_PatientDetails_DateofBirth"].ToString()) : DateTime.MinValue; account.birthDate = dt; account.email = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPayment_EmailAddress") ? row["PatientInformation_PersonResponsibleforAccountPayment_EmailAddress"].ToString() : String.Empty; account.patientNumber = row.Table.Columns.Contains("PatientInformation_PatientDetails_PatientNumber") ? int.Parse(row["PatientInformation_PatientDetails_PatientNumber"].ToString()) : 0; account.patientTitle = row.Table.Columns.Contains("PatientInformation_PatientDetails_Title") ? row["PatientInformation_PatientDetails_Title"].ToString().ToUpper() : String.Empty; if (account.patientTitle.Length > 1) account.patientTitle = account.patientTitle.Substring(0, 1).ToUpper() + account.patientTitle.Substring(1).ToLower(); account.patientName = row.Table.Columns.Contains("PatientInformation_PatientDetails_FirstNames") ? row["PatientInformation_PatientDetails_FirstNames"].ToString() : String.Empty; if (account.patientName.Length > 1) account.patientName = account.patientName.Substring(0, 1).ToUpper() + account.patientName.Substring(1).ToLower(); account.patientSurname = row.Table.Columns.Contains("PatientInformation_PatientDetails_Surname") ? row["PatientInformation_PatientDetails_Surname"].ToString() : String.Empty; if (account.patientSurname.Length > 1) account.patientSurname = account.patientSurname.Substring(0, 1).ToUpper() + account.patientSurname.Substring(1).ToLower(); account.patientInitials = account.patientName.Length < 1 ? "" : account.patientName.Substring(0, 1).ToUpper(); //account.planCode = row["PatientInformation_MedicalAidIfapplicable_PlanOption"].ToString();///tariff code account.medAidNumber = row.Table.Columns.Contains("PatientInformation_MedicalAidifapplicable_MembershipNumber") ? row["PatientInformation_MedicalAidifapplicable_MembershipNumber"].ToString() : String.Empty; //CVH 2018-05-15 GWC-30 account.patientCode = row.Table.Columns.Contains("PatientInformation_MedicalAidifapplicable_DependentCode") ? row["PatientInformation_MedicalAidifapplicable_DependentCode"].ToString() : String.Empty; account.medCode = row.Table.Columns.Contains("PatientInformation_MedicalAidifapplicable_MedicalAidSchemeName") ? row["PatientInformation_MedicalAidifapplicable_MedicalAidSchemeName"].ToString() : String.Empty;///medical scheme code //account.isIOD = row.Table.Columns.Contains("PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_InjuryonDuty") ? row["PatientInformation_PersonResponsibleforAccountPaymentMainMemberofMedicalAid_InjuryonDuty"].ToString() == "1" : false; //account.iodEmployerName = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_EmployerName") ? row["PatientInformation_EmployerDetailsInjuryonDuty_EmployerName"].ToString() : String.Empty; //account.iodEmployerRegNo = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_EmployerRegistrationNumber") ? row["PatientInformation_EmployerDetailsInjuryonDuty_EmployerRegistrationNumber"].ToString() : String.Empty; //account.iodEmployeeNo = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_EmployeeNumber") ? row["PatientInformation_EmployerDetailsInjuryonDuty_EmployeeNumber"].ToString() : String.Empty; //account.iodRefNo = row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_ReferenceNumber") ? row["PatientInformation_EmployerDetailsInjuryonDuty_ReferenceNumber"].ToString() : String.Empty; //if (row.Table.Columns.Contains("PatientInformation_EmployerDetailsInjuryonDuty_DateofInjury") && row["PatientInformation_EmployerDetailsInjuryonDuty_DateofInjury"].ToString() != "") //{ // DateTime iodDate = DateTime.Parse(row["PatientInformation_EmployerDetailsInjuryonDuty_DateofInjury"].ToString()); // account.iodDate = iodDate; //} foreach (oMedicalScheme medScheme in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", account.medCode)) { account.medAidName = medScheme.name; } } } account.userId = usr.recId; } catch (Exception ex) { throw new Exception(MethodBase.GetCurrentMethod().Name + ":" + ex.Message); } return account; } /// /// Add Modifier Lines /// /// /// private static void AddModifierLines(List modList, oAccount accBilling, ref ArrayList billings) { modList.Sort(); string modEntry = "", mod = ""; decimal modMinutes = 0, totalAmount = accBilling.amount, modAmount = 0; ; int sequenceNo = accBilling.sequence; oAccount acc = (oAccount)utils.CloneObject(accBilling); /* Emergency procedure - every 30 mins should be equal to 12RVU's (1 RVU = 16.998, so R12RVU's = R2013.98) */ if (modList.Any(r => r.Substring(0, 4) == "0011")) { modEntry = modList.Single(r => r.Substring(0, 4) == "0011"); mod = modEntry.Split(';')[0]; if (mod.Length > 0) { if (modEntry.Contains(';')) { modMinutes = Convert.ToDecimal(modEntry.Split(';')[1]); } decimal RVU = 16.998M; modAmount = (modMinutes / 30) * (12 * RVU); acc = (oAccount)utils.CloneObject(accBilling); acc.modifier1 = mod; acc.modifier2 = modMinutes.ToString(); acc.amount = modAmount; //default to scheme liable acc.liableMed = modAmount; acc.liablePat = 0; //now check the trf the account is on to determine the liability foreach (oTariffPlan pln in xData.GetTypedByCriteriaSpecific("recId", typeof(oTariffPlan), "code", accBilling.planCode)) { if (pln.liableIndicator == 0) { acc.liableMed = modAmount; acc.liablePat = 0; } else { acc.liableMed = 0; acc.liablePat = modAmount; } } sequenceNo++; acc.sequence = sequenceNo; totalAmount += acc.amount; billings.Add(acc); } } /* Obese patient - All operational procedures should be 50% more */ if (modList.Any(r => r.Substring(0, 4) == "0018")) { modEntry = modList.Single(r => r.Substring(0, 4) == "0018"); mod = modEntry.Split(';')[0]; string modHeight = modEntry.Split(';')[1]; string modWeight = modEntry.Split(';')[2]; if (mod.Length > 0) { acc = (oAccount)utils.CloneObject(accBilling); acc.modifier1 = mod; acc.modifier2 = modHeight; acc.modifier3 = modWeight; foreach (oMedicalProcedure proc in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalProcedure), "code", mod)) { if (proc.modifier > 0) { modAmount = (accBilling.amount * ((proc.modifier - 100) / 100)); } } acc.amount = accBilling.amount + modAmount; //default to scheme liable acc.liableMed = accBilling.amount + modAmount; acc.liablePat = 0; //now check the trf the account is on to determine the liability foreach (oTariffPlan pln in xData.GetTypedByCriteriaSpecific("recId", typeof(oTariffPlan), "code", accBilling.planCode)) { if (pln.liableIndicator == 0) { acc.liableMed = accBilling.amount + modAmount; acc.liablePat = 0; } else { acc.liableMed = 0; acc.liablePat = accBilling.amount + modAmount; } } sequenceNo++; acc.sequence = sequenceNo; totalAmount += acc.amount; billings.Add(acc); } } /* Specialist Assistant = 33.3% of the procedure costs the Specialist was involved in */ if (modList.Any(r => r.Substring(0, 4) == "0008")) { modEntry = modList.Single(r => r.Substring(0, 4) == "0008"); mod = modEntry.Split(';')[0]; string modAssistReg = modEntry.Split(';')[1]; string modAssistSur = modEntry.Split(';')[2]; if (mod.Length > 0) { acc = (oAccount)utils.CloneObject(accBilling); acc.modifier1 = mod; acc.modifier2 = modAssistReg; acc.modifier3 = modAssistSur; foreach (oMedicalProcedure proc in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalProcedure), "code", mod)) { if (proc.modifier > 0) { modAmount = (totalAmount * ((proc.modifier - 100) / 100)); } } acc.amount = totalAmount + modAmount; //default to scheme liable acc.liableMed = totalAmount + modAmount; acc.liablePat = 0; //now check the trf the account is on to determine the liability foreach (oTariffPlan pln in xData.GetTypedByCriteriaSpecific("recId", typeof(oTariffPlan), "code", accBilling.planCode)) { if (pln.liableIndicator == 0) { acc.liableMed = totalAmount + modAmount; acc.liablePat = 0; } else { acc.liableMed = 0; acc.liablePat = totalAmount + modAmount; } } sequenceNo++; acc.sequence = sequenceNo; billings.Add(acc); } } /* Assistant = 20% of the procedure costs that the Assistant was involved in */ if (modList.Any(r => r.Substring(0, 4) == "0009")) { modEntry = modList.Single(r => r.Substring(0, 4) == "0009"); mod = modEntry.Split(';')[0]; string modAssistReg = modEntry.Split(';')[1]; string modAssistSur = modEntry.Split(';')[2]; if (mod.Length > 0) { acc = (oAccount)utils.CloneObject(accBilling); acc.modifier1 = mod; acc.modifier2 = modAssistReg; acc.modifier3 = modAssistSur; foreach (oMedicalProcedure proc in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalProcedure), "code", mod)) { if (proc.modifier > 0) { modAmount = (totalAmount * ((proc.modifier - 100) / 100)); } } acc.amount = totalAmount + modAmount; //default to scheme liable acc.liableMed = totalAmount + modAmount; acc.liablePat = 0; //now check the trf the account is on to determine the liability foreach (oTariffPlan pln in xData.GetTypedByCriteriaSpecific("recId", typeof(oTariffPlan), "code", accBilling.planCode)) { if (pln.liableIndicator == 0) { acc.liableMed = totalAmount + modAmount; acc.liablePat = 0; } else { acc.liableMed = 0; acc.liablePat = totalAmount + modAmount; } } sequenceNo++; acc.sequence = sequenceNo; // billings.Add(acc); } } //0014 if (modList.Any(r => r.Substring(0, 4) == "0014")) { modEntry = modList.Single(r => r.Substring(0, 4) == "0014"); mod = modEntry.Split(';')[0]; if (mod.Length > 0) { acc = (oAccount)utils.CloneObject(accBilling); foreach (oMedicalProcedure proc in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalProcedure), "code", mod)) { if (proc.modifier > 0) { modAmount = (acc.amount * proc.modifier / 100); } else { modAmount = 0; } } acc.modifier1 = mod; acc.amount = modAmount; //default to scheme liable acc.liableMed = modAmount; acc.liablePat = 0; sequenceNo++; acc.sequence = sequenceNo; billings.Add(acc); } } } public static ArrayList SetAccountBillingLines(oAccount mainAccount, List modifiers, DateTime billingDate, string primaryIcd10, string externalCause, string secondaryIcd10, string authorizationNumber, string referringDoctor, string referringDoctorPracticeNumber, int placeOfServiceIndicator, string tendons) { ArrayList billingLines = new ArrayList(); try { //build billing lines from Booking for Procedure in Examinations surface if (handler.ReturnSetup().code == "SHOU-1" && mainAccount.surfaceItemId > 0) { int examId = 0; foreach (oSurface surfExams in xData.GetTypedByCriteriaSpecific("recId", typeof(oSurface), "name", "Examinations")) { DataTable dtExam = xData.GetChildSurfaceQueryData(surfExams.recId, mainAccount.surfaceItemId); if (dtExam != null && dtExam.Rows.Count > 0) { int.TryParse(dtExam.Rows[dtExam.Rows.Count - 1]["itemID"].ToString(), out examId); } } if (examId > 0) { oTariffPlan tariffPlan = new oTariffPlan(); foreach (oMedicalScheme med in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalScheme), "code", mainAccount.medCode)) { string code = med.planCode; //CVH 2018-04-13 Default selected tariff to DISC B for TSP where patient is NOT linked to WCA or FedHealth if (handler.ReturnSetup().code == "SHOU-1" && (med.planCode == String.Empty || (med.planCode != "WCA" && !med.name.ToUpper().Contains("FEDHEALTH")))) code = "DISC B"; foreach (oTariffPlan trf in xData.GetTypedByCriteriaSpecific("recId", typeof(oTariffPlan), "code", code)) { tariffPlan = trf; break; } break; } oMedicalDoctor billingDoc = new oMedicalDoctor(); foreach (oMedicalDoctor doc in xData.GetTypedCollection("recId", typeof(oMedicalDoctor))) { if (doc.isAssistant == false) { billingDoc = doc; break; } } foreach (oMedicalPatientProcedureBooking book in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalPatientProcedureBooking), "surfaceItemId", examId.ToString())) { oMedicalProcedure proc = new global::oMedicalProcedure(); foreach (oMedicalProcedure bookProc in xData.GetTypedByCriteriaSpecific("recId", typeof(oMedicalProcedure), "recId", book.procedureId.ToString())) { proc = bookProc; break; } //skip modifiers if (proc.recId <= 0 || proc.codeType == 2) continue; oAccount newAcc = (oAccount)utils.CloneObject(mainAccount); newAcc.procedureCode = proc.code; newAcc.procedureDescription = proc.description; if (proc.additionalDescription) { //get tendon from surgical notes string selectedTendon = ""; foreach (string str in tendons.Split(new string[] { "~|~" }, StringSplitOptions.None)) { if (str.StartsWith(proc.recId + ",")) { selectedTendon = str.Substring(str.IndexOf(",") + 1); break; } } //CVH 2017-09-27 If tendon line was removed on surgical notes grid, don't add billing line here if (selectedTendon == "REMOVE") continue; newAcc.procedureDescription += " - " + selectedTendon; } newAcc.consumableCode = proc.consumableCode; newAcc.procedureNAPPI = proc.nappi + proc.nappiSuffix; //ICD newAcc.icd1 = primaryIcd10; newAcc.icd2 = secondaryIcd10; newAcc.externalCause = externalCause; newAcc.procedureType = "TI"; newAcc.dateOfService = billingDate.Date; newAcc.dateOfCapture = DateTime.Now; newAcc.dateOfTransaction = DateTime.Now; newAcc.placeOfService = placeOfServiceIndicator; newAcc.vatRate = handler.ReturnSetup().vatRate; newAcc.serviceType = "T"; newAcc.inHospital = false; newAcc.category = 0; newAcc.authorisationNo = authorizationNumber; newAcc.referringDocNo = referringDoctorPracticeNumber; newAcc.referringDoctor = referringDoctor; //calcs newAcc.qty = book.procedureQty; decimal unitFee = 0; foreach (oTariffRate rate in xData.GetTypedByCriteriaSpecific("recId", typeof(oTariffRate), "planCode,procedureCode", tariffPlan.code + "," + proc.code)) { foreach (oPlaceOfService poc in xData.GetTypedByCriteriaSpecific("recId", typeof(oPlaceOfService), "indicator", placeOfServiceIndicator.ToString())) { if (rate.procedureCode == "C2" || rate.procedureCode == "3602") { unitFee = rate.rate; } else { if (poc.rateType == "IH") unitFee = rate.iHRate; if (poc.rateType == "OH") unitFee = rate.oHRate; } } break; } newAcc.unitFee = unitFee; newAcc.amount = unitFee * newAcc.qty; if (tariffPlan.liableIndicator == 0) { newAcc.liablePat = 0; newAcc.liableMed = newAcc.amount; } else { newAcc.liablePat = newAcc.amount; newAcc.liableMed = 0; } newAcc.isVisible = true; newAcc.planCode = tariffPlan.code; newAcc.claimSend = tariffPlan.claimActivated; newAcc.doctor = billingDoc.surname + ", " + billingDoc.title + " " + billingDoc.initials; newAcc.doctorNo = billingDoc.recId; newAcc.practiceNo = billingDoc.practiceId; //running balance decimal bal = 0; foreach (oAccount billBal in billingLines) { bal += billBal.amount; } newAcc.runningBal += newAcc.amount + bal; billingLines.Add(newAcc); //add modifiers if (!proc.nonSurgical) { AddModifierLines(modifiers, newAcc, ref billingLines); //remove modifier 11 after it has been applied once. not applied to all procedures, just first one List newmodList = new List(); foreach (string mod in modifiers) { if (mod.Length > 3) { if (mod.Substring(0, 4) != "0011") { newmodList.Add(mod); } } } if (newmodList.Count > 0) { modifiers = newmodList; } else { modifiers = null; } } } } } } catch (Exception ex) { throw new Exception(MethodBase.GetCurrentMethod().Name + ":" + ex.Message); } return billingLines; } } }