using System.Security.Principal; using Microsoft.Extensions.Logging; using Quadarax.Application.QLiberace.Base.Dtos; using Quadarax.Application.QLiberace.Base.Entities; using Quadarax.Application.QLiberace.Base.Repositories; using Quadarax.Application.QLiberace.Common; using Quadarax.Application.QLiberace.Common.Attributes; using Quadarax.Application.QLiberace.Common.Settings; using Quadarax.Foundation.Core.Business; using Quadarax.Foundation.Core.Data; using Quadarax.Foundation.Core.Data.Interface; using Quadarax.Foundation.Core.Data.Interface.Entity.Dto; using Quadarax.Foundation.Core.Reflection; namespace Quadarax.Application.QLiberace.Base.Services { internal class SettingsService : AbstractRepositoryService { #region *** Constructor *** public SettingsService(RepoSetting repository, IPrincipal currentPrincipal, ILoggerFactory logger) : base(repository, currentPrincipal, logger) { } #endregion #region *** Public Operations *** public ResultDto CreateSettings(ModuleSetting settings) where TSettings : ModuleSetting { if (settings == null) throw new ArgumentNullException(nameof(settings)); return TryCatchBlock(() => { var attrs = AttributeQuery.FindAll(typeof(TSettings), true); if (attrs.Length == 0) throw new InvalidOperationException( $"ModuleAttribute is not defined on class '{typeof(TSettings).Name}'."); if (attrs.Length > 1) throw new InvalidOperationException( "ModuleAttribute is defined on more than one ModuleSetting class."); var settingsFlat = settings.GetData(); foreach (var flat in settingsFlat) { var setting = Repository.New(); setting.Code = flat.Item1; setting.ModuleCode = attrs[0].ModuleCode; setting.IsEnabled = true; setting.Description = string.Empty; setting.ValueTypeQualified = flat.Item2; setting.Value = flat.Item3?.ToString(); Repository.Set(setting); } Repository.Commit(); return new ResultPlain(); }); } public ResultValueDto GetSettings(string moduleCode) where TSettings : ModuleSetting, new() { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); return TryCatchBlock(() => { if (!Repository.QueryModule(moduleCode, Paging.NoPaging()).Any()) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.SettingsNotFoundForModuleCode, moduleCode); var settingDto = default(TSettings); if (settingDto == null) throw new ArgumentNullException(nameof(settingDto)); var settings = Repository.QueryModule(moduleCode,Paging.NoPaging()); settingDto.SetData(settings.Select(x=>new Tuple(x.Code,x.ValueTypeQualified,x.GetTypedValue()))); return new ResultValueDto(settingDto); }); } public ResultValueDto GetSettingsValue(string moduleCode, string valueCode) { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); if (string.IsNullOrEmpty(valueCode)) throw new ArgumentNullException(nameof(valueCode)); return TryCatchBlock(() => { var settings = GetSettings(moduleCode, valueCode); if (settings == null) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.SettingsNotFoundCode, valueCode, moduleCode); return new ResultValueDto(settings.GetTypedValue()); }); } public ResultBoolDto ExistsSettings(string moduleCode) { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); return TryCatchBlock(() => { var result = Repository.QueryModule(moduleCode, Paging.NoPaging()).Any(); return new ResultBoolDto(result); }); } public ResultBoolDto ExistsSettingsValue(string moduleCode, string valueCode) { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); if (string.IsNullOrEmpty(valueCode)) throw new ArgumentNullException(nameof(valueCode)); return TryCatchBlock(() => { var result = Repository.QueryModule(moduleCode, Paging.NoPaging()).Any(x => x.Code == valueCode); return new ResultBoolDto(result); }); } public ResultDto AddSettingsValue(string moduleCode, string valueCode, string valueDescription, object value) { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); if (string.IsNullOrEmpty(valueCode)) throw new ArgumentNullException(nameof(valueCode)); return TryCatchBlock(() => { var exists = ExistsSettingsValue(moduleCode, valueCode); if (!exists.IsSuccess) return (ResultDto)exists; if (exists.Value) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.SettingsAlreadyExistsCode, valueCode, moduleCode); var settings = Repository.New(); settings.ModuleCode = moduleCode; settings.Code = valueCode; settings.Description = valueDescription; settings.Value = value?.ToString(); settings.IsEnabled = true; Repository.Commit(); return new ResultPlain(); }); } public ResultDto UpdateSettings(ModuleSetting settings) where TSettings : ModuleSetting { if (settings == null) throw new ArgumentNullException(nameof(settings)); return TryCatchBlock(() => { var attrs = AttributeQuery.FindAll(typeof(TSettings), true); if (attrs.Length == 0) throw new InvalidOperationException( $"ModuleAttribute is not defined on class '{typeof(TSettings).Name}'."); if (attrs.Length > 1) throw new InvalidOperationException( "ModuleAttribute is defined on more than one ModuleSetting class."); var settingsFlat = settings.GetData(); foreach (var flat in settingsFlat) { var setting = GetSettings(attrs[0].ModuleCode, flat.Item1); if (setting == null) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.SettingsNotFoundCode, flat.Item1, attrs[0].ModuleCode); Repository.Set(setting); } Repository.Commit(); return new ResultPlain(); }); } public ResultDto UpdateSettingsValue(string moduleCode, string valueCode, object value) { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); if (string.IsNullOrEmpty(valueCode)) throw new ArgumentNullException(nameof(valueCode)); return TryCatchBlock(() => { var exists = ExistsSettingsValue(moduleCode, valueCode); if (!exists.IsSuccess) return (ResultDto)exists; if (!exists.Value) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.SettingsNotFoundCode, valueCode, moduleCode); var settings = Repository.Get(moduleCode, valueCode); if (settings==null) throw ExceptionFactory.CreateException(ExceptionLibrary.ExceptionsCodes.SettingsNotFoundCode, valueCode, moduleCode); settings.Value = value?.ToString(); Repository.Commit(); return new ResultPlain(); }); } public ResultDto AddOrUpdateSettingsValue(string moduleCode, string valueCode, object value) { return AddOrUpdateSettingsValue(moduleCode, valueCode, value, string.Empty); } public ResultDto AddOrUpdateSettingsValue(string moduleCode, string valueCode, object value, string valueDescription) { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); if (string.IsNullOrEmpty(valueCode)) throw new ArgumentNullException(nameof(valueCode)); return TryCatchBlock(() => { var exists = ExistsSettingsValue(moduleCode, valueCode); if (!exists.IsSuccess) return (ResultDto)exists; if (exists.Value) { return UpdateSettingsValue(moduleCode, valueCode, value); } else { return AddSettingsValue(moduleCode, valueCode, valueDescription, value); } }); } public ResultSettingsValuesListDto GetSettingsValues(string moduleCode, IPaging paging) { if (string.IsNullOrEmpty(moduleCode)) throw new ArgumentNullException(nameof(moduleCode)); return TryCatchBlock(() => { var result = Repository.QueryModule(moduleCode, paging) .ToDictionary(x => x.Code, y => y.GetTypedValue()); return new ResultSettingsValuesListDto(result); }); } #endregion #region ** Private Operations *** private Setting? GetSettings(string moduleCode, string valueCode) { var settings = Repository.Get(moduleCode, valueCode); return settings; } #endregion } }