< Summary

Information
Class: OzonRepositories.Data.OzonChatResponseStatisticRepository
Assembly: OzonRepositories
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonRepositories/Data/OzonChatResponseStatisticRepository.cs
Line coverage
10%
Covered lines: 15
Uncovered lines: 132
Coverable lines: 147
Total lines: 276
Line coverage: 10.2%
Branch coverage
6%
Covered branches: 2
Total branches: 30
Branch coverage: 6.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonRepositories/Data/OzonChatResponseStatisticRepository.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore;
 2using OzonDomains.Models;
 3using OzonRepositories.Context;
 4
 5namespace OzonRepositories.Data
 6{
 7    public class OzonChatResponseStatisticRepository : MainRepository, IRepository<OzonChatResponseStatistic>
 8    {
 19        public OzonChatResponseStatisticRepository(ApplicationDbContext orderContext) : base(orderContext)
 10        {
 111        }
 12
 13        public async Task<int> Add(OzonChatResponseStatistic value)
 14        {
 015            await _context.OzonChatResponseStatistics.AddAsync(value);
 016            return await _context.SaveChangesAsync();
 017        }
 18
 19        public async Task<int> Delete(OzonChatResponseStatistic value)
 20        {
 021            _context.OzonChatResponseStatistics.Remove(value);
 022            return await _context.SaveChangesAsync();
 023        }
 24
 25        public async Task<List<OzonChatResponseStatistic>> Get()
 26        {
 027            return await _context.OzonChatResponseStatistics
 028                .Include(x => x.Client)
 029                .Include(x => x.Order)
 030                .OrderByDescending(x => x.ClientMessageDate)
 031                .ToListAsync();
 032        }
 33
 34        public async Task<OzonChatResponseStatistic?> GetAsync(int id)
 35        {
 036            return await _context.OzonChatResponseStatistics
 037                .Include(x => x.Client)
 038                .Include(x => x.Order)
 039                .FirstOrDefaultAsync(x => x.Id == id) ?? new OzonChatResponseStatistic();
 040        }
 41
 42        public async Task<OzonChatResponseStatistic?> GetAsync(OzonChatResponseStatistic value)
 43        {
 044            return await _context.OzonChatResponseStatistics
 045                .Include(x => x.Client)
 046                .Include(x => x.Order)
 047                .FirstOrDefaultAsync(x => x.ChatId == value.ChatId &&
 048                                          x.ClientMessageId == value.ClientMessageId) ?? new OzonChatResponseStatistic()
 049        }
 50
 51        public async Task<int> Update(OzonChatResponseStatistic value)
 52        {
 053            value.UpdatedAt = DateTime.UtcNow;
 054            _context.OzonChatResponseStatistics.Update(value);
 055            return await _context.SaveChangesAsync();
 056        }
 57
 58        /// <summary>
 59        /// Получить статистику по чату
 60        /// </summary>
 61        public async Task<List<OzonChatResponseStatistic>> GetByChatIdAsync(string chatId)
 62        {
 063            return await _context.OzonChatResponseStatistics
 064                .Include(x => x.Client)
 065                .Include(x => x.Order)
 066                .Where(x => x.ChatId == chatId)
 067                .OrderByDescending(x => x.ClientMessageDate)
 068                .ToListAsync();
 069        }
 70
 71        /// <summary>
 72        /// Получить статистику по клиенту (фильтруем по дате ответа или создания записи)
 73        /// </summary>
 74        public async Task<List<OzonChatResponseStatistic>> GetByClientIdAsync(int clientId, DateTime? from = null, DateT
 75        {
 076            var query = _context.OzonChatResponseStatistics
 077                .Include(x => x.Client)
 078                .Include(x => x.Order)
 079                .Where(x => x.ClientId == clientId);
 80
 081            if (from.HasValue)
 082                query = query.Where(x => (x.SellerResponseDate ?? x.CreatedAt) >= from.Value);
 83
 084            if (to.HasValue)
 085                query = query.Where(x => (x.SellerResponseDate ?? x.CreatedAt) <= to.Value);
 86
 087            return await query
 088                .OrderByDescending(x => x.SellerResponseDate ?? x.CreatedAt)
 089                .ToListAsync();
 090        }
 91
 92        /// <summary>
 93        /// Получить неотвеченные сообщения по клиенту
 94        /// </summary>
 95        public async Task<List<OzonChatResponseStatistic>> GetUnansweredByClientIdAsync(int clientId)
 96        {
 097            return await _context.OzonChatResponseStatistics
 098                .Include(x => x.Client)
 099                .Include(x => x.Order)
 0100                .Where(x => x.ClientId == clientId && !x.IsAnswered)
 0101                .OrderBy(x => x.ClientMessageDate)
 0102                .ToListAsync();
 0103        }
 104
 105        /// <summary>
 106        /// Получить статистику по заказу
 107        /// </summary>
 108        public async Task<List<OzonChatResponseStatistic>> GetByOrderIdAsync(int orderId)
 109        {
 0110            return await _context.OzonChatResponseStatistics
 0111                .Include(x => x.Client)
 0112                .Include(x => x.Order)
 0113                .Where(x => x.OrderId == orderId)
 0114                .OrderByDescending(x => x.ClientMessageDate)
 0115                .ToListAsync();
 0116        }
 117
 118        /// <summary>
 119        /// Получить запись по ID сообщения клиента
 120        /// </summary>
 121        public async Task<OzonChatResponseStatistic?> GetByClientMessageIdAsync(string chatId, long clientMessageId)
 122        {
 0123            return await _context.OzonChatResponseStatistics
 0124                .Include(x => x.Client)
 0125                .Include(x => x.Order)
 0126                .FirstOrDefaultAsync(x => x.ChatId == chatId && x.ClientMessageId == clientMessageId);
 0127        }
 128
 129        /// <summary>
 130        /// Обновить информацию об ответе продавца
 131        /// </summary>
 132        public async Task<int> UpdateResponseAsync(string chatId, long clientMessageId,
 133            long sellerResponseMessageId, string sellerResponseText, DateTime sellerResponseDate, string? responderName 
 134        {
 0135            var statistic = await GetByClientMessageIdAsync(chatId, clientMessageId);
 136
 0137            if (statistic == null)
 0138                return 0;
 139
 0140            statistic.SellerResponseMessageId = sellerResponseMessageId;
 0141            statistic.SellerResponseText = sellerResponseText;
 0142            statistic.SellerResponseDate = sellerResponseDate;
 0143            statistic.ResponseTimeSeconds = (int)(sellerResponseDate - statistic.ClientMessageDate).TotalSeconds;
 0144            statistic.IsAnswered = true;
 0145            statistic.ResponderName = responderName;
 0146            statistic.UpdatedAt = DateTime.UtcNow;
 147
 0148            return await Update(statistic);
 0149        }
 150
 151        /// <summary>
 152        /// Получить среднее время ответа по клиенту за период
 153        /// </summary>
 154        public async Task<double?> GetAverageResponseTimeAsync(int clientId, DateTime? from = null, DateTime? to = null)
 155        {
 0156            var query = _context.OzonChatResponseStatistics
 0157                .Where(x => x.ClientId == clientId && x.IsAnswered && x.ResponseTimeSeconds.HasValue);
 158
 0159            if (from.HasValue)
 0160                query = query.Where(x => x.ClientMessageDate >= from.Value);
 161
 0162            if (to.HasValue)
 0163                query = query.Where(x => x.ClientMessageDate <= to.Value);
 164
 0165            if (!await query.AnyAsync())
 0166                return null;
 167
 0168            return await query.AverageAsync(x => x.ResponseTimeSeconds!.Value);
 0169        }
 170
 171        /// <summary>
 172        /// Получить статистику ответов (всего/отвечено) по клиенту за период
 173        /// </summary>
 174        public async Task<(int Total, int Answered, double AnswerRate)> GetAnswerStatsAsync(
 175            int clientId, DateTime? from = null, DateTime? to = null)
 176        {
 0177            var query = _context.OzonChatResponseStatistics
 0178                .Where(x => x.ClientId == clientId);
 179
 0180            if (from.HasValue)
 0181                query = query.Where(x => x.ClientMessageDate >= from.Value);
 182
 0183            if (to.HasValue)
 0184                query = query.Where(x => x.ClientMessageDate <= to.Value);
 185
 0186            var total = await query.CountAsync();
 0187            var answered = await query.CountAsync(x => x.IsAnswered);
 0188            var answerRate = total > 0 ? (double)answered / total * 100 : 0;
 189
 0190            return (total, answered, answerRate);
 0191        }
 192
 193        /// <summary>
 194        /// Получить топ-N самых медленных ответов по клиенту
 195        /// </summary>
 196        public async Task<List<OzonChatResponseStatistic>> GetSlowestResponsesAsync(int clientId, int topN = 10)
 197        {
 0198            return await _context.OzonChatResponseStatistics
 0199                .Include(x => x.Client)
 0200                .Include(x => x.Order)
 0201                .Where(x => x.ClientId == clientId && x.IsAnswered && x.ResponseTimeSeconds.HasValue)
 0202                .OrderByDescending(x => x.ResponseTimeSeconds)
 0203                .Take(topN)
 0204                .ToListAsync();
 0205        }
 206
 207        /// <summary>
 208        /// Получить статистику по типам чатов
 209        /// </summary>
 210        public async Task<Dictionary<string, int>> GetStatsByChatTypeAsync(int clientId, DateTime? from = null, DateTime
 211        {
 0212            var query = _context.OzonChatResponseStatistics
 0213                .Where(x => x.ClientId == clientId && !string.IsNullOrEmpty(x.ChatType));
 214
 0215            if (from.HasValue)
 0216                query = query.Where(x => x.ClientMessageDate >= from.Value);
 217
 0218            if (to.HasValue)
 0219                query = query.Where(x => x.ClientMessageDate <= to.Value);
 220
 0221            return await query
 0222                .GroupBy(x => x.ChatType)
 0223                .Select(g => new { ChatType = g.Key!, Count = g.Count() })
 0224                .ToDictionaryAsync(x => x.ChatType, x => x.Count);
 0225        }
 226
 227        public new async Task<int> SaveChanges()
 228        {
 0229            return await _context.SaveChangesAsync();
 0230        }
 231
 232        /// <summary>
 233        /// Получить ChatId чатов, где сообщение покупателя содержит поисковый запрос
 234        /// </summary>
 235        public async Task<List<string>> GetChatIdsByMessageQueryAsync(string query, int clientId = 0, int limit = 100)
 236        {
 1237            var q = _context.OzonChatResponseStatistics
 1238                .AsNoTracking()
 1239                .Where(x => x.ClientMessageText != null &&
 1240                            EF.Functions.Like(x.ClientMessageText, $"%{query}%"));
 241
 1242            if (clientId > 0)
 1243                q = q.Where(x => x.ClientId == clientId);
 244
 1245            return await q
 1246                .Select(x => x.ChatId)
 1247                .Distinct()
 1248                .OrderBy(x => x)
 1249                .Take(limit)
 1250                .ToListAsync();
 1251        }
 252
 253        /// <summary>
 254        /// Получить образцы сообщений покупателей для построения списка подсказок
 255        /// </summary>
 256        public async Task<List<(string ChatId, string MessageText, string? PostingNumber, int ClientId)>> GetSampleBuyer
 257            string query, int clientId = 0, int limit = 200)
 258        {
 0259            var q = _context.OzonChatResponseStatistics
 0260                .AsNoTracking()
 0261                .Where(x => x.ClientMessageText != null &&
 0262                            EF.Functions.Like(x.ClientMessageText, $"%{query}%"));
 263
 0264            if (clientId > 0)
 0265                q = q.Where(x => x.ClientId == clientId);
 266
 0267            var rows = await q
 0268                .OrderByDescending(x => x.ClientMessageDate)
 0269                .Take(limit)
 0270                .Select(x => new { x.ChatId, x.ClientMessageText, x.PostingNumber, x.ClientId })
 0271                .ToListAsync();
 272
 0273            return rows.Select(r => (r.ChatId, r.ClientMessageText!, r.PostingNumber, r.ClientId)).ToList();
 0274        }
 275    }
 276}