Files
zszq-trs/YLErpDAL/BLL/GenerateDocument/BaseGenerate.cs
T

377 lines
14 KiB
C#

using YLErp.Commons;
using YLErp.DBModels.Consts;
using YLErp.Model;
using YLErp.Modules;
using YLErp.Modules.TradeModule;
using YLErp.MsOffice;
using YLErp.Office.Converters;
namespace YLErp.BLL.GenerateDocument
{
public abstract class BaseGenerate
{
protected YLContext db = new();
protected BaseGenerate() { }
protected BaseGenerate(trade_contract_group tradeContractGroup, string docType, int optId, string optName)
{
InitContractDataSet(tradeContractGroup);
DocType = docType;
OptId = optId;
OptName = optName;
}
public string DocType { get; set; }
public int OptId { get; set; }
public string OptName { get; set; }
protected virtual string ContractType { get; }
protected string ContractFileDirectory => Path.Combine(OtcAppContext.AppDocsPath, @"contractdoc\");
public virtual string TemplateDirectory => Path.Combine(ContractFileDirectory, @"template\");
public virtual string TemplateFile { get; }
protected ContractDataSet CurrentContractDataSet;
public virtual string OutputFileDirectory => Path.Combine(ContractFileDirectory, @"output\");
public virtual string ContractNOSeed => "";
protected virtual Func<trade_contract_group, bool> FuncAfterGenerated => null;
protected OptUserInfo GetOptUser()
{
return new OptUserInfo(OptId, OptName, OptUserFrom.System);
}
private string GetClientBuySell(string BuySell)
{
if ("卖出".Equals(BuySell))
{
BuySell = "买入";
}
else
{
BuySell = "卖出";
}
return BuySell;
}
public virtual ReturnInfo<Dictionary<string, string>> GetDictionary()
{
var tradeContractGroup = CurrentContractDataSet.ContractGroup;
var dic = CurrentContractDataSet.ModelDic;
var trade = tradeContractGroup.trade;
var isGJBuyer = trade.BuySell == "买入";
var client = CurrentContractDataSet.Client;
var underlying = CurrentContractDataSet.Underlying;
#region 客户信息
dic["{{乙方名称}}"] = client.Name;
dic["{{客户名称}}"] = client.Name;
#endregion
dic["{{交易编号}}"] = trade.TradeNumber;
dic["{{交易方向}}"] = $"贵司{GetClientBuySell(trade.BuySell)}";
if (isGJBuyer)
{
dic["{{甲方方向}}"] = "买方";
dic["{{乙方方向}}"] = "卖方";
}
else
{
dic["{{甲方方向}}"] = "卖方";
dic["{{乙方方向}}"] = "买方";
}
dic["{{交易日}}"] = trade.TradeDate?.ToString("yyyy年M月d日");
if (trade.TradeType == "香草期权" || trade.TradeType == "亚式期权")
{
dic["{{生效日}}"] = trade.TradeDate?.ToString("yyyy年M月d日");
}
else
{
dic["{{生效日}}"] = trade.StartDate?.ToString("yyyy年M月d日");
}
if (trade.TradeType == "亚式期权")
{
dic["{{均价起算日}}"] = trade.trade_asian_option.AveragingPeriodStartDate?.ToString("yyyy年M月d日");
dic["{{奇异结构}}"] = $"{trade.trade_asian_option.StrikeTypeCn}的{trade.trade_asian_option.PayoffTypeCn}亚式";
}
dic["{{到期日}}"] = trade.ExerciseDate?.ToString("yyyy年M月d日");
dic["{{行权日}}"] = "到期日";
dic["{{自动行权}}"] = "到期实值自动行权";
var strUnit = underlying.TradeUnitString;
var notional = trade.Notional;
#region 标的信息
dic["{{报价单位}}"] = strUnit;
dic["{{商品标的数量}}"] = $"{notional}{strUnit}";
dic["{{商品标的交易所}}"] = underlying.MarketName;
if (trade.TradeType == "合成价差期权")
{
dic["{{商品标的名称}}"] = synthetic_underlyingBLL.GetUnderlyingTipsInfo(trade.UnderlyingCode);
}
else
{
dic["{{商品标的名称}}"] = trade.UnderlyingCode;
}
#endregion
//价格
if (trade.ActualStrike != null)
{
dic["{{执行价格}}"] = $"{trade.ActualStrike:f2}元/{strUnit}";
}
else
{
dic["{{执行价格}}"] = "不适用";
}
if (trade.SpotPrice != null)
{
dic["{{期初价格}}"] = $"{trade.SpotPrice:f2}元/{strUnit}";
}
var tradeType = trade.TradeType == "香草期权" ? "普通" : (trade.TradeType == "结构化交易" ? trade.StructureType : trade.TradeType.Replace("期权", ""));
dic["{{期权类型}}"] = $"{trade.ExerciseModeCn}{tradeType}{trade.OptionType}期权";
dic["{{期权费}}"] = $"{trade.TradePrice ?? 0:f3}元";
dic["{{期权价格}}"] = $"{trade.TradeSinglePrice ?? 0:f3}元/{strUnit}";
dic["{{支付时间}}"] = trade.PremiumPayDate != null ? "提前终止/到期时支付" : "已支付";
dic["{{结算方式}}"] = "人民币现金结算";
dic["{{补充}}"] = "补充";
return Return.Success(dic);
}
public virtual ReturnInfo<Dictionary<string, string>> AppendDictionary()
{
return Return.Success(new Dictionary<string, string>());
}
protected virtual string GetContractIndex(trade_contract_group tradeContractGroup)
{
return "";
}
protected virtual string GetContractNO(trade_contract_group tradeContractGroup, string contractIndex)
{
return "";
}
protected virtual string GetOutputFileName(trade_contract_group tradeContractGroup, string contractIndex)
{
return "";
}
protected virtual ReturnInfo InitContractDataSet(trade_contract_group tradeContractGroup)
{
CurrentContractDataSet = new ContractDataSet
{
ContractGroup = tradeContractGroup,
ModelDic = new Dictionary<string, string>()
};
var trade = tradeContractGroup.trade;
tradeBLL.SetFieldsByTradeType(trade);
#region 标的
var underlying = CurrentContractDataSet.Underlying;
underlying ??= db.underlying_manager.AsNoTracking().FirstOrDefault(x => x.UnderlyingCode == trade.UnderlyingCode);
if (underlying == null)
{
return Return.Fail($"标的资产{trade.UnderlyingCode}信息未找到");
}
CurrentContractDataSet.Underlying = underlying;
#endregion
#region 客户
using (var db2 = DbContextFactory.GetClientDbContext(null))
{
var client = CurrentContractDataSet.Client;
client ??= db2.client.AsNoTracking().FirstOrDefault(c => c.id == trade.ClientId);
if (client == null)
{
return Return.Fail($"客户{trade.ClientName}信息未找到");
}
CurrentContractDataSet.Client = client;
var clientContactDuty = db2.clientduty.AsNoTracking().OrderBy(x => x.id).FirstOrDefault(x => x.ApprovalOrder < 1 && x.ClientId == client.id && x.ContactTypeId.Contains("1"));
clientContactDuty ??= db2.clientduty.AsNoTracking().OrderBy(x => x.id).FirstOrDefault(x => x.ApprovalOrder < 1 && x.ClientId == client.id && x.ContactTypeId.Contains("2"));
CurrentContractDataSet.ClientDuty = clientContactDuty;
}
#endregion
#region 标的品种
var variety = CurrentContractDataSet.Variety;
variety ??= db.variety.AsNoTracking().FirstOrDefault(x => x.id == underlying.UnderlyingTypeId);
if (variety == null)
{
return Return.Fail($"标的{underlying.UnderlyingCode}对应的品种信息未找到");
}
CurrentContractDataSet.Variety = variety;
#endregion
return Return.Success();
}
private ReturnInfo GenerateDoc(Dictionary<string, object> dic, string outPutFileName)
{
var templateFullPath = Path.Combine(TemplateDirectory, TemplateFile);
if (DocType != FileTypeEnum.Word && DocType != FileTypeEnum.Pdf)
{
return Return.Fail($"{DocType}文档类型暂时不支持");
}
MsWordTempalteHelper.GenerateFromTemplate(templateFullPath, dic, outPutFileName);
return Return.Success();
}
public virtual ReturnInfo<string> GenerateBook()
{
var contractGroup = CurrentContractDataSet.ContractGroup;
var trade = contractGroup.trade;
var needAddData = true;
#region 如果之前确认书已经生成过,则直接返回
var contractBLL = new TradeContractBLL(OptId, OptName);
var confirmDoc = contractBLL.GetContractDoc(trade.id, ContractType);
if (confirmDoc != null)
{
if (File.Exists(confirmDoc.AbsolutePath))
{
if (DocType == "PDF")
{
var pdfPath = confirmDoc.AbsolutePath.Replace(".docx", ".pdf");
if (!File.Exists(pdfPath))
{
OfficeFileConverter.ConvertDocxToPDF(confirmDoc.AbsolutePath, pdfPath);
}
return Return.Success<string>(confirmDoc.RelativePath.Replace(".docx", ".pdf"));
}
return Return.Success<string>(confirmDoc.RelativePath);
}
else
{
needAddData = false;
}
}
#endregion
//合同编号
string contractNo;
string outPutFileName;
if (confirmDoc != null)
{
contractNo = confirmDoc.Code;
outPutFileName = confirmDoc.FileName.Replace(".docx", $".{DocType.ToLower()}");
}
else
{
var contractIndex = GetContractIndex(contractGroup);
contractNo = GetContractNO(contractGroup, contractIndex);
outPutFileName = GetOutputFileName(contractGroup, contractIndex);
}
var dicReturnInfo = GetDictionary();
if (!dicReturnInfo.Success)
{
return Return.Fail<string>(dicReturnInfo.Msg);
}
dicReturnInfo = AppendDictionary();
if (!dicReturnInfo.Success)
{
return Return.Fail<string>(dicReturnInfo.Msg);
}
var dic = dicReturnInfo.Content.ToDictionary(K => K.Key, V => (object)V.Value);
dic["{{合同编号}}"] = contractNo;
var outPutFilePath = Path.Combine(OutputFileDirectory, outPutFileName);
var returnInfo = GenerateDoc(dic, outPutFilePath);
if (!returnInfo.Success)
{
return Return.Fail<string>(returnInfo.Msg);
}
//更新操作时间
var now = DateTime.Now;
File.SetLastAccessTime(outPutFilePath, now);
if (needAddData)
{
confirmDoc = SaveData(contractGroup, outPutFileName, contractNo);
}
FuncAfterGenerated?.Invoke(contractGroup);
return Return.Success<string>(confirmDoc.RelativePath.Replace(".docx", $".{DocType.ToLower()}"));
}
public trade_contract_document SaveData(trade_contract_group contractGroup, string outPutFileName, string contractCode)
{
var trade = contractGroup.trade;
var isGJBuyer = trade.BuySell == "买入";
var savedOutputFileName = outPutFileName.Replace(".pdf", ".docx");
var nowDate = DateTime.Now;
var cd = new trade_contract_document();
db.trade_contract_document.Add(cd);
cd.Code = contractCode;
cd.ValueDate = valuedateBLL.ValueDate;
cd.BuyerId = isGJBuyer ? 0 : trade.ClientId;
cd.BuyerName = isGJBuyer ? (PS.Config.CompanyName ?? "") : trade.ClientName;
cd.SellerId = isGJBuyer ? trade.ClientId : 0;
cd.SellerName = isGJBuyer ? trade.ClientName : (PS.Config.CompanyName ?? "");
cd.FileType = FileTypeEnum.Word;
cd.Status = ContractStatusEnum.Draft;
cd.SourceType = 1; // 系统生成
cd.Paths = $"App_Docs\\contractdoc\\output\\{savedOutputFileName}";
cd.FileName = savedOutputFileName;
cd.Type = ContractType;
cd.OptId = OptId;
cd.OptName = OptName;
cd.OptDate = nowDate;
var cr = new trade_contract_r();
db.trade_contract_r.Add(cr);
cr.TradeId = trade.id;
cr.TradeNumber = trade.TradeNumber;
cr.ContractCode = cd.Code;
cr.Type = ContractType;
cr.OptId = OptId;
cr.OptName = OptName;
cr.OptDate = nowDate;
cr.TradeCashId = contractGroup.trade_cash.id;
cr.IsValid = true;
var table = db.GetTableName<trade_contract_r>();
var sql = $@"update {table} set {nameof(cr.TradeId)}=-{nameof(cr.TradeId)} where
{nameof(cr.TradeId)}={cr.TradeId} and {nameof(cr.Type)}='{cr.Type}'";
db.Database.ExecuteSqlRaw(sql);
db.SaveChanges();
return cd;
}
}
}