Ejemplo n.º 1
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);

                try
                {
                    using var scope = _serviceScopeFactory.CreateScope();

                    var defenderDbContext = scope.ServiceProvider.GetRequiredService <DefenderDbContext>();

                    var pushes = await defenderDbContext.Pushes.Include(p => p.User).Where(p => p.Pushed == null)
                                 .ToListAsync(stoppingToken);

                    if (pushes.Count > 0)
                    {
                        var usersWithMinSince =
                            pushes.GroupBy(p => p.UserId).SelectMany(g => g.Where(x => x.Since == g.Min(y => y.Since)))
                            .Select(s => new { s.UserId, s.Since })
                            .ToList();

                        var userWithMinSinceForQuery = defenderDbContext.FromLocalList(usersWithMinSince);

                        var creditRequestsForPushQuery =
                            from creditRequest in defenderDbContext.CreditRequests.AsNoTracking().Include(r => r.Bank)
                            join userWithMinSince in userWithMinSinceForQuery on creditRequest.UserId equals
                            userWithMinSince.UserId
                            where creditRequest.OrderDate >= userWithMinSince.Since
                            select creditRequest;

                        var creditRequestsForPush = await creditRequestsForPushQuery.ToListAsync(stoppingToken);

                        foreach (var userCreditRequests in creditRequestsForPush.GroupBy(cr => cr.UserId))
                        {
                            var userId = userCreditRequests.Key;

                            var user = pushes.First(x => x.UserId == userCreditRequests.Key).User;

                            var creditsCount = userCreditRequests.Count();

                            var isMoreThenOneCredit = creditsCount > 1;

                            var firstCredit = userCreditRequests.First();

                            var pushTitle = isMoreThenOneCredit
                                ? "Обнаружены новые кредиты!"
                                : "Обнаружен новый кредит!";

                            var pushMessage = new PushMessage
                            {
                                Aps = new PushMessageAps {
                                    Alert = pushTitle
                                },
                                Data = new PushMessageData
                                {
                                    BankName   = firstCredit.Bank.Name,
                                    BankIcoUrl = firstCredit.Bank.IcoUrl,
                                    OrderDate  = firstCredit.OrderDate,
                                    TotalSum   = firstCredit.Amount,
                                    Text       = isMoreThenOneCredit
                                        ? $"На ваше имя взято более одного кредита: {creditsCount} шт!"
                                        : "На ваше имя взят кредит! Это были вы?"
                                }
                            };

                            var data = new Dictionary <string, string>
                            {
                                { "bankName", firstCredit.Bank.Name },
                                { "bankIcoUrl", firstCredit.Bank.IcoUrl },
                                { "orderDate", firstCredit.OrderDate.ToLongDateString() },
                                { "totalSum", firstCredit.Amount.ToString(CultureInfo.InvariantCulture) },
                                {
                                    "text", isMoreThenOneCredit
                                        ? $"На ваше имя взято более одного кредита: {creditsCount} шт!"
                                        : "На ваше имя взят кредит! Это были вы?"
                                }
                            };

                            var pushMessageString =
                                JsonConvert.SerializeObject(pushMessage, Formatting.Indented,
                                                            new JsonSerializerSettings
                            {
                                ContractResolver = new CamelCasePropertyNamesContractResolver()
                            });

                            await _notificationClient.SendAsync(new[] { user.Token }, pushTitle, data);

                            _logger.LogInformation(
                                "Push done to {Phone}, total credits: {Count} with message {Message}", user.Phone,
                                creditsCount, pushMessageString);


                            foreach (var push in pushes.Where(p => p.UserId == userId))
                            {
                                push.Pushed = push.Updated = DateTime.Now;
                            }
                        }

                        await defenderDbContext.SaveChangesAsync(stoppingToken);
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Error");
                }

                await Task.Delay(5000, stoppingToken);
            }
        }