Esempio n. 1
0
 public ApiCaller(int id, ApiCallerTypes type)
 {
     Id   = id;
     Type = type;
 }
        private async Task <Result> Update(int userId, ApiCallerTypes userType, int?agencyId, Dictionary <NotificationTypes, NotificationSettings> notificationOptions)
        {
            return(await Result.Success()
                   .BindWithTransaction(_context, () => UpdateAll()
                                        .Tap(() => SaveAll())));


            async Task <Result> UpdateAll()
            {
                foreach (var option in notificationOptions)
                {
                    var result = await Validate(option)
                                 .Bind(defaultOptions => Update(option, defaultOptions));

                    if (result.IsFailure)
                    {
                        return(Result.Failure(result.Error));
                    }
                }

                return(Result.Success());


                async Task <Result <SlimNotificationOptions> > Validate(KeyValuePair <NotificationTypes, NotificationSettings> option)
                {
                    var defaultOptions = await TryGetDefaultOptions(option.Key, userType);

                    if (defaultOptions.IsFailure)
                    {
                        return(Result.Failure <SlimNotificationOptions>(defaultOptions.Error));
                    }

                    if (defaultOptions.Value.IsMandatory && defaultOptions.Value.EnabledProtocols != GetEnabledProtocols(option.Value))
                    {
                        return(Result.Failure <SlimNotificationOptions>($"Notification type '{option.Key}' is mandatory"));
                    }

                    return(defaultOptions);
                }

                async Task <Result> Update(KeyValuePair <NotificationTypes, NotificationSettings> option, SlimNotificationOptions defaultOptions)
                {
                    var entity = await GetOptions(userId, userType, agencyId, option.Key);

                    if (entity is null)
                    {
                        _context.NotificationOptions.Add(new NotificationOptions
                        {
                            UserId           = userId,
                            UserType         = userType,
                            AgencyId         = agencyId,
                            Type             = option.Key,
                            EnabledProtocols = GetEnabledProtocols(option.Value),
                            IsMandatory      = defaultOptions.IsMandatory
                        });
                    }
                    else
                    {
                        entity.EnabledProtocols = GetEnabledProtocols(option.Value);
                        entity.IsMandatory      = defaultOptions.IsMandatory;
                        _context.Update(entity);
                    }

                    return(Result.Success());
                }

                ProtocolTypes GetEnabledProtocols(NotificationSettings options)
                {
                    ProtocolTypes protocols = 0;

                    foreach (var(protocol, isEnabled) in options.EnabledProtocols)
                    {
                        if (isEnabled)
                        {
                            protocols |= protocol;
                        }
                    }

                    return(protocols);
                }
            }

            async Task SaveAll()
            {
                await _context.SaveChangesAsync();
            }
        }
        public async Task <Result <SlimNotificationOptions> > GetNotificationOptions(int userId, ApiCallerTypes userType, int?agencyId, NotificationTypes notificationType)
        {
            var options = await GetOptions(userId, userType, agencyId, notificationType);

            var(_, isFailure, defaultOptions, error) = await TryGetDefaultOptions(notificationType, userType);

            if (isFailure)
            {
                return(Result.Failure <SlimNotificationOptions>(error));
            }

            return(options is null
                ? defaultOptions
                : new SlimNotificationOptions {
                EnabledProtocols = options.EnabledProtocols, IsMandatory = defaultOptions.IsMandatory,
                EmailTemplateId = defaultOptions.EmailTemplateId
            });
        }
        private async Task <Result <SlimNotificationOptions> > TryGetDefaultOptions(NotificationTypes type, ApiCallerTypes userType)
        {
            var receiver = userType.ToReceiverType();
            var options  = await _context.DefaultNotificationOptions.SingleOrDefaultAsync(o => o.Type == type);

            if (options is null)
            {
                return(Result.Failure <SlimNotificationOptions>($"Cannot find notification options for the type '{type}'"));
            }

            var emailTemplateId = userType switch
            {
                ApiCallerTypes.Agent => options.AgentEmailTemplateId,
                ApiCallerTypes.Admin => options.AdminEmailTemplateId,
                ApiCallerTypes.PropertyOwner => options.PropertyOwnerEmailTemplateId,
                _ => throw new NotImplementedException("No email templates are defined for the specified API caller type")
            };

            return(options.EnabledReceivers.HasFlag(receiver)
                ? new SlimNotificationOptions(enabledProtocols: options.EnabledProtocols,
                                              isMandatory: options.IsMandatory,
                                              enabledReceivers: options.EnabledReceivers,
                                              emailTemplateId: emailTemplateId)
                : Result.Failure <SlimNotificationOptions>($"Cannot find notification options for the type '{type}' and the receiver '{receiver}'"));
        }
 private Task <NotificationOptions> GetOptions(int userId, ApiCallerTypes userType, int?agencyId, NotificationTypes notificationType)
 => _context.NotificationOptions
 .SingleOrDefaultAsync(o => o.UserId == userId && o.UserType == userType && o.AgencyId == agencyId && o.Type == notificationType);
 public static ReceiverTypes ToReceiverType(this ApiCallerTypes apiCallerType)
 => apiCallerType switch
 {