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
}