From 0e7d44e3bb8fddaca9af8a2aec0027b21e57c377 Mon Sep 17 00:00:00 2001 From: tdx Date: Sun, 16 Mar 2025 02:35:47 +0000 Subject: [PATCH] SVN r326 SVN-Revision: r326 --- 插件库/Lskj.PubBill/BillModule.cs | 443 +++++++++++++++++++++++++++- 插件库/Lskj.PubBill/BillModule.resx | 2 +- 2 files changed, 439 insertions(+), 6 deletions(-) diff --git a/插件库/Lskj.PubBill/BillModule.cs b/插件库/Lskj.PubBill/BillModule.cs index 727b415..15796d1 100644 --- a/插件库/Lskj.PubBill/BillModule.cs +++ b/插件库/Lskj.PubBill/BillModule.cs @@ -31,6 +31,8 @@ using DevExpress.XtraGrid.Views.Grid.ViewInfo; using Lskj.Core; using DevExpress.XtraTreeList.Columns; using System.Threading.Tasks; +using DevExpress.Utils; +using System.Data.SqlClient; namespace Lskj.PubBill { @@ -189,7 +191,10 @@ namespace Lskj.PubBill /// 单据来源控件集合 /// public Dictionary BillModuleModelDic = new Dictionary(); - + /// + /// 主表动态生成的日期列 + /// + public List DateColumnList = new List(); public BillModule() { @@ -984,11 +989,11 @@ namespace Lskj.PubBill this.ControlObj.InitControl(controls, this.pl_main_center_master, groups); this.ControlObj.refGridLookUpData = this.BillModel.RefGridLookUpData;//2023-3-17,新增单据时刷新下拉框数据源 this.ControlObj.OnSourceRefrshCallBack += OnRefreshBillSource; + this.ControlObj.OnDataFileRefrshCallBack += OnDataFileRefrshFile; this.ControlObj.OnDataSourceBindCallBack += new EventHandler(OnInitializeHeaderCallBack); this.pl_main_center_master.Height = (this.BillModel.ParentHeight - 36) > this.pl_main_center_master.Height ? this.pl_main_center_master.Height : this.BillModel.ParentHeight - 36; - // 初始化明细 // 创建多表头,默认标准表格 if (this.SysModel.GridEnumObj == GridEnum.BandedGridView || this.BillModel.AutoMultiHeader == 1) @@ -1078,7 +1083,7 @@ namespace Lskj.PubBill { this.gcMain.GridView.RowCellClick += OngcMainRowCellClick; } - + this.gcMain.GridView.DataSourceChanged += OnGcMainDataSourceChanged; } @@ -1131,6 +1136,71 @@ namespace Lskj.PubBill } } } + + private void AddDataColumns() + { + foreach (GridColumn gridColumn in gcMain.GridView.Columns) + { + gridColumn.Fixed = DevExpress.XtraGrid.Columns.FixedStyle.Left; + } + for (int i = 0; i < 7; i++) + { + GridColumn gridColumn = new GridColumn(); + gridColumn.AppearanceCell.Options.UseTextOptions = true; + gridColumn.AppearanceCell.TextOptions.HAlignment = HorzAlignment.Center; + gridColumn.AppearanceHeader.Options.UseTextOptions = true; + gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; + gridColumn.OptionsColumn.AllowMove = false; + gridColumn.OptionsColumn.AllowSize = false; + gridColumn.OptionsFilter.AllowFilter = false; + gridColumn.OptionsColumn.AllowMerge = DefaultBoolean.False; + gridColumn.OptionsColumn.AllowSort = DefaultBoolean.False; + gridColumn.FieldName = $"DDay_{i}"; + gridColumn.Width = 70; + gridColumn.DisplayFormat.FormatType = FormatType.Numeric; + gridColumn.DisplayFormat.FormatString = "{0:#,##0.####}"; + gridColumn.Visible = false; + gridColumn.SummaryItem.SummaryType = SummaryItemType.Sum; + gridColumn.SummaryItem.DisplayFormat = "{0:#,##0.####}"; + gcMain.GridView.Columns.Add(gridColumn); + DateColumnList.Add(gridColumn); + } + } + + /// + /// 根据日期修改列状态 + /// + /// + private void UpdateDynamicColumns(DateTime currentDate) + { + DateTime endDate = currentDate.AddDays(7); + gcMain.GridView.BeginUpdate(); + try + { + for (int i = 0; i < DateColumnList.Count; i++) + { + GridColumn gridColumn = DateColumnList[i]; + // 当前列对应的日期 = 起始日期加 i 天 + DateTime dateForColumn = currentDate.AddDays(i); + if (dateForColumn <= endDate) + { + gridColumn.FieldName = dateForColumn.ToString("yyyy-MM-dd"); + gridColumn.Caption = dateForColumn.ToString("MM-dd"); + gridColumn.Visible = true; + gridColumn.Tag = dateForColumn; + } + else + { + gridColumn.Visible = false; + } + } + } + finally + { + gcMain.GridView.EndUpdate(); + } + } + /// /// 说明:表格编辑时,判断是否是否编辑 /// 创建人:王一帆 @@ -2782,6 +2852,30 @@ namespace Lskj.PubBill } } /// + /// 说明:刷新表格列(时间) + /// 创建人:王一帆 + /// 创建日期:2018-08-16 + /// 修改人: + /// 修改日期: + /// 修改备注: + /// 版本:1.0 + /// + /// + /// + private void OnDataFileRefrshFile(object sender, EventArgs e) + { + BaseUserControl baseControl = (sender as System.Windows.Forms.Control).ToBaseUserControl(); + if (baseControl is LabelDateEdit labelDateEdit) + { + DateTime dateTime = labelDateEdit.TextEdit.DateTime; + if (DateColumnList.Count == 0) + { + AddDataColumns(); + } + UpdateDynamicColumns(dateTime); + } + } + /// /// 说明:刷新单据来源明细 /// 创建人:龚宇超 /// 创建日期:2017-11-30 @@ -3222,7 +3316,10 @@ namespace Lskj.PubBill { // 未包含字段,则使用控件默认值. GridColumnModel model = col.Tag as GridColumnModel; - + if (model == null) + { + continue; + } if (rowItem.Table.Columns.Contains(col.FieldName)) { // 来源列中是否包含对应字段,包含则使用值 @@ -3422,6 +3519,7 @@ namespace Lskj.PubBill try { GridColumnModel model = col.Tag as GridColumnModel; + if (model == null) continue; if (dataTable.Columns.Contains(col.FieldName)) { // 来源列中是否包含对应字段,包含则使用值 @@ -4291,6 +4389,12 @@ namespace Lskj.PubBill bool saveResult = false; if (this.ControlObj.VerifyNull()) { + //若存在分配则优先保存数据 + if (DateColumnList.Count > 0) + { + SaveDatePlanRecord(); + } + // 保存之前先进行表格更新 if (this.BillModel.DetailTreeTable) { @@ -4871,6 +4975,298 @@ namespace Lskj.PubBill } } + /// + /// 主表数据源改变时 + /// + /// + /// + private void OnGcMainDataSourceChanged(object sender, EventArgs e) + { + if (DateColumnList.Count > 0 && DateColumnList[0].Tag is DateTime dateTime) + { + this.gcMain.GridView.DataSourceChanged -= OnGcMainDataSourceChanged; + DataTable dataTable = gcMain.GridControl.DataSource as DataTable; + //DataTable dataMain = dataTable.Copy(); + string sqlValue = "select * from RD_worktimetab where 1 = 1"; + sqlValue = $"{sqlValue} and showday >= '{dateTime.ToString("yyyy-MM-dd")}'"; + DataTable dataDayPlan = BaseImpl.GetDataTableResult(sqlValue); + MergeMainDataWithDayPlan(dataTable, dataDayPlan, dateTime); + //gcMain.GridControl.DataSource = dataMain; + this.gcMain.GridView.DataSourceChanged += OnGcMainDataSourceChanged; + dataTable.TableNewRow += OnDataTableTableNewRow; + } + } + + /// + /// 表格行添加数据时 + /// + /// + /// + private void OnDataTableTableNewRow(object sender, DataTableNewRowEventArgs e) + { + if (DateColumnList.Count > 0 && DateColumnList[0].Tag is DateTime dateTime) + { + DataRow focusedRow = gcMain.GridView.GetFocusedDataRow(); + if (focusedRow != null) + { + string key = focusedRow.Table.Columns.Contains(BillModel.PrimaryKey) ? focusedRow[BillModel.PrimaryKey] + "" : ""; + if (!string.IsNullOrEmpty(key)) + { + string sqlValue = $"select * from RD_worktimetab where billdocument_id = '{key}'"; + sqlValue = $"{sqlValue} and showday >= '{dateTime.ToString("yyyy-MM-dd")}'"; + DataTable dataDayPlan = BaseImpl.GetDataTableResult(sqlValue); + UpdateRowWithDayPlan(focusedRow, dataDayPlan, dateTime); + } + } + } + } + + private bool SaveDatePlanRecord() + { + // 获取主数据源,假设已绑定到 gridControl1 + DataTable mainDataSource = gcMain.GridControl.DataSourceTable(); + if (mainDataSource == null) + { + return true; + } + // 当前操作用户(例如从全局获取) + string currentUser = ERPInfo.Instance.UserName; + DataTable tvp = new DataTable(); + tvp.Columns.Add("billdocument_id", typeof(string)); + tvp.Columns.Add("showday", typeof(string)); + tvp.Columns.Add("amount", typeof(decimal)); + // 遍历主数据源所有行,仅处理已修改行 + foreach (DataRow row in mainDataSource.Rows) + { + if (row.RowState == DataRowState.Modified|| row.RowState == DataRowState.Added) + { + // 获取关联的 keyvalue(用于匹配 mps_dayplantab.billdocument_id) + string key = row["bom_rdl_productid"].ToString(); + // 遍历每个列,处理虚拟列(列名格式必须为 "yyyy-MM-dd") + foreach (DataColumn col in mainDataSource.Columns) + { + // 忽略固定字段 + if (col.ColumnName == "ID" || col.ColumnName == "key" || col.ColumnName == "Name") + continue; + // 仅处理列名符合完整日期格式的虚拟列 + if (!Regex.IsMatch(col.ColumnName, @"^\d{4}-\d{2}-\d{2}$")) + continue; + bool isVerifyupd =true ; + if (row.RowState == DataRowState.Modified) + { + // 比较原始值和当前值 + object originalValue = row[col, DataRowVersion.Original]; + object currentValue = row[col, DataRowVersion.Current]; + isVerifyupd=!object.Equals(originalValue, currentValue); + } + if (isVerifyupd) + { + decimal newAmount = 0m; + if (row[col] != DBNull.Value && !string.IsNullOrWhiteSpace(row[col].ToString())) + { + decimal.TryParse(row[col].ToString(), out newAmount); + } + DataRow dr = tvp.NewRow(); + dr["billdocument_id"] = key; + dr["showday"] = col.ColumnName; // 列名如 "2025-03-06" + dr["amount"] = newAmount; + tvp.Rows.Add(dr); + } + } + } + } + if (tvp.Rows.Count == 0) + { + return true; + } + // 调用存储过程保存变更数据 + string msg; + int ret = SaveDayPlanChanges(tvp, out msg); + if (ret == 1) + { + return true; + } + else + { + return false; + } + } + + /// + /// 保存日计划变更数据(批量保存)。 + /// 调用存储过程 usp_MergeDayPlanChanges,将所有变更记录一次性提交到数据库。 + /// 通过 TVP 参数传递数据,同时捕获输出参数 @msg 和返回值。 + /// + /// 包含所有变更记录的 DataTable,必须与 dbo.DayPlanChangeType 定义一致 + /// 输出提示信息,存储过程执行后的返回消息 + /// 存储过程返回值,成功返回 1,失败返回 0 + public int SaveDayPlanChanges(DataTable tvp, out string message) + { + // 创建输出参数 @msg + SqlParameter pMsg = new SqlParameter("@msg", SqlDbType.VarChar, 2000) + { + Direction = ParameterDirection.Output + }; + // 创建返回值参数 @return + SqlParameter returnValue = new SqlParameter("@return", SqlDbType.Int) + { + Direction = ParameterDirection.ReturnValue + }; + // 创建 TVP 参数,名称必须与存储过程参数一致 + SqlParameter tvpParam = new SqlParameter("@DayPlanChanges", SqlDbType.Structured) + { + TypeName = "dbo.DayPlanChangeType", + Value = tvp + }; + // 构造参数数组 + SqlParameter[] parameters = new SqlParameter[] { tvpParam, pMsg, returnValue }; + // 执行存储过程,此处调用 ExecuteNonQuery 即可,不需要返回数据集 + // 请确保 DBUtil.ExecuteNonQuery 方法能够传递参数并执行存储过程 + BaseImpl.ExecProcedure("usp_MergeDayPlanChanges2025", parameters); + // 获取输出参数 @msg 中的提示信息 + message = pMsg.Value.ToString(); + // 获取存储过程的返回值 + int result = Convert.ToInt32(returnValue.Value); + return result; + } + + /// + /// 构建带日期的数据源 + /// + /// + /// + /// + /// + private DataTable MergeMainDataWithDayPlan(DataTable dataMain, DataTable dataDayPlan, DateTime startDate) + { + string rightPrimaryKey = "key"; + string topPrimaryKey = this.BillModel.PrimaryKey; + DateTime endDate = startDate.AddDays(7); // 计算结束日期 + // **1. 预索引 dataDayPlan 数据(billdocument_id -> 该 key 相关的所有行)** + Dictionary> dayPlanMap = new Dictionary>(); + foreach (DataRow row in dataDayPlan.Rows) + { + string billId = row[rightPrimaryKey].ToString(); + if (!dayPlanMap.ContainsKey(billId)) + { + dayPlanMap[billId] = new List(); + } + dayPlanMap[billId].Add(row); + } + // **2. 预构建主数据的列** + for (DateTime dt = startDate; dt <= endDate; dt = dt.AddDays(1)) + { + string colName = dt.ToString("yyyy-MM-dd"); + if (!dataMain.Columns.Contains(colName)) + { + dataMain.Columns.Add(colName, typeof(decimal)); // 确保列存在 + } + } + // **3. 预构建数据填充映射表** + Dictionary> dataMap = new Dictionary>(); + foreach (DataRow row in dataMain.Rows) + { + string key = row[topPrimaryKey].ToString(); + if (!dataMap.ContainsKey(key)) + { + dataMap[key] = new Dictionary(); + } + // **查找 key 关联的时间数据** + if (dayPlanMap.ContainsKey(key)) + { + foreach (DataRow dayRow in dayPlanMap[key]) + { + if (dayRow["date"] != DBNull.Value) + { + DateTime dayValue = Convert.ToDateTime(dayRow["date"]); + string colName = dayValue.ToString("yyyy-MM-dd"); + if (dayValue >= startDate && dayValue <= endDate && dataMain.Columns.Contains(colName)) + { + dataMap[key][colName] = Convert.ToDecimal(dayRow["amount"]); + } + } + } + } + } + // **4. 一次性填充 DataTable(避免逐行赋值带来的性能问题)** + foreach (DataRow row in dataMain.Rows) + { + string key = row[topPrimaryKey].ToString(); + if (dataMap.ContainsKey(key)) + { + foreach (var col in dataMap[key]) + { + row[col.Key] = col.Value; + } + } + } + return dataMain; + } + /// + /// 构建带日期的数据源 + /// + /// + /// + /// + /// + private void UpdateRowWithDayPlan(DataRow focusedRow, DataTable dataDayPlan, DateTime startDate) + { + string rightPrimaryKey = "key"; + string topPrimaryKey = this.BillModel.PrimaryKey; + DateTime endDate = startDate.AddDays(7); // 计算结束日期 + // **1. 预索引 dataDayPlan 数据(billdocument_id -> 该 key 相关的所有行)** + Dictionary> dayPlanMap = new Dictionary>(); + foreach (DataRow row in dataDayPlan.Rows) + { + string billId = row[rightPrimaryKey].ToString(); + if (!dayPlanMap.ContainsKey(billId)) + { + dayPlanMap[billId] = new List(); + } + dayPlanMap[billId].Add(row); + } + // **2. 预构建主数据的列** + for (DateTime dt = startDate; dt <= endDate; dt = dt.AddDays(1)) + { + string colName = dt.ToString("yyyy-MM-dd"); + if (!focusedRow.Table.Columns.Contains(colName)) + { + focusedRow.Table.Columns.Add(colName, typeof(decimal)); // 确保列存在 + } + } + // **3. 预构建数据填充映射表** + Dictionary> dataMap = new Dictionary>(); + string key = focusedRow[topPrimaryKey].ToString(); + if (!dataMap.ContainsKey(key)) + { + dataMap[key] = new Dictionary(); + } + // **查找 key 关联的时间数据** + if (dayPlanMap.ContainsKey(key)) + { + foreach (DataRow dayRow in dayPlanMap[key]) + { + if (dayRow["date"] != DBNull.Value) + { + DateTime dayValue = Convert.ToDateTime(dayRow["date"]); + string colName = dayValue.ToString("yyyy-MM-dd"); + if (dayValue >= startDate && dayValue <= endDate && focusedRow.Table.Columns.Contains(colName)) + { + dataMap[key][colName] = Convert.ToDecimal(dayRow["amount"]); + } + } + } + } + // **4. 一次性填充 DataTable(避免逐行赋值带来的性能问题)** + if (dataMap.ContainsKey(key)) + { + foreach (var col in dataMap[key]) + { + focusedRow[col.Key] = col.Value; + } + } + } + /// /// 说明:单据明细选中刷新附件明细(明细为树表格时) /// 创建人:曹屹峰 @@ -5276,6 +5672,10 @@ namespace Lskj.PubBill foreach (GridColumn col in gridColumns) { GridColumnModel model = col.Tag as GridColumnModel; + if (model == null) + { + continue; + } string fieldValue = BaseImpl.GetDefaultValue(model.DefaultValue); if (model.DefaultValue.Contains("{#")) @@ -7518,4 +7918,37 @@ namespace Lskj.PubBill /// /// The cond. /// The data row. - /// true if XXXX, < \ No newline at end of file + /// true if XXXX, false otherwise. + private bool ValidateCond(string cond, DataRow dataRow) + { + bool result = false; + string condition = cond; + try + { + if (string.IsNullOrWhiteSpace(cond)) return true;//如果值是空格或者空行,默认正确 + cond = ReplaceHelper.ReplaceRowParam(dataRow, cond); + if (cond.StartsWith("@") || cond.StartsWith("!")) + { + result = "1".Equals(BaseImpl.GetDefaultValue(cond)); + } + else if (dataRow == null) + { + result = ReplaceHelper.EvalCond(cond); + } + else + { + result = ReplaceHelper.ReplaceRowParamCond(dataRow, cond); + } + return result; + } + catch (Exception ex) + { + + } + return result; + + } + + + } +} \ No newline at end of file diff --git a/插件库/Lskj.PubBill/BillModule.resx b/插件库/Lskj.PubBill/BillModule.resx index 6043357..d11908a 100644 --- a/插件库/Lskj.PubBill/BillModule.resx +++ b/插件库/Lskj.PubBill/BillModule.resx @@ -121,7 +121,7 @@ 642, 21 - 83 + 59 1078, 23