现需要通过插件在点击按钮时,实现:复制当前整张单据(包括单据头以及所有单据体),更改其中部分字段后保存生成新的单据。
通过Clone复制单据信息,更该字段后再通过ISaveService进行保存;
public override void EndOperationTransaction(EndOperationTransactionArgs e) { base.EndOperationTransaction(e); if (e.DataEntitys.Length > 0) { for (int i = 0; i < e.DataEntitys.Length; i++) { string billno = e.DataEntitys[i]["BillNO"].ToString(); //e.DataEntitys[i].Clone(); IViewService ivs = Kingdee.BOS.App.ServiceHelper.GetService(); MetaDataService metaService = new MetaDataService(); FormMetadata formmeta = metaService.Load(this.Context, "YL_T_TMS_ForwardInfo") as FormMetadata; DynamicObjectType dt = formmeta.BusinessInfo.GetDynamicObjectType(); DynamicObject[] dyos = ivs.Load(this.Context, new object[] {e.DataEntitys[i]["Id"]}, dt); if (dyos.Length > 0) { DynamicObject[] dyosclon = dyos.Clone() as DynamicObject[]; if (dyosclon != null) { IEnumerable infopk =ServiceHelper.GetService().GetSequenceInt64(this.Context, "YL_T_TMS_ForwardInfo", 1); dyosclon[0]["Id"] = infopk.ElementAt(0); dyosclon[0]["BillNo"] = dyosclon[0]["BillNo"] + "QC"; //dyosclon[0][""] DynamicObjectCollection forwardInfoForw =dyosclon[0]["YL_T_TMS_ForwardInfoForw"] as DynamicObjectCollection; if (forwardInfoForw.Count > 0) { //int[] forwpk = ServiceHelper.GetService().GetSequenceInt32(this.Context, "YL_T_TMS_ForwardInfoForw", forwardInfoForw.Count); //for (int j = 0; j < forwardInfoForw.Count; j++) //{ // forwardInfoForw[j]["Id"] = forwpk[j]; //} forwardInfoForw.Clear(); } DynamicObjectCollection dyocmat = dyosclon[0]["YL_T_TMS_ForwardInfoMAT"] as DynamicObjectCollection; if (dyocmat.Count > 0) { //int[] matpk = ServiceHelper.GetService().GetSequenceInt32(this.Context, "YL_T_TMS_ForwardInfoMAT", dyocmat.Count); for (int j = 0; j < dyocmat.Count; j++) { dyocmat[j]["Id"] = infopk.ElementAt(0); } } ISaveService ise = Kingdee.BOS.App.ServiceHelper.GetService(); ise.Save(this.Context, formmeta.BusinessInfo, dyosclon); } } } } }
①先根据单据ID调用Load方法加载出完整的数据包:
formID="PUR_PurchaseOrder";#单据FormId
meta = MetaDataServiceHelper.Load(this.Context, formID);#读取单据的元数据
objType=meta.BusinessInfo.GetDynamicObjectType();#获取单据数据包的对象类型
注意:如果是当前单据,可以直接通过this.BusinessInfo获取元数据信息
formID=this.BusinessInfo.GetForm().Id; #当前单据的FormId
objType=this.BusinessInfo.GetDynamicObjectType();
#根据单据内码集合读取多个单据的完整数据包
billObjs=BusinessDataServiceHelper.Load(this.Context, pkIds.ToArray(),objType);
#根据单据内码读取一个单据的完整数据包
obj=BusinessDataServiceHelper.LoadSingle(this.Context, "10001", objType);
②调用调用Clone方法复制单据数据包:需要引用 Kingdee.BOS.DataEntity.dll
C#插件中添加引用:using Kingdee.BOS.Orm;
可以直接调用Clone, newObj=obj.Clone() as DynamicObject;
或者直接 :newObj=Kingdee.BOS.Orm.OrmUtils.Clone(linkObj);
上面2种写法都可以,除了写法不同,其他是一样的。
#Python插件添加引用信息后,直接newObj=OrmUtils.Clone(linkObj);仅此一种写法
③调用Save方法,保存复制出来的新单据数据包,创建新的单据:
ObjList=List[DynamicObject]();#单据的数据包集合
ObjList.Add(newObj);
#注意!调用保存时,传入的必须是完整的单据数据包
#Q:既然是Save方法,为什么还要传操作代码"Save"呢?
#A:Save方法调用的是单据操作列表中,"操作类型=保存"的操作,可以为单据添加多个"操作类型=保存"的操作。
#例如,可以添加一个"OnlySave",这个操作不注册任何服务插件和服务端服务,仅用于保存单据数据到数据库
saveRslt=BusinessDataServiceHelper.Save(this.Context, meta.BusinessInfo,ObjList.ToArray(), None, "Save");
if(saveRslt.IsShowMessage):#读取保存操作结果数据
OperationResultExt.MergeValidateErrors(saveRslt);
msg="";
msglst=list(rst.Message for rst in saveRslt.OperateResult);
msg=("{0}").format("\r\n".join(msglst));#拼接提示信息
注意:单据上不能复制的字段,要自行清空,例如,一些由下游业务反写回来的字段...等等!
Clone方法是默认清除主键ID信息的,所以单据ID、明细ID等等主键复制问题,可以暂时不处理!