Files
GateDge2023_ljy/HW.PRD_MO.Python/类1.py
PastSaid 5e2781182d a
2024-03-04 16:50:20 +08:00

182 lines
8.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import clr
clr.AddReference("System")
clr.AddReference("Kingdee.BOS")
clr.AddReference("Kingdee.BOS.Core")
clr.AddReference("Kingdee.BOS.DataEntity")
clr.AddReference("Kingdee.BOS.App")
clr.AddReference("Kingdee.BOS.Contracts")
clr.AddReference("Kingdee.BOS.ServiceHelper")
from Kingdee.BOS import*
from Kingdee.BOS.Contracts import*
from Kingdee.BOS.Contracts.Report import*
from Kingdee.BOS.Core import *
from Kingdee.BOS.Core.Metadata import *
from Kingdee.BOS.Core.Report import*
from Kingdee.BOS.Core.SqlBuilder import*
from Kingdee.BOS.Core.Enums import *
from Kingdee.BOS.App.Data import*
from Kingdee.BOS.Orm.DataEntity import*
from System import*
from System.ComponentModel import*
from System.Collections.Generic import*
from System.Text import*
from System.Threading.Tasks import*
from Kingdee.BOS.ServiceHelper import *
#初始化,在此事件中设置报表的属性全局参数
def Initialize():
this.ReportProperty.ReportType=ReportType.REPORTTYPE_NORMAL;
this.IsCreateTempTableByPlugin=True;
#是否支持分组汇总,在后面GetSummaryColumnInfo方法中添加汇总字段,
#要在BOS中过滤框的汇总页签配置汇总信息,可参考:简单账表分组汇总设置
this.ReportProperty.IsGroupSummary=True;
#IsUIDesignerColumns=False,表示报表的列通过插件控制,后续在GetReportHeaders中构建列头
#需要在BOS过滤框的显示隐藏列中维护,字段标识与临时表字段保持一致
#账表列头构建更多详细说明参考:账表列构建
this.ReportProperty.IsUIDesignerColumns=False;
#创建临时报表,正式进入账表取数sql拼接并取数把账表取数结果放到创建的临时表中
#如果参数(this.IsCreateTempTableByPlugin=True)即调用BuilderReportSqlAndTempTable构建临时表
#否则调用以下3个接口完成账表取数逻辑的sql指令即BuilderSelectFieldSQL、BuilderTempTableOrderBySQL、BuilderFormWhereSQL
#rptfilter:账表参数,可以从这里获取过滤条件等
#tableName:系统自动创建的账表临时表名,具备唯一性,最终报表页面展示的数据绑定此临时表,所以最终的报表结果数据要写入此临时表中
def BuilderReportSqlAndTempTable(rptfilter,tableName):
#baseDataTemp=filter.BaseDataTempTable;#基础资料临时表;若设置了数据范围权限,该表会把根据数据范围过滤出来的内码存入临时表;
#循环获取所有基础资料数据范围的数据可用来拼接到报表SQL里面实现数据权限过滤
#for b in baseDataTemp:
# baseType=b.BaseDataFormId;#基础资料FormId
# PKFldName=b.PKFieldName;#临时表中基础资料主键字段名,例如,FORGID
# baseTempTab=b.TempTable;#基础资料数据范围临时表名
#filterStr=filter.FilterParameter.FilterString;#过滤框条件页签过滤表达式
#过滤框快捷过滤页签的实体数据包,从这里面获取自定义的过滤字段值
#DynamicObject类型,用前面讲的实体数据包操作方式取值,用绑定实体属性标识
custFilter = rptfilter.FilterParameter.CustomFilter;
if(custFilter==None):
return;
orgObj=custFilter["F_BPW_OrgId"];#获取组织
whereOrgs="";
if(orgObj != None):
orgId=("{0}").format(orgObj["Id"]);#组织ID
whereOrgs=(" and a.FPURCHASEORGID in ({0}) ").format(orgId);#选择了组织,拼接组织过滤
materials=custFilter["F_BPW_Materials"];#物料多选过滤
matList=List[str]();
if(materials != None):
for m in materials:
materialNum="'"+str(m["F_BPW_Materials"]["Number"])+"'";#取出过滤框选择的多个物料编码
matList.Add(materialNum);
whereMat=(" and m.FNumber in ({0})").format(str.Join(",",matList)) if(matList.Count>0) else "";#拼接物料多选过滤
beginDate=str(custFilter["F_BPW_BeginDate"]);#获取开始日期
EndDate=str(custFilter["F_BPW_EndDate"]);#获取结束日期
beginDate=str(DateTime.Parse(("{0}").format(beginDate)).AddDays(-1));#开始日期的前一天
itemDate=beginDate;
fldsSql=List[str]();#动态列头SQL,相当于Select后面的部分字段是动态拼接的以此来实现动态列
#从开始日期起循环加1天一直到结束日期过滤界面要控制录入的开始日期必须<结束日期,在过滤界面注册表单插件即可实现
while(itemDate != EndDate):
myDate=DateTime.Parse(("{0}").format(itemDate));
fldKey=("F{0}_{1}_{2}").format(myDate.Year,myDate.Month,myDate.Day);#根据每个日期构建唯一的列名
ss=("{0}=SUM(Case when a.FDATE='{1}' then b.FQty else 0 end)").format(fldKey,myDate);#构建每天订单数量合计SQL
fldsSql.Add(ss);#将SQL添加到动态列SQL集合中备用
nextDate=myDate.AddDays(1);
itemDate=str(nextDate);#迭代+1天
myDate=DateTime.Parse(("{0}").format(itemDate));#这里是选择的截止日期,由于循环到最后一天跳出了,这里补充一天的数据
fldKey=("F{0}_{1}_{2}").format(myDate.Year,myDate.Month,myDate.Day);
ss=("{0}=SUM(Case when a.FDATE='{1}' then b.FQty else 0 end)").format(fldKey,myDate);
fldsSql.Add(ss);#将SQL添加到动态列SQL集合中备用
#raise Exception(str.Join(',',fldsSql));#调试时可用此行代码看看构建的动态列SQL对不对
#组装最终写入报表临时表的SQL
#注意!!!: 最终临时表一定要有FIDENTITYID 要从1开始且不重复 ,不断号,不然前台显示空白!!!!
sql=("""/*dialect*/?select row_Number() Over(order by a.orgName,a.MaterialNum) FIDENTITYID, a.*
into {0}
from
(select orgL.FNAME orgName,m.FNUMBER MaterialNum,mL.FNAME materialName,mL.FSPECIFICATION SpecNum,unitL.FNAME unit,
{1}
from t_PUR_POOrder a
inner join T_ORG_ORGANIZATIONS org on org.FORGID=a.FPURCHASEORGID
inner join T_ORG_ORGANIZATIONS_L orgL on orgL.FORGID=org.FORGID and orgL.FLOCALEID=2052
inner join t_PUR_POOrderEntry b on a.FID=b.FID
inner join T_BD_MATERIAL m on m.FMATERIALID=b.FMATERIALID
inner join T_BD_MATERIAL_L mL on mL.FMATERIALID=m.FMATERIALID and mL.FLOCALEID=2052
inner Join T_BD_UNIT_L unitL on unitL.FUNITID=b.FUNITID and unitL.FLOCALEID=2052
where a.FDATE>='{3}' and a.FDATE<='{4}' {2} {5}
group by orgL.FNAME,m.FNUMBER,mL.FNAME,mL.FSPECIFICATION,unitL.FNAME
) a
""").format(tableName,str.Join(',',fldsSql),whereOrgs,beginDate,EndDate,whereMat);
#raise Exception(sql);#可以通过此方法弹出Sql语句进行调试验证
DBUtils.Execute(this.Context,sql);#执行SQL将报表数据写入临时表
#构建账表列头
def GetReportHeaders(Filter):
header=ReportHeader();
localEid=this.Context.UserLocale.LCID;#获取当前语言环境代码,中文为2052
header.AddChild("orgName",LocaleValue("采购组织",localEid));#字段名,列头标题,字段名与临时表中的字段名保持对应,相当于每一个列头对应临时表的哪个字段
header.AddChild("MaterialNum",LocaleValue("物料编码",localEid));
header.AddChild("materialName",LocaleValue("物料名称",localEid));
header.AddChild("SpecNum",LocaleValue("规格型号",localEid));
header.AddChild("unit",LocaleValue("采购单位",localEid));
#下面根据过滤条件选择的日期区间,动态构建列头,和上面构建SQL字段的逻辑类似
custFilter = Filter.FilterParameter.CustomFilter;
beginDate=str(custFilter["F_BPW_BeginDate"]);#获取开始日期
EndDate=str(custFilter["F_BPW_EndDate"]);#获取结束日期
itemDate=beginDate;
fldsSql=List[str]();
while(itemDate != EndDate):
myDate=DateTime.Parse(("{0}").format(itemDate));
fldKey=("F{0}_{1}_{2}").format(myDate.Year,myDate.Month,myDate.Day);#这里的字段名要和前面构建的SQL字段对应
header.AddChild(fldKey,LocaleValue(str(("{0}-{1}-{2}").format(myDate.Year,myDate.Month,myDate.Day)),localEid),SqlStorageType.SqlDecimal);
nextDate=myDate.AddDays(1);
itemDate=str(nextDate);
myDate=DateTime.Parse(("{0}").format(itemDate));
fldKey=("F{0}_{1}_{2}").format(myDate.Year,myDate.Month,myDate.Day);#这里的字段名要和前面构建的SQL字段对应
header.AddChild(fldKey,LocaleValue(str(("{0}-{1}-{2}").format(myDate.Year,myDate.Month,myDate.Day)),localEid),SqlStorageType.SqlDecimal);
#设置列的索引,使其可以按照以上列头构建的顺序显示
colIndex=0;
for child in header.GetChilds():
if(child.GetChildCount()==0):
child.ColIndex=colIndex;
colIndex=colIndex+1;
else:
child.ColIndex = colIndex;
colIndex=colIndex+1;
for childHeader in child.GetChilds():
childHeader.ColIndex=colIndex;
colIndex=colIndex+1;
return header;
#设置报表表头字段值
#这里主要是把过滤框设置的字段值,显示到报表表头
def GetReportTitles(Filter):
reportTitles=ReportTitles();
custFilter=Filter.FilterParameter.CustomFilter;#获取过滤框的数据包
orgObj=custFilter["F_BPW_OrgId"];#获取组织
beginDate=str(custFilter["F_BPW_BeginDate"]);#获取开始日期
EndDate=str(custFilter["F_BPW_EndDate"]);#获取结束日期
if(orgObj != None):
reportTitles.AddTitle("F_BPW_OrgId", orgObj["Name"]);
reportTitles.AddTitle("F_BPW_BeginDate", beginDate);
reportTitles.AddTitle("F_BPW_EndDate", EndDate);
return reportTitles;
#设置报表底部合计列
def GetSummaryColumnInfo(rptfilter):
result=List[SummaryField]();
#由于这里的数量字段是动态构建的,所以也需要动态添加合计列,字段名与前面保持一致
custFilter = rptfilter.FilterParameter.CustomFilter;
beginDate=str(custFilter["F_BPW_BeginDate"]);#获取开始日期
EndDate=str(custFilter["F_BPW_EndDate"]);#获取结束日期
itemDate=beginDate;
fldsSql=List[str]();
while(itemDate != EndDate):
myDate=DateTime.Parse(("{0}").format(itemDate));
fldKey=("F{0}_{1}_{2}").format(myDate.Year,myDate.Month,myDate.Day);#这里的字段名要和前面构建的SQL字段对应
result.Add(SummaryField(fldKey,BOSEnums.Enu_SummaryType.SUM));
nextDate=myDate.AddDays(1);
itemDate=str(nextDate);
myDate=DateTime.Parse(("{0}").format(itemDate));
fldKey=("F{0}_{1}_{2}").format(myDate.Year,myDate.Month,myDate.Day);
result.Add(SummaryField(fldKey,BOSEnums.Enu_SummaryType.SUM));
return result;
#报表关闭触发,通常在此处清理报表过程产生的临时表
def CloseReport():
this.DropTempTable();