复制整张单据并保存原创
金蝶云社区-独眼兽
独眼兽
78人赞赏了该文章 735次浏览 未经作者许可,禁止转载编辑于2023年11月15日 14:14:07

现需要通过插件在点击按钮时,实现:复制当前整张单据(包括单据头以及所有单据体),更改其中部分字段后保存生成新的单据。
  通过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等等主键复制问题,可以暂时不处理!


赞 78