108 lines
4.5 KiB
C#
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}";
|
|
}
|
|
}
|
|
}
|