using CMSMicroservice.Protobuf.Protos.Commission; namespace FrontOffice.Main.Utilities; /// /// Service for Commission operations /// Connected to FrontOffice.BFF gRPC CommissionCQ /// public class CommissionService { private readonly CommissionContract.CommissionContractClient _client; public CommissionService(CommissionContract.CommissionContractClient client) { _client = client; } /// /// Get week definitions for dropdown /// Maps to: CommissionCQ.GetWeekDefinitions /// public async Task> GetWeekDefinitionsAsync( string? searchText = null, int? gregorianYear = null, int? persianYear = null, bool? isActive = null, int pageSize = 100) { try { var request = new GetWeekDefinitionsRequest { PageNumber = 1, PageSize = pageSize }; if (!string.IsNullOrWhiteSpace(searchText)) request.SearchText = searchText; if (gregorianYear.HasValue) request.GregorianYear = gregorianYear.Value; if (persianYear.HasValue) request.PersianYear = persianYear.Value; if (isActive.HasValue) request.IsActive = isActive.Value; var response = await _client.GetWeekDefinitionsAsync(request); return response.Data.Select(w => new WeekDefinitionDto { Id = w.Id, WeekOrder = w.WeekOrder, DisplayName = w.DisplayName, StartDate = w.StartDate?.ToDateTime() ?? DateTime.MinValue, EndDate = w.EndDate?.ToDateTime() ?? DateTime.MinValue, GregorianYear = w.GregorianYear, PersianYear = w.PersianYear, IsActive = w.IsActive, IsCurrentWeek = w.IsCurrentWeek, StartDatePersian = w.StartDatePersian, EndDatePersian = w.EndDatePersian }).ToList(); } catch { // Return empty list if backend is unavailable return new List(); } } /// /// Get commission payouts with pagination and filters /// Maps to: CommissionCQ.GetMyCommissionPayouts /// public async Task GetMyCommissionPayoutsAsync( long? weekDefinitionId, string? status, int pageNumber, int pageSize) { try { var request = new GetMyCommissionPayoutsRequest { PageNumber = pageNumber, PageSize = pageSize }; if (weekDefinitionId.HasValue) { request.WeekDefinitionId = weekDefinitionId.Value; } // Map status string to int if (!string.IsNullOrEmpty(status)) { request.Status = status switch { "Pending" or "در انتظار" or "Created" or "ایجاد شده" => 0, "Paid" or "پرداخت شده" => 1, "WithdrawalRequested" or "درخواست برداشت" => 2, "Withdrawn" or "برداشت شده" => 3, "PaymentFailed" or "شکست خورده" => 4, "Cancelled" or "لغو شده" => 5, _ => null }; } var response = await _client.GetMyCommissionPayoutsAsync(request); return new CommissionPayoutsResponseDto { Payouts = response.Payouts.Select(p => new CommissionPayoutDto { Id = p.Id, WeekDefinitionId = p.WeekDefinitionId, WeekDisplayName = p.WeekDisplayName, BalancesEarned = p.BalancesEarned, TotalAmount = p.TotalAmount, AmountFormatted = p.AmountFormatted, Status = p.Status, DatePersian = p.DatePersian }).ToList(), TotalCount = (int)(response.MetaData?.TotalCount ?? 0), PageNumber = pageNumber, PageSize = pageSize }; } catch { // Return empty response if backend is unavailable return new CommissionPayoutsResponseDto { Payouts = new List(), TotalCount = 0, PageNumber = pageNumber, PageSize = pageSize }; } } /// /// Get weekly balance details for a specific week /// Maps to: CommissionCQ.GetMyWeeklyBalances /// public async Task GetMyWeeklyBalanceAsync(long? weekDefinitionId = null) { try { var request = new GetMyWeeklyBalancesRequest { PageNumber = 1, PageSize = 1, OnlyActive = false }; if (weekDefinitionId.HasValue) { request.WeekDefinitionId = weekDefinitionId.Value; }else { request.WeekDefinitionId=7; } var response = await _client.GetMyWeeklyBalancesAsync(request); if (response.Balances.Count > 0) { var balance = response.Balances[0]; return new WeeklyBalanceDto { WeekDefinitionId = balance.WeekDefinitionId, WeekDisplayName = balance.WeekDisplayName, LeftBalance = balance.LeftLegBalances, RightBalance = balance.RightLegBalances, MinBalance = Math.Min(balance.LeftLegBalances, balance.RightLegBalances), BalanceCount = balance.TotalBalances, CalculatedCommission = balance.WeeklyPoolContribution, LeftCarryover = balance.LeftLegCarryover, RightCarryover = balance.RightLegCarryover, LeftNewMembers = balance.LeftLegNewMembers, RightNewMembers = balance.RightLegNewMembers, StartDate = balance.CalculatedAt?.ToDateTime().AddDays(-7) ?? DateTime.Now.AddDays(-7), EndDate = balance.CalculatedAt?.ToDateTime() ?? DateTime.Now }; } return CreateEmptyWeeklyBalance(); } catch { return CreateEmptyWeeklyBalance(); } } #region Helper Methods /// /// Get payouts that are eligible for withdrawal (all statuses except Withdrawn=3) /// public async Task> GetWithdrawablePayoutsAsync() { try { // Get all payouts that are not yet withdrawn // We'll get all and filter out Withdrawn (status=3) on client side var request = new GetMyCommissionPayoutsRequest { PageNumber = 1, PageSize = 100 // No status filter - get all }; var response = await _client.GetMyCommissionPayoutsAsync(request); // Filter: exclude already withdrawn (status=3) and withdrawal requested (status=2) return response.Payouts .Where(p => p.Status != 2 && p.Status != 3) .Select(p => new CommissionPayoutDto { Id = p.Id, WeekDefinitionId = p.WeekDefinitionId, WeekDisplayName = p.WeekDisplayName, BalancesEarned = p.BalancesEarned, TotalAmount = p.TotalAmount, AmountFormatted = p.AmountFormatted, Status = p.Status, DatePersian = p.DatePersian }).ToList(); } catch { return new List(); } } private static WeeklyBalanceDto CreateEmptyWeeklyBalance() { return new WeeklyBalanceDto { WeekDefinitionId = 0, WeekDisplayName = string.Empty, LeftBalance = 0, RightBalance = 0, MinBalance = 0, BalanceCount = 0, CalculatedCommission = 0, LeftCarryover = 0, RightCarryover = 0, StartDate = DateTime.MinValue, EndDate = DateTime.MinValue }; } #endregion }