生产订单执行明细表二开增加字段
- 业务背景
- 业务需求
- 方案设计
- 详细设计和实现
一、业务背景
标准产品目前的逻辑是入库数量/计划数量=达成率,需要加入计划完成时间和数据/实际完成时间和数量=达成率。
二、业务需求
过滤匡提供输入时间段,作为入库单的时间限制,算出入库数,实际达成率=入库数/计划数*100%。
三、方案设计
二开标准产品,添加字段,创建插件继承标准产品插件,重写方法,修改临时表添加字段,更新字段取值,替换标准产品插件。
四、详细设计和实现
标准报表引入到应用
查询《生产订单执行明细表》引入到应用,同样引入《生产订单执行明细表过滤》
扩展报表,添加自定义字段相关
生产订单执行明细报表新增字段,字段的标识名命名一致。
保存后:
生产订单执行明细报表过滤框的快捷界面添加查询条件-入库的起止日期,日期控件,默认今天。
生产订单执行明细报表过滤框的显示隐藏列添加过滤字段,字段的标识名和报表一致。
创建插件,挂载插件
新建类库 Krystal.K3.SCGL.App.Report,添加引用
创建类,继承报表原插件
重写BuilderReportSqlAndTempTable方法,对临时表添加自定义字段,对添加的字段进行逻辑计算后赋值
#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 版权所有 (c) 2024 NJRN 保留所有权利。 * CLR版本:4.0.30319.42000 * 机器名称:INC1507245 * 公司名称:Increase * 命名空间:Krystal.K3.SCGL.App.Report.PRD * 唯一标识:5d1dc27c-1776-4835-9f85-739566192920 * 文件名:Krystal_MOExecuteDetailRpt * 当前用户域:INC1507245 * * 创建者:Krystal * 电子邮箱:543375940@qq.com * 创建时间:2024/7/8 14:48:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 时间: * 修改说明: * * 版本:V1.0.1 *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using Kingdee.BOS.App.Data; using Kingdee.BOS.Core.Report; using Kingdee.BOS.Orm.DataEntity; using Kingdee.BOS.Util; using Kingdee.K3.MFG.PRD.App.ReportPlugIn.MOExecute; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Krystal.K3.SCGL.App.Report.PRD { /// <summary> /// 功能描述 :Krystal_MOExecuteDetailRpt /// 创 建 者 :Administrator /// 创建日期 :2024/7/8 14:48:36 /// 最后修改者 :Krystal /// 最后修改日期:2024/7/8 14:48:36 /// </summary> [Description("生产订单执行明细表服务端插件二开-报表插件"), HotUpdate] public class Krystal_MOExecuteDetailRpt: MOExecuteDetailRpt { #region <常量> #endregion <常量> #region <变量> /// <summary> /// 页面过滤参数 /// </summary> FilterArgs _filterArgs = new FilterArgs(); #endregion <变量> #region <属性> #endregion <属性> #region <构造方法和析构方法> #endregion <构造方法和析构方法> #region <方法> public override void BuilderReportSqlAndTempTable(IRptParams filter, string tableName) { //调用基类的方法,获取初步的查询结果到临时表tableName【基类默认的存放查询结果的临时表】 base.BuilderReportSqlAndTempTable(filter, tableName); //构造过滤条件 DynamicObject dyFilter = this.GetFilter(filter); this.AddSecondField(tableName); } //, IRptParams filter /// <summary> /// 添加字段入库数,实际达成率 /// </summary> /// <param name="tableName"></param> private void AddSecondField(string tableName) { //1、对临时表tableName添加字段入库数,实际达成率 //添加的字段长度,类型,是否为空,尽量和原字段保持一致 //,添加的字段中间加上二开标识,防止和标准产品字段冲突 StringBuilder sqlStr = new StringBuilder(); sqlStr.AppendFormat(@"alter table {0} add F_XHWT_InStockQty decimal(23, 10) NOT NULL default 0; alter table {0} add F_XHWT_FinishPercent decimal(19, 2) NOT NULL default 0;", tableName); int uc = DBUtils.Execute(this.Context, sqlStr.ToString()); // 高级过滤条件已自动存放在FilterParameter.FilterString中,账表插件可以直接拿来使用 //var commonFilter = filter.FilterParameter.FilterString; //测试临时表 //string sql1 = string.Format(@"select top 10000 * from {0}", tableName); //var sd = DBUtils.ExecuteDynamicObject(this.Context, sql1); //2、更新该字段 sqlStr.Clear(); sqlStr.AppendFormat(@" MERGE INTO {0} T0", tableName); sqlStr.AppendFormat(@" using (SELECT b.FMOENTRYID ,SUM(b.FREALQTY) FInstockQty FROM T_PRD_INSTOCK a JOIN T_PRD_INSTOCKENTRY b ON a.FID=b.FID WHERE a.FDOCUMENTSTATUS='C' AND a.FAPPROVEDATE BETWEEN '{0}' AND '{1}' GROUP BY b.FMOENTRYID ) T ", _filterArgs.ISBeginTime, _filterArgs.ISEndTime); sqlStr.AppendFormat(@" ON T0.FMOENTRYID=T.FMOENTRYID ");//round(20 * 1.0 / 120, 4) * 100 sqlStr.AppendFormat(@" WHEN matched THEN UPDATE SET F_XHWT_InStockQty=T.FInstockQty ,F_XHWT_FinishPercent=(case when T0.FPLANQTY>0 then round(T.FInstockQty*1.0/T0.FPLANQTY,4)*100 else 0 end) "); int uc1 = DBUtils.Execute(this.Context, sqlStr.ToString()); } /// <summary> /// 获取过滤条件 /// </summary> /// <param name="filter"></param> private DynamicObject GetFilter(IRptParams filter) { DynamicObject dyFilter = filter.FilterParameter.CustomFilter; _filterArgs.ISBeginTime = this.GetDataByKey(dyFilter, "F_Krystal_InStockBeginTime") == string.Empty ? DateTime.MinValue : Convert.ToDateTime(this.GetDataByKey(dyFilter, "F_Krystal_InStockBeginTime")); _filterArgs.ISEndTime = this.GetDataByKey(dyFilter, "F_Krystal_InStockEndTime") == string.Empty ? DateTime.MaxValue : Convert.ToDateTime(this.GetDataByKey(dyFilter, "F_Krystal_InStockEndTime")); return dyFilter; } /// <summary> /// 查询条件标题 /// </summary> /// <param name="filter"></param> /// <returns></returns> public override ReportTitles GetReportTitles(IRptParams filter) { ReportTitles reportTitle = base.GetReportTitles(filter); string beginApplicationMonthStr = _filterArgs.ISBeginTime.ToString("yyyy-MM-dd"); string endApplicationMonthStr = _filterArgs.ISEndTime.ToString("yyyy-MM-dd"); reportTitle.AddTitle("F_Krystal_InStockTitle", string.Format("{0}{1}{2}" , beginApplicationMonthStr , Kingdee.BOS.Resource.ResManager.LoadKDString(" 至 ", "004102030003172" , Kingdee.BOS.Resource.SubSystemType.SCM) , endApplicationMonthStr)); return reportTitle; } #endregion <方法> #region 过滤参数 FilterArgs internal class FilterArgs { public DateTime ISBeginTime { get; set; }//起始年月 public DateTime ISEndTime { get; set; }//结束年月 } #endregion } }
如果入库数,需要汇总。
/// <summary> /// 构造汇总字段信息集合 /// </summary> /// <param name="filter"></param> /// <returns></returns> public override List<SummaryField> GetSummaryColumnInfo(IRptParams filter) { var lstGroupField = base.GetSummaryColumnInfo(filter); lstGroupField.Add(new Kingdee.BOS.Core.Report.SummaryField("F_Krystal_InStockQty", BOSEnums.Enu_SummaryType.SUM)); return lstGroupField; }
测试