namespace Service.Budget;
///
/// 预算明细项计算辅助类
/// 用于计算单个预算项的有效金额(计算用金额)
///
public static class BudgetItemCalculator
{
///
/// 计算预算项的有效金额
///
/// 预算类别(收入/支出)
/// 预算金额
/// 实际金额
/// 是否为硬性消费
/// 是否为归档数据
/// 参考日期
/// 预算周期类型(月度/年度)
/// 有效金额(用于计算的金额)
public static decimal CalculateEffectiveAmount(
BudgetCategory category,
decimal budgetLimit,
decimal actualAmount,
bool isMandatory,
bool isArchived,
DateTime referenceDate,
BudgetPeriodType periodType)
{
// 归档数据直接返回实际值
if (isArchived)
{
return actualAmount;
}
// 收入:实际>0取实际,否则取预算
if (category == BudgetCategory.Income)
{
return actualAmount > 0 ? actualAmount : budgetLimit;
}
// 支出(硬性且实际=0):按天数折算
if (category == BudgetCategory.Expense && isMandatory && actualAmount == 0)
{
return CalculateMandatoryAmount(budgetLimit, referenceDate, periodType);
}
// 支出(普通):取MAX
if (category == BudgetCategory.Expense)
{
return Math.Max(budgetLimit, actualAmount);
}
return budgetLimit;
}
///
/// 计算硬性消费按天数折算的金额
///
private static decimal CalculateMandatoryAmount(
decimal limit,
DateTime date,
BudgetPeriodType periodType)
{
if (periodType == BudgetPeriodType.Month)
{
var daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);
return limit / daysInMonth * date.Day;
}
else // Year
{
var daysInYear = DateTime.IsLeapYear(date.Year) ? 366 : 365;
return limit / daysInYear * date.DayOfYear;
}
}
///
/// 生成计算说明
///
/// 预算类别
/// 预算金额
/// 实际金额
/// 有效金额
/// 是否为硬性消费
/// 是否为归档数据
/// 计算说明文本
public static string GenerateCalculationNote(
BudgetCategory category,
decimal budgetLimit,
decimal actualAmount,
decimal effectiveAmount,
bool isMandatory,
bool isArchived)
{
if (isArchived)
{
return "归档实际";
}
if (category == BudgetCategory.Income)
{
return actualAmount > 0 ? "使用实际" : "使用预算";
}
if (category == BudgetCategory.Expense)
{
if (isMandatory && actualAmount == 0)
{
return "按天折算";
}
if (actualAmount > budgetLimit)
{
return "使用实际(超支)";
}
return effectiveAmount == actualAmount ? "使用实际" : "使用预算";
}
return "使用预算";
}
}