Files
MyMcKesson/TomcatServer/PlutoServer.MSL/Connectors/MedisoftConnector.cs
2016-07-27 00:32:34 -04:00

1343 lines
65 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sdaleo;
using Sdaleo.Systems.SQLServer;
using Pluto.Api;
using System.Data;
using Sdaleo.Systems;
using Yaulw.Win32;
using Sdaleo.Systems.Advantage;
namespace PlutoServer.MSL.Connectors
{
public static class MedisoftConnector
{
internal static string MAKE_SURE_APOSTROPHY_IS_SQL_READY(string str)
{
if (!String.IsNullOrEmpty(str))
{
str = str.Replace("'", "''");
return str;
}
return String.Empty;
}
internal static bool IS_VALID_FOUR_DIGIT_PIN(string fourdigitpin)
{
if (!String.IsNullOrEmpty(fourdigitpin))
{
fourdigitpin = fourdigitpin.Trim();
if (fourdigitpin.Length == 4)
{
foreach (char c in fourdigitpin)
{
if (!Char.IsDigit(c))
return false;
}
return true;
}
}
return false;
}
#region System / Setup Specific
/// <summary>
/// Retrieve the entire Practice List for the given Shared DB Credential * Credential must point to Shared DB *
/// </summary>
/// <param name="credential"></param>
/// <returns></returns>
public static DBRetVal GetPracticeList(AdvantageCredential credential)
{
if (credential != null)
{
DB db = DB.Create(credential);
DBRetVal retVal = db.FillDataTable("SELECT [DataSet Name],[Data Path],[UserAPIKey] FROM [MWDBList]");
if (!retVal.IsValid)
MSLSpecific.Logger.Error("Medisoft. Failed to retrieve Practice List for DataSource:{0}", credential.DataSource);
return retVal;
}
return new DBRetVal();
}
/// <summary>
/// Retrieve the userapi key for a given practice, given Shared DB Credential * Credential must point to Shared DB *
/// </summary>
/// <param name="credential"></param>
/// <returns></returns>
public static string GetUserApiKeyForPractice(AdvantageCredential credential, string DataSetOrDataBaseName, out bool bErrorOccured)
{
bErrorOccured = true;
if (credential != null && !String.IsNullOrEmpty(DataSetOrDataBaseName))
{
DB db = DB.Create(credential);
DBRetVal retVal = db.ExecuteScalar(String.Format("SELECT [UserAPIKey] FROM [MWDBList] WHERE [DataSet Name]='{0}'", MAKE_SURE_APOSTROPHY_IS_SQL_READY(DataSetOrDataBaseName)));
bErrorOccured = retVal.ErrorOccured;
if(retVal.IsValid)
return retVal.GetScalarRetVal().Trim();
}
return String.Empty;
}
/// <summary>
/// Use this to Set the User API Key * Credential must point to Shared DB *
/// </summary>
/// <param name="credential"></param>
/// <param name="PracticeName"></param>
/// <param name="UserApiKey"></param>
/// <returns></returns>
public static bool SetUserApiKeyForPractice(AdvantageCredential credential, string DataSetOrDataBaseName, string UserApiKey)
{
if (credential != null && !String.IsNullOrEmpty(DataSetOrDataBaseName))
{
DB db = DB.Create(credential);
DBRetVal retVal = db.ExecuteNonQuery(String.Format("UPDATE [MWDBList] SET [UserApiKey]='{0}' WHERE [DataSet Name]='{1}'", UserApiKey, MAKE_SURE_APOSTROPHY_IS_SQL_READY(DataSetOrDataBaseName)));
if (!retVal.IsValid)
MSLSpecific.Logger.Error("Medisoft. Failed to set ApiKey for DataSource:{0} DataSet:{1}", credential.DataSource, DataSetOrDataBaseName);
return retVal.IsValid;
}
return false;
}
/// <summary>
/// we must ensure uniqueness amongst all our userapikeys (Lytec and somehow Medisoft get into an
/// invalid state) where they duplicate them * Credential must point to Shared DB *
/// </summary>
/// <param name="credential"></param>
/// <param name="PracticeName"></param>
/// <param name="UserApiKey"></param>
/// <returns></returns>
public static void CleanUpDuplicateUserApiKeyExists(AdvantageCredential credential)
{
DBRetVal retVal = GetPracticeList(credential);
if (retVal.IsValid)
{
Stack<string> userApiStack = new Stack<string>();
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
{
string UserApiKey = DataRet.Retrieve(row["UserAPIKey"]);
if (!String.IsNullOrEmpty(UserApiKey))
{
if (!userApiStack.Contains(UserApiKey))
{
userApiStack.Push(UserApiKey);
}
else
{
// we found a duplicate!!! (Clear the UserApiKey for that Database - IMP!)
string DBName = DataRet.Retrieve(row["DataSet Name"]);
SetUserApiKeyForPractice(credential, DBName, String.Empty);
}
}
}
}
}
#endregion
#region User Authentication
/// <summary>
/// User Authentication
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="User"></param>
/// <param name="Password"></param>
/// <returns></returns>
public static UserInfo1 AuthenticateUserLogin(string SystemApiKey, string User, string Password)
{
if (!String.IsNullOrEmpty(User) && !String.IsNullOrEmpty(Password))
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
DBRetVal result = db.FillDataTable(String.Format("SELECT [Code],[Name],[Access Level],[Password] FROM [mwSEC] Where upper([Code])='{0}'", MAKE_SURE_APOSTROPHY_IS_SQL_READY(User).ToUpper()));
//if ((result != null) && (result.IsValid)) /* Rameshes fix that should not be needed and didn't make sense */
if (result.IsValid)
{
DataRow row = result.GetDataTableFirstRow();
string dbName = DataRet.Retrieve(row["Name"]);
string dbPwd = DataRet.Retrieve(row["Password"]);
// Authenticate! Password must match (case-insensitive) Medisoft also doesn't care about case
if (!String.IsNullOrEmpty(dbName) && (String.Compare(Password.Trim(), dbPwd, true) == 0))
{
UserInfo1 info = new UserInfo1();
info.AuthToken = SystemApiKey;
info.Id = DataRet.Retrieve(row["Code"]);
info.UserName = info.Id;
// Seperate First n' Last name, if possible
info.Name = dbName;
int nFirst = dbName.IndexOf(' ');
if (nFirst != -1)
{
info.FirstName = dbName.Substring(0, nFirst);
info.LastName = dbName.Substring(nFirst + 1);
}
else
{
info.FirstName = dbName;
info.LastName = "";
}
// Authenticated, return the object
info.IsProvider = true;
return info;
}
}
// Users must be setup with Mobile Privilege * ignore code below *
//else
//{
// // Check to see if any users are set up in the table
// result = db.ExecuteScalar("SELECT COUNT([Code]) FROM [mwSEC]");
// uint nCount = 0;
// // If there no users, let them in anyway
// if (result.IsValid && uint.TryParse(result.GetScalarRetVal(), out nCount) && nCount == 0)
// {
// UserInfo1 info = new UserInfo1();
// info.AuthToken = SystemApiKey;
// info.Id = "(Unspecified)";
// info.UserName = "(Unspecified)";
// // Default Authenticated, return the object (No Users exist in table)
// info.IsProvider = true;
// return info;
// }
//}
}
return null;
}
/// <summary>
/// Pin Authentication
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="User"></param>
/// <param name="pin"></param>
/// <returns></returns>
public static UserInfo1 AuthenticateUserPIN(string SystemApiKey, string User, string pin)
{
if (!String.IsNullOrEmpty(User) && IS_VALID_FOUR_DIGIT_PIN(pin))
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
DBRetVal result = db.FillDataTable(String.Format("SELECT [Code],[Name],[MobilePIN] FROM [mwSEC] Where upper([Code])='{0}'", MAKE_SURE_APOSTROPHY_IS_SQL_READY(User).ToUpper()));
if (result.IsValid)
{
DataRow row = result.GetDataTableFirstRow();
string dbName = DataRet.Retrieve(row["Name"]);
string dbPin = DataRet.Retrieve(row["MobilePIN"]);
// Authenticate! Password must match (case-insensitive) Medisoft also doesn't care about case
if (!String.IsNullOrEmpty(dbName) && (String.Compare(pin.Trim(), dbPin, true) == 0))
{
UserInfo1 info = new UserInfo1();
info.AuthToken = SystemApiKey;
info.Id = DataRet.Retrieve(row["Code"]);
info.UserName = info.Id;
// Seperate First n' Last name, if possible
info.Name = dbName;
int nFirst = dbName.IndexOf(' ');
if (nFirst != -1)
{
info.FirstName = dbName.Substring(0, nFirst);
info.LastName = dbName.Substring(nFirst + 1);
}
else
{
info.FirstName = dbName;
info.LastName = "";
}
// Authenticated, return the object
info.IsProvider = true;
return info;
}
}
}
return null;
}
/// <summary>
/// Create Pin
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="User"></param>
/// <param name="pin"></param>
/// <returns></returns>
public static bool CreatePin(string SystemApiKey, string User, string pin)
{
if (!String.IsNullOrEmpty(User) && IS_VALID_FOUR_DIGIT_PIN(pin))
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = String.Format("UPDATE [mwSEC] SET [MobilePIN]='{0}' WHERE upper([Code])='{1}'", MAKE_SURE_APOSTROPHY_IS_SQL_READY(pin), MAKE_SURE_APOSTROPHY_IS_SQL_READY(User).ToUpper());
DBRetVal result = db.ExecuteNonQuery(sql);
return result.IsValid;
}
return false;
}
/// <summary>
/// Pin is Set
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="User"></param>
/// <returns></returns>
public static bool PinIsSet(string SystemApiKey, string User)
{
if (!String.IsNullOrEmpty(User))
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = String.Format("SELECT [MobilePIN] FROM [mwSEC] Where upper([Code])='{0}'", MAKE_SURE_APOSTROPHY_IS_SQL_READY(User).ToUpper());
DBRetVal result = db.ExecuteScalar(sql);
if (result.IsValid)
{
string currentPin = DataRet.Retrieve(result.GetScalarRetVal());
return IS_VALID_FOUR_DIGIT_PIN(currentPin);
}
}
return false;
}
#endregion
#region Medisoft User Options
internal enum DefaultCase
{
DateModified = 0,
HighestCase = 1,
LowestCase = 2
}
/// <summary>
/// Which is the default case to use?
/// </summary>
/// <param name="SystemApiKey"></param>
/// <returns></returns>
internal static DefaultCase GetDefaultCase(string SystemApiKey)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
DBRetVal result = db.ExecuteScalar("SELECT [Case Default] from [MWOPT]");
if (result.IsValid)
{
try
{
DefaultCase Case = (DefaultCase) Enum.Parse(typeof(DefaultCase), result.GetScalarRetVal());
return Case;
}
catch (Exception e)
{
MSLSpecific.Logger.Error("Failed to retrieve Default Case", e);
}
}
return DefaultCase.DateModified;
}
/// <summary>
/// Use CopayRemainder Calculation or plain Patient Balance Calculation
/// </summary>
/// <param name="SystemApiKey"></param>
/// <returns></returns>
internal static bool UseCopayRemainderCalculation(string SystemApiKey)
{
//AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
//DB db = DB.Create(credential);
////The figureMissedCopay was the Boolean from the mwopt table
//DBRetVal result = db.ExecuteScalar("SELECT [Case Default] from MWOPT");
//if (result.IsValid)
//{
// bool bSomethingSomething = DataRet.Retrieve<bool>(result.GetScalarRetVal(), false);
// return bSomethingSomething;
//}
// For Testing Purpose
if ((DateTime.Now.Ticks % 2) == 0)
return true;
else
return false;
}
#endregion
#region Public Simple Info Getters
/// <summary>
/// get Providers
/// </summary>
/// <param name="SystemApiKey"></param>
/// <returns></returns>
public static ProviderInfo1[] GetProviderList(string SystemApiKey)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
DBRetVal result = db.FillDataTable("SELECT [Code],[First Name],[Middle Name],[Last Name],[Phone] FROM [MWPHY] WHERE [Inactive] = false");
List<ProviderInfo1> providers = new List<ProviderInfo1>();
if (result.IsValid)
{
foreach (DataRow row in result.GetDataTableRetVal().Rows)
{
ProviderInfo1 info = new ProviderInfo1();
info.UserId = DataRet.Retrieve(row["Code"]);
info.FirstName = DataRet.Retrieve(row["First Name"]);
info.MiddleName = DataRet.Retrieve(row["Middle Name"]);
info.LastName = DataRet.Retrieve(row["Last Name"]);
info.Id = -1;
string phone = DataRet.Retrieve(row["Phone"]);
if (!String.IsNullOrEmpty(phone) && phone != "( ) -")
{
info.Phone = phone;
}
providers.Add(info);
}
return providers.ToArray();
}
return null;
}
/// <summary>
/// Get Diagnosis
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="searchStr"></param>
/// <returns></returns>
public static TerminologyInfo1[] GetDiagnosisList(string SystemApiKey, string searchStr)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = "SELECT [Code 1],[Description] FROM [MWDIA] WHERE [Inactive] = false";
if (!String.IsNullOrEmpty(searchStr))
sql += String.Format(" AND (upper([Code 1]) like '%{0}%' OR upper([Description]) like '%{0}%')", MAKE_SURE_APOSTROPHY_IS_SQL_READY(searchStr).ToUpper());
DBRetVal result = db.FillDataTable(sql);
List<TerminologyInfo1> diagnoses = new List<TerminologyInfo1>();
if (result.IsValid)
{
foreach (DataRow row in result.GetDataTableRetVal().Rows)
{
TerminologyInfo1 info = new TerminologyInfo1();
info.Code = DataRet.Retrieve(row["Code 1"]);
info.Description = DataRet.Retrieve(row["Description"]);
diagnoses.Add(info);
}
return diagnoses.ToArray();
}
return null;
}
/// <summary>
/// Get Procedures
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="chart"></param>
/// <param name="searchStr"></param>
/// <returns></returns>
public static TerminologyInfo1[] GetProceduresList(string SystemApiKey, string chart, string searchStr)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = "SELECT [Code 1],[Description],[Default Modifier 1],[Default Modifier 2],[Default Modifier 3],[Default Modifier 4],[Default Units] FROM [MWPRO] WHERE [Inactive] = 0";
if (!String.IsNullOrEmpty(searchStr))
sql += String.Format(" AND (upper([Code 1]) like '%{0}%' OR upper([Description]) like '%{0}%')", MAKE_SURE_APOSTROPHY_IS_SQL_READY(searchStr).ToUpper());
DBRetVal result = db.FillDataTable(sql);
List<TerminologyInfo1> procedures = new List<TerminologyInfo1>();
if (result.IsValid)
{
foreach (DataRow row in result.GetDataTableRetVal().Rows)
{
TerminologyInfo1 info = new TerminologyInfo1();
info.Code = DataRet.Retrieve(row["Code 1"]);
info.Description = DataRet.Retrieve(row["Description"]);
info.Modifier1 = DataRet.Retrieve(row["Default Modifier 1"]);
info.Modifier2 = DataRet.Retrieve(row["Default Modifier 2"]);
info.Modifier3 = DataRet.Retrieve(row["Default Modifier 3"]);
info.Modifier4 = DataRet.Retrieve(row["Default Modifier 4"]);
info.Units = DataRet.Retrieve<decimal>(row["Default Units"]);
procedures.Add(info);
}
return procedures.ToArray();
}
return null;
}
/// <summary>
/// Get Facilities
/// </summary>
/// <param name="SystemApiKey"></param>
/// <returns></returns>
public static FacilityInfo1[] GetFacilitiesList(string SystemApiKey)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = "SELECT [Code],[Name],[Street 1],[Street 2],[City],[State],[Zip Code],[Phone],[Contact],[Email] FROM mwadd WHERE Type='Facility' OR Type='Laboratory' AND [Inactive] = false";
DBRetVal result = db.FillDataTable(sql);
List<FacilityInfo1> facilities = new List<FacilityInfo1>();
if (result.IsValid)
{
foreach (DataRow row in result.GetDataTableRetVal().Rows)
{
FacilityInfo1 info = new FacilityInfo1();
info.Code = DataRet.Retrieve(row["Code"]);
info.Name = DataRet.Retrieve(row["Name"]);
// Address Info
info.Address = new AddressInfo1();
info.Address.Address1 = DataRet.Retrieve(row["Street 1"]);
info.Address.Address2 = DataRet.Retrieve(row["Street 2"]);
info.Address.City = DataRet.Retrieve(row["City"]);
info.Address.State = DataRet.Retrieve(row["State"]);
info.Address.Zip = DataRet.Retrieve(row["Zip Code"]);
facilities.Add(info);
}
return facilities.ToArray();
}
return null;
}
/// <summary>
/// Not implemented (NOT CALLED)
/// </summary>
/// <param name="SystemApiKey"></param>
/// <returns></returns>
public static ResourceInfo1[] GetResourcesList(string SystemApiKey)
{
// Not implemented
return null;
}
/// <summary>
/// Get Patients
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="lastName"></param>
/// <param name="firstName"></param>
/// <param name="dateOfBirth"></param>
/// <returns></returns>
public static PatientInfo1[] GetPatientList(string SystemApiKey, string lastName, string firstName, string dateOfBirth)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = "SELECT [Chart Number],[First Name],[Middle Name],[Last Name],[Date of Birth] as [Birth Date],[Sex],[Street 1],[Street 2],[City],[State],[Zip Code],[Phone 1],[Phone 2],[Phone 3],[Social Security Number] FROM [MWPAT]";
// Allow them to search by patient name or by date of birth,
// not both that is just too confusing
bool bWhereIsSet = false;
if (!String.IsNullOrEmpty(dateOfBirth))
{
DateTime dt;
if (DateTime.TryParse(dateOfBirth, out dt))
{
sql = sql + String.Format(" WHERE [Date of Birth] = '{0:D4}-{1:D2}-{2:D2}' ", dt.Year, dt.Month, dt.Day);
bWhereIsSet = true;
}
}
else
{
if (!String.IsNullOrEmpty(lastName))
{
sql = sql + String.Format(" WHERE upper([Last Name]) like '%{0}%' {1}", MAKE_SURE_APOSTROPHY_IS_SQL_READY(lastName).ToUpper(), !String.IsNullOrEmpty(firstName) ? "OR" : "");
bWhereIsSet = true;
}
if (!String.IsNullOrEmpty(firstName) && !String.IsNullOrEmpty(lastName))
{
sql = sql + String.Format(" {1} upper([First Name]) like '%{0}%' ", MAKE_SURE_APOSTROPHY_IS_SQL_READY(firstName).ToUpper(), String.IsNullOrEmpty(lastName) ? "WHERE" : "");
}
}
// Only query for Active Patients
if(bWhereIsSet)
sql = sql + " AND [Inactive] = false ";
else
sql = sql + " WHERE [Inactive] = false ";
// Order Correctly
sql = sql + " ORDER BY [Last Name],[First Name],[Middle Name] ";
DBRetVal result = db.FillDataTable(sql);
List<PatientInfo1> patients = new List<PatientInfo1>();
if (result.IsValid)
{
foreach (DataRow row in result.GetDataTableRetVal().Rows)
{
PatientInfo1 info = FillInPatientInformation(row, false, true);
patients.Add(info);
}
return patients.ToArray();
}
return null;
}
#endregion
#region Private Static SQL Query Helper
/// <summary>
/// Fills in the Patient Info from the Patient Table Columns
/// </summary>
/// <param name="row"></param>
/// <param name="bFillAsMuchPatientInfoAsPossible">If Set to true, will fill in as much patient information as possible, otherwise will on fill basic patient name / chart information</param>
/// <param name="bFillInPhoneInfo">if set to true will fill try to fill in phone information</param>
/// <returns></returns>
private static PatientInfo1 FillInPatientInformation(DataRow row, bool bFillAsMuchPatientInfoAsPossible, bool bFillInPhoneInfo)
{
PatientInfo1 info = new PatientInfo1();
// Basic Patient Info (Always fill that information)
info.ChartId = DataRet.Retrieve(row["Chart Number"]);
info.Id = DataRet.Retrieve(row["Chart Number"]);
info.FirstName = DataRet.Retrieve(row["First Name"]);
info.MiddleName = DataRet.Retrieve(row["Middle Name"]);
info.LastName = DataRet.Retrieve(row["Last Name"]);
info.Weight = ""; // we don't track weight
// Birth Date & Age Calculation
info.DOB = DataRet.Retrieve<DateTime>(row["Birth Date"]);
if (info.DOB > DateTime.MinValue)
{
DateTime now = DateTime.Today;
int age = now.Year - info.DOB.Year;
if (info.DOB > now.AddYears(-age)) age--;
info.Age = age.ToString();
}
// Gender
info.Gender = DataRet.Retrieve(row["Sex"], "Unknown", true);
// If we want more details on the Patient, this will be set to false
if (bFillAsMuchPatientInfoAsPossible)
{
// Social Security
info.SocialSecurity = DataRet.Retrieve(row["Social Security Number"]);
// Primary Address
AddressInfo1 address = new AddressInfo1();
address.Address1 = DataRet.Retrieve(row["Street 1"]);
address.Address2 = DataRet.Retrieve(row["Street 2"]);
address.City = DataRet.Retrieve(row["City"]);
address.State = DataRet.Retrieve(row["State"]);
address.Zip = DataRet.Retrieve(row["Zip Code"]);
info.PrimaryAddress = address;
}
// Phone Number may already be filled in for us
if (bFillInPhoneInfo)
{
// Primary Phone
string Phone = DataRet.Retrieve(row["Phone 1"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
{
info.PrimaryPhone = Phone;
}
else
{
Phone = DataRet.Retrieve(row["Phone 2"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
{
info.PrimaryPhone = Phone;
}
else
{
Phone = DataRet.Retrieve(row["Phone 3"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
{
info.PrimaryPhone = Phone;
}
}
}
}
return info;
}
/// <summary>
/// Basically the same query as Appointment Query except with no Appointment information because all we have
/// is a Chart
/// </summary>
/// <param name="PatientChart">Patient Chart</param>
/// <returns></returns>
private static string BuildPatientQuery(string PatientChart, DefaultCase Case)
{
if (!String.IsNullOrEmpty(PatientChart))
{
StringBuilder sb = new StringBuilder();
sb.Append("SELECT TOP 1 p.[Chart Number], p.[First Name],p.[Middle Name],p.[Last Name],p.[Date of Birth] as [Birth Date],p.[Sex],p.[Street 1],p.[Street 2],p.[City]");
//sb.Append(",p.[State],p.[Zip Code],p.[Phone 1],p.[Phone 2],p.[Phone 3],p.[Work Phone],p.[Work Extension], p.[Social Security Number]"); // Not using Work Phone / Work Extension
sb.Append(",p.[State],p.[Zip Code],p.[Phone 1],p.[Phone 2],p.[Phone 3],p.[Social Security Number]");
sb.Append(",c.[Copayment Amount] as [Patient Copay]");
sb.Append(",i.[Name] as [Primary Insurance Name]");
sb.Append(",h.[Last Name] as [Ref Phy Last Name],h.[First Name] as [Ref Phy First Name],h.[Office] as [Ref Physician Phone],h.[Phone] as [Ref Physician Main Phone], h.[Cell] as [Ref Physician Mobile Phone]");
sb.Append(" FROM [MWPAT] p LEFT JOIN");
sb.Append(" [MWCAS] c ON p.[Chart Number] = c.[Chart Number]");
sb.Append(" LEFT JOIN [MWINS] i ON c.[Insurance Carrier #1] = i.[Code]");
sb.Append(" LEFT JOIN [MWRPH] h ON c.[Referring Provider] = h.[Code]");
sb.Append(" WHERE ");
sb.Append(String.Format("p.[Chart Number] = '{0}' ", MAKE_SURE_APOSTROPHY_IS_SQL_READY(PatientChart)));
// Don't forget the order by
switch (Case)
{
case DefaultCase.DateModified:
sb.Append("Order By c.[Date Modified] DESC");
break;
case DefaultCase.HighestCase:
sb.Append("Order By c.[Case Number] DESC");
break;
case DefaultCase.LowestCase:
sb.Append("Order By c.[Case Number] ASC");
break;
}
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Build the Appointment / Patient SQL Query as needed, either specify a Date Range or give a specific ID
/// </summary>
/// <param name="startDT"></param>
/// <param name="endDT"></param>
/// <returns></returns>
private static string BuildAppointmentQuery(int nApptID, DateTime startDT, DateTime endDT, string[] providers, string[] resources)
{
StringBuilder sb = new StringBuilder();
sb.Append("SELECT a.[ID],a.[Resource],a.[Date], a.[Status],a.[Start Time],a.[Case Number],a.[Length],a.[Name],a.[Chart Number],a.[Provider],a.[Procedure Code],a.[Note],a.[Color],a.[Reason Code]");
sb.Append(",a.[Phone] as [Appt Home Phone],a.[Cell Phone] as [Appt Mobile Phone]");
sb.Append(",p.[First Name],p.[Middle Name],p.[Last Name],p.[Date of Birth] as [Birth Date],p.[Sex],p.[Street 1],p.[Street 2],p.[City]");
//sb.Append(",p.[State],p.[Zip Code],p.[Phone 1],p.[Phone 2],p.[Phone 3],p.[Work Phone],p.[Work Extension], p.[Social Security Number]"); // Not using Work Phone / Work Extension
sb.Append(",p.[State],p.[Zip Code],p.[Phone 1],p.[Phone 2],p.[Phone 3],p.[Social Security Number]");
sb.Append(",c.[Copayment Amount] as [Patient Copay]");
sb.Append(",r.[Description] as [Reason Description]");
sb.Append(",i.[Name] as [Primary Insurance Name]");
sb.Append(",h.[Last Name] as [Ref Phy Last Name],h.[First Name] as [Ref Phy First Name],h.[Office] as [Ref Physician Phone],h.[Phone] as [Ref Physician Main Phone], h.[Cell] as [Ref Physician Mobile Phone]");
sb.Append(" FROM [OHAPP] a LEFT JOIN");
sb.Append(" [MWPAT] p ON p.[Chart Number] = a.[Chart Number]");
sb.Append(" LEFT JOIN [OHRSN] r ON a.[Reason Code] = r.[Code]");
sb.Append(" LEFT JOIN [MWCAS] c ON a.[Case Number] = c.[Case Number]");
sb.Append(" LEFT JOIN [MWINS] i ON c.[Insurance Carrier #1] = i.[Code]");
sb.Append(" LEFT JOIN [MWRPH] h ON c.[Referring Provider] = h.[Code]");
sb.Append(" WHERE ");
// if ID is specified, we are looking for a single appointment,
// otherwise we are looking for a range
if (nApptID >= 0)
{
sb.Append(String.Format(" [ID] = {0} ", nApptID));
}
else
{
// [Date] between '10/24/2012' and '10/27/2012' AND
const string DATE_FORMAT = "{0:D2}/{1:D2}/{2:D4}";
string StartDate = String.Format(DATE_FORMAT, startDT.Month, startDT.Day, startDT.Year);
string EndDate = String.Format(DATE_FORMAT, endDT.Month, endDT.Day, endDT.Year);
sb.Append(String.Format("[Date] between '{0}' AND '{1}' AND ", StartDate, EndDate));
// [Appt Time] between '9:00:00 AM' AND '12:30:00 PM'
string StartTime = startDT.ToString("hh:mm:ss tt");
string EndTime = endDT.ToString("hh:mm:ss tt");
sb.Append(String.Format("[Start Time] between '{0}' AND '{1}' ", StartTime, EndTime));
// Do we have providers?
// AND [Provider] in ('LAB',)
if (providers != null && providers.Length > 0)
{
sb.Append("AND [Provider] in ('',"); // Allow '' blank providers
for (int i = 0; i < providers.Length; ++i)
{
sb.Append("'");
sb.Append(MAKE_SURE_APOSTROPHY_IS_SQL_READY(providers[i]));
sb.Append("'");
if (i != providers.Length - 1)
sb.Append(",");
}
sb.Append(") ");
}
// Do we have resources?
// AND [Resource] in (2, )
if (resources != null && resources.Length > 0)
{
sb.Append("AND [Resource] in ('',"); // Allow '' blank resources
for (int i = 0; i < resources.Length; ++i)
{
sb.Append(resources[i]);
if (i != resources.Length - 1)
sb.Append(",");
}
sb.Append(") ");
}
// Filter out all Cancelled Appointments
sb.Append("AND (a.[Status] <> '4' ");
// Allow "Break" appointment types
sb.Append("OR a.[Status] IS NULL) ");
// Don't forget the order by
sb.Append("Order By [Date],[Start Time],[ID]");
}
return sb.ToString();
}
#endregion
#region Public Appointment Methods
/// <summary>
/// Retrieve all appointments for the given time period for the given providers or resources
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="providerInfo"></param>
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
public static AppointmentInfo1[] GetAppointments(string SystemApiKey, ProviderInfo1[] providerInfo, ResourceInfo1[] resourceInfo, DateTime startDate, DateTime endDate)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = "";
List<string> providers = new List<string>();
List<string> resources = new List<string>();
if (providerInfo != null)
{
foreach (ProviderInfo1 info1 in providerInfo)
{
if (!String.IsNullOrEmpty(info1.UserId))
providers.Add(info1.UserId);
}
}
if (resourceInfo != null)
{
foreach (ResourceInfo1 info1 in resourceInfo)
{
if (!String.IsNullOrEmpty(info1.Name))
resources.Add(info1.Name);
}
}
// Build the Appointment QUERY (don't pass in an Appt ID and it will use a range)
sql = BuildAppointmentQuery(-1, startDate, endDate, providers.ToArray(), resources.ToArray());
DBRetVal result = db.FillDataTable(sql);
List<AppointmentInfo1> appointments = new List<AppointmentInfo1>();
if (result.IsValid)
{
foreach (DataRow row in result.GetDataTableRetVal().Rows)
{
AppointmentInfo1 info = new AppointmentInfo1();
info.Id = DataRet.Retrieve<long>(row["ID"]);
// Retrieving Description for the Appointment Reason Code via join
info.Reason = DataRet.Retrieve(row["Reason Description"]);
//Retrieving Provider code for the appointment
info.ProviderCode = DataRet.Retrieve(row["Provider"]);
// Let's figgure out the Appointment DTs
// StartDateTime = DateTime.Parse(string.Format("{0} {1}:{2}:00 AM", today.ToShortDateString(), 2, 15)),
// EndDateTime = DateTime.Parse(string.Format("{0} {1}:{2}:00 PM", today.ToShortDateString(), 2, 30)),
DateTime dtDate = DataRet.Retrieve<DateTime>(row["Date"]);
DateTime dtTime = DataRet.Retrieve<DateTime>(row["Start Time"]);
int nDuration = DataRet.Retrieve<int>(row["Length"]);
info.StartDateTime = DateTime.Parse(string.Format("{0} {1:D2}:{2:D2}:{3:D2}", dtDate.ToShortDateString(), dtTime.Hour, dtTime.Minute, dtTime.Second));
if (nDuration == 0)
{
// Leave it as is (no duration was set)
info.EndDateTime = info.StartDateTime;
}
else
{
dtTime = dtTime.AddMinutes(nDuration);
info.EndDateTime = DateTime.Parse(string.Format("{0} {1:D2}:{2:D2}:{3:D2}", dtDate.ToShortDateString(), dtTime.Hour, dtTime.Minute, dtTime.Second));
}
// Appointment Primary Phone
bool bAppointmentPhoneFound = false;
string Phone = DataRet.Retrieve(row["Appt Home Phone"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
{
bAppointmentPhoneFound = true;
}
else
{
Phone = DataRet.Retrieve(row["Appt Mobile Phone"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
bAppointmentPhoneFound = true;
}
// Attach Chart Information (Only the most basic information, try to attach Phone Number if none found in appointment)
bool bHasChart = (DataRet.Retrieve(row["Chart Number"]) != "");
if (bHasChart)
info.Patient = FillInPatientInformation(row, false, !bAppointmentPhoneFound);
else
info.AppointmentDescription = DataRet.Retrieve(row["Name"]);
// Attach Appointment Phone always, if found
if (bAppointmentPhoneFound)
info.AppointmentPhone = Phone;
//[Background Color]
//#define DEFAULT_GRID_TEXT_COLOR (RGB(0,0,0))
//#define DEFAULT_GRID_BKGND_COLOR (RGB(255,255,255))
int ColorRef = DataRet.Retrieve<int>(row["Color"], 0);
if (ColorRef == 0)
info.AppointmentColor = new AppointmentColor1() { Red = 255, Green = 255, Blue = 255 };
else
info.AppointmentColor = new AppointmentColor1() { Red = Functions.GetRValue(ColorRef), Green = Functions.GetGValue(ColorRef), Blue = Functions.GetBValue(ColorRef) };
// Determine the Appointment Status
/*
* Medisoft Status
0 Unconfirmed
1 Confirmed
2 Checked In
3 Missed
4 Cancelled
5 Being Seen
6 Checked Out
7 Rescheduled
* --------------------------
* Medisoft To Mobile Mapping
0 Unconfirmed_Pending
1 Confirmed
2 CheckedIn_Waiting
3 Missed
4 Cancelled
5 Being Seen
6 CheckedOut_Completed
7 - Rescheduled
* */
string status = DataRet.Retrieve(row["Status"]);
switch (status)
{
case "0":
info.AppointmentStatus = AppointmentStatusEnum.Unconfirmed_Pending;
break;
case "1":
info.AppointmentStatus = AppointmentStatusEnum.Confirmed;
break;
case "2":
info.AppointmentStatus = AppointmentStatusEnum.CheckedIn_Waiting;
break;
case "3":
info.AppointmentStatus = AppointmentStatusEnum.Missed;
break;
case "4":
info.AppointmentStatus = AppointmentStatusEnum.Cancelled;
break;
case "5":
info.AppointmentStatus = AppointmentStatusEnum.BeingSeen;
break;
case "6":
info.AppointmentStatus = AppointmentStatusEnum.CheckedOut_Completed;
break;
case "7":
info.AppointmentStatus = AppointmentStatusEnum.Rescheduled;
break;
default:
break;
}
// Finally, add the appointment
appointments.Add(info);
}
return appointments.ToArray();
}
return null;
}
/// <summary>
/// Appointment Detail query. Fills in useful information for the patient regarding the Appointment
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="ApptID"></param>
/// <returns></returns>
public static AppointmentDetail1 GetAppointmentDetail(string SystemApiKey, int ApptID, bool bCalculateBalance)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
string sql = BuildAppointmentQuery(ApptID, DateTime.MinValue, DateTime.MinValue, null, null);
DBRetVal result = db.FillDataTable(sql);
if (result.IsValid)
{
DataRow row = result.GetDataTableFirstRow();
AppointmentDetail1 detail = new AppointmentDetail1();
// Appointment Stuff
detail.ApptNote = DataRet.Retrieve(row["Note"]);
detail.ApptReason = DataRet.Retrieve(row["Reason Description"]);
// Chart Info
bool bHasChart = (DataRet.Retrieve(row["Chart Number"]) != "");
if (bHasChart)
detail.PatientDetail = GetPatientDetail(SystemApiKey, row, String.Empty, bCalculateBalance);
// Return the Appointment Detail Item
return detail;
}
return null;
}
/// <summary>
/// Similar to GetAppointmentDetail, except all we have here is only the chart, so no appointment information
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="UseThisRowInsteadOfQuery">if this is set to not null (a valid DBRetVal), it will use the DBRetVal and not re-query</param>
/// <param name="ApptID"></param>
/// <returns></returns>
public static PatientDetail1 GetPatientDetail(string SystemApiKey, DataRow UseThisRowInsteadOfQuery, string PatientChart, bool bCalculateBalance)
{
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
DataRow row = null;
// Query only if the row has not been passed in
if (UseThisRowInsteadOfQuery == null)
{
string sql = BuildPatientQuery(PatientChart, GetDefaultCase(SystemApiKey));
DBRetVal result = db.FillDataTable(sql);
if (result.IsValid)
row = result.GetDataTableFirstRow();
}
else
{
row = UseThisRowInsteadOfQuery;
}
// Fill in the information
if (row != null)
{
PatientDetail1 detail = new PatientDetail1();
// Chart Info
detail.Patient = FillInPatientInformation(row, true, true);
// Patient Billing Information
detail.PatientBilling = new PatientBillingInfo1();
detail.PatientBilling.CopayAmount = DataRet.Retrieve<decimal>(row["Patient Copay"], 0);
detail.PatientBilling.PrimaryInsCarrier = DataRet.Retrieve(row["Primary Insurance Name"]);
// Refering Provider comes from Patient Table also
detail.PatientBilling.RefProvider = DataRet.Retrieve(row["Ref Phy First Name"]) + " " + DataRet.Retrieve(row["Ref Phy Last Name"]);
// Fill in Refering Provider Phone
string Phone = DataRet.Retrieve(row["Ref Physician Phone"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
{
detail.PatientBilling.RefProviderPhone = Phone;
}
else
{
Phone = DataRet.Retrieve(row["Ref Physician Main Phone"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
{
detail.PatientBilling.RefProviderPhone = Phone;
}
else
{
Phone = DataRet.Retrieve(row["Ref Physician Mobile Phone"]);
if (!String.IsNullOrEmpty(Phone) && Phone != "( ) -")
{
detail.PatientBilling.RefProviderPhone = Phone;
}
}
}
// Calculate Account Balance (May take awhile)
if (bCalculateBalance)
{
detail.PatientBilling.AccountBalance = CalculatePatientBalance(detail.Patient.ChartId, SystemApiKey);
}
// Return the Appointment Detail Item
return detail;
}
return null;
}
/// <summary>
/// Used to calculate the Patient Balance (stripped out of Lytec)
/// </summary>
/// <param name="Chart"></param>
/// <returns></returns>
private static decimal CalculatePatientBalance(string Chart, string SystemApiKey)
{
if (!String.IsNullOrEmpty(Chart))
{
// Copied from Medisoft Source Code (Sent to my by Scott Toney)
// Query1: This is used to get the patient balance without the missed copays
StringBuilder sb1 = new StringBuilder();
sb1.Append("SELECT SUM([Amount] + ");
sb1.Append("[Insurance 1 Amount Paid] + ");
sb1.Append("[Insurance 2 Amount Paid] + ");
sb1.Append("[Insurance 3 Amount Paid] + ");
sb1.Append("[Guarantor Amount Paid] + ");
sb1.Append("[Attorney Amount Paid] + ");
sb1.Append("[Adjustment Amount] ");
sb1.Append(") as RemainderBalance ");
sb1.Append("FROM [MWTRN] ");
//sb1.Append("WHERE [Transaction type] <= " + QuotedStr('H') + " AND ");
sb1.Append("WHERE [Transaction type] <= 'H' AND ");
sb1.Append("( [Guarantor Responsible] = True ) ");
sb1.Append("AND ([Insurance 1 Paid] = True ) ");
sb1.Append("AND ([Insurance 2 Paid] = True ) ");
sb1.Append("AND ([Insurance 3 Paid] = True ) ");
sb1.Append("AND ([Guarantor Paid] = False ) AND ");
sb1.Append("[case number] IN ");
sb1.Append("(SELECT [case number] FROM [MWCAS] WHERE [guarantor] = ");
sb1.Append("(SELECT TOP 1 [guarantor] FROM [MWCAS] WHERE [chart number] = '" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(Chart) + "')) ");
string sqlQuery1 = sb1.ToString();
// Copied from Medisoft Source Code (Sent to my by Scott Toney)
// Query2: run the query to get the missed copays
StringBuilder sb2 = new StringBuilder();
sb2.Append("SELECT SUM([Copayment_Expected_Amount] + ");
sb2.Append("[Copayment_Amount_Paid] ");
sb2.Append(") as CopayBalance ");
sb2.Append("from [MWTRN] ");
//sb2.Append("WHERE [Transaction type] <= " + QuotedStr('H') + " AND ");
sb2.Append("WHERE [Transaction type] <= 'H' AND ");
sb2.Append("( [Guarantor Responsible] = True ) ");
sb2.Append("AND ( (( [Insurance 1 Responsible] = True ) and ( [Insurance 1 Paid] <> [Insurance 1 Responsible] )) ");
sb2.Append("OR (( [Insurance 2 Responsible] = True ) and ( [Insurance 2 Paid] <> [Insurance 2 Responsible] )) ");
sb2.Append("OR (( [Insurance 3 Responsible] = True ) and ( [Insurance 3 Paid] <> [Insurance 3 Responsible] )) ");
sb2.Append(") ");
sb2.Append("AND ( [Guarantor Paid] = False ) and ");
sb2.Append("[case number] in ");
sb2.Append("(SELECT [case number] From [MWCAS] WHERE [guarantor] = ");
sb2.Append("(SELECT TOP 1 [guarantor] from [MWCAS] where [chart number] = '" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(Chart) + "')) ");
string sqlQuery2 = sb2.ToString();
// Determine which query to run (Balance or CoPay Remainder)
string sql = "";
if (UseCopayRemainderCalculation(SystemApiKey))
sql = sqlQuery2;
else
sql = sqlQuery1;
// Run the Query
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
DBRetVal result = db.ExecuteScalar(sql);
if (result.IsValid)
{
decimal Balance = DataRet.Retrieve<decimal>(result.GetScalarRetVal(), 0);
return Balance;
}
}
return 0;
}
#endregion
#region Post Billing
/// <summary>
/// Post Billing to Unproccessed Transactions
/// </summary>
/// <param name="SystemApiKey"></param>
/// <param name="User"></param>
/// <param name="billingInfo"></param>
/// <returns></returns>
public static bool PostBilling(string SystemApiKey, string User, BillingPost1 billingInfo)
{
// Make sure this is a valid BillingPost we are getting passed in
if ((billingInfo == null) || (billingInfo.BillingDetails == null) ||
(billingInfo.BillingDetails.Length == 0))
return false;
// Generate new Unique ID
string UniqueID = Guid.NewGuid().ToString();
UniqueID = UniqueID.Replace("-", "").Substring(0, 32);
// Create encryption code.
string sSource = billingInfo.ChartID + billingInfo.PatientLastName + UniqueID;
string s64Trimmed = CrossProduct.Core.Utils.MD5EncryptMsg(sSource, 20);
bool bSuccessfulPost = true;
// Setup Main DB
AdvantageCredential credential = DBCache.GetAdvantageConnection(SystemApiKey);
DB db = DB.Create(credential);
// for auditing * may not work *
AdvantageCredential credentialUser = null;
DB dbUser = null;
// Try to Audit, following Scott's instructions, however, there seems to be no
// guarantee that this works (Advantage can get quickly out of sync it seems)
bool bTryToAudit = !String.IsNullOrEmpty(User);
bTryToAudit = false;
if (bTryToAudit)
{
credentialUser = DBCache.GetAdvantageConnection(SystemApiKey, User);
dbUser = DB.Create(credentialUser);
}
// Deal with Notes first * Load them all up into a Memo Field *
StringBuilder sbBillingNotes = new StringBuilder();
for (int i = 0; i < billingInfo.BillingDetails.Length; ++i)
{
BillingDetail1 detail = billingInfo.BillingDetails[i];
if (!String.IsNullOrEmpty(detail.BillingNote))
{
sbBillingNotes.Append(detail.BillingNote);
sbBillingNotes.Append("\n"); // Could be '\r' - test
}
}
if(sbBillingNotes.Length > 0)
sbBillingNotes.Remove(sbBillingNotes.Length - 1, 1); // remove trailing '\n'
// Deal with the rest of the items, notes are stuffed into the first item only
bool bFirstInsert = true;
int nNotesFound = 0;
for (int i = 0; i < billingInfo.BillingDetails.Length && bSuccessfulPost; ++i)
{
BillingDetail1 detail = billingInfo.BillingDetails[i];
// Skip Billing Notes (already dealt with)
if (!String.IsNullOrEmpty(detail.BillingNote))
{
nNotesFound++;
continue;
}
StringBuilder ValueList = new StringBuilder();
string newID = CrossProduct.Core.Utils.CreateGUID();
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(newID) + "', "); // ID // ID
ValueList.Append("0, "); // Post, tinyint
ValueList.Append("0, "); // Transaction status, int
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(billingInfo.ChartID) + "', "); // varchar15
ValueList.Append("0, "); // Billing, Case int
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(billingInfo.ProviderID) + "', "); // varchar 15
// Make sure valid Date From
if (billingInfo.DateFrom != null && billingInfo.DateFrom != DateTime.MinValue)
ValueList.Append(" CONVERT('" + CrossProduct.Core.Utils.AdvDTStringDateOnly(billingInfo.DateFrom) + "', sql_timestamp), "); // datetime
else
ValueList.Append(" CONVERT('" + CrossProduct.Core.Utils.AdvDTStringDateOnly(DateTime.Now) + "', sql_timestamp), "); // datetime
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(detail.ProcedureCode) + "', "); // varchar 15
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(detail.ProcedureModifier1) + "', "); // varchar 3
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(detail.ProcedureModifier2) + "', "); // varchar 3
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(detail.ProcedureModifier3) + "', "); // varchar 3
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(detail.ProcedureModifier4) + "', "); // varchar 3
ValueList.Append(detail.Units + ", "); // real
ValueList.Append((i + 1 - nNotesFound).ToString() + ", "); // Procedure Order, int
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(billingInfo.PatientLastName) + "', "); // patient last name
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(billingInfo.PatientFirstName) + "', "); // patient first name
// Don't insert an invalid birthday (Medisoft allows nulls)
if (billingInfo.BirthDate != null && billingInfo.BirthDate != DateTime.MinValue)
ValueList.Append(" CONVERT('" + CrossProduct.Core.Utils.AdvDTStringDateOnly(billingInfo.BirthDate) + "', sql_timestamp), "); // datetime
else
ValueList.Append(" NULL, "); // datetime
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(billingInfo.PatientSocialSecurity) + "', ");// varchar 11
ValueList.Append("-1, "); // Exception // int
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(billingInfo.Facility) + "', "); // Facility
ValueList.Append("0, "); // Created By Application. // int
ValueList.Append("0, "); // Amount
ValueList.Append("'" + UniqueID + "', "); // varchar 32
ValueList.Append("'', "); // Error msg. varchar 80
ValueList.Append(" CONVERT('" + CrossProduct.Core.Utils.AdvDTString(DateTime.Now) + "', sql_timestamp), "); // Created Date, datetime
ValueList.Append("NULL, "); // mod date, datetime
ValueList.Append("0,"); // Viewed, tinyint
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(s64Trimmed) + "',"); // Encryption Code.
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(detail.ImmunizationBatchNumber) + "', "); // Immunization Batch Number ?
// On First Insert, add the billing notes to first post
if (bFirstInsert)
{
if (sbBillingNotes.Length > 0)
ValueList.Append("'" + MAKE_SURE_APOSTROPHY_IS_SQL_READY(sbBillingNotes.ToString()) + "', "); // Mobile Notes. Memo.
else
ValueList.Append("'', "); // Mobile Notes. Memo.
bFirstInsert = false;
}
else
ValueList.Append("'', "); // Mobile Notes. Memo.
/// *******
/// Attach each Diagnosis Code (we can do up to 12) for each procedure
/// Always do this last, deals with trailing Comma (,)
/// *******
for (int j = 0; j < 12; ++j)
{
try
{
ValueList.Append("'");
ValueList.Append(MAKE_SURE_APOSTROPHY_IS_SQL_READY(detail.DiagnosisCodes[j])); // Diagnosis 1 - 12, varchar 15
if (j < 11)
ValueList.Append("', ");
else
ValueList.Append("'");
}
catch (IndexOutOfRangeException)
{
if (j < 11)
ValueList.Append("', ");
else
ValueList.Append("'");
}
catch(NullReferenceException)
{
if (j < 11)
ValueList.Append("', ");
else
ValueList.Append("'");
}
}
// Build our sql statement.
StringBuilder sb = new StringBuilder("INSERT INTO [MWUTC] ");
sb.Append(" ([ID], [Post], [Transaction_Status], [Chart_Number], [Case_Number], [Provider], [Date_From], [Procedure_Code], [Modifier_1], [Modifier_2], [Modifier_3], [Modifier_4], [Units], [Procedure_Order], [Patient_Last_Name], [Patient_First_Name], [Birth_Date], [SSN], [Exception], [Facility], [Creating_App], [Amount], [HL7MessageID], [ErrorMsg], [Date_Created], [Date_Modified], [Viewed], [Checksum], [Immunization Batch Number], [Mobile Notes], [Diagnosis_Code_1], [Diagnosis_Code_2], [Diagnosis_Code_3], [Diagnosis_Code_4], [Diagnosis_Code_5], [Diagnosis_Code_6], [Diagnosis_Code_7], [Diagnosis_Code_8], [Diagnosis_Code_9], [Diagnosis_Code_10], [Diagnosis_Code_11], [Diagnosis_Code_12])");
sb.Append(" VALUES (" + ValueList.ToString() + ")");
string StrSQL = sb.ToString();
DBRetVal result = null;
if (bTryToAudit)
{
// Post the Billing (via user way)
result = dbUser.ExecuteNonQuery(StrSQL);
bSuccessfulPost = result.IsValid;
if (bSuccessfulPost)
{
// posted succesful for user moving on
continue;
}
else
{
MSLSpecific.Logger.Info("submitting superbill via the user {0} didn't work, will submitt the superbill without the user credential (msg:{1})", User, result.ErrorMsg);
bTryToAudit = false;
}
}
// Post the Billing (the regular way)
result = db.ExecuteNonQuery(StrSQL);
bSuccessfulPost = result.IsValid;
}
return bSuccessfulPost;
}
#endregion
}
}