using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using _0_Framework.Application; using _0_Framework.InfraStructure; using Company.Domain.ContractingPartyBankAccountsAgg; using Company.Domain.PaymentTransactionAgg; using CompanyManagment.App.Contracts.PaymentTransaction; using Microsoft.EntityFrameworkCore; namespace CompanyManagment.EFCore.Repository; public class PaymentTransactionRepository : RepositoryBase, IPaymentTransactionRepository { private readonly CompanyContext _companyContext; public PaymentTransactionRepository(CompanyContext companyContext) : base(companyContext) { _companyContext = companyContext; } public async Task> GetPaymentTransactionList(GetPaymentTransactionListSearchModel searchModel) { var query = _companyContext.PaymentTransactions.AsQueryable(); if (searchModel.ContractingPartyId > 0) { query = query.Where(x => x.ContractingPartyId == searchModel.ContractingPartyId); } if (!string.IsNullOrWhiteSpace(searchModel.FromDate) && !string.IsNullOrWhiteSpace(searchModel.ToDate)) { searchModel.FromDate.TryToGeorgianDateTime(out var fromDateGr); searchModel.ToDate.TryToGeorgianDateTime(out var toDateGr); query = query.Where(x => x.TransactionDate >= fromDateGr && x.TransactionDate <= toDateGr); } if (searchModel.FromAmount > 0 || searchModel.ToAmount > 0) { if (searchModel.FromAmount > 0 && searchModel.ToAmount > 0) { query = query.Where(x => x.Amount >= searchModel.FromAmount && x.Amount <= searchModel.ToAmount); } else if (searchModel.FromAmount > 0) { query = query.Where(x => x.Amount >= searchModel.FromAmount); } else if (searchModel.ToAmount > 0) { query = query.Where(x => x.Amount <= searchModel.ToAmount); } } if (searchModel.StatusEnum != null) { query = query.Where(x => x.Status == searchModel.StatusEnum); } // 1. گرفتن تراکنش‌ها var paymentTransactionsData = await query.OrderByDescending(x => x.CreationDate) .AsNoTracking() .Skip(searchModel.PageIndex) .Take(30) .ToListAsync(); // 2. استخراج prefix و suffix از کارت‌های ماسک‌شده var maskedCardInfos = paymentTransactionsData.Where(x=>x.CardNumber!=null) .Select(x => new { MaskedCard = x.CardNumber, Prefix = x.CardNumber.Substring(0, 4), Suffix = x.CardNumber.Substring(x.CardNumber.Length - 4) }) .Distinct() .ToList(); // 3. گرفتن شماره کارت‌های واقعی var matchedBankAccounts = (await _companyContext.ContractingPartyBankAccounts.Where(x=>x.CardNumber!= null) .ToListAsync()).Where(account => maskedCardInfos.Any(mask => account.CardNumber.StartsWith(mask.Prefix) && account.CardNumber.EndsWith(mask.Suffix) )); // 4. ساختن خروجی var result = paymentTransactionsData .Select(x => { var prefix = x.CardNumber?.Substring(0, 4); var suffix = x.CardNumber?.Substring(x.CardNumber.Length - 4); // پیدا کردن شماره کارت کامل و اطلاعات بانک و صاحب حساب ContractingPartyBankAccount matchedAccount = null; if (prefix != null && suffix != null) { matchedAccount = matchedBankAccounts .FirstOrDefault(account => account.CardNumber.StartsWith(prefix) && account.CardNumber.EndsWith(suffix)); } return new GetPaymentTransactionListViewModel { Id = x.id, ContractingPartyName = x.ContractingPartyName, BankName = x.BankName, CardNumber = matchedAccount?.CardNumber ?? x.CardNumber, Status = x.Status switch { PaymentTransactionStatus.Failed => "ناموفق", PaymentTransactionStatus.Success => "موفق", _ => "نامشخص" }, StatusEnum = x.Status, Amount = x.Amount, TransactionId = x.TransactionId, PaymentDate = x.TransactionDate.ToFarsi(), PaymentTime = $"{x.TransactionDate:HH:mm}" }; }) .ToList(); return result; } public async Task GetDetails(long id) { var transaction = await _companyContext.PaymentTransactions.FirstOrDefaultAsync(x => x.id == id); if (transaction == null) return null; var result = new PaymentTransactionDetailsViewModel() { Id = transaction.id, Amount = transaction.Amount, CallBackUrl = transaction.CallBackUrl, ContractingPartyId = transaction.ContractingPartyId, CardNumber = transaction.CardNumber, TransactionId = transaction.TransactionId, Status = transaction.Status, ContractingPartyName = transaction.ContractingPartyName, BankName = transaction.BankName, TransactionDate = transaction.TransactionDate }; return result; } }