文章目录
生产订单执行明细表二开增加字段
业务背景
目前的逻辑是入库数量/计划数量=达成率,需要加入计划完成时间和数据/实际完成时间和数量=达成率。
业务需求
过滤框提供输入时间段,作为入库单的时间限制,算出入库数,实际达成率=入库数/计划数*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;
}