Files
zszq-trs/YLErpDAL/Modules/ReportModule/SettlementMailTemplateHelper.cs
T

108 lines
4.5 KiB
C#

using System.Globalization;
using Microsoft.EntityFrameworkCore;
using YLErp.BLL;
using YLErp.Modules.AppModule;
namespace YLErp.Modules.ReportModule
{
/// <summary>
/// 为结算确认书邮件准备交易编号和平仓总额模板变量。
/// </summary>
public static class SettlementMailTemplateHelper
{
/// <summary>
/// 根据当前客户的确认书反查对应交易和平仓记录。
/// 文档编号可能在不同文档类型中重复,因此必须同时匹配编号和类型。
/// </summary>
public static List<Datas> GetSettlementRows(YLContext dbContext, IEnumerable<trade_contract_document> documents, int clientId)
{
var documentKeys = documents
.Where(document => !string.IsNullOrWhiteSpace(document.Code))
.Select(document => BuildDocumentKey(document.Code, document.Type))
.Distinct()
.ToHashSet();
if (documentKeys.Count == 0)
{
return new List<Datas>();
}
var contractCodes = documents.Select(document => document.Code).Distinct().ToList();
var rows = (from relation in dbContext.trade_contract_r
join tradeCash in dbContext.trade_cash on relation.TradeCashId equals tradeCash.id
join tradeData in dbContext.trade on tradeCash.TradeId equals tradeData.id
where contractCodes.Contains(relation.ContractCode)
&& relation.IsValid
&& !tradeCash.IsDeleted
&& tradeData.ClientId == clientId
select new
{
relation.ContractCode,
relation.Type,
Trade = tradeData,
TradeCash = tradeCash
}).AsNoTracking().ToList();
return rows
// 数据库先按编号缩小范围,再在内存中用“编号+类型”精确匹配附件。
.Where(row => documentKeys.Contains(BuildDocumentKey(row.ContractCode, row.Type)))
.Select(row => new Datas
{
trade = row.Trade,
tradecash = row.TradeCash
}).ToList();
}
/// <summary>
/// 将批量加载的数据限制到当前结算日,避免跨日发送时变量汇总串日。
/// </summary>
public static List<Datas> ForValueDate(IEnumerable<Datas> rows, DateTime valueDate)
{
return (rows ?? Enumerable.Empty<Datas>())
.Where(row => row?.tradecash != null && row.tradecash.ValueDate.Date == valueDate.Date)
.ToList();
}
/// <summary>
/// 将去重后的交易编号及客户视角平仓总额写入邮件模板参数。
/// </summary>
public static void PopulateSettlementFields(MailInfoRequestModel request, IEnumerable<Datas> rows)
{
ArgumentNullException.ThrowIfNull(request);
// 同一平仓记录可能因关联多份文档重复出现,按 trade_cash.id 去重以避免重复计入金额。
var distinctRows = (rows ?? Enumerable.Empty<Datas>())
.Where(row => row?.trade != null && row.tradecash != null)
.GroupBy(row => row.tradecash.id)
.Select(group => group.First())
.ToList();
request.TradeNumber = string.Join(",", distinctRows
.Select(row => row.trade.TradeNumber)
.Where(number => !string.IsNullOrWhiteSpace(number))
.Distinct()
.OrderBy(number => number));
if (distinctRows.Count == 0)
{
request.UnwindTotalAmount = string.Empty;
return;
}
// trade_cash.Amount 为交易员视角,邮件展示需取反转换为客户视角。
var customerAmount = -distinctRows.Sum(row => row.tradecash.Amount);
if (customerAmount == 0)
{
// 消除浮点求和可能产生的 -0.00。
customerAmount = 0;
}
request.UnwindTotalAmount = customerAmount.ToString("F2", CultureInfo.InvariantCulture);
}
private static string BuildDocumentKey(string code, string type)
{
return $"{code}\u001f{type}";
}
}
}