Files
TakeoutSaaS.TenantApi/src/Application/TakeoutSaaS.Application/App/Finance/Transactions/Handlers/FinanceTransactionMapping.cs

156 lines
5.9 KiB
C#

using System.Globalization;
using TakeoutSaaS.Application.App.Finance.Transactions.Dto;
using TakeoutSaaS.Domain.Finance.Enums;
using TakeoutSaaS.Domain.Finance.Models;
using TakeoutSaaS.Domain.Orders.Enums;
using TakeoutSaaS.Domain.Payments.Enums;
namespace TakeoutSaaS.Application.App.Finance.Transactions.Handlers;
/// <summary>
/// 交易流水映射与文案转换。
/// </summary>
internal static class FinanceTransactionMapping
{
/// <summary>
/// 生成交易复合标识。
/// </summary>
public static string BuildTransactionId(FinanceTransactionSourceType sourceType, long sourceId)
{
var sourceCode = sourceType switch
{
FinanceTransactionSourceType.PaymentRecord => "payment",
FinanceTransactionSourceType.PaymentRefundRecord => "payment_refund",
FinanceTransactionSourceType.RefundRequest => "refund_request",
FinanceTransactionSourceType.StoredCardRechargeRecord => "stored_card_recharge",
FinanceTransactionSourceType.MemberPointLedger => "member_point",
_ => "unknown"
};
return $"{sourceCode}:{sourceId}";
}
/// <summary>
/// 解析交易类型编码。
/// </summary>
public static string ToTransactionTypeCode(FinanceTransactionType transactionType)
{
return transactionType switch
{
FinanceTransactionType.Income => "income",
FinanceTransactionType.Refund => "refund",
FinanceTransactionType.StoredCardRecharge => "stored_card_recharge",
FinanceTransactionType.PointRedeem => "point_redeem",
_ => "unknown"
};
}
/// <summary>
/// 解析交易类型文案。
/// </summary>
public static string ToTransactionTypeText(FinanceTransactionType transactionType)
{
return transactionType switch
{
FinanceTransactionType.Income => "收入",
FinanceTransactionType.Refund => "退款",
FinanceTransactionType.StoredCardRecharge => "储值充值",
FinanceTransactionType.PointRedeem => "积分抵扣",
_ => "未知"
};
}
/// <summary>
/// 解析渠道文案。
/// </summary>
public static string ToChannelText(DeliveryType? deliveryType)
{
return deliveryType switch
{
DeliveryType.Delivery => "外卖",
DeliveryType.Pickup => "自提",
DeliveryType.DineIn => "堂食",
_ => "—"
};
}
/// <summary>
/// 解析支付方式文案。
/// </summary>
public static string ToPaymentMethodText(PaymentMethod? paymentMethod)
{
return paymentMethod switch
{
PaymentMethod.WeChatPay => "微信",
PaymentMethod.Alipay => "支付宝",
PaymentMethod.Cash => "现金",
PaymentMethod.Card => "刷卡",
PaymentMethod.Balance => "储值余额",
_ => "—"
};
}
/// <summary>
/// 映射列表行。
/// </summary>
public static FinanceTransactionListItemDto ToListItem(FinanceTransactionRecord source)
{
return new FinanceTransactionListItemDto
{
TransactionId = BuildTransactionId(source.SourceType, source.SourceId),
TransactionNo = source.TransactionNo ?? string.Empty,
OrderNo = source.OrderNo,
TransactionType = ToTransactionTypeCode(source.TransactionType),
TransactionTypeText = ToTransactionTypeText(source.TransactionType),
ChannelText = ToChannelText(source.DeliveryType),
PaymentMethodText = ToPaymentMethodText(source.PaymentMethod),
AmountSigned = decimal.Round(source.AmountSigned, 2, MidpointRounding.AwayFromZero),
OccurredAt = source.OccurredAt,
Remark = string.IsNullOrWhiteSpace(source.Remark) ? "—" : source.Remark.Trim(),
IsIncome = source.AmountSigned > 0
};
}
/// <summary>
/// 映射详情。
/// </summary>
public static FinanceTransactionDetailDto ToDetail(FinanceTransactionRecord source)
{
return new FinanceTransactionDetailDto
{
TransactionId = BuildTransactionId(source.SourceType, source.SourceId),
TransactionNo = source.TransactionNo ?? string.Empty,
TransactionType = ToTransactionTypeCode(source.TransactionType),
TransactionTypeText = ToTransactionTypeText(source.TransactionType),
StoreId = source.StoreId,
OrderNo = source.OrderNo,
ChannelText = ToChannelText(source.DeliveryType),
PaymentMethodText = ToPaymentMethodText(source.PaymentMethod),
AmountSigned = decimal.Round(source.AmountSigned, 2, MidpointRounding.AwayFromZero),
OccurredAt = source.OccurredAt,
Remark = string.IsNullOrWhiteSpace(source.Remark) ? "—" : source.Remark.Trim(),
CustomerName = string.IsNullOrWhiteSpace(source.CustomerName) ? "—" : source.CustomerName.Trim(),
CustomerPhone = string.IsNullOrWhiteSpace(source.CustomerPhone) ? "—" : source.CustomerPhone.Trim(),
RefundNo = source.RefundNo,
RefundReason = source.RefundReason,
MemberName = source.MemberName,
MemberMobileMasked = source.MemberMobileMasked,
RechargeAmount = source.RechargeAmount,
GiftAmount = source.GiftAmount,
ArrivedAmount = source.ArrivedAmount,
PointChangeAmount = source.PointChangeAmount,
PointBalanceAfterChange = source.PointBalanceAfterChange
};
}
/// <summary>
/// 导出金额文本。
/// </summary>
public static string FormatAmount(decimal amountSigned)
{
var rounded = decimal.Round(amountSigned, 2, MidpointRounding.AwayFromZero);
var sign = rounded >= 0 ? "+" : string.Empty;
return $"{sign}{rounded.ToString("0.00", CultureInfo.InvariantCulture)}";
}
}