Files
PatientMgr-CSharp/SaPatMgrCore/Core/Mgr/SpmItemMgr.cs
T

198 lines
8.0 KiB
C#

using Sarand.PatientMgr.Core.App;
using Sarand.Core.Bus;
using Sarand.Core.CodeTypes;
using System;
using System.Collections.Generic;
using System.Text;
using Sarand.Core.Base;
using System.Linq;
using Sarand.Core.App;
namespace Sarand.PatientMgr.Core.Mgr
{
//=======================================================================
public abstract class SpmItemMgr : SacsItemMgr
{
//-------------------------------------------------------------------
// System code cache.
/// <summary>Central repository for system codes used by manager.</summary>
private class SystemCodeCache
{
public SystemCodeCache (SpmUserContext userContext)
{
this.userContext = userContext;
}
private readonly SpmUserContext userContext;
private Dictionary<Spm.SystemCode, List<TypeCodeDesc>> systemCodes = new Dictionary<Spm.SystemCode, List<TypeCodeDesc>>();
public List<TypeCodeDesc> GetCodesOfType (Spm.SystemCode systemCode)
{
if (!systemCodes.ContainsKey(systemCode))
systemCodes[systemCode] = SpmSystem.GetCodesOfType(systemCode);
return new List<TypeCodeDesc>(systemCodes.GetValue(systemCode, new List<TypeCodeDesc>()));
}
}
//-------------------------------------------------------------------
// Code type cache.
public class CodeTypeCache
{
/// <summary>
/// Cached codes by code type.
/// <para>NB Likely to only contain a subset of code types depending on context.</para>
/// </summary>
private Dictionary<String, List<SaCode>> codesByCodeType { get; }
// Construction.
public CodeTypeCache (Dictionary<String, List<SaCode>> codes)
{
codesByCodeType = codes;
}
/// <summary>Are there any codes of the specified type.</summary>
public bool CodeTypeHasCodes (Spm.CodeType codeType)
{
String codeTypeCode = SpmSystem.GetCodeTypeCode(codeType);
return codesByCodeType.ContainsKey(codeTypeCode)
? codesByCodeType[codeTypeCode].Count > 0
: false;
}
/// <summary>Get the description for the code belonging to the specified code type.</summary>
public String GetDescForCodeTypeCode (Spm.CodeType codeType, String code, bool defaultToCode = true)
{
List<SaCode> codes = GetCodesForCodeType(codeType, false);
return codes?.GetDescForCode(code, defaultToCode ? code : "") ?? "";
}
/// <summary>Retrieve codes for specified code type.</summary>
public List<SaCode> GetCodesForCodeType (Spm.CodeType codeType, bool activeOnly = true)
{
String codeTypeCode = SpmSystem.GetCodeTypeCode(codeType);
return codesByCodeType.ContainsKey(codeTypeCode)
? new List<SaCode>(codesByCodeType[codeTypeCode].FindAll(code => !activeOnly || code.Status == SaCode.ActiveStatus))
: null;
}
/// <summary>Retrieve code descs for specified code type.</summary>
public List<CodeDesc> GetCodeDescsForCodeType (Spm.CodeType codeType, bool activeOnly = true)
{
String codeTypeCode = SpmSystem.GetCodeTypeCode(codeType);
return codesByCodeType.ContainsKey(codeTypeCode)
? new List<CodeDesc>(codesByCodeType[codeTypeCode].FindAll(code => !activeOnly || code.Status == SaCode.ActiveStatus).Select(code => new CodeDesc(code.Code, code.Description)))
: null;
}
}
//-------------------------------------------------------------------
// Data members.
private SpmInternals internals;
private readonly SystemCodeCache systemCodeCache;
//-------------------------------------------------------------------
// Static initialisation.
static SpmItemMgr ()
{
}
//-------------------------------------------------------------------
// Construction.
protected SpmItemMgr (SpmUserContext userContext)
{
if (userContext == null)
throw new NotSupportedException("SpmItemMgr User context must be supplied");
UserContext = userContext;
systemCodeCache = new SystemCodeCache(userContext);
}
protected override void Dispose (bool disposing)
{
if (disposing)
{
if (internals != null) internals.Dispose();
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
protected bool DebugMode { get; } = SacsSystem.DebugMode;
public SpmUserContext UserContext { get; }
public SpmInternals Internals { get { if (internals == null) internals = new SpmInternals(UserContext); return internals; } }
public SpmSessionContext SessionContext { get { return UserContext.SessionContext; } }
// Consoles.
public SaCodeTypeConsole CodeTypeConsole { get { return internals.CodeTypeConsole; } }
// Managers.
public SpmAdmissionMgr AdmissionMgr { get { return internals.AdmissionMgr; } }
//-------------------------------------------------------------------
// Utilities.
public List<TypeCodeDesc> GetCodesOfType (Spm.SystemCode systemCode)
{
return systemCodeCache.GetCodesOfType(systemCode);
}
// Database utilities.
public bool TableExists (SpmDbDfn.TableIdx tableIdx)
{
SpmApplication application = SpmGlobals.Application;
if (application != null)
return application.TableExists(SessionContext, tableIdx);
return false;
}
public bool ColumnExists (SpmDbDfn.ColumnIdx columnIdx)
{
SpmApplication application = SpmGlobals.Application;
if (application != null)
return application.ColumnExists(SessionContext, columnIdx);
return false;
}
//-------------------------------------------------------------------
// C o d e T y p e s
//-------------------------------------------------------------------
public virtual List<Spm.CodeType> SupportedCodeTypes { get; } = new List<Spm.CodeType>();
private CodeTypeCache codeTypeCache;
public bool CodeTypeHasCodes (Spm.CodeType codeType)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException(GetType().Name + ".CodeTypeHasCodes Unsupported code type: " + codeType);
PopulateCodeTypes();
return codeTypeCache.CodeTypeHasCodes(codeType);
}
public String GetCodeTypeCodeDesc (Spm.CodeType codeType, String code, bool defaultToCode = true)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException(GetType().Name + ".GetCodeTypeCodeDesc Unsupported code type: " + codeType);
PopulateCodeTypes();
List<SaCode> codes = codeTypeCache.GetCodesForCodeType(codeType, false);
if (codes != null)
return codes.GetDescForCode(code, defaultToCode ? code : "");
return "";
}
public List<SaCode> GetCodesForCodeType (Spm.CodeType codeType, bool activeOnly = true)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException(GetType().Name + ".GetCodesForCodeType Unsupported code type: " + codeType);
PopulateCodeTypes();
return codeTypeCache.GetCodesForCodeType(codeType, activeOnly);
}
public List<CodeDesc> GetCodeDescsForCodeType (Spm.CodeType codeType, bool activeOnly = true)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException(GetType().Name + ".GetCodeDescsForCodeType Unsupported code type: " + codeType);
PopulateCodeTypes();
return codeTypeCache.GetCodeDescsForCodeType(codeType, activeOnly);
}
private void PopulateCodeTypes ()
{
if (codeTypeCache != null) return;
// Populate cache with codes for all supported code types.
// Intended to minimise db I/O to retrieve all required codes.
SaCode.Params prmCode = new SaCode.Params();
foreach (Spm.CodeType codeType in SupportedCodeTypes)
prmCode.CodeTypeCodes.Add(SpmSystem.GetCodeTypeCode(codeType));
prmCode.StatusCat = SaCode.StatusCat.Any;
Dictionary<String, List<SaCode>> codesByCodeType = CodeTypeConsole.GetCodesByCodeType(prmCode);
// Populate any supported code types without codes.
foreach (Spm.CodeType codeType in SupportedCodeTypes)
{
String codeTypeCode = SpmSystem.GetCodeTypeCode(codeType);
if (!codesByCodeType.ContainsKey(codeTypeCode))
codesByCodeType[codeTypeCode] = new List<SaCode>();
}
codeTypeCache = new CodeTypeCache(codesByCodeType);
}
//-------------------------------------------------------------------
}
//=======================================================================
}