使用操作插件把附件反写到上游单据原创
金蝶云社区-eris
eris
11人赞赏了该文章 1968次浏览 未经作者许可,禁止转载编辑于2021年08月24日 10:36:11

1、说明

单据A携带“单据A附件”下推生成单据B,单据B新增附件“单据B附件”,并下推生成单据C,单据C新增附件“单据C附件”之后,点击保存或审核,把“单据B附件”和"单据C附件”反写到单据A。

2. 编写操作插件,并在保存操作上注册插件,如下图:

image.png

3. 运行效果

image.png

4. 操作插件代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.Interaction;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Util;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.BusinessFlow.ServiceArgs;
using Kingdee.BOS.App.Core.BusinessFlow;
using Kingdee.BOS.BusinessEntity.BusinessFlow;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.App.Core;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.App.Core.Query;
using Kingdee.BOS.Core.Metadata.FieldElement;
namespace Kingdee.BOS.TestPlugIn.FormOperationPlugIn
{
    [HotUpdate]
    [Description("单据操作插件")]
    public class BillAOperationPlugIn : AbstractOperationServicePlugIn
    {
        /// <summary>
        ///  在操作事务后处理
        /// </summary>
        /// <param name="e"></param>
        public override void AfterExecuteOperationTransaction(AfterExecuteOperationTransaction e)
        {
            base.AfterExecuteOperationTransaction(e);
            //得到所有保存操作成功的数据
            var succIndexs = this.OperationResult.OperateResult.Where(x => x.SuccessStatus).Select(x => x.DataEntityIndex);
            if (succIndexs.Count() == 0) return;
            List<DynamicObject> succObjs = new List<DynamicObject>();
            foreach (var index in succIndexs)
            {
                succObjs.Add(e.DataEntitys[index]);
            }
           
            //得到所有关联数据
            var entity = this.BusinessInfo.GetEntity("FEntity1");
                  var formId = this.BusinessInfo.GetForm().Id;
            var dicPkIdAndEntityId = this.GetEntityPkIds(succObjs, entity);
            List<long> relateEntityPkIds = new List<long>();
            dicPkIdAndEntityId.Values.ToList().ForEach(x => relateEntityPkIds.AddRange(x));
            StringBuilder sql = new StringBuilder();
            var bfMetaService = new BusinessFlowMetadataService();
            List<BusinessFlowTracker> allTrack = new List<BusinessFlowTracker>();
           using (SessionScope scope = new SessionScope())
            {
                BusinessFlowDataService bfService = new BusinessFlowDataService();
                var instArgs = new ReadInstDatasWithHisArgs("KKK_BillC", "FEntity1", relateEntityPkIds.ToArray());
                instArgs.IsGetInst = false;
                instArgs.IsGetAmount = false;
                var bfResult = bfService.LoadInstDatasWithHis(this.Context, instArgs);
                var trackType = new BusinessFlowTrackerType(BOSTableConst.BF_Instance, BOSTableConst.BF_InstanceEntry, BOSTableConst.BF_InstanceAmount); ;
                sql.AppendFormat("SELECT FRouteId,FInstanceId,FSTableName,FSID,FTTableName,FTID,FFirstNode FROM {0} ", bfResult.TmpTableEntry);
                using (IDataReader reader = DBUtils.ExecuteReader(this.Context, sql.ToString()))
                {
                    while (reader.Read())
                    {
                        var instanceId = reader["FInstanceId"] as String;
                        var route = new BusinessFlowTracker(new DynamicObject(trackType));
                        route.InstanceId = instanceId;
                        route.Id = reader["FRouteId"] as String;
                        route.SourceTableName = reader["FSTableName"] as String;//.ToString();
                        route.SourceId = Convert.ToInt64(reader["FSID"]);
                        route.TargetTableName = reader["FTTableName"] as String;
                        route.TargetId = Convert.ToInt64(reader["FTID"]);
                        route.FirstNode = (reader["FFirstNode"] as String) == "1";
                        allTrack.Add(route);
                    }
                }
                DBUtils.DropSessionTemplateTable(this.Context, bfResult.TmpTableMasterIds);
                DBUtils.DropSessionTemplateTable(this.Context, bfResult.TmpTableEntry);
            }
                  if (allTrack.Count > 0) //存在关联数据
            {
                //取到所有单据头附件
                var pkIds = succObjs.Select(x => Convert.ToInt64(x["Id"]));
                Dictionary<long, List<long>> dicBillIDAndAttId = new Dictionary<long, List<long>>(); //单据内码和附件内码的集合
                List<SqlParam> lstParam = new List<SqlParam>();
                long[] disPkIds = pkIds.Distinct().ToArray();
                String sqlWithCard = StringUtils.GetSqlWithCardinality(disPkIds.Length, "@PkId", 1);
                lstParam.Add(new SqlParam("@PkId", KDDbType.udt_inttable, disPkIds));
                lstParam.Add(new SqlParam("@FormId", KDDbType.AnsiString, formId));
                var sql1 = string.Format("select t0.FID,t0.FINTERID from T_BAS_ATTACHMENT t0 INNER JOIN {0} t1 ON t0.FInterId=t1.FID " +
                          "Where t0.FBillType =@FormId and t0.FEntryInterId = '-1' ", sqlWithCard);
                using (IDataReader reader1 = DBUtils.ExecuteReader(this.Context, sql1, lstParam))
                {
                    while (reader1.Read())
                    {
                        var billId = Convert.ToInt64(reader1["FINTERID"]);
                        var attachId = Convert.ToInt64(reader1["FID"]);
                        if (dicBillIDAndAttId.ContainsKey(billId))
                        {
                            dicBillIDAndAttId[billId].Add(attachId);
                        }
                        else
                        {
                            dicBillIDAndAttId[billId] = new List<long>() { attachId };
                        }
                    }
                }
              //得到所有单据C对应的单据A
                TableDefine billATableDefine = bfMetaService.LoadTableDefine(this.Context, "KKK_BillA", "FEntity");
                TableDefine billCTableDefine = bfMetaService.LoadTableDefine(this.Context, "KKK_BillC", "FEntity1");
                Dictionary<long, List<long>> dicBillCPKIdAndBillAEntityId = new Dictionary<long, List<long>>();
                foreach (var item in dicPkIdAndEntityId)
                {
                    List<string> cId = new List<string>();
                    item.Value.ForEach(x => cId.Add(billCTableDefine.TableNumber + "," + x.ToString()));
                    var filterInstanceIds  = allTrack.Where(x => cId.Contains(x.TargetCId)).Select(x=>x.InstanceId);
                   dicBillCPKIdAndBillAEntityId[item.Key]= allTrack.Where(x => filterInstanceIds.Contains(x.InstanceId) && 
                       x.SourceTableName == billATableDefine.TableNumber).Select(x => x.SourceId).ToList();
                }
                //得到单据A的所有内码
                 Dictionary<long, List<long>> dicBillCPKIdAndBillAPkId = new Dictionary<long, List<long>>();
                var billABInfo = this.LoadBusinessInfo("KKK_BillA");
                var pkName = billABInfo.GetForm().PkFieldName;
                var billAEntity = billABInfo.GetEntity("FEntity");
                List<long> billAPKIdId = new List<long>();
                if (billAEntity is HeadEntity) //如果是单据头直接等于
                {
                    dicBillCPKIdAndBillAPkId = dicBillCPKIdAndBillAEntityId;
                    dicBillCPKIdAndBillAEntityId.Values.ToList().ForEach(x => billAPKIdId.AddRange(x));
                }
               else
                {
                     List<long> billAEntityId = new List<long>();
                    dicBillCPKIdAndBillAEntityId.Values.ToList().ForEach(x => billAEntityId.AddRange(x));
                    var entityPkName = string.Concat(billAEntity.Key, "_", billAEntity.EntryPkFieldName);
                    QueryBuilderParemeter qbParemeter = new QueryBuilderParemeter();
                    qbParemeter.FormId = billABInfo.GetForm().Id;
                    qbParemeter.SelectItems.Add(new SelectorItemInfo(pkName));
                    qbParemeter.SelectItems.Add(new SelectorItemInfo(entityPkName));
                    qbParemeter.FilterClauseWihtKey = string.Format(entityPkName+" in ({0}) ", string.Join(",",billAEntityId.ToArray()));
                    QueryService dataReader = new QueryService();
                    DynamicObjectCollection rows = dataReader.GetDynamicObjectCollection(this.Context, qbParemeter);
                    foreach (var item in dicBillCPKIdAndBillAEntityId)
                    {
                       var billPkIds=  rows.Where(x => item.Value.Contains(Convert.ToInt64(x[entityPkName]))).Select(x =>Convert.ToInt64(x[pkName])).Distinct().ToList();
                       billAPKIdId.AddRange(billPkIds);
                       dicBillCPKIdAndBillAPkId[item.Key] = billPkIds;
                    }
                }
                //把到单据C复制一份到单据A
                var attBInfo = this.LoadBusinessInfo("BOS_Attachment");
                var dynamicType = attBInfo.GetDynamicObjectType(); //附件实体类型
                var createTime = (new TimeService()).GetSystemDateTime(this.Context);
                foreach (var item in dicBillCPKIdAndBillAPkId)
                {
                    if (dicBillIDAndAttId.ContainsKey(item.Key)) //单据C存在附件
                    {
                        var attachIds = dicBillIDAndAttId[item.Key];
                        QueryBuilderParemeter qbParemeter = new QueryBuilderParemeter();
                        qbParemeter.FormId = attBInfo.GetForm().Id;
                        qbParemeter.FilterClauseWihtKey = string.Format("FINTERID ={0} and FFileId not in( select FFileId from T_BAS_ATTACHMENT where FBILLTYPE='{1}' and FINTERID in ({2}) )",
                                                                   item.Key, billABInfo.GetForm().Id, string.Join(",", item.Value.ToArray()));
                        IViewService viewService = ServiceFactory.GetViewService(this.Context);
                        DynamicObject[] srcDynObjs = viewService.LoadFromCache(this.Context, dynamicType, qbParemeter);
                        if(srcDynObjs.Length ==0) return;
                        //把单据C附件复制到单据A
                        List<DynamicObject> lstTargetObjs = new List<DynamicObject>();
                        int index = 0;
                        var multiLangField = attBInfo.GetField("FAttachmentDes");
                        foreach (var billAPkid in item.Value)
                        {
                            foreach (var srcObj in srcDynObjs)
                            {
                                var pkId = ObjectUtils.Object2Int(srcObj["Id"]);
                                var targetObj = new DynamicObject(dynamicType);
                                targetObj["BillType"] = billABInfo.GetForm().Id;
                                targetObj["InterID"] = billAPkid;
                                targetObj["EntryInterID"] = -1;
                                targetObj["EntryKey"] = "";
                                targetObj["CreateTime"] = createTime;
                                targetObj["AttachmentSize"] = srcObj["AttachmentSize"];
                                targetObj["AttachmentName"] = srcObj["AttachmentName"];
                                targetObj["AttachmentDes"] = srcObj["AttachmentDes"];
                                targetObj["FBillStatus"] = "A";
                                targetObj["Attachment"] = srcObj["Attachment"];
                                targetObj["CreateMen_Id"] = ObjectUtils.Object2Int(this.Context.UserId);
                                targetObj["FileId"] = srcObj["FileId"];
                                targetObj["AliasFileName"] = srcObj["AliasFileName"];
                                targetObj["ExtName"] = srcObj["ExtName"];
                                targetObj["FileStorage"] = srcObj["FileStorage"];
                                targetObj["IsAllowDownLoad"] = ObjectUtils.Object2Bool(srcObj["IsAllowDownLoad"]);
                                var srcMultiLangObjs = srcObj["MultiLanguageText"] as LocalDynamicObjectCollection;
                                var targetMultiLangObjs = targetObj["MultiLanguageText"] as LocalDynamicObjectCollection;
                                if (!srcMultiLangObjs.IsEmpty() && targetMultiLangObjs != null)
                                {
                                    targetMultiLangObjs.Clear();
                                    //  var lstMultiSeq = seqReader.GetSequence<Int32>("T_BAS_ATTACHMENT_L", srcMultiLangObjs.Count).ToList();
                                    int subIndex = 0;
                                    foreach (var multiObj in srcMultiLangObjs)
                                    {
                                        var targetMutilLangObj = new DynamicObject(multiObj.DynamicObjectType);
                                        //   targetMutilLangObj["PkId"] = lstMultiSeq[subIndex];
                                        targetMutilLangObj["LocaleId"] = ObjectUtils.Object2Int(multiObj["LocaleId"]);
                                        targetMutilLangObj[multiLangField.PropertyName] = ObjectUtils.Object2String(multiObj[multiLangField.PropertyName]);
                                        targetMultiLangObjs.Add(targetMutilLangObj);
                                        subIndex++;
                                    }
                                }
                                lstTargetObjs.Add(targetObj);
                                index++;
                            }
                        }
                        SaveService saveService = new SaveService();
                        saveService.Save(this.Context, attBInfo, lstTargetObjs.ToArray(), null);
                    }
                }
               
            }
        }
         /// <summary>
        /// 加载单据的元数据包
        /// </summary>
        /// <param name="formId"></param>
        /// <returns></returns>
        private BusinessInfo LoadBusinessInfo(string formId)
        {
            IMetaDataService service = new MetaDataService();
            var metadata = service.Load(this.Context, formId) as FormMetadata;
            return metadata.BusinessInfo;
        }
        /// <summary>
        /// 得到关联实体内码
        /// </summary>
        /// <param name="dataObjects"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        private  Dictionary<long, List<long>> GetEntityPkIds(List<DynamicObject> dataObjects, Entity entity)
        {
            Dictionary<long, List<long>> dicPKId = new Dictionary<long, List<long>>();
            foreach (var dataObj in dataObjects)
            {
                var pkId =Convert.ToInt64( dataObj[0]);
                if (entity is HeadEntity)//实体为单据头
                {
                    dicPKId[pkId] = new List<long>() { pkId };
                }
                else//实体为单据体或子单据头
                {
                    var dynObjs = (DynamicObjectCollection)entity.DynamicProperty.GetValue(dataObj);
                    dicPKId[pkId] = dynObjs.Select(x => Convert.ToInt64(x[0])).ToList();
                }
            }
            return dicPKId;
        }
    }
}





赞 11