|
|
@@ -1,4 +1,5 @@
|
|
|
using System.Globalization;
|
|
|
+using Common;
|
|
|
using Database.Database;
|
|
|
using Kitty_Fall.Cms.Helpers;
|
|
|
using Kitty_Fall.Cms.Models;
|
|
|
@@ -12,6 +13,8 @@ public class MonthlyRewardPayoutReportController : CmsAuthorizedController
|
|
|
private const int PageSize = 20;
|
|
|
private const decimal DataToMmkRate = 0.665m;
|
|
|
private const decimal LoyaltyToMmkRate = 1.33m;
|
|
|
+ private const string RewardExpenseDescriptionPrefix = "Exchange expense ";
|
|
|
+ private const string RewardExpenseSeparator = " - ";
|
|
|
private readonly ModelContext _db;
|
|
|
|
|
|
public MonthlyRewardPayoutReportController(ModelContext db)
|
|
|
@@ -61,36 +64,59 @@ public class MonthlyRewardPayoutReportController : CmsAuthorizedController
|
|
|
.Distinct()
|
|
|
.ToListAsync();
|
|
|
|
|
|
- var payouts = await _db.GameRewardLogs
|
|
|
+ var chargeLogs = await _db.ChargeLogs
|
|
|
.AsNoTracking()
|
|
|
- .Where(x => x.Status == 2
|
|
|
- && x.CreatedTime >= monthStart
|
|
|
- && x.CreatedTime < monthEnd
|
|
|
- && (x.RewardType == "DATA" || x.RewardType == "LOYALTY"))
|
|
|
- .GroupBy(x => new { PayoutDate = x.CreatedTime.Date, x.RewardType, x.RewardValue, x.RewardUnit })
|
|
|
+ .Where(x => x.Status == CommonConstants.UNCHARGE_STATUS
|
|
|
+ && x.Description != null
|
|
|
+ && x.Description.StartsWith(RewardExpenseDescriptionPrefix)
|
|
|
+ && ((x.ChargeTime.HasValue
|
|
|
+ && x.ChargeTime.Value >= monthStart
|
|
|
+ && x.ChargeTime.Value < monthEnd)
|
|
|
+ || (!x.ChargeTime.HasValue
|
|
|
+ && x.InsertTime.HasValue
|
|
|
+ && x.InsertTime.Value >= monthStart
|
|
|
+ && x.InsertTime.Value < monthEnd)))
|
|
|
.Select(x => new
|
|
|
{
|
|
|
- x.Key.PayoutDate,
|
|
|
- x.Key.RewardType,
|
|
|
- x.Key.RewardValue,
|
|
|
- x.Key.RewardUnit,
|
|
|
- Count = x.Count()
|
|
|
+ PayoutTime = x.ChargeTime ?? x.InsertTime,
|
|
|
+ x.Fee,
|
|
|
+ x.Description
|
|
|
})
|
|
|
.ToListAsync();
|
|
|
|
|
|
- var items = payouts
|
|
|
- .Where(payout => rewardOptions.Any(option =>
|
|
|
- option.RewardType == payout.RewardType
|
|
|
- && option.RewardValue == payout.RewardValue
|
|
|
- && option.RewardUnit == payout.RewardUnit))
|
|
|
- .Select(payout => new MonthlyRewardPayoutItemViewModel
|
|
|
+ var rewardCharges = chargeLogs
|
|
|
+ .Select(x => ParseRewardCharge(x.PayoutTime, x.Fee, x.Description))
|
|
|
+ .Where(x => x != null)
|
|
|
+ .Select(x => x!)
|
|
|
+ .ToList();
|
|
|
+
|
|
|
+ var items = rewardCharges
|
|
|
+ .GroupBy(x => new
|
|
|
+ {
|
|
|
+ PayoutDate = x.PayoutTime.Date,
|
|
|
+ x.RewardType,
|
|
|
+ x.RewardValue
|
|
|
+ })
|
|
|
+ .Select(group =>
|
|
|
{
|
|
|
- PayoutDate = payout.PayoutDate,
|
|
|
- RewardType = payout.RewardType,
|
|
|
- RewardValue = payout.RewardValue,
|
|
|
- RewardUnit = payout.RewardUnit,
|
|
|
- PayoutCount = payout.Count,
|
|
|
- MmkRate = GetMmkRate(payout.RewardType)
|
|
|
+ var rewardUnits = rewardOptions
|
|
|
+ .Where(option => option.RewardType == group.Key.RewardType
|
|
|
+ && option.RewardValue == group.Key.RewardValue)
|
|
|
+ .Select(option => option.RewardUnit)
|
|
|
+ .Where(x => !string.IsNullOrWhiteSpace(x))
|
|
|
+ .Distinct(StringComparer.OrdinalIgnoreCase)
|
|
|
+ .OrderBy(x => x)
|
|
|
+ .ToList();
|
|
|
+
|
|
|
+ return new MonthlyRewardPayoutItemViewModel
|
|
|
+ {
|
|
|
+ PayoutDate = group.Key.PayoutDate,
|
|
|
+ RewardType = group.Key.RewardType,
|
|
|
+ RewardValue = group.Key.RewardValue,
|
|
|
+ RewardUnit = rewardUnits.Count == 0 ? string.Empty : string.Join(" / ", rewardUnits),
|
|
|
+ PayoutCount = group.Count(),
|
|
|
+ MmkRate = GetMmkRate(group.Key.RewardType)
|
|
|
+ };
|
|
|
})
|
|
|
.OrderByDescending(x => x.PayoutDate)
|
|
|
.ThenBy(x => x.RewardType)
|
|
|
@@ -103,7 +129,7 @@ public class MonthlyRewardPayoutReportController : CmsAuthorizedController
|
|
|
if (model.IsMonthlySummary)
|
|
|
{
|
|
|
var monthlyItems = items
|
|
|
- .GroupBy(x => x.RewardType, StringComparer.OrdinalIgnoreCase)
|
|
|
+ .GroupBy(x => new { x.RewardType, x.RewardValue })
|
|
|
.Select(group =>
|
|
|
{
|
|
|
var rewardUnits = group
|
|
|
@@ -116,14 +142,17 @@ public class MonthlyRewardPayoutReportController : CmsAuthorizedController
|
|
|
return new MonthlyRewardPayoutSummaryItemViewModel
|
|
|
{
|
|
|
Month = monthStart,
|
|
|
- RewardType = group.Key,
|
|
|
+ RewardType = group.Key.RewardType,
|
|
|
+ RewardPackage = $"{group.Key.RewardType}_{FormatRewardValue(group.Key.RewardValue)}",
|
|
|
+ RewardValue = group.Key.RewardValue,
|
|
|
RewardUnit = rewardUnits.Count == 0 ? string.Empty : string.Join(" / ", rewardUnits),
|
|
|
PayoutCount = group.Sum(x => x.PayoutCount),
|
|
|
TotalRewardValue = group.Sum(x => x.TotalRewardValue),
|
|
|
- MmkRate = GetMmkRate(group.Key)
|
|
|
+ MmkRate = GetMmkRate(group.Key.RewardType)
|
|
|
};
|
|
|
})
|
|
|
.OrderBy(x => x.RewardType)
|
|
|
+ .ThenBy(x => x.RewardValue)
|
|
|
.ToList();
|
|
|
|
|
|
model.TotalRows = monthlyItems.Count;
|
|
|
@@ -160,4 +189,51 @@ public class MonthlyRewardPayoutReportController : CmsAuthorizedController
|
|
|
? LoyaltyToMmkRate
|
|
|
: 0;
|
|
|
}
|
|
|
+
|
|
|
+ private static string FormatRewardValue(decimal value)
|
|
|
+ {
|
|
|
+ return value % 1 == 0
|
|
|
+ ? value.ToString("0", CultureInfo.InvariantCulture)
|
|
|
+ : value.ToString("0.##", CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static RewardChargeRecord? ParseRewardCharge(
|
|
|
+ DateTime? payoutTime,
|
|
|
+ decimal? fee,
|
|
|
+ string? description)
|
|
|
+ {
|
|
|
+ if (!payoutTime.HasValue || !fee.HasValue || string.IsNullOrWhiteSpace(description)) return null;
|
|
|
+
|
|
|
+ var descriptionText = description.Trim();
|
|
|
+ if (!descriptionText.StartsWith(RewardExpenseDescriptionPrefix, StringComparison.OrdinalIgnoreCase)) return null;
|
|
|
+
|
|
|
+ var separatorIndex = descriptionText.IndexOf(
|
|
|
+ RewardExpenseSeparator,
|
|
|
+ RewardExpenseDescriptionPrefix.Length,
|
|
|
+ StringComparison.Ordinal);
|
|
|
+ if (separatorIndex < 0) return null;
|
|
|
+
|
|
|
+ var rewardType = descriptionText[
|
|
|
+ RewardExpenseDescriptionPrefix.Length..separatorIndex].Trim().ToUpperInvariant();
|
|
|
+ if (rewardType != "DATA" && rewardType != "LOYALTY") return null;
|
|
|
+
|
|
|
+ var rewardPackage = descriptionText[(separatorIndex + RewardExpenseSeparator.Length)..].Trim();
|
|
|
+ if (!rewardPackage.StartsWith($"{rewardType}_", StringComparison.OrdinalIgnoreCase)) return null;
|
|
|
+
|
|
|
+ return new RewardChargeRecord
|
|
|
+ {
|
|
|
+ PayoutTime = payoutTime.Value,
|
|
|
+ RewardType = rewardType,
|
|
|
+ RewardValue = Math.Abs(fee.Value)
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private sealed class RewardChargeRecord
|
|
|
+ {
|
|
|
+ public DateTime PayoutTime { get; init; }
|
|
|
+
|
|
|
+ public string RewardType { get; init; } = string.Empty;
|
|
|
+
|
|
|
+ public decimal RewardValue { get; init; }
|
|
|
+ }
|
|
|
}
|