using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; using Sarand.Core.App; using Sarand.Core.Base; using Sarand.Core.Bus; using Sarand.Core.Dbas.Base; using Sarand.Win.Dbas.Base; using Sarand.PatientMgr.Core.App; using Sarand.PatientMgr.Core.Bus; using Sarand.PatientMgr.Core.Mgr; using Sarand.PatientMgr.Win.Dbas.Bus; using Sarand.PatientMgr.Win.Dbas.Internal; //using Sarand.PatientMgr.Win.Dbas.UpdateLog; using Sarand.Win.Dbas.Data; namespace Sarand.PatientMgr.Win.Dbas.Mgr { //======================================================================= internal partial class SpmInstitutionMgr_Dbas : SpmInstitutionMgr { //******************************************************************* // P a t i e n t //******************************************************************* // Utilities. //------------------------------------------------------------------- // Create Patient. public override SpmPatient CreatePatient(SysId id, SysId institutionId) { return new SpmPatient_Dbas(UserContext, id, institutionId, 0); } private SpmPatient_Dbas CreatePatient(SwmPatient_Db dbPatient) { ClearErrorState(); SpmPatient_Dbas admissionAction = new SpmPatient_Dbas(UserContext, new SysId(dbPatient._Id), new SysId(dbPatient._InstitutionId), (ushort)dbPatient._Flags); PopulateFrom(dbPatient, admissionAction); return admissionAction; } //------------------------------------------------------------------- // Get Patient. public override SpmPatient GetPatient(SpmPatient.Params prm) { return GetPatient(GetPatientQueryFilter(prm).Concat(" AND ", "(", ")")); } private SpmPatient GetPatient(String filter) { ClearErrorState(); long count = GetPatientCount(filter); if (count == 0) return null; if (count != 1) { SetErrorState("Multiple Patientes found"); return null; } SpmPatient admissionAction = null; // Query data. using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { dbConnection.Open(); SwmPatient_Db dbPatient = new SwmPatient_Db(DbInfo); dbPatient.PopulateFrom(dbCommand, aliasPatient, filter); admissionAction = CreatePatient(dbPatient); } catch (Exception exc) { SetErrorState("Database query exception"); Logger.Warn(GetType().Name + ".GetPatient\n\tQuery: " + dbCommand.CommandText + "\n\tException: " + exc.Message); } } return admissionAction; } //------------------------------------------------------------------- // Validate Patient. public override bool IsValidPatientData(SpmPatient.Data data, SpmPatient.ErrField errField) { ClearErrorState(); if (!base.IsValidPatientData(data, errField)) return false; return true; } //------------------------------------------------------------------- // Insert Patient. public override bool InsertPatient(SpmPatient admissionAction, DbUpdateInfo dbUpdateInfo) { ClearErrorState(); if (!IsValidPatient(admissionAction)) return false; if (SysId.IsValid(admissionAction.Id)) return SetErrorState(ErrorMessage.ValiditemId); using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { dbConnection.Open(); SwmPatient_Db dbPatient = new SwmPatient_Db(DbInfo); PopulateTo(dbPatient, admissionAction, dbUpdateInfo); if (SwmPatient_Db.FieldsNonId.Contains("Id")) { // Generate next Id. dbPatient._Id = SysId.ToInt(Database.GetNextId("Patient", dbUpdateInfo)); } dbPatient.ExecuteInsertCommand(dbCommand); admissionAction.Id = new SysId(dbPatient._Id); } catch (Exception exc) { SetErrorState(exc.Message); } } return !HasErrorState(); } //------------------------------------------------------------------- // Update Patient. public override bool UpdatePatient(SpmPatient admissionAction, DbUpdateInfo dbUpdateInfo) { ClearErrorState(); if (!IsValidPatient(admissionAction)) return false; if (!SysId.IsValid(admissionAction.Id)) return SetErrorState(ErrorMessage.InvalidItemId); using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { // Retrieve Patient. dbConnection.Open(); SwmPatient_Db dbPatient = new SwmPatient_Db(DbInfo); dbPatient.PopulateFrom(dbCommand, aliasPatient, "Id=" + SysId.ToString(admissionAction.Id)); //SpmUpdateLogItemMonitor_Patient updateLogMonitor = new SpmUpdateLogItemMonitor_Patient(UserContext, CreatePatient(dbPatient)); // Update properties. PopulateTo(dbPatient, admissionAction, dbUpdateInfo); dbPatient.ExecuteUpdateCommand(dbCommand); /* Record updates. updateLogMonitor.RecordUpdatedValues(admissionAction); updateLogMonitor.LogUpdates();*/ } catch (Exception exc) { SetErrorState(exc.Message); } } return !HasErrorState(); } //------------------------------------------------------------------- // Delete Patient. public override bool PatientCanBeDeleted(SpmPatient admissionAction) { ClearErrorState(); if (!base.PatientCanBeDeleted(admissionAction)) return false; return true; } public override bool DeletePatient(SpmPatient admissionAction, DbUpdateInfo dbUpdateInfo) { ClearErrorState(); if (!PatientCanBeDeleted(admissionAction)) return false; using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { // Retrieve Patient. dbConnection.Open(); SwmPatient_Db dbPatient = new SwmPatient_Db(DbInfo); dbPatient.PopulateFrom(dbCommand, aliasPatient, "Id=" + admissionAction.Id.ToString()); // Delete Patient. dbCommand.CommandType = System.Data.CommandType.Text; dbCommand.CommandText = "DELETE FROM " + SpmDbDfn.GetTableName(SpmDbDfn.TableIdx.SwmPatient) + " WHERE Id=" + SysId.ToString(admissionAction.Id) + ";"; dbCommand.ExecuteNonQuery(); } catch (Exception exc) { SetErrorState(exc.Message); } } return !HasErrorState(); } //------------------------------------------------------------------- // Copy data properties to and from database. private void PopulateTo(SwmPatient_Db dbPatient, SpmPatient patient, DbUpdateInfo dbUpdateInfo) { dbPatient._Id = patient.Id.ToInt(); dbPatient._PatientNo = patient.PatientNo; dbPatient._NhsNumber = patient.NhsNumber; dbPatient._Title = patient.Title; dbPatient._Forename = patient.Forename; dbPatient._Surname = patient.Surname; dbPatient._Gender = (short)patient.Gender; dbPatient._Age = patient.Age; dbPatient._AgeOn = patient.AgeOn; dbPatient._BirthOn = patient.BirthOn.DateToInt32(); dbPatient._Notes = patient.Notes; dbPatient._Status = SacsSystem.GetStatusCode(patient.Status); dbPatient._Flags = (short)patient.Flags; if (!SysId.IsValid(patient.Id)) { dbPatient._CreateOn = DateTime.UtcNow; dbPatient._CreateBy = dbUpdateInfo.UserId.ToInt(); dbPatient._CreateHost = dbUpdateInfo.Host; } dbPatient._UpdateOn = DateTime.UtcNow; dbPatient._UpdateBy = dbUpdateInfo.UserId.ToInt(); dbPatient._UpdateHost = dbUpdateInfo.Host; } private void PopulateFrom(SwmPatient_Db dbPatient, SpmPatient patient) { patient.Id = new SysId(dbPatient._Id); patient.PatientNo = dbPatient._PatientNo; patient.NhsNumber = dbPatient._NhsNumber; patient.Title = dbPatient._Title; patient.Forename = dbPatient._Forename; patient.Surname = dbPatient._Surname; patient.Gender = (Spm.Gender)dbPatient._Gender; patient.Age = dbPatient._Age; patient.AgeOn = dbPatient._AgeOn; patient.BirthOn = new DateTime(dbPatient._BirthOn); patient.Notes = dbPatient._Notes; patient.Status = SacsSystem.GetStatusForCode(dbPatient._Status); patient.SetCreateStamp(dbPatient._CreateOn, new SysId(dbPatient._CreateBy), dbPatient._CreateHost); patient.SetUpdateStamp(dbPatient._UpdateOn, new SysId(dbPatient._UpdateBy), dbPatient._UpdateHost); patient.AcceptChanges(); } //------------------------------------------------------------------- // Patient column definitions. private static readonly String aliasPatient = "aAdmAct"; private void SetPatientColDfn (ColumnDfn col, String caption, int width, SpmDbDfn.ColumnIdx dbCol, ColumnAlignment align = ColumnAlignment.Default, DataValue.DataType dataType = DataValue.DataType.String, String alias = "", String prefix = "") { if (String.IsNullOrEmpty(alias) && SpmDbDfn.GetTableForColumn(dbCol) == SpmDbDfn.TableIdx.SwmPatient) alias = aliasPatient; col.Set(caption, width, (int)dbCol, prefix + SpmDbDfn.GetColumnName(dbCol, false), SpmDbDfn.GetColumnNameQual(dbCol, alias), dataType, align); if (dataType == DataValue.DataType.String && dbCol != SpmDbDfn.ColumnIdx.Unknown) col.MaxLength = (int)SpmDbDfn.GetColTextLen(dbCol); } //------------------------------------------------------------------- // Getting prmPatient column definition. public override ColumnDfn GetPatientColumnDfn(SpmPatient.Column columnId, string caption = "", int width = 0) { ColumnDfn columnDfn = new ColumnDfn((int)columnId, caption, width); switch (columnId) { case SpmPatient.Column.Pos: SetPatientColDfn(columnDfn, "Pos", 42, SpmDbDfn.ColumnIdx.Unknown, ColumnAlignment.Right); columnDfn.SortMode = ColumnDfn.ColumnSortMode.Off; columnDfn.ReadOnly = true; columnDfn.Resizable = false; break; case SpmPatient.Column.Id: SetPatientColDfn(columnDfn, "Id", 40, SpmDbDfn.ColumnIdx.SwmPatient_Id, ColumnAlignment.Right, DataValue.DataType.Long); columnDfn.ReadOnly = true; break; // Patient Properties. case SpmPatient.Column.InstitutionId: SetPatientColDfn(columnDfn, "InstitutionId", 40, SpmDbDfn.ColumnIdx.SwmPatient_InstitutionId, ColumnAlignment.Right, DataValue.DataType.Long); columnDfn.ReadOnly = true; break; case SpmPatient.Column.Title: SetPatientColDfn(columnDfn, "Title", 90, SpmDbDfn.ColumnIdx.SwmPatient_Title); break; case SpmPatient.Column.Surname: SetPatientColDfn(columnDfn, "Surname", 90, SpmDbDfn.ColumnIdx.SwmPatient_Surname); break; case SpmPatient.Column.Forename: SetPatientColDfn(columnDfn, "Forename", 90, SpmDbDfn.ColumnIdx.SwmPatient_Forename); break; case SpmPatient.Column.BirthOn: SetPatientColDfn(columnDfn, "DOB", 75, SpmDbDfn.ColumnIdx.SwmPatient_BirthOn, ColumnAlignment.Center, DataValue.DataType.Date); columnDfn.DateFormat = "dd-MMM-yyyy"; break; case SpmPatient.Column.Age: SetPatientColDfn(columnDfn, "Age", 40, SpmDbDfn.ColumnIdx.SwmPatient_Age, ColumnAlignment.Center); break; case SpmPatient.Column.AgeOn: SetPatientColDfn(columnDfn, "AgeOn", 75, SpmDbDfn.ColumnIdx.SwmPatient_AgeOn, ColumnAlignment.Center, DataValue.DataType.Date); columnDfn.DateFormat = "d-MMM-yy"; break; // Common properties. case SpmPatient.Column.Notes: SetPatientColDfn(columnDfn, "Notes", 200, SpmDbDfn.ColumnIdx.SwmPatient_Notes); break; case SpmPatient.Column.Status: SetPatientColDfn(columnDfn, "Status", 50, SpmDbDfn.ColumnIdx.SwmPatient_Status, ColumnAlignment.Center); break; case SpmPatient.Column.Status_Desc: SetPatientColDfn(columnDfn, "Status", 50, SpmDbDfn.ColumnIdx.SwmPatient_Status, ColumnAlignment.Center); break; case SpmPatient.Column.Status_Ind: SetPatientColDfn(columnDfn, "Status", 50, SpmDbDfn.ColumnIdx.SwmPatient_Status, ColumnAlignment.Center, DataValue.DataType.TriState); columnDfn.TriStateFormat = ColumnTriStateFormat.Lights; break; case SpmPatient.Column.CreateOn_Date: SetPatientColDfn(columnDfn, "Created", 65, SpmDbDfn.ColumnIdx.SwmPatient_CreateOn, ColumnAlignment.Center, DataValue.DataType.Date); columnDfn.ReadOnly = true; break; case SpmPatient.Column.UpdateOn_Date: SetPatientColDfn(columnDfn, "Updated", 65, SpmDbDfn.ColumnIdx.SwmPatient_UpdateOn, ColumnAlignment.Center, DataValue.DataType.Date); columnDfn.ReadOnly = true; break; } if (!String.IsNullOrEmpty(caption)) columnDfn.Caption = caption; if (width > 0) columnDfn.Width = width; return columnDfn; } //------------------------------------------------------------------- // Patient query filter. public override List GetPatientQueryFilter(SpmPatient.Params prm) { List filters = new List(); // Patient Id. String includedIds = prm.IncludedIds.Concat(","); if (!includedIds.IsEmpty()) filters.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Id, aliasPatient) + " IN (" + includedIds + ")"); String excludedIds = prm.ExcludedIds.Concat(","); if (!excludedIds.IsEmpty()) filters.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Id, aliasPatient) + " NOT IN (" + excludedIds + ")"); // Institution Id. String colInstitutionId = SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_InstitutionId, aliasPatient); if (SysId.IsValid(prm.InstitutionId)) filters.Add(colInstitutionId + "=" + prm.InstitutionId.ToString()); // Partial No. String patientNo = DbQuery.FormatForCondition(prm.PatientNo); String colPatientNo = SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_PatientNo, aliasPatient); if (!StringUtil.IsEmpty(patientNo)) filters.Add(DbQuery.FormatFn_Left(colPatientNo, prm.PatientNo.Length) + "='" + patientNo + "'"); // Partial Surname. String surname = DbQuery.FormatForCondition(prm.Surname); String colSurname = SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Surname, aliasPatient); if (!StringUtil.IsEmpty(surname)) filters.Add(DbQuery.FormatFn_Left(colSurname, prm.Surname.Length) + "='" + surname + "'"); if (filters.Count < 1) filters.Add("1=1"); return filters; } //------------------------------------------------------------------- // Patient sort columns. public List GetPatientSortColumns(SpmPatient.Params prm) { // Sort sequence. List sortColumnNames = new List(); foreach (var columnDfn in prm.SortColumns) { // Need to ensure correct alias used for Patient columns in case of conflict. String sortCol = String.Empty; if (SpmDbDfn.GetTableForColumn((SpmDbDfn.ColumnIdx)columnDfn.DbColumn) == SpmDbDfn.TableIdx.SwmPatient) { sortCol = SpmDbDfn.GetColumnNameQual((SpmDbDfn.ColumnIdx)columnDfn.DbColumn, aliasPatient); } else { sortCol = columnDfn.DataName; if (!StringUtil.IsEmpty(columnDfn.SortDataName)) sortCol = columnDfn.SortDataName; } if (!sortCol.IsEmpty()) { DbOrderByNullMode orderByNullMode = DbOrderByNullMode.Default; // eSaOrderByDemoteNulls, eSaOrderByPromoteNulls sortColumnNames.Add(DbQuery.FormatForOrderBy(sortCol, columnDfn.SortAscending, orderByNullMode).Concat(", ")); } } sortColumnNames.RemoveBlanks(); if (sortColumnNames.IsEmpty()) { // Default sort columns: //sortColumnNames.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Type, aliasPatient) + " ASC"); } return sortColumnNames; } //------------------------------------------------------------------- // Patient count. private long GetPatientCount(String filter) { ClearErrorState(); return Database.GetRowCount(SpmDbDfn.GetTableName(SpmDbDfn.TableIdx.SwmPatient) + " As " + aliasPatient, filter); } public override long GetPatientCount(SpmPatient.Params prm) { ClearErrorState(); return GetPatientCount(GetPatientQueryFilter(prm).Concat(" AND ", "(", ")")); } //------------------------------------------------------------------- // Patient list. public override List GetPatientList(SpmPatient.Params prm) { List Patientes = new List(); DbQuery qry = new DbQuery(Database.DbmsType); qry.Tables.Add(SpmDbDfn.GetTableName(SpmDbDfn.TableIdx.SwmPatient), aliasPatient); qry.Columns.AddRange(SwmPatient_Db.Fields); qry.Filters.AddRange(GetPatientQueryFilter(prm)); // Query data. using (var dbConnection = Database.CreateConnection()) using (var dbCommand = dbConnection.CreateCommand()) { try { dbConnection.Open(); dbCommand.CommandText = qry.BuildQuery(); using (DbDataReader dbDataReader = dbCommand.ExecuteReader()) { while (dbDataReader.Read()) { SwmPatient_Db dbPatient = new SwmPatient_Db(DbInfo); dbPatient.PopulateFrom(dbDataReader); Patientes.Add(CreatePatient(dbPatient)); } } } catch (Exception exc) { Logger.Warn(GetType().Name + ".GetPatientList\n\tQuery: " + dbCommand.CommandText + "\n\tException: " + exc.Message); } } return Patientes; } //------------------------------------------------------------------- // Patient query execution. public override DbResultSet ExecutePatientQuery(List columns, SpmPatient.Params prm) { ClearErrorState(); //--------------------------------------------------------------- // Construct query. DbQuery query = new DbQuery(Database.DbmsType); query.Tables.Add(SpmDbDfn.GetTableName(SpmDbDfn.TableIdx.SwmPatient), aliasPatient); // Patient Properties - add columns as defined in query list. if (columns.HasId((int)SpmPatient.Column.Id)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Id, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.InstitutionId)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_InstitutionId, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.PatientNo)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_PatientNo, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.NhsNumber)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_NhsNumber, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.Title)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Title, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.Forename)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Forename, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.Surname)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Surname, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.BirthOn)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_BirthOn, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.Age)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Age, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.AgeOn)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_AgeOn, aliasPatient)); // Common Properties if (columns.HasId((int)SpmPatient.Column.Notes)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Notes, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.Status) || columns.HasId((int)SpmPatient.Column.Status_Desc) || columns.HasId((int)SpmPatient.Column.Status_Ind)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_Status, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.CreateOn_Date)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_CreateOn, aliasPatient)); if (columns.HasId((int)SpmPatient.Column.UpdateOn_Date)) query.Columns.Add(SpmDbDfn.GetColumnNameQual(SpmDbDfn.ColumnIdx.SwmPatient_UpdateOn, aliasPatient)); //--------------------------------------------------------------- // Populate filter. query.Filters.AddRange(GetPatientQueryFilter(prm)); if (prm.IncludedIds.Count != 1) { // Configure sort sequence. foreach (String sortColumn in GetPatientSortColumns(prm)) query.OrderBy.Add(sortColumn); } //--------------------------------------------------------------- //return new DbResultSet_DataTableReader(Database, query.BuildQuery()); return new Sarand.Win.Dbas.Data.DbResultSet_DataReader(Database, query.BuildQuery()); } //------------------------------------------------------------------- } //======================================================================= }