using _0_Framework.Application; using _0_Framework.InfraStructure; using Company.Domain.SmsResultAgg; using CompanyManagment.App.Contracts.SmsResult; using CompanyManagment.App.Contracts.SmsResult.Dto; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using _0_Framework.Application.Enums; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace CompanyManagment.EFCore.Repository; public class SmsResultRepository : RepositoryBase, ISmsResultRepository { private readonly CompanyContext _context; public SmsResultRepository(CompanyContext context) : base(context) { _context = context; } #region ForApi public async Task> GetSmsReportList(SmsReportSearchModel searchModel) { // مرحله 1: همه رکوردها را با projection ساده بگیرید var rawQuery = await _context.SmsResults .Select(x => new { x.id, x.ContractingPatyId, x.Mobile, x.Status, x.TypeOfSms, x.CreationDate, DateOnly = x.CreationDate.Date // فقط تاریخ بدون ساعت }) .AsNoTracking() .ToListAsync(); // اینجا SQL اجرا می‌شود و همه داده‌ها به client می‌آیند if (searchModel.ContractingPatyId > 0) { rawQuery = rawQuery.Where(x => x.ContractingPatyId == searchModel.ContractingPatyId).ToList(); } if (!string.IsNullOrWhiteSpace(searchModel.Mobile)) { rawQuery = rawQuery.Where(x => x.Mobile.Contains(searchModel.Mobile)).ToList(); } if (searchModel.TypeOfSms != TypeOfSmsSetting.All && searchModel.TypeOfSms != TypeOfSmsSetting.Warning) { var typeOfSms = "All"; switch (searchModel.TypeOfSms) { case TypeOfSmsSetting.InstitutionContractDebtReminder: typeOfSms = "یادآور بدهی ماهانه"; break; case TypeOfSmsSetting.MonthlyInstitutionContract: typeOfSms = "صورت حساب ماهانه"; break; case TypeOfSmsSetting.BlockContractingParty: typeOfSms = "اعلام مسدودی طرف حساب"; break; case TypeOfSmsSetting.LegalAction: typeOfSms = "اقدام قضایی"; break; case TypeOfSmsSetting.InstitutionContractConfirm: typeOfSms = "یادآور تایید قرارداد مالی"; break; case TypeOfSmsSetting.SendInstitutionContractConfirmationCode: typeOfSms = "کد تاییدیه قرارداد مالی"; break; case TypeOfSmsSetting.SendInstitutionContractConfirmationLink: typeOfSms = "لینک تاییدیه ایجاد قرارداد مالی"; break; case TypeOfSmsSetting.TaskReminder: typeOfSms = "یادآور وظایف"; break; } rawQuery = rawQuery.Where(x => x.TypeOfSms == typeOfSms).ToList(); } if (searchModel.TypeOfSms == TypeOfSmsSetting.Warning) { rawQuery = rawQuery.Where(x => x.TypeOfSms.Contains("هشدار")).ToList(); } if (searchModel.SendStatus != SendStatus.All) { var status = "All"; switch (searchModel.SendStatus) { case SendStatus.Success: status = "موفق"; break; case SendStatus.Failed: status = "ناموفق"; break; } rawQuery = rawQuery.Where(x => x.Status == status).ToList(); } #region searchByDate if (!string.IsNullOrWhiteSpace(searchModel.StartDateFa) && !string.IsNullOrWhiteSpace(searchModel.EndDateFa)) { if (searchModel.StartDateFa.TryToGeorgianDateTime(out var startGr) == false || searchModel.EndDateFa.TryToGeorgianDateTime(out var endGr) == false) return new List(); rawQuery = rawQuery.Where(x => x.CreationDate.Date >= startGr.Date && x.CreationDate.Date <= endGr.Date).ToList(); } else { if (!string.IsNullOrWhiteSpace(searchModel.Year) && !string.IsNullOrWhiteSpace(searchModel.Month)) { var start = searchModel.Year + "/" + searchModel.Month + "/01"; var end = start.FindeEndOfMonth(); var startGr = start.ToGeorgianDateTime(); var endGr = end.ToGeorgianDateTime(); rawQuery = rawQuery.Where(x => x.CreationDate.Date >= startGr.Date && x.CreationDate.Date <= endGr.Date).ToList(); } else if (!string.IsNullOrWhiteSpace(searchModel.Year) && string.IsNullOrWhiteSpace(searchModel.Month)) { var start = searchModel.Year + "/01/01"; var findEndOfYear = searchModel.Year + "/12/01"; var end = findEndOfYear.FindeEndOfMonth(); var startGr = start.ToGeorgianDateTime(); var endGr = end.ToGeorgianDateTime(); rawQuery = rawQuery.Where(x => x.CreationDate.Date >= startGr.Date && x.CreationDate.Date <= endGr.Date).ToList(); } } #endregion // مرحله 2: گروه‌بندی و انتخاب آخرین رکورد هر روز روی Client var grouped = rawQuery .GroupBy(x => (x.DateOnly, x.TypeOfSms)) .Select(g => g.OrderByDescending(x => x.CreationDate).First()) .OrderByDescending(x => x.CreationDate) .ToList(); // مرحله 3: تبدیل به DTO و ToFarsi var result = grouped.Select(x => new SmsReportDto { SentDate = x.CreationDate.ToFarsi(), TypeOfSms = x.TypeOfSms }).ToList(); return result; } public async Task> GetSmsReportExpandList(SmsReportSearchModel searchModel, string date, string typeOfSmsSetting) { if(string.IsNullOrWhiteSpace(date) || string.IsNullOrWhiteSpace(typeOfSmsSetting)) return new List(); if (date.TryToGeorgianDateTime(out var searchDate) == false) return new List(); var query = await _context.SmsResults.Where(x => x.CreationDate.Date == searchDate.Date) .Select(x => new { x.id, x.MessageId, x.Status, x.TypeOfSms, x.ContractingPartyName, x.Mobile, x.ContractingPatyId, x.InstitutionContractId, x.CreationDate, x.CreationDate.Hour, x.CreationDate.Minute }).AsNoTracking() .ToListAsync(); ; if (searchModel.ContractingPatyId > 0) { query = query.Where(x => x.ContractingPatyId == searchModel.ContractingPatyId).ToList(); } if (!string.IsNullOrWhiteSpace(searchModel.Mobile)) { query = query.Where(x => x.Mobile.Contains(searchModel.Mobile)).ToList(); } if (typeOfSmsSetting.Contains("هشدار")) { query = query.Where(x => x.TypeOfSms.Contains("هشدار")).ToList(); } query = query.Where(x => x.TypeOfSms == typeOfSmsSetting).ToList(); if (searchModel.SendStatus != SendStatus.All) { var status = "All"; switch (searchModel.SendStatus) { case SendStatus.Success: status = "موفق"; break; case SendStatus.Failed: status = "ناموفق"; break; } query = query.Where(x => x.Status == status).ToList(); } if (query.Count == 0) return new List(); var result = query.OrderByDescending(x => x.CreationDate.Hour) .ThenByDescending(x => x.CreationDate.Minute).Select(x => new SmsReportListDto() { Id = x.id, MessageId = x.MessageId, Status = x.Status, TypeOfSms = x.TypeOfSms, ContractingPartyName = x.ContractingPartyName, Mobile = x.Mobile, HourAndMinute = x.CreationDate.TimeOfDay.ToString(@"hh\:mm"), }).ToList(); return result; } #endregion public List Search(SmsResultSearchModel searchModel) { var query = _context.SmsResults.Select(x => new App.Contracts.SmsResult.SmsResultViewModel() { Id = x.id, MessageId = x.MessageId, Status = x.Status, TypeOfSms = x.TypeOfSms, ContractingPartyName = x.ContractingPartyName, Mobile = x.Mobile, ContractingPartyId = x.ContractingPatyId, InstitutionContractId = x.InstitutionContractId, CreationDate = x.CreationDate, Hour = x.CreationDate.Hour > 9 ? $"{x.CreationDate.Hour}" : $"0{x.CreationDate.Hour}", Minute = x.CreationDate.Minute > 9 ? $"{x.CreationDate.Minute}" : $"0{x.CreationDate.Minute}", }); if (searchModel.ContractingPatyId > 0) query = query.Where(x => x.ContractingPartyId == searchModel.ContractingPatyId); if (!string.IsNullOrWhiteSpace(searchModel.Status)) query = query.Where(x => x.Status == searchModel.Status); if (!string.IsNullOrWhiteSpace(searchModel.TypeOfSms)) query = query.Where(x => x.TypeOfSms == searchModel.TypeOfSms); if (!string.IsNullOrWhiteSpace(searchModel.Mobile)) query = query.Where(x => x.Mobile.Contains(searchModel.Mobile)); #region searchByDate if (!string.IsNullOrWhiteSpace(searchModel.StartDateFa) && !string.IsNullOrWhiteSpace(searchModel.EndDateFa)) { var startGr = searchModel.StartDateFa.ToGeorgianDateTime(); var endGr = searchModel.EndDateFa.ToGeorgianDateTime(); query = query.Where(x => x.CreationDate.Date >= startGr.Date && x.CreationDate.Date <= endGr.Date); } else { if (!string.IsNullOrWhiteSpace(searchModel.Year) && !string.IsNullOrWhiteSpace(searchModel.Month)) { var start = searchModel.Year + "/" + searchModel.Month + "/01"; var end = start.FindeEndOfMonth(); var startGr = start.ToGeorgianDateTime(); var endGr = end.ToGeorgianDateTime(); query = query.Where(x => x.CreationDate.Date >= startGr.Date && x.CreationDate.Date <= endGr.Date); } else if (!string.IsNullOrWhiteSpace(searchModel.Year) && string.IsNullOrWhiteSpace(searchModel.Month)) { var start = searchModel.Year + "/01/01"; var findEndOfYear = searchModel.Year + "/12/01"; var end = findEndOfYear.FindeEndOfMonth(); var startGr = start.ToGeorgianDateTime(); var endGr = end.ToGeorgianDateTime(); query = query.Where(x => x.CreationDate.Date >= startGr.Date && x.CreationDate.Date <= endGr.Date); } } #endregion query = query.OrderByDescending(x => x.CreationDate) .ThenByDescending(x => x.CreationDate.Hour).ThenByDescending(x => x.CreationDate.Minute); return query.Skip(searchModel.PageIndex).Take(30).ToList(); } }