Files
BusinessMgr-2019/SaBusMgrStandardBase/Base/Mgr/SbmCoreMgr.cs
T

423 lines
18 KiB
C#

using Sarand.BusinessMgr.Net.Standard.Base.App;
using Sarand.BusinessMgr.Net.Standard.Base.Bus;
using Sarand.BusinessMgr.Net.Standard.Base.Consoles;
using Sarand.BusinessMgr.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.CodeTypes;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Interfaces;
using Sarand.Net.Standard.Base.ItemDocs;
using Sarand.Net.Standard.Base.ItemOptions;
using Sarand.Net.Standard.Base.ReferenceData;
using Sarand.Net.Standard.Base.Security;
using Sarand.Net.Standard.Base.UpdateLog;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sarand.BusinessMgr.Net.Standard.Base.Mgr
{
//=======================================================================
public abstract class SbmCoreMgr : SbmItemMgr
{
//-------------------------------------------------------------------
// 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(Sbm.ApplCodeType codeType)
{
String codeTypeCode = SbmSystem.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(Sbm.ApplCodeType 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(Sbm.ApplCodeType codeType, bool activeOnly = true)
{
String codeTypeCode = SbmSystem.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(Sbm.ApplCodeType codeType, bool activeOnly = true)
{
String codeTypeCode = SbmSystem.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 class Members
{
// Externally supplied Internals - disposed elsewhere.
public SbmInternals internalsSupplied;
// Internally constructed Internals - disposed here.
public SbmInternals internals;
// Numeric control values.
public bool numericControlValuesInitialised = false;
public int weightDecimals;
public int lengthDecimals;
public int volumeDecimals;
public int densityDecimals;
public int boxQuantityDecimals;
public int orderQuantityDecimals;
// Reference data.
public List<TypeCodeDesc> currencyCodes;
public List<SaCurrency> currencies;
public List<SaLanguage> languages;
public List<SaRegion> regions;
public List<SaTaxCode> taxCodes;
public List<SaUnitMeasure> unitsOfMeasure;
}
private readonly Members mbr = new Members();
//-------------------------------------------------------------------
// Static initialisation.
static SbmCoreMgr()
{
}
//-------------------------------------------------------------------
// Construction.
protected SbmCoreMgr(SbmInternals internals)
{
if (internals == null)
throw new NotSupportedException("SbmItemMgr Internals must be supplied");
mbr.internalsSupplied = internals;
UserContext = internals.UserContext;
Initialise();
}
protected SbmCoreMgr(ISbmUserOrganisationContext userContext)
{
if (userContext == null)
throw new NotSupportedException("SbmItemMgr User context must be supplied");
mbr.internalsSupplied = null;
this.UserContext = userContext;
Initialise();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (mbr.internals != null) mbr.internals.Dispose();
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Initialisation.
private void Initialise()
{
}
private void InitialiseNumericControlValues()
{
if (mbr.numericControlValuesInitialised) return;
mbr.numericControlValuesInitialised = true;
// Numeric formatting values.
mbr.weightDecimals = Internals.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityWeight);
mbr.lengthDecimals = Internals.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityLength);
mbr.volumeDecimals = Internals.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityVolume);
mbr.densityDecimals = Internals.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityDensity);
mbr.boxQuantityDecimals = 0;
mbr.orderQuantityDecimals = Internals.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.OrderQuantity);
}
//-------------------------------------------------------------------
// Async initialisation.
public async void InitialiseCodeTypesAsync()
{
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 (Sbm.ApplCodeType codeType in SupportedCodeTypes)
prmCode.CodeTypeCodes.Add(SbmSystem.GetCodeTypeCode(codeType));
prmCode.StatusCat = SaCode.StatusCat.Any;
codeTypeCache = new CodeTypeCache(await CodeTypeConsole.GetCodesByCodeTypeAsync(prmCode));
}
//-------------------------------------------------------------------
// Properties.
// System codes.
protected List<TypeCodeDesc> ItemTypes { get { return GetCodesOfType(Sbm.SystemCode.ItemType); } }
protected List<TypeCodeDesc> InterfaceOptionCodes { get { return GetCodesOfType(Sbm.SystemCode.InterfaceOption); } }
// Numeric control values.
protected int WeightDecimals { get { InitialiseNumericControlValues(); return mbr.weightDecimals; } }
protected int LengthDecimals { get { InitialiseNumericControlValues(); return mbr.lengthDecimals; } }
protected int VolumeDecimals { get { InitialiseNumericControlValues(); return mbr.volumeDecimals; } }
protected int DensityDecimals { get { InitialiseNumericControlValues(); return mbr.densityDecimals; } }
protected int BoxQuantityDecimals { get { InitialiseNumericControlValues(); return mbr.boxQuantityDecimals; } }
protected int OrderQuantityDecimals { get { InitialiseNumericControlValues(); return mbr.orderQuantityDecimals; } }
// Internals.
protected SbmInternals Internals
{
get
{
if (mbr.internalsSupplied != null) return mbr.internalsSupplied;
if (mbr.internals == null) mbr.internals = new SbmInternals(UserContext);
return mbr.internals;
}
}
// Session.
protected ISbmUserOrganisationContext UserContext { get; }
protected SbmSessionContext SessionContext { get { return UserContext.SessionContext; } }
public SysId AffiliateId_Owner { get { return UserContext.OrganisationAffiliateId; } }
protected SbmAccountsDfn AccountsDfn { get { return Internals.AccountsDfn; } }
protected DbUpdateInfo DbUpdateInfo { get { return Internals.DbUpdateInfo; } }
// User security profile.
public bool UserCanViewCommoditySalesFinancials() { return UserContext.SecurityProfile_Core.UserCanViewFinancials(Sbm.FinancialType.CommoditySales); }
public bool UserCanViewCommoditySupplyFinancials() { return UserContext.SecurityProfile_Core.UserCanViewFinancials(Sbm.FinancialType.CommoditySupply); }
// Managers.
protected SbmAccountMgr AccountMgr { get { return Internals.AccountMgr; } }
protected SbmCommodityMgr CommodityMgr { get { return Internals.CommodityMgr; } }
protected SbmPriceMgr PriceMgr { get { return Internals.PriceMgr; } }
protected SbmTransactionMgr TransactionMgr { get { return Internals.TransactionMgr; } }
protected SbmStockMgr StockMgr { get { return Internals.StockMgr; } }
protected SbmProcessMgr ProcessMgr { get { return Internals.ProcessMgr; } }
protected SbmDataItemMgr DataItemMgr { get { return Internals.DataItemMgr; } }
// Consoles.
protected SbmSessionConsole SessionConsole { get { return Internals.SessionConsole; } }
protected SaSecurityConsole SecurityConsole { get { return Internals.SecurityConsole; } }
protected SaCodeTypeConsole CodeTypeConsole { get { return Internals.CodeTypeConsole; } }
protected SaReferenceDataConsole ReferenceDataConsole { get { return Internals.ReferenceDataConsole; } }
protected SaUpdateLogConsole UpdateLogConsole { get { return Internals.UpdateLogConsole; } }
protected SaItemOptionConsole ItemOptionConsole { get { return Internals.ItemOptionConsole; } }
protected SaInterfaceConsole InterfaceConsole { get { return Internals.InterfaceConsole; } }
protected SaItemDocConsole ItemDocConsole { get { return Internals.ItemDocConsole; } }
// Configurations.
protected SbmStockControlConfig StockControlConfig { get { return Internals.StockControlConfig; } }
protected SbmRequirementCostingConfig RequirementCostingConfig { get { return Internals.RequirementCostingConfig; } }
// Currencies.
protected List<TypeCodeDesc> CurrencyCodes
{
get
{
if (mbr.currencyCodes == null)
mbr.currencyCodes = SaReferenceDataConsole.GetReferenceDataCodes(ReferenceDataSystemCode.CurrencyCode);
return new List<TypeCodeDesc>(mbr.currencyCodes);
}
}
protected List<SaCurrency> GetCurrencies()
{
return Internals.GetCurrencies();
}
protected SaCurrency GetCurrencyById(SysId currencyId)
{
return Internals.GetCurrencyById(currencyId);
}
protected SaCurrency GetCurrencyByCode(String currencyCode)
{
return Internals.GetCurrencyByCode(currencyCode);
}
protected static byte CurrencyDecimalsDefault { get { return SbmInternals.CurrencyDecimalsDefault; } }
protected byte GetCurrencyDecimalsForCurrencyById(SysId currencyId)
{
return Internals.GetCurrencyDecimalsForCurrencyById(currencyId);
}
//-------------------------------------------------------------------
// Utilities.
public List<TypeCodeDesc> GetCodesOfType(Sbm.SystemCode systemCode)
{
return Internals.GetSystemCodes(systemCode);
}
// Database utilities.
public bool TableExists(SbmDbDfn.TableIdx tableIdx)
{
SbmApplication application = SbmGlobals.Application;
if (application != null)
{
ISacsDatabase busMgrDb = application.GetBusMgrDatabase(SessionContext);
return application.DbTableExists(busMgrDb, tableIdx);
}
return false;
}
public virtual bool ColumnExists(SbmDbDfn.ColumnIdx columnIdx)
{
SbmApplication application = SbmGlobals.Application;
if (application != null)
{
ISacsDatabase busMgrDb = application.GetBusMgrDatabase(SessionContext);
return application.DbColumnExists(busMgrDb, columnIdx);
}
return false;
}
//-------------------------------------------------------------------
// Session console utilities.
public bool AllowConfigOption(Sbm.ConfigOption configOption)
{
return SessionConsole.AllowOption(configOption);
}
public bool AllowAffiliateType(Sbm.AffiliateType affiliateType)
{
return SessionConsole.AllowAffiliateType(affiliateType);
}
public bool AllowAssociationType(Sbm.AssociationType associationType)
{
return SessionConsole.AllowAssociationType(associationType);
}
public bool AllowTransactionType(Sbm.TransactionType transactionType)
{
return SessionConsole.AllowTransactionType(transactionType);
}
public String GetAttributeCaption(SbmDbDfn.ColumnIdx columnIdx, String defaultValue)
{
return SessionConsole.GetAttributeCaption(columnIdx, defaultValue);
}
//-------------------------------------------------------------------
// C o d e T y p e s
//-------------------------------------------------------------------
public virtual List<Sbm.ApplCodeType> SupportedCodeTypes { get; } = new List<Sbm.ApplCodeType>();
private CodeTypeCache codeTypeCache;
public bool CodeTypeHasCodes(Sbm.ApplCodeType codeType)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException($"{SysUtil.Fn} Unsupported code type: {codeType}");
PopulateCodeTypes();
return codeTypeCache.CodeTypeHasCodes(codeType);
}
public String GetCodeTypeCodeDesc(Sbm.ApplCodeType codeType, String code, bool defaultToCode = true)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException($"{SysUtil.Fn} 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(Sbm.ApplCodeType codeType, bool activeOnly = true)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException($"{SysUtil.Fn} Unsupported code type: {codeType}");
PopulateCodeTypes();
return codeTypeCache.GetCodesForCodeType(codeType, activeOnly);
}
public List<CodeDesc> GetCodeDescsForCodeType(Sbm.ApplCodeType codeType, bool activeOnly = true)
{
if (DebugMode && !SupportedCodeTypes.Contains(codeType)) throw new NotSupportedException($"{SysUtil.Fn} 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 (Sbm.ApplCodeType codeType in SupportedCodeTypes)
prmCode.CodeTypeCodes.Add(SbmSystem.GetCodeTypeCode(codeType));
prmCode.StatusCat = SaCode.StatusCat.Any;
Dictionary<String, List<SaCode>> codesByCodeType = CodeTypeConsole.GetCodesByCodeType(prmCode);
// Populate any supported code types without codes.
foreach (Sbm.ApplCodeType codeType in SupportedCodeTypes)
{
String codeTypeCode = SbmSystem.GetCodeTypeCode(codeType);
if (!codesByCodeType.ContainsKey(codeTypeCode))
codesByCodeType[codeTypeCode] = new List<SaCode>();
}
codeTypeCache = new CodeTypeCache(codesByCodeType);
}
//-------------------------------------------------------------------
// R e f e r e n c e D a t a
//-------------------------------------------------------------------
// Currencies.
private void PopulateCurrencies()
{
if (mbr.currencies != null) return;
SaCurrency.Params prmCurrency = new SaCurrency.Params();
prmCurrency.StatusCat = SaCurrency.StatusCat.Any;
mbr.currencies = ReferenceDataConsole.GetCurrencyList(prmCurrency);
}
public SaCurrency GetDefaultCurrency()
{
PopulateCurrencies();
String currencyCode = CurrencyCodes.GetCodeForType(SaCurrencyCode.Sterling);
return mbr.currencies.Find(item => item.Code.EqualsCI(currencyCode));
}
public SaCurrency GetCurrency(SysId currencyId)
{
PopulateCurrencies();
return mbr.currencies.Find(item => item.Id.Equals(currencyId));
}
//-------------------------------------------------------------------
// Regions.
private void PopulateRegions()
{
if (mbr.regions != null) return;
SaRegion.Params prmRegion = new SaRegion.Params();
mbr.regions = ReferenceDataConsole.GetRegionList(prmRegion);
}
public SaRegion FindRegionById(SysId regionId)
{
PopulateRegions();
return mbr.regions.FindById(regionId);
}
//-------------------------------------------------------------------
// Tax codes.
private void PopulateTaxCodes()
{
if (mbr.taxCodes != null) return;
SaTaxCode.Params prmTaxCode = new SaTaxCode.Params();
mbr.taxCodes = ReferenceDataConsole.GetTaxCodeList(prmTaxCode);
}
public SaTaxCode FindTaxCodeById(SysId taxCodeId)
{
PopulateTaxCodes();
return mbr.taxCodes.Find(item => item.Id.Equals(taxCodeId));
}
public SaTaxCode FindTaxCodeEffectiveOn(String taxCode, DateTime effectiveOn)
{
PopulateTaxCodes();
return mbr.taxCodes.FindByCodeEffectiveOn(taxCode, effectiveOn);
}
//-------------------------------------------------------------------
// Units of measure.
private void PopulateUnitsOfMeasure()
{
if (mbr.unitsOfMeasure != null) return;
SaUnitMeasure.Params prmUnitOfMeasure = new SaUnitMeasure.Params();
prmUnitOfMeasure.StatusCat = SaUnitMeasure.StatusCat.Any;
mbr.unitsOfMeasure = ReferenceDataConsole.GetUnitMeasureList(prmUnitOfMeasure);
}
public SaUnitMeasure FindUnitOfMeasureById(SysId uomId)
{
PopulateUnitsOfMeasure();
return mbr.unitsOfMeasure.FindById(uomId);
}
public List<SaUnitMeasure> FindUnitsOfMeasureByCategory(SaUomCategory uomCategory)
{
PopulateUnitsOfMeasure();
return mbr.unitsOfMeasure.FindAll(item => item.Category == uomCategory);
}
//-------------------------------------------------------------------
}
//=======================================================================
}