394 lines
16 KiB
C#
394 lines
16 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
|
|
{
|
|
//-------------------------------------------------------------------
|
|
// System code cache.
|
|
/// <summary>Central repository for system codes used by manager.</summary>
|
|
private class SystemCodeCache
|
|
{
|
|
public SystemCodeCache(ISbmUserContext_Core userContext)
|
|
{
|
|
this.userContext = userContext;
|
|
}
|
|
private readonly ISbmUserContext_Core userContext;
|
|
private Dictionary<Sbm.SystemCode, List<TypeCodeDesc>> systemCodes = new Dictionary<Sbm.SystemCode, List<TypeCodeDesc>>();
|
|
public List<TypeCodeDesc> GetCodesOfType(Sbm.SystemCode systemCode)
|
|
{
|
|
if (!systemCodes.ContainsKey(systemCode))
|
|
systemCodes[systemCode] = SbmSystem.GetCodesOfType(userContext, 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(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 SbmInternals internals;
|
|
private readonly SystemCodeCache systemCodeCache;
|
|
private readonly List<TypeCodeDesc> currencyCodes;
|
|
private List<SaCurrency> currencies;
|
|
private List<SaLanguage> languages;
|
|
private List<SaRegion> regions;
|
|
private List<SaTaxCode> taxCodes;
|
|
private List<SaUnitMeasure> unitsOfMeasure;
|
|
|
|
//-------------------------------------------------------------------
|
|
// Static initialisation.
|
|
static SbmCoreMgr()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Construction.
|
|
protected SbmCoreMgr(ISbmUserContext_Core userContext)
|
|
{
|
|
if (userContext == null)
|
|
throw new NotSupportedException("SbmItemMgr User context must be supplied");
|
|
UserContext = userContext;
|
|
systemCodeCache = new SystemCodeCache(userContext);
|
|
// Numeric formatting values.
|
|
WeightDecimals = UserContext.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityWeight);
|
|
LengthDecimals = UserContext.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityLength);
|
|
VolumeDecimals = UserContext.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityVolume);
|
|
DensityDecimals = UserContext.GetOwnerOption_NumericDecimals(Sbm.OrgOption_NumericDecimals.CommodityDensity);
|
|
BoxQuantityDecimals = 0;
|
|
// Reference data.
|
|
currencyCodes = SaReferenceDataConsole.GetReferenceDataCodes(ReferenceDataSystemCode.CurrencyCode);
|
|
}
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
if (internals != null) internals.Dispose();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// 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; set; } = 0;
|
|
protected int LengthDecimals { get; set; } = 0;
|
|
protected int VolumeDecimals { get; set; } = 0;
|
|
protected int DensityDecimals { get; set; } = 0;
|
|
protected int BoxQuantityDecimals { get; set; } = 0;
|
|
protected int OrderQuantityDecimals { get; set; } = 0;
|
|
// Session.
|
|
protected ISbmUserContext_Core UserContext { get; }
|
|
protected SbmSessionContext SessionContext { get { return UserContext.SessionContext; } }
|
|
protected SbmInternals Internals
|
|
{
|
|
get
|
|
{
|
|
if (internals == null) internals = new SbmInternals(UserContext);
|
|
return internals;
|
|
}
|
|
}
|
|
public SysId AffiliateId_Owner { get { return UserContext.OrganisationAffiliateId; } }
|
|
protected SbmAccountsDfn AccountsDfn { get { return Internals.AccountsDfn; } }
|
|
protected DbUpdateInfo DbUpdateInfo { get { return Internals.DbUpdateInfo; } }
|
|
// 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 { return new List<TypeCodeDesc>(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 systemCodeCache.GetCodesOfType(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;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Configuration 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 (currencies != null) return;
|
|
SaCurrency.Params prmCurrency = new SaCurrency.Params();
|
|
prmCurrency.StatusCat = SaCurrency.StatusCat.Any;
|
|
currencies = ReferenceDataConsole.GetCurrencyList(prmCurrency);
|
|
}
|
|
public SaCurrency GetDefaultCurrency()
|
|
{
|
|
PopulateCurrencies();
|
|
String currencyCode = CurrencyCodes.GetCodeForType(SaCurrencyCode.Sterling);
|
|
return currencies.Find(item => item.Code.EqualsCI(currencyCode));
|
|
}
|
|
public SaCurrency GetCurrency(SysId currencyId)
|
|
{
|
|
PopulateCurrencies();
|
|
return currencies.Find(item => item.Id.Equals(currencyId));
|
|
}
|
|
//-------------------------------------------------------------------
|
|
// Regions.
|
|
private void PopulateRegions()
|
|
{
|
|
if (regions != null) return;
|
|
SaRegion.Params prmRegion = new SaRegion.Params();
|
|
regions = ReferenceDataConsole.GetRegionList(prmRegion);
|
|
}
|
|
public SaRegion FindRegionById(SysId regionId)
|
|
{
|
|
PopulateRegions();
|
|
return regions.FindById(regionId);
|
|
}
|
|
//-------------------------------------------------------------------
|
|
// Tax codes.
|
|
private void PopulateTaxCodes()
|
|
{
|
|
if (taxCodes != null) return;
|
|
SaTaxCode.Params prmTaxCode = new SaTaxCode.Params();
|
|
taxCodes = ReferenceDataConsole.GetTaxCodeList(prmTaxCode);
|
|
}
|
|
public SaTaxCode FindTaxCodeById(SysId taxCodeId)
|
|
{
|
|
PopulateTaxCodes();
|
|
return taxCodes.Find(item => item.Id.Equals(taxCodeId));
|
|
}
|
|
public SaTaxCode FindTaxCodeEffectiveOn(String taxCode, DateTime effectiveOn)
|
|
{
|
|
PopulateTaxCodes();
|
|
return taxCodes.FindByCodeEffectiveOn(taxCode, effectiveOn);
|
|
}
|
|
//-------------------------------------------------------------------
|
|
// Units of measure.
|
|
private void PopulateUnitsOfMeasure()
|
|
{
|
|
if (taxCodes != null) return;
|
|
SaUnitMeasure.Params prmUnitOfMeasure = new SaUnitMeasure.Params();
|
|
prmUnitOfMeasure.StatusCat = SaUnitMeasure.StatusCat.Any;
|
|
unitsOfMeasure = ReferenceDataConsole.GetUnitMeasureList(prmUnitOfMeasure);
|
|
}
|
|
public SaUnitMeasure FindUnitOfMeasureById(SysId uomId)
|
|
{
|
|
PopulateUnitsOfMeasure();
|
|
return unitsOfMeasure.FindById(uomId);
|
|
}
|
|
public List<SaUnitMeasure> FindUnitsOfMeasureByCategory(SaUomCategory uomCategory)
|
|
{
|
|
PopulateUnitsOfMeasure();
|
|
return unitsOfMeasure.FindAll(item => item.Category == uomCategory);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|