using _0_Framework.Application; using _0_Framework.Exceptions; using _0_Framework.InfraStructure; using Company.Domain.FinancialStatmentAgg; using CompanyManagment.App.Contracts.FinancialStatment; using CompanyManagment.App.Contracts.FinancilTransaction; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AccountManagement.Application.Contracts.SubAccount; using ZstdSharp.Unsafe; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace CompanyManagment.EFCore.Repository; public class FinancialStatmentRepository : RepositoryBase, IFinancialStatmentRepository { private readonly CompanyContext _context; public FinancialStatmentRepository(CompanyContext context) : base(context) { _context = context; } public FinancialStatmentViewModel GetDetailsByContractingPartyId(long contractingPartyId) { var res = _context.FinancialStatments.Include(x => x.FinancialTransactionList) .FirstOrDefault(x => x.ContractingPartyId == contractingPartyId); if (res == null) { return new FinancialStatmentViewModel(); } else { return new FinancialStatmentViewModel() { Id = res.id, ContractingPartyId = res.ContractingPartyId, ContractingPartyName = res.ContractingPartyName, FinancialTransactionViewModels = res.FinancialTransactionList.Select(t => new FinancialTransactionViewModel() { Id = t.id, TdateFa = t.TdateFa, TdateGr = t.TdateGr, Description = t.TypeOfTransaction == "debt" ? "ایجاد درآمد" + " " + t.DescriptionOption + " " + t.Description : "دریافت درآمد" + " " + t.DescriptionOption + " " + t.Description, Deptor = t.Deptor, DeptorString = t.Deptor != 0 ? t.Deptor.ToMoney() : "", Creditor = t.Creditor, CreditorString = t.Creditor != 0 ? t.Creditor.ToMoney() : "", Balance = t.Balance, MessageText = t.MessageText, SentSms = t.SentSms, SentSmsDateFa = t.SentSmsDateFa, FinancialStatementId = t.FinancialStatementId, TypeOfTransaction = t.TypeOfTransaction }).OrderBy(t => t.TdateGr).ToList(), }; } } public List Search(FinancialStatmentSearchModel searchModel) { throw new NotImplementedException(); } public async Task GetClientFinancialStatement(long accountId, FinancialStatementSearchModel searchModel) { bool searched = false; var contractingPartyId = _context.ContractingPartyAccounts.Any(x => x.AccountId == accountId) ? _context.ContractingPartyAccounts.FirstOrDefault(x => x.AccountId == accountId)!.PersonalContractingPartyId : 0; if (contractingPartyId == 0) throw new BadRequestException("طرف حساب مورد نظر یافت نشد"); var resStatement = await _context.FinancialStatments.Include(x=>x.FinancialTransactionList) .FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId); if (resStatement == null) throw new BadRequestException("صورت حساب مالی شخص یافت نشد"); var resTransaction = resStatement.FinancialTransactionList.ToList(); #region Search if (searchModel.FromAmount > 0 || searchModel.ToAmount > 0) { searched = true; if (searchModel.FromAmount > 0 && searchModel.ToAmount > 0) { resTransaction = resTransaction.Where(x => (x.Deptor >= searchModel.FromAmount && x.Deptor <= searchModel.FromAmount) || (x.Creditor >= searchModel.FromAmount && x.Creditor <= searchModel.FromAmount)).ToList(); } else if (searchModel.FromAmount > 0) { resTransaction = resTransaction.Where(x => x.Deptor >= searchModel.FromAmount || x.Creditor >= searchModel.FromAmount).ToList(); } else if (searchModel.ToAmount > 0) { resTransaction = resTransaction.Where(x => x.Deptor <= searchModel.ToAmount || x.Creditor <= searchModel.ToAmount).ToList(); } } if (!string.IsNullOrWhiteSpace(searchModel.FromDate) && !string.IsNullOrWhiteSpace(searchModel.ToDate)) { searched = true; if (searchModel.FromDate.TryToGeorgianDateTime(out var fromDate) == false) throw new BadRequestException("تاریخ وارد شده نامعتبر است"); if (searchModel.FromDate.TryToGeorgianDateTime(out var toDate) == false) throw new BadRequestException("تاریخ وارد شده نامعتبر است"); resTransaction = resTransaction.Where(x => x.TdateGr >= fromDate && x.TdateGr <= toDate).ToList(); } if (searchModel.Type != null) { searched = true; var type = searchModel.Type switch { FinancialTransactionType.Credit => "credit", FinancialTransactionType.Debt => "debt" }; resTransaction = resTransaction.Where(x => x.TypeOfTransaction == type).ToList(); } #endregion double balance = 0; return new ClientFinancialStatementViewModel() { Id = resStatement.id, TotalAmountPayable = resStatement.FinancialTransactionList.Sum(x => x.Deptor) - resStatement.FinancialTransactionList.Sum(x => x.Creditor), TotalCredit = resTransaction.Sum(x => x.Creditor), TotalDebt = resTransaction.Sum(x => x.Deptor), Transactions = resTransaction.OrderBy(t => t.TdateGr).Select(t => { if (!searched) { if (t.TypeOfTransaction == "debt") { balance += t.Deptor; } else { balance -= t.Creditor; } } return new FinancialTransactionDetailViewModel() { DateTimeGr = t.TdateGr, DateFa = t.TdateGr.ToFarsi(), TimeFa = $"{t.TdateGr:HH:mm}", Description = t.DescriptionOption + " " + t.Description, Debtor = t.Deptor, Creditor = t.Creditor, Balance = balance, Type = t.TypeOfTransaction == "debt" ? FinancialTransactionType.Debt : FinancialTransactionType.Credit, TypeStr = t.TypeOfTransaction == "debt" ? "ایجاد درآمد" : "دریافت درآمد", Id = t.id }; }).OrderByDescending(x=>x.DateTimeGr).ToList(), }; } public async Task> GetDetailsByPublicId(string publicId) { var op = new OperationResult(); if(!Guid.TryParse(publicId,out var publicIdGuid)) return op.Failed("شناسه ارسال شده نامعتبر است"); var financialStatement = await _context.FinancialStatments .Include(x=>x.FinancialTransactionList) .FirstOrDefaultAsync(x=>x.PublicId == publicIdGuid ); if (financialStatement == null) { return op.Failed("شناسه ارسال شده نامعتبر است"); } double balance = 0; var res = new ClientFinancialStatementViewModel() { Id = financialStatement.id, TotalAmountPayable = financialStatement.FinancialTransactionList.Sum(x => x.Deptor) - financialStatement.FinancialTransactionList.Sum(x => x.Creditor), TotalCredit = financialStatement.FinancialTransactionList.Sum(x => x.Creditor), TotalDebt = financialStatement.FinancialTransactionList.Sum(x => x.Deptor), ContractingPartyName = financialStatement.ContractingPartyName, Transactions = financialStatement.FinancialTransactionList.Select(t => { if (t.TypeOfTransaction == "debt") { balance += t.Deptor; } else { balance -= t.Creditor; } return new FinancialTransactionDetailViewModel() { DateTimeGr = t.TdateGr, DateFa = t.TdateGr.ToFarsi(), TimeFa = $"{t.TdateGr:HH:mm}", Description = t.DescriptionOption + " " + t.Description, Debtor = t.Deptor, Creditor = t.Creditor, Balance = balance, Type = t.TypeOfTransaction == "debt" ? FinancialTransactionType.Debt : FinancialTransactionType.Credit, TypeStr = t.TypeOfTransaction == "debt" ? "ایجاد درآمد" : "دریافت درآمد" }; }).OrderByDescending(t => t.DateTimeGr).ToList(), }; return op.Succcedded(res); } public async Task GetBalanceAmount(long id) { var financialTransactions = _context.FinancialTransactions.Where(x => x.FinancialStatementId == id); if (!financialTransactions.Any()) throw new BadRequestException("تراکنش مالی یافت نشد"); var totalCredit = await financialTransactions.SumAsync(x => x.Creditor); var totalDebt = await financialTransactions.SumAsync(x => x.Deptor); var balance = totalDebt - totalCredit; var contractingPartyId = await _context.FinancialStatments .Where(x => x.id == id) .Select(x => x.ContractingPartyId) .FirstOrDefaultAsync(); return new GetFinancialStatementBalanceAmount { Amount = balance, ContractingPartyId = contractingPartyId }; } public async Task GetClientDebtAmount(long accountId) { var contractingPartyId = (await _context.ContractingPartyAccounts.FirstOrDefaultAsync(x => x.AccountId == accountId))?.PersonalContractingPartyId ?? 0; var resStatement = await _context.FinancialStatments.Include(x => x.FinancialTransactionList) .FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId); if (resStatement == null) return 0; return resStatement.FinancialTransactionList.Sum(x => x.Deptor) - resStatement.FinancialTransactionList.Sum(x => x.Creditor); } public async Task GetDetailsByContractingParty(long contractingPartyId,FinancialStatementSearchModel searchModel) { var contractingParty = await _context.PersonalContractingParties .FirstOrDefaultAsync(x=>x.id == contractingPartyId); if (contractingParty == null) throw new NotFoundException("طرف حساب یافت نشد"); var financialStatement = await _context.FinancialStatments .Include(x=>x.FinancialTransactionList) .FirstOrDefaultAsync(x=>x.ContractingPartyId == contractingPartyId); if (financialStatement == null) { financialStatement = new FinancialStatment(contractingPartyId,contractingParty.FName+" "+contractingParty.LName); await _context.AddAsync(financialStatement); await _context.SaveChangesAsync(); } bool searched = false; #region Search if (searchModel.FromAmount > 0 || searchModel.ToAmount > 0) { searched = true; if (searchModel.FromAmount > 0 && searchModel.ToAmount > 0) { financialStatement.FinancialTransactionList = financialStatement.FinancialTransactionList.Where(x => (x.Deptor >= searchModel.FromAmount && x.Deptor <= searchModel.FromAmount) || (x.Creditor >= searchModel.FromAmount && x.Creditor <= searchModel.FromAmount)).ToList(); } else if (searchModel.FromAmount > 0) { financialStatement.FinancialTransactionList = financialStatement.FinancialTransactionList.Where(x => x.Deptor >= searchModel.FromAmount || x.Creditor >= searchModel.FromAmount).ToList(); } else if (searchModel.ToAmount > 0) { financialStatement.FinancialTransactionList = financialStatement.FinancialTransactionList.Where(x => x.Deptor <= searchModel.ToAmount || x.Creditor <= searchModel.ToAmount).ToList(); } } if (!string.IsNullOrWhiteSpace(searchModel.FromDate) && !string.IsNullOrWhiteSpace(searchModel.ToDate)) { searched = true; if (searchModel.FromDate.TryToGeorgianDateTime(out var fromDate) == false) throw new BadRequestException("تاریخ وارد شده نامعتبر است"); if (searchModel.FromDate.TryToGeorgianDateTime(out var toDate) == false) throw new BadRequestException("تاریخ وارد شده نامعتبر است"); financialStatement.FinancialTransactionList = financialStatement.FinancialTransactionList.Where(x => x.TdateGr >= fromDate && x.TdateGr <= toDate).ToList(); } if (searchModel.Type != null) { searched = true; var type = searchModel.Type switch { FinancialTransactionType.Credit => "credit", FinancialTransactionType.Debt => "debt" }; financialStatement.FinancialTransactionList = financialStatement.FinancialTransactionList.Where(x => x.TypeOfTransaction == type).ToList(); } #endregion double balance = 0; // var list = financialStatement.FinancialTransactionList.Select(t => // { // if (!searched) // { // if (t.TypeOfTransaction == "debt") // { // balance += t.Deptor; // } // else // { // balance -= t.Creditor; // } // } // return new FinancialTransactionDetailViewModel() // { // Id = t.id, // DateTimeGr = t.TdateGr, // DateFa = t.TdateGr.ToFarsi(), // TimeFa = $"{t.TdateGr:HH:mm}", // Description = t.DescriptionOption + " " + t.Description, // Debtor = t.Deptor, // Creditor = t.Creditor, // Balance = balance, // Type = t.TypeOfTransaction == "debt" // ? FinancialTransactionType.Debt // : FinancialTransactionType.Credit, // TypeStr = t.TypeOfTransaction == "debt" ? "ایجاد درآمد" : "دریافت درآمد" // }; // }).OrderByDescending(t => t.DateTimeGr).ToList(); var list = new List(); foreach (var financialTransaction in financialStatement.FinancialTransactionList.OrderBy(t=>t.TdateGr)) { if (!searched) { if (financialTransaction.TypeOfTransaction == "debt") { balance += financialTransaction.Deptor; } else { balance -= financialTransaction.Creditor; } } var item = new FinancialTransactionDetailViewModel() { Id = financialTransaction.id, DateTimeGr = financialTransaction.TdateGr, DateFa = financialTransaction.TdateGr.ToFarsi(), TimeFa = $"{financialTransaction.TdateGr:HH:mm}", Description = financialTransaction.DescriptionOption + " " + financialTransaction.Description, Debtor = financialTransaction.Deptor, Creditor = financialTransaction.Creditor, Balance = balance, Type = financialTransaction.TypeOfTransaction == "debt" ? FinancialTransactionType.Debt : FinancialTransactionType.Credit, TypeStr = financialTransaction.TypeOfTransaction == "debt" ? "ایجاد درآمد" : "دریافت درآمد" }; list.Add(item); } list.Reverse(); var res = new FinancialStatmentDetailsByContractingPartyViewModel() { Id = financialStatement.id, TotalAmountPayable = financialStatement.FinancialTransactionList.Sum(x => x.Deptor) - financialStatement.FinancialTransactionList.Sum(x => x.Creditor), TotalCredit = financialStatement.FinancialTransactionList.Sum(x => x.Creditor), TotalDebt = financialStatement.FinancialTransactionList.Sum(x => x.Deptor), ContractingPartyName = financialStatement.ContractingPartyName, List = list, }; return res; } public async Task GetByContractingPartyId(long contractingPartyId) { return await _context.FinancialStatments.FirstOrDefaultAsync(x => x.ContractingPartyId == contractingPartyId); } }