| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Text.Json;
- using System.Text.Json.Serialization;
- using System.Drawing.Text;
- using System.IO;
- using static ddq.Utility;
- using static ddq.DataAccess;
- using System.Diagnostics.Eventing.Reader;
- using System.Diagnostics.Metrics;
- using Org.BouncyCastle.Bcpg.OpenPgp;
- namespace ddq
- {
- public partial class FundQ : Form
- {
- private string fundId;
- private string companyId;
- private int userId;
- private DataTable fundInfoTable;
- public FundQ(string fundId, string companyId, int userId)
- {
- InitializeComponent();
- this.fundId = fundId;
- this.companyId = companyId;
- this.userId = userId;
- InitializeData();
-
- }
- private void InitializeData()
- {
- DataTable dt = DataAccess.Get_fund_info(fundId, null);
- if (dt == null || dt.Rows.Count <= 0) return;
- this.lblFundName.Text = dt.Rows[0].Field<string>("fund_short_name");
- //this.lblMainCode.Text = "Code: " + dt.Rows[0].Field<string>("register_number");
- this.lblMainCode.Text = "Code: " + fundId;
- this.lblCategory.Text = "Category: " + dt.Rows[0].Field<string>("strategy");
- this.lblInceptionDate.Text = "Launched: " + dt.Rows[0].Field<DateTime?>("inception_date")?.ToString("yyyy-MM-dd");
- this.lblDomicile.Text = "Domicile: ";
- fundInfoTable = DataAccess.Get_dd_fund_info(fundId, null, 1);
- if (fundInfoTable != null && fundInfoTable.Rows.Count > 0)
- {
- string jsonString = fundInfoTable.Rows[0].Field<string>("info").Trim();
- JsonDocument document = JsonDocument.Parse(jsonString);
- JsonElement root = document.RootElement;
- if (root.ValueKind != JsonValueKind.Undefined)
- {
- //
- // General Info
- //
- LoadTextDataFromJson(this.txtInvestmentObjective, root, "investmentObjective", this.tspInvestmentObjective);
-
- LoadTextDataFromJson(this.txtBenchmark, root, "benchmark", this.tspBenchmark);
-
- LoadTextDataFromJson(this.txtInvestmentPhilosophy, root, "investmentPhilosophy", this.tspInvestmentPhilosophy);
- LoadCurrentFees(root);
- LoadTextDataFromJson(this.txtPolicyOfClosingFund, root, "policyOfClosingFund", this.tspPolicyOfClosingFund);
- LoadPortfolioManager(root);
- LoadTER(root);
- //
- // Process
- //
- LoadDerivates(root);
- LoadPriceTarget(root);
- }
- }
- }
- private void LoadPortfolioManager(JsonElement jsonElement)
- {
- bool hasData = jsonElement.TryGetProperty("portfolioManagers", out JsonElement element);
- string strUpdateTime = "";
- DataTable dt = new DataTable();
- if (hasData == true && element.ValueKind == JsonValueKind.Object)
- {
- hasData &= element.TryGetProperty("v", out JsonElement elm);
- Utility.DDData dddata = Utility.Json2Table2(element);
- if (dddata != null)
- {
- dt = (DataTable)dddata.Value;
- strUpdateTime = dddata.UpdateTime;
- }
- }
- else
- {
- // 没有基金经理数据时,初始化表
- dt.Columns.Add("personnel_id", typeof(string));
- dt.Columns.Add("name", typeof(string));
- dt.Columns.Add("startDate", typeof(DateTime));
- dt.Columns.Add("endDate", typeof(DateTime));
- }
- InitPortfolioManagerGrid(dt, strUpdateTime);
- }
- private void InitPortfolioManagerGrid(DataTable dt, string updateTime)
- {
- if (dt == null && updateTime == null) return;
- this.grdPortfolioManager.DataSource = dt;
- this.grdPortfolioManager.Columns["personnel_id"].Visible = false;
- this.grdPortfolioManager.Columns["name"].HeaderText = "Manager Name";
- this.grdPortfolioManager.Columns["name"].DisplayIndex = 0;
- this.grdPortfolioManager.Columns["startDate"].HeaderText = "Start Date";
- this.grdPortfolioManager.Columns["startDate"].DefaultCellStyle.Format = "yyyy-MM-dd";
- this.grdPortfolioManager.Columns["startDate"].DisplayIndex = 1;
- this.grdPortfolioManager.Columns["endDate"].HeaderText = "End Date";
- this.grdPortfolioManager.Columns["endDate"].DefaultCellStyle.Format = "yyyy-MM-dd";
- this.grdPortfolioManager.Columns["endDate"].DisplayIndex = 2;
- this.tspPortfolioManager.Text = updateTime;
- this.tspPortfolioManager.ForeColor = IsChangedRecently(this.tspPortfolioManager.Text) ? COLOR_MODIFIED : COLOR_NORMAL;
- }
- private void LoadCurrentFees(JsonElement jsonElement)
- {
- if (jsonElement.ValueKind != JsonValueKind.Object) return;
- bool hasData = jsonElement.TryGetProperty("currentFees", out JsonElement element);
- if (hasData)
- {
- if (element.ValueKind == JsonValueKind.Object)
- {
- hasData = element.TryGetProperty("v", out JsonElement elm);
- if (hasData)
- {
- this.txtManagementFee.Text = Json2Text(elm, "managementFee");
- this.txtSubscriptionFee.Text = Json2Text(elm, "subscriptionFee");
- this.txtRedemptionFee.Text = Json2Text(elm, "redemptionFee");
- this.txtAdministrationFee.Text = Json2Text(elm, "administrationFee");
- this.txtSwitchingFee.Text = Json2Text(elm, "switchingFee");
- this.txtTrusteeFee.Text = Json2Text(elm, "trusteeFee");
- this.txtPerformanceFee.Text = Json2Text(elm, "performanceFee");
- this.tspCurrentFee.Text = element.GetProperty("t").ToString();
- this.tspCurrentFee.ForeColor = IsChangedRecently(this.tspCurrentFee.Text) ? COLOR_MODIFIED : COLOR_NORMAL;
- }
- }
- }
- }
- private void LoadTER(JsonElement jsonElement)
- {
- bool hasData = jsonElement.TryGetProperty("totalExpenseRatio", out JsonElement element);
- string strUpdateTime = "";
- DataTable dt = new DataTable();
- if (hasData == true && element.ValueKind == JsonValueKind.Object)
- {
- hasData &= element.TryGetProperty("v", out JsonElement elm);
- Utility.DDData dddata = Utility.Json2Table2(element);
- if (dddata != null)
- {
- dt = (DataTable)dddata.Value;
- strUpdateTime = dddata.UpdateTime;
- }
- }
- else
- {
- dt.Columns.Add("year", typeof(string));
- dt.Columns.Add("ter", typeof(string));
- int year = DateTime.Today.Year - 1;
- for (int i = 0; i < 5; i++)
- {
- DataRow row = dt.NewRow();
- row["year"] = year - i;
- dt.Rows.Add(row);
- }
- }
- InitTERGrid(dt, strUpdateTime);
- }
- private void InitTERGrid(DataTable dt, string updateTime)
- {
- if (dt == null || updateTime == null) return;
- this.grdTER.DataSource = dt;
- this.grdTER.Columns["year"].HeaderText = "Year";
- this.grdTER.Columns["year"].ReadOnly = true;
- this.grdTER.Columns["year"].DisplayIndex = 0;
- this.grdTER.Columns["ter"].HeaderText = "Total Expense Ratio %";
- this.grdTER.Columns["ter"].ValueType = typeof(decimal);
- this.grdTER.Columns["ter"].DefaultCellStyle.Format = "N3";
- this.grdTER.Columns["ter"].DisplayIndex = 1;
- this.tspTER.Text = updateTime;
- this.tspTER.ForeColor = Utility.IsChangedRecently(updateTime) ? COLOR_MODIFIED : COLOR_NORMAL;
- }
- private void LoadDerivates(JsonElement jsonElement)
- {
- if (jsonElement.ValueKind != JsonValueKind.Object) return;
- bool hasData = jsonElement.TryGetProperty("derivatives", out JsonElement element);
- if (hasData)
- {
- if (element.ValueKind == JsonValueKind.Object)
- {
- hasData = element.TryGetProperty("v", out JsonElement elm);
- if (hasData)
- {
- this.chkAllowDerivatives.Checked = Json2Boolean(elm, "allowed");
- this.chkUseDerivatives.Checked = Json2Boolean(elm, "currentUse");
- this.chkDerivativesForEfficent.Checked = Json2Boolean(elm, "effectiveManagement");
- this.chkDerivatesForHedging.Checked = Json2Boolean(elm, "hedging");
- this.chkDerivativesForMarket.Checked = Json2Boolean(elm, "marketAccess");
- this.chkDerivatesForLeverage.Checked = Json2Boolean(elm, "leverage");
- this.tspDerivatives.Text = element.GetProperty("t").ToString();
- this.tspDerivatives.ForeColor = IsChangedRecently(this.tspDerivatives.Text) ? COLOR_MODIFIED : COLOR_NORMAL;
- }
- }
- }
- }
- private void LoadPriceTarget(JsonElement jsonElement)
- {
- if (jsonElement.ValueKind != JsonValueKind.Object) return;
- bool hasData = jsonElement.TryGetProperty("priceTarget", out JsonElement element);
- if (hasData)
- {
- if (element.ValueKind == JsonValueKind.Object)
- {
- hasData = element.TryGetProperty("v", out JsonElement elm);
- if (hasData)
- {
- this.chkPriceTarget.Checked = Json2Boolean(elm, "assigned");
- this.txtOverrunPriceTarget.Text = Json2Text(elm, "overrun");
- this.tspPriceTarget.Text = element.GetProperty("t").ToString();
- this.tspPriceTarget.ForeColor = IsChangedRecently(this.tspPriceTarget.Text) ? COLOR_MODIFIED : COLOR_NORMAL;
- }
- }
- }
- }
- private void FundQ_Load(object sender, EventArgs e)
- {
- }
- private void btnSaveGeneralInfo_Click(object sender, EventArgs e)
- {
- try
- {
- // 数据对象
- var textData = new
- {
- // -- General Info --
- investmentObjective = AddInfo(this.txtInvestmentObjective.Text, userId),
- benchmark = AddInfo(this.txtBenchmark.Text, userId),
- investmentPhilosophy = AddInfo(this.txtInvestmentPhilosophy.Text, userId),
- portfolioManagers = AddInfo(Utility.DataTable2List((DataTable)this.grdPortfolioManager.DataSource), userId),
- totalExpenseRatio = AddInfo(Utility.DataTable2List((DataTable)this.grdTER.DataSource), userId),
- currentFees = AddInfo(new
- {
- managementFee = this.txtManagementFee.Text,
- subscriptionFee = this.txtSubscriptionFee.Text,
- redemptionFee = this.txtRedemptionFee.Text,
- administrationFee = this.txtAdministrationFee.Text,
- switchingFee = this.txtSwitchingFee.Text,
- trusteeFee = this.txtTrusteeFee.Text,
- performanceFee = this.txtPerformanceFee.Text
- }, userId),
- policyOfClosingFund = AddInfo(this.txtPolicyOfClosingFund.Text, userId),
- // -- Process --
- derivatives = AddInfo( new
- {
- allowed = this.chkAllowDerivatives.Checked,
- currentUse = this.chkUseDerivatives.Checked,
- effectiveManagement = this.chkDerivativesForEfficent.Checked,
- hedging = this.chkDerivatesForHedging.Checked,
- marketAccess = this.chkDerivativesForMarket.Checked,
- leverage = this.chkDerivatesForLeverage.Checked
- }, userId),
- priceTarget = AddInfo( new
- {
- assigned = this.chkPriceTarget.Checked,
- overrun = this.txtOverrunPriceTarget.Text
- }, userId)
- };
- // 序列化选项
- var options = new JsonSerializerOptions
- {
- WriteIndented = true,
- PropertyNamingPolicy = JsonNamingPolicy.CamelCase
- };
- string jsonString = JsonSerializer.Serialize(textData, options);
- //MessageBox.Show($"Save JSON: \n{jsonString}", "Json Result");
- int ret = DataAccess.Set_dd_fund_info(this.fundId, DateTime.Today, jsonString, 1, 1, userId);
- if (ret == 1)
- {
- this.Close();
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show($"Error: {ex.Message}", "Error");
- }
- }
- private void grdTER_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
- {
- string errMsg = "Please enter a number between 0 and 100, with up to 3 decimal digits";
- if (grdTER.Columns[e.ColumnIndex].Name == "ter" && e.RowIndex >= 0)
- {
- // 先清除可能存在的旧错误提示
- grdTER.Rows[e.RowIndex].ErrorText = "";
- if (e.FormattedValue.ToString().Trim() == "") return;
- // 尝试将输入的值转换为小数
- if (!decimal.TryParse(e.FormattedValue.ToString(), out decimal newValue))
- {
- // 如果转换失败,说明输入的不是有效数字
- e.Cancel = true;
- grdTER.Rows[e.RowIndex].ErrorText = errMsg;
- return;
- }
- // 验证数值范围(例如限制在0到100之间)
- if (newValue < 0 || newValue > 100)
- {
- e.Cancel = true;
- grdTER.Rows[e.RowIndex].ErrorText = errMsg;
- return;
- }
- // (可选) 自定义验证小数位数
- string[] parts = e.FormattedValue.ToString().Split('.');
- if (parts.Length > 1 && parts[1].Length > 3) // 检查小数点后的位数
- {
- e.Cancel = true;
- grdTER.Rows[e.RowIndex].ErrorText = errMsg;
- }
- }
- }
- private void btnSaveFundProcess_Click(object sender, EventArgs e)
- {
-
- }
- private void chkAllowDerivatives_CheckedChanged(object sender, EventArgs e)
- {
- bool isChecked = chkAllowDerivatives.Checked;
- this.chkUseDerivatives.Enabled = isChecked;
- if (isChecked == false)
- {
- this.chkUseDerivatives.Checked = false;
- }
- }
- private void chkUseDerivatives_CheckedChanged(object sender, EventArgs e)
- {
- bool isChecked = chkUseDerivatives.Checked;
- this.chkDerivativesForEfficent.Enabled = isChecked;
- this.chkDerivatesForHedging.Enabled = isChecked;
- this.chkDerivativesForMarket.Enabled = isChecked;
- this.chkDerivatesForLeverage.Enabled = isChecked;
- if (isChecked == false)
- {
- this.chkDerivativesForEfficent.Checked = false;
- this.chkDerivatesForHedging.Checked = false;
- this.chkDerivativesForMarket.Checked = false;
- this.chkDerivatesForLeverage.Checked = false;
- }
- }
- private void chkPriceTarget_CheckedChanged(object sender, EventArgs e)
- {
- bool isChecked = chkPriceTarget.Checked;
- if (!isChecked) { this.txtOverrunPriceTarget.Text = ""; }
- }
- private void btnUploadProcessDiagram_Click(object sender, EventArgs e)
- {
- this.ofdProcessDiagram.Title = "Upload Diagram File -- FAKE";
- if (this.ofdProcessDiagram.ShowDialog() == DialogResult.OK)
- {
- // TODO: upload files to server. let's fake it for now
- string filePath = ofdProcessDiagram.FileName;
- string fileName = Path.GetFileName(filePath);
- try
- {
- }
- catch (Exception ex)
- {
- MessageBox.Show("File was not able to be uploaded:" + ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
- }
- private void btnAddManager_Click(object sender, EventArgs e)
- {
- using (PersonSelectionDialog dialog = new PersonSelectionDialog(companyId))
- {
- dialog.StartPosition = FormStartPosition.CenterParent;
- DialogResult result = dialog.ShowDialog(this);
- if (result == DialogResult.OK && dialog.PersonnelId != "")
- {
- DataTable dt = (DataTable)this.grdPortfolioManager.DataSource;
-
- DataRow row = dt.NewRow();
- row["personnel_id"] = dialog.PersonnelId;
- row["name"] = dialog.PersonnelName;
- row["startDate"] = dialog.StartDate.Date;
- dt.Rows.Add(row);
- }
-
- }
- }
- private void grdPortfolioManager_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
- {
- int rowIndex = e.RowIndex;
- int columnIndex = e.ColumnIndex;
- if (rowIndex < 0 || columnIndex < 0) { return; }
- // 先清除可能存在的旧错误提示
- grdPortfolioManager.Rows[rowIndex].ErrorText = "";
- // 如果转换失败,说明输入的不是有效日期
- bool isPass = DateTime.TryParse(grdPortfolioManager.Rows[rowIndex].Cells["startDate"].Value.ToString(), out DateTime newDate);
- if (!isPass || newDate < new DateTime(1900, 1, 1) || newDate > DateTime.Today)
- {
- e.Cancel = true;
- grdPortfolioManager.Rows[columnIndex].ErrorText = "Please enter a proper start date";
- return;
- }
- if (grdPortfolioManager.Rows[rowIndex].Cells["endDate"].Value.ToString() == "") return;
- isPass = DateTime.TryParse(grdPortfolioManager.Rows[rowIndex].Cells["endDate"].Value.ToString(), out newDate);
- if (!isPass || newDate < new DateTime(1900, 1, 1) || newDate > DateTime.Today)
- {
- e.Cancel = true;
- grdPortfolioManager.Rows[columnIndex].ErrorText = "Please enter a proper end date"; ;
- return;
- }
- }
- private void grdPortfolioManager_Validating(object sender, CancelEventArgs e)
- {
- }
- }
- }
|