using FactorySystemBll;
using FactorySystemCommon;
using FactorySystemModel.BusinessModel;
using FactorySystemModel.EnumModel;
using FactorySystemModel.ResponseModel;
using FactorySystemModel.SqlSugarModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Web.Http;
using System.Data;
using System.IO;
using Newtonsoft.Json.Linq;
using FactorySystemApi.Plm_Formula;
using System.Linq;
using SqlSugar;
using Aspose.Cells;
using System.Web;
using System.Web.Http.Results;

namespace FactorySystemApi.Controllers
{
    /// <summary>
    /// 协同接口
    /// </summary>
    [UserLoginFilter]
    public class TeamworkController : BaseController<TFS_FTeamwork>
    {
        /// <summary>
        /// 数据处理层
        /// </summary>
        public readonly TeamworkBll TeamworkBll = new TeamworkBll();
        /// <summary>
        /// 事项操作日志
        /// </summary>
        public readonly OperateLogBll OperateLogBll = new OperateLogBll();
        /// <summary>
        /// 初始化
        /// </summary>
        public TeamworkController()
        {
            //设置可新增、修改字段
            InsertField = UpdateField = "";
        }

        /// <summary>
        /// 获取子项集合
        /// </summary>
        [HttpPost]
        public ApiResult GetTeamworkPageList(Dictionary<string, object> pageParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                apiResult.Data = new
                {
                    List = TeamworkBll.GetTeamworkPageList(pageParam, user.FID, out int totalCount),
                    Total = totalCount
                };
            }, apiResult, Request, pageParam);
        }

        /// <summary>
        /// 获取流程集合
        /// </summary>
        [HttpPost]
        public ApiResult GetTeamProcessList(Dictionary<string, object> pageParam)
        {
            return GetTPageList<TFS_FTeamProcess>(pageParam, null, "FGroup,FType");
        }

        /// <summary>
        /// 新增协同
        /// </summary>
        [HttpPost]
        public override ApiResult InsertDataModel(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                //对接获取
                inParam.Add("FMdmCode", GetMdmCode(inParam));
                //var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                //inParam.Add("FMdmCode", ts.TotalSeconds.ToString("F0"));
                if (!inParam.ContainsKey("FMdmCode") || string.IsNullOrEmpty(inParam["FMdmCode"].ToString().Trim()))
                {
                    apiResult.Error("获取MDM失败");
                }
                else if (TeamworkBll.CheckTeamName(inParam["FSaleCode"].ToString()))
                {
                    apiResult.Error("销售号已存在！");
                }
                else
                {
                    inParam.TryGetValue("FState", out object state);
                    if (null == state) { 
                        inParam["FState"] = state = 1; 
                    }
                    inParam.Remove("FID");
                    ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                    if (inParam.ContainsKey("FAddUser")) { 
                        inParam["FAddUser"] = user.FID; 
                    } else { 
                        inParam.Add("FAddUser", user.FID);
                    }
                    if (inParam.ContainsKey("FEditUser")) { 
                        inParam["FEditUser"] = user.FID;
                    }  else { 
                        inParam.Add("FEditUser", user.FID);
                    }
                    if (inParam.ContainsKey("FEditDate")) {
                        inParam["FEditDate"] = DateTime.Now; 
                    } else {
                        inParam.Add("FEditDate", DateTime.Now); 
                    }
                    //TUser tUser = BaseBll.GetTempModel<TUser>(user.FID);
                    TFS_Factory factory = BaseBll.GetTempModel<TFS_Factory>(int.Parse(inParam["FCreateFactoryID"].ToString()));
                    if (inParam.ContainsKey("FCreateFactoryID")) 
                    {
                        inParam.Remove("FCreateFactoryID");
                    }
                    inParam.Add("FCreateFactoryID", factory.FID);
                    inParam.Add("FCreateFactoryCode", factory.FCode);
                    inParam.Add("FCreateFactoryType", factory.FType);
                    if (factory.FType != (int)Constant.FactoryType.单工厂) {
                        factory = BaseBll.GetTempModel<TFS_Factory>(factory.FFactoryID);
                        inParam.Add("FProdFactoryID", factory.FID);
                        inParam.Add("FProdFactoryCode", factory.FCode);
                    } else {
                        inParam.Add("FProdFactoryID", factory.FID);
                        inParam.Add("FProdFactoryCode", factory.FCode);
                    }
                    //创建 TFS_FTeamwork 
                    int teamId = BaseBll.InsertDataModel(inParam, "TFS_FTeamwork");
                    apiResult.Data = teamId;
                    if (teamId > 0) {
                        inParam.Add("FID", teamId);
                        //创建流程
                        int resultProcessCreate = TeamworkBll.CreateProcessData(teamId, user.FID);
                        if (resultProcessCreate > 0) {
                            //直接走下一步
                            if (state.ToString().Contains("1")) {
                                TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
                                //List<TFS_Material> materialList = TeamworkBll.CheckMaterialListByTest(teamwork.FTestCode, teamwork.FVersionCode);
                                List<TFS_Material> materialList = TeamworkBll.CheckMaterialListByTest(teamwork.FFormulaTestCode, teamwork.FVersionCode);
                                if (materialList.Count == 0) {
                                    TeamworkBll.CreateProductView(teamwork, null, user.FID);

                                    // 20230726 不论新增或暂存，都在创建协同时生成成品事项
                                    BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                                    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);

                                    //开始BOM下载
                                    DockGetBomData(teamwork.FID, user.FID);
                                }
                                else {
                                    TeamworkBll.CreateProductView(teamwork, materialList, user.FID);

                                    // 20230726 不论新增或暂存，都在创建协同时生成成品事项
                                    BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                                    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);

                                    TeamworkBll.HasMaterialTestCode(teamwork);

                                    /**
                                    * 20230414 需求变更
                                    * 在创建各类事项前，先创建物料分类事项
                                    * 此处创建各类事项流程中断，转移至物料分类事项提交后进行
                                    * **/
                                    BaseBll.CreateTaskData(teamwork.FID, user.FID, "15"); //新增物料分类事项
                                    BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.物料分类, 2, 1); // 更新物料分类流程

                                    ////补充包材规格
                                    //BaseBll.CreateTaskData(teamId, user.FID, "14");
                                    ////成品视图
                                    //BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                                    ////成品视图物料组复核，有权限的所有
                                    //BaseBll.CreateTaskData(teamwork.FID, user.FID, "12");
                                    //teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
                                    //if (teamwork.FPackID == -1) {
                                    //    //新增新包材事项
                                    //    BaseBll.CreateTaskData(teamId, user.FID, "9");
                                    //    BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.组装BOM包含新包材, 2, 1);
                                    //} else {
                                    //    BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.组装BOM包含新包材, 3, 2);
                                    //}
                                    //BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.协同发起, 3, 2);
                                    //BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);
                                }
                            }
                            else
                            {
                                // 20230726 不论新增或暂存，都在创建协同时生成成品事项
                                TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
                                TeamworkBll.CreateProductView(teamwork, null, user.FID);
                                BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                                BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);

                                BaseBll.CreateTaskData(teamId, user.FID, ((int)Constant.TaskType.配方选择).ToString());
                                BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.协同发起, 1, 1);
                            }
                        }
                        else
                        {
                            BaseBll.DeleteDataById(teamId, "TFS_FTeamwork", true);
                            apiResult.Error("流程创建失败，请稍后重试");
                        }
                        TeamworkBll.ChangeTeamProcess(teamId);
                    }
                }
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 修改协同
        /// </summary>
        [HttpPost]
        public override ApiResult UpdateDataModel(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                inParam.TryGetValue("FState", out object state);
                if (null == state) { inParam["FState"] = state = 1; }
                inParam.Remove("FEditUser");
                inParam.Remove("FEditDate");
                inParam.Add("FEditUser", user.FID);
                inParam.Add("FEditDate", DateTime.Now);
                apiResult.Data = UpdateData(inParam);
                int updateCount = BaseBll.UpdateDataModel(inParam, "TFS_FTeamwork");
                if (updateCount > 0)
                {
                    if (state.ToString().Contains("1"))
                    {
                        int teamId = int.Parse(inParam["FID"].ToString());
                        TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
                        List<TFS_Material> materialList = TeamworkBll.CheckMaterialListByTest(teamwork.FTestCode, teamwork.FVersionCode);
                        if (materialList.Count == 0)
                        {
                            if (!TeamworkBll.UpdateProductView(teamwork, user.FID))
                            {
                                TeamworkBll.CreateProductView(teamwork, null, user.FID);
                            }                            
                            //开始BOM下载
                            DockGetBomData(teamwork.FID, user.FID);
                        }
                        else
                        {
                            if (!TeamworkBll.UpdateProductView(teamwork, user.FID))
                            {
                                TeamworkBll.CreateProductView(teamwork, materialList, user.FID);
                            }

                            TeamworkBll.HasMaterialTestCode(teamwork);

                            /**
                            * 20230414 需求变更
                            * 在创建各类事项前，先创建物料分类事项
                            * 此处创建各类事项流程中断，转移至物料分类事项提交后进行
                            * **/
                            BaseBll.CreateTaskData(teamwork.FID, user.FID, "15"); //新增物料分类事项
                            BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.物料分类, 2, 1); // 更新物料分类流程

                            //if (teamwork.FPackID == -1)
                            //{
                            //    BaseBll.CreateTaskData(teamId, user.FID, "9");//新增新包材事项
                            //    BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.组装BOM包含新包材, 2, 1);
                            //}
                            //else
                            //{
                            //    BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.组装BOM包含新包材, 3, 2);
                            //}
                            //BaseBll.CreateTaskData(teamId, user.FID, "14");//补充包材规格
                            //BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.协同发起, 3, 2);
                            //BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.成品视图, 2, 1);
                        }
                        TeamworkBll.ChangeTeamProcess(teamId);
                        TeamworkBll.CloseUpdateTeamTask(teamId);
                    }
                }
                apiResult.Data = inParam["FID"];
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 手动对接BOM下载
        /// </summary>
        [HttpPost]
        public ApiResult DockDownBomData(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam.ContainsKey("FTeamID"))
                {
                    ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                    int teamId = int.Parse(inParam["FTeamID"].ToString());
                    apiResult.Data = DockGetBomData(teamId, user.FID);
                }
                else
                {
                    apiResult.Error("获取协同信息失败");
                }
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 获取协同视图信息
        /// </summary>
        [HttpPost]
        public ApiResult GetTeamworkView(Dictionary<string, object> inParam)
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() =>
            {
                if (inParam.ContainsKey("FTeamID"))
                {
                    inParam.TryGetValue("FViewType", out object objType);
                    int intType = null == objType ? (int)Constant.TeamViewType.物料视图 : int.Parse(objType.ToString());
                    string selectSql = "", joinSql = "", whereSql = string.Format("TFS_FTeamwork.FID={0} ", inParam["FTeamID"]);
                    string basePath = AppDomain.CurrentDomain.BaseDirectory.Trim('\\');
                    string savePath = basePath + string.Format("\\File\\Temp\\{0}_{1}\\", inParam["FTeamID"], intType);
                    if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
                    string tempPath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                    if (!Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath);
                    switch (intType)
                    {
                        case (int)Constant.TeamViewType.配方视图:
                            savePath += Constant.TeamViewType.配方视图.ToString();
                            //原始配方
                            whereSql = string.Format(@"dbo.StrExistInStr(TFS_ViewMaterial.FMaterialID,(select FMaterialFormulaIDs from TFS_FTeamwork where FID={0}))>0
                            and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FFactoryID=(select FProdFactoryID from TFS_FTeamwork where FID={0})", inParam["FTeamID"]);
                            //生产、计划配方
                            joinSql = string.Format(@"(dbo.StrExistInStr(TFS_ViewMaterial.FMaterialID,(select FMaterialFormulaIDs from TFS_FTeamwork where FID={0}))>0
                            and TFS_Material.FSuccedaneumID<1) and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FFactoryID=(select FProdFactoryID from TFS_FTeamwork where FID={0})",
                            inParam["FTeamID"]);
                            break;
                        case (int)Constant.TeamViewType.生产工艺路线视图:
                            savePath += Constant.TeamViewType.生产工艺路线视图.ToString();
                            //只要生产工厂
                            whereSql += string.Format(" and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FFactoryID in(select FID from TFS_Factory where FType={0})", (int)Constant.FactoryType.单工厂);
                            //视图类型
                            List<int> tempInt3_1 = new List<int>
                            {
                                (int)Constant.ViewType.成品视图,
                                (int)Constant.ViewType.半成品视图,
                                (int)Constant.ViewType.香基视图,
                                (int)Constant.ViewType.中间品视图
                            };
                            whereSql += string.Format(" and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FViewType in({0})", string.Join(",", tempInt3_1));
                            break;
                        case (int)Constant.TeamViewType.生产版本视图:
                            savePath += Constant.TeamViewType.生产版本视图.ToString();
                            //只要生产工厂
                            whereSql += string.Format(" and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FFactoryID in(select FID from TFS_Factory where FType={0})", (int)Constant.FactoryType.单工厂);
                            //视图类型
                            List<int> tempInt4_1 = new List<int>
                            {
                                (int)Constant.ViewType.成品视图,
                                (int)Constant.ViewType.半成品视图,
                                (int)Constant.ViewType.中间品视图,
                                (int)Constant.ViewType.香基视图
                            };
                            whereSql += string.Format(" and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FViewType in({0})", string.Join(",", tempInt4_1));
                            break;
                        case (int)Constant.TeamViewType.组装BOM视图:
                            savePath += Constant.TeamViewType.组装BOM视图.ToString();
                            //一级半成品、包材→无替代料的
                            whereSql = string.Format(@"(dbo.StrExistInStr(TFS_ViewMaterial.FMaterialID,(select FMaterialHalfIDs from TFS_FTeamwork where FID={0}))>0 or (
                            TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FMaterialID in(select FMaterialID from TFS_PackageChild where FTeamID={0}) or 
                            FPackageID=(select FPackID from TFS_FTeamwork where FID={0})))
                            ", inParam["FTeamID"]);
                            //只要生产工厂
                            whereSql += string.Format(" and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FFactoryID=(select FProdFactoryID from TFS_FTeamwork where FID={0})", inParam["FTeamID"]);
                            break;
                        case (int)Constant.TeamViewType.物料视图:
                        default:
                            savePath += Constant.TeamViewType.物料视图.ToString();
                            whereSql += " and TFS_ViewMaterial.FTeamType = 0 and TFS_ViewMaterial.FMaterialID>0";
                            break;
                    }
                    savePath += ".xlsx";

                    bool hasFinish = inParam.ContainsKey("FFinish");
                    if (hasFinish) savePath = savePath.Replace("\\File\\Temp\\", "\\File\\View\\");
                    if (!File.Exists(savePath) || !hasFinish)
                    {
                        if (inParam.ContainsKey("HalfId")) {
                            CreateExeclFile(intType, savePath, selectSql, whereSql, joinSql, inParam["FTeamID"].ToString(), inParam["HalfId"].ToString());
                        } else {
                            CreateExeclFile(intType, savePath, selectSql, whereSql, joinSql, inParam["FTeamID"].ToString(), "");
                        }
                    }
                    if (inParam.TryGetValue("FType", out objType) && objType.ToString().Equals("1"))
                    {
                        if (intType == (int)Constant.TeamViewType.配方视图)
                        {
                            apiResult.Data = new
                            {
                                List1 = NPOIHelper.ImportExceltoDt(savePath.Replace(".xlsx", "1.xlsx")),
                                List2 = NPOIHelper.ImportExceltoDt(savePath.Replace(".xlsx", "2.xlsx")),
                                List3 = NPOIHelper.ImportExceltoDt(savePath.Replace(".xlsx", "3.xlsx"))
                            };
                        }
                        else if (intType == (int)Constant.TeamViewType.生产版本视图 || intType == (int)Constant.TeamViewType.组装BOM视图)
                        {
                            //生产和计划
                            apiResult.Data = new
                            {
                                List1 = NPOIHelper.ImportExceltoDt(savePath.Replace(".xlsx", "1.xlsx")),
                                List2 = NPOIHelper.ImportExceltoDt(savePath.Replace(".xlsx", "2.xlsx")),
                            };
                        }
                        else
                        {
                            apiResult.Data = new
                            {
                                List1 = NPOIHelper.ImportExceltoDt(savePath)
                            };
                        }
                    }
                    else
                    {
                        if (savePath.Contains(Constant.TeamViewType.物料视图.ToString()))
                        {
                            apiResult.Data = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, "") + savePath.Replace(basePath, "").Replace("\\", "/").Replace(Constant.TeamViewType.物料视图.ToString(), "SAP视图");
                        }
                        else
                        {
                            apiResult.Data = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, "") + savePath.Replace(basePath, "").Replace("\\", "/");
                        }                        
                    }
                }
                else
                {
                    apiResult.Error("获取协同信息失败");
                }
            }, apiResult, Request, inParam);
        }

        /// <summary>
        /// 更新物料分类
        /// </summary>
        /// <param name="inParam"></param>
        /// <returns></returns>
        [HttpPost]
        public ApiResult EditTypeList(Dictionary<string, object> inParam) 
        {
            ApiResult apiResult = new ApiResult();
            return ExceptionHelper.TryReturnException(() => {
                if (inParam["tempId"] != null && inParam["taskId"]!=null)
                {
                    string sql = "";
                    JArray item = JArray.Parse(inParam["list"].ToString());
                    for (int i = 0; i < item.Count; i++)
                    {
                        JObject a = JObject.Parse(item[i].ToString());
                        sql += string.Format("update TFS_Material set FTypeID1={0},FTypeID2={1} where FID={2};", a["FTypeID1"].ToString(), a["FTypeID2"].ToString(), a["FMaterialID"].ToString());
                    }
                    int count = TeamworkBll.ExecSql(sql);
                    apiResult.Data = NextTask(int.Parse(inParam["tempId"].ToString()),int.Parse(inParam["taskId"].ToString()));
                }
                

            }, apiResult, Request, inParam);
            
        }

        #region 对接相关


        private int NextTask(int teamId,int taskId)
        {
            int result = 0;
            List<Specifications> specifList = new List<Specifications>() { new Specifications() };
            TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
            try
            {
                ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                TFS_Formula formula = BaseBll.GetTempModel<TFS_Formula>(teamwork.FFormulaID);
                OAService oAService = new OAService();
                //specifList[0].Code = formula.FTestCode;
                //specifList[0].Version = formula.FVersionCode;

                //修改
                specifList[0].SP = formula.FPlmCode;
                specifList[0].SP_Version = formula.FVersionCode;

                InputSpecifications oaParam = new InputSpecifications();
                oaParam.USERNAME = AppSettingsHelper.GetAppSettingVal("Plm_Formula_Username");
                oaParam.PASSWORD = AppSettingsHelper.GetAppSettingVal("Plm_Formula_Password"); ;

                oaParam.Specifications = specifList.ToArray();

                RestResult restResult = oAService.GetSpecificationsList(oaParam);
                string bomStr = restResult.data == null ? "[]" : restResult.data.ToString();
                ExceptionHelper.AddSystemJournal(Request, specifList[0], restResult,user.FID, "DockGetBomData");
                List<BomModel> bomList = JsonConvert.DeserializeObject<List<BomModel>>(bomStr);


                if (bomList != null && bomList.Count > 0) 
                {

                    //修改协同主数据
                    Dictionary<string, object> upParam = new Dictionary<string, object>
                        {
                            { "FID", teamwork.FID },
                            { "FBomState", 1 },
                            { "FBomJson", bomStr }
                        };
                    BaseBll.UpdateDataModel(upParam, "TFS_FTeamwork");
                    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.物料分类, 2, 2);
                    int count= TeamworkBll.ExecSql(BaseBll.GetTaskSql(taskId, 2, teamId, (int)Constant.ProcessType.物料分类));


                    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.替代品确认, 2, 1);
                    BaseBll.CreateTaskData(teamwork.FID, user.FID, "16");//替代品确认


                    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.协同发起, 3, 2);

                    if (teamwork.FPackID == -1)
                    {
                        BaseBll.CreateTaskData(teamwork.FID, user.FID, "9");//新增新包材事项
                        BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.组装BOM包含新包材, 2, 1);
                    }
                    else
                    {
                        BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.组装BOM包含新包材, 3, 2);
                    }
                    //等类型修改结束使用
                    //成品视图
                    BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                    //补充包材规格
                    BaseBll.CreateTaskData(teamwork.FID, user.FID, "14");
                    //成品视图物料组复核，有权限的所有
                    BaseBll.CreateTaskData(teamwork.FID, user.FID, "12");
                    TeamworkBll.ChangeTeamProcess(teamwork.FID);
                    result = 1;
                }

            }
            catch (Exception)
            {

                throw;
            }
            return result;
        }

        /// <summary>
        /// 对接获取Bom数据
        /// </summary>
        private int DockGetBomData(int teamId, int userId)
        {
            int result = 0;
            List<Specifications> specifList = new List<Specifications>() { new Specifications() };
            TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
            try
            {
                TFS_Formula formula = BaseBll.GetTempModel<TFS_Formula>(teamwork.FFormulaID);
                OAService oAService = new OAService();

                //specifList[0].Code = formula.FTestCode;
                //specifList[0].Code = formula.FPlmCode;
                //specifList[0].Version = formula.FVersionCode;

                //修改
                specifList[0].SP= formula.FPlmCode;
                specifList[0].SP_Version= formula.FVersionCode;

                InputSpecifications oaParam = new InputSpecifications();
                oaParam.USERNAME = AppSettingsHelper.GetAppSettingVal("Plm_Formula_Username");
                oaParam.PASSWORD = AppSettingsHelper.GetAppSettingVal("Plm_Formula_Password"); ;

                oaParam.Specifications = specifList.ToArray();

                RestResult restResult = oAService.GetSpecificationsList(oaParam);
                string bomStr = restResult.data == null ? "[]" : restResult.data.ToString();
                ExceptionHelper.AddSystemJournal(Request, specifList[0], restResult, userId, "DockGetBomData");
                List<BomModel> bomList = JsonConvert.DeserializeObject<List<BomModel>>(bomStr);
                if (bomList != null && bomList.Count > 0)
                {
                    //BOM数据梳理
                    Dictionary<string, object> bomResult = CheckBomMaterial(bomList, 0, new Random());
                    bomResult["formulaIds"] = bomResult["formulaIds"].ToString().Replace(",,", ",").Trim(',');
                    bomResult["halfIds"] = bomResult["halfIds"].ToString().Replace(",,", ",").Trim(',');
                    List<TFS_Material> mateList = (List<TFS_Material>)bomResult["mateList"];
                    List<TFS_ViewMaterial> viewList = (List<TFS_ViewMaterial>)bomResult["viewList"];
                    //日志分开写12
                    ExceptionHelper.AddSystemJournal(Request, null, mateList, userId, "CheckBomMaterial1");
                    ExceptionHelper.AddSystemJournal(Request, null, viewList, userId, "CheckBomMaterial2");
                    //BOM数据处理
                    if (TeamworkBll.AnalysisBomData(mateList, viewList, teamwork.FID, userId, null, bomResult["halfIds"].ToString()))
                    {
                        mateList.Clear(); viewList.Clear();
                        List<TFS_Formula> formulaList = (List<TFS_Formula>)bomResult["formulaList"];
                        //日志分开写3
                        ExceptionHelper.AddSystemJournal(Request, null, new { formulaIds = bomResult["formulaIds"], halfIds = bomResult["halfIds"], formulaList }, userId, "CheckBomMaterial3");
                        //2022-09-22：要求写入配方中间表（有子集就是配方，走配方逻辑）
                        new FormulaBll().DockingRecipeData(formulaList, userId);
                        //修改协同主数据
                        Dictionary<string, object> upParam = new Dictionary<string, object>
                        {
                            { "FID", teamwork.FID },
                            { "FBomState", 1 },
                            { "FBomJson", bomStr }
                        };
                        BaseBll.UpdateDataModel(upParam, "TFS_FTeamwork");

                        /**
                        * 20230414 需求变更
                        * 在创建各类事项前，先创建物料分类事项
                        * 此处创建各类事项流程中断，转移至物料分类事项提交后进行
                        * **/
                        BaseBll.CreateTaskData(teamwork.FID, userId, "15"); //新增物料分类事项
                        BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.物料分类, 2, 1); // 更新物料分类流程

                        ////协同发起事项
                        //BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.协同发起, 3, 2);
                        //BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);
                        //if (teamwork.FPackID == -1)
                        //{
                        //    BaseBll.CreateTaskData(teamwork.FID, userId, "9");//新增新包材事项
                        //    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.组装BOM包含新包材, 2, 1);
                        //}
                        //else
                        //{
                        //    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.组装BOM包含新包材, 3, 2);
                        //}
                        ////成品视图
                        //BaseBll.CreateTaskData(teamwork.FID, userId, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                        ////补充包材规格
                        //BaseBll.CreateTaskData(teamwork.FID, userId, "14");
                        ////成品视图物料组复核，有权限的所有
                        //BaseBll.CreateTaskData(teamwork.FID, userId, "12");
                        OperateLogBll.Add(2, teamwork.FID, 2, "BOM下载成功", userId);
                        TeamworkBll.ChangeTeamProcess(teamwork.FID);
                        result = 1;
                    }
                }
                else
                {
                    OperateLogBll.Add(2, teamwork.FID, 2, "BOM下载失败，BOM数据为空", userId);
                    BaseBll.CreateTaskData(teamwork.FID, userId, ((int)Constant.TaskType.BOM下载).ToString());
                    BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.协同发起, 2, 1);
                    TeamworkBll.ChangeTeamProcess(teamwork.FID);
                }
            }
            catch (Exception ex)
            {
                OperateLogBll.Add(2, teamwork.FID, 2, "BOM下载失败，请稍后重试（对接）", userId);
                BaseBll.CreateTaskData(teamwork.FID, userId, ((int)Constant.TaskType.BOM下载).ToString());
                BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.协同发起, 2, 1);
                ExceptionHelper.AddSystemJournal(Request, specifList[0], ex.Message, userId, "DockGetBomData");
            }
            //日志添加
            return result;
        }

        /// <summary>
        /// 递归梳理BOM
        /// </summary>
        /// <param name="dataList">需要解析的集合</param>
        /// <param name="materLevel">层级</param>
        /// <param name="random">内部定义会有问题，需要外部传入</param>
        /// <param name="parentId">父子级关系ID</param>
        private Dictionary<string, object> CheckBomMaterial(List<BomModel> dataList, int materLevel, Random random, int parentId = -1)
        {
            List<TFS_Material> mateList = new List<TFS_Material>();
            List<TFS_ViewMaterial> viewList = new List<TFS_ViewMaterial>();
            List<TFS_Formula> formulaList = new List<TFS_Formula>();
            string ids1 = "", ids2 = "";//需求变更ids2弃用
            if (dataList != null && dataList.Count > 0)
            {
                foreach (BomModel item in dataList)
                {
                    if (!string.IsNullOrWhiteSpace(item.SP)) 
                    {
                        item.Code = item.SP;
                    }
                    if (!string.IsNullOrWhiteSpace(item.SP_Version)) 
                    {
                        item.Version=item.SP_Version;
                    }
                    if (!string.IsNullOrWhiteSpace(item.SP_VALUE)) 
                    {
                        item.TestNO = item.SP_VALUE;
                    }

                    int dataId = random.Next(1, 99) * random.Next(1, 99);
                    dataId += random.Next(10, 99) * random.Next(10, 99) * 2;
                    dataId += random.Next(1, 99) * random.Next(1, 99) * 10;
                    TFS_Material material = new TFS_Material()
                    {
                        FID = DateTime.Now.DayOfYear * 10 + dataId,
                        FPlmCode = item.Code,
                        FName = item.Name,
                        //FCode = item.Code,
                        FType = item.Type.ToLower(),
                        FTestCode = item.TestNO,
                        FVersionCode = item.Version,
                        FParentID = parentId
                    };

                    TFS_ViewMaterial view = new TFS_ViewMaterial()
                    {
                        //FBaseFameCode = "",
                        //FBaseMaterialCode = material.FCode,
                        FBaseTestCode = material.FTestCode,
                        FExtraQuantity = item.Quantity,
                        FBaseMaterialDesc = material.FName,
                        FLevel = materLevel,
                        FBomMaterialID = material.FID
                    };
                    if (material.FType == "a" || material.FType == "f")
                    {
                        material.FType = "20";
                    }
                    else if (material.FType == "b" || material.FType == "bb" || material.FType == "i" || material.FType == "iz")
                    {
                        material.FType = "30";
                    }
                    else
                    {
                        material.FType = "40";
                    }

                    if (materLevel == 0)
                    {
                        material.FType = "20";
                        ids2 = material.FID + "";
                    }
                    if (material.FType == "40")
                    {
                        material.FCode = material.FPlmCode;
                        material.FPlmCode = "";
                    }

                    int.TryParse(material.FType, out int mType);
                    if (materLevel == 1) ids1 += material.FID + ",";
                    switch (mType)
                    {
                        case (int)Constant.MaterialType.产成品:
                            view.FViewType = 1;
                            break;
                        case (int)Constant.MaterialType.半成品:
                            view.FViewType = (int)Constant.ViewType.半成品视图;
                            break;
                        case (int)Constant.MaterialType.中间品:
                            view.FViewType = material.FName.Contains("香基") ? (int)Constant.ViewType.香基视图 : (int)Constant.ViewType.中间品视图;
                            break;
                        case (int)Constant.MaterialType.原辅料:
                            view.FViewType = (int)Constant.ViewType.原料视图;
                            view.FBaseMaterialCode = material.FCode;
                            //默认值不同
                            view.FPurchaseCompany = "kg";
                            view.FPurchaseCompanyCount = "1";
                            view.FPurchaseBaseCompanyCount = "1000";
                            view.FSaleAccountSettingGroup = "15";
                            view.FStorageTotalShelfLife = "7300";
                            view.FMRP2ExternalStoragePlace = "1000";
                            view.FPlanUnlimitedOverDelivery = "";
                            view.FAccountPriceControl = "V";
                            view.FAccountPriceDetermine = "2";
                            view.FAccountAccessType = "1000";
                            view.FAccountSaleOrderInventory = "1010";
                            break;
                    }
                    mateList.Add(material);
                    viewList.Add(view);

                    if (item.Specifications != null && item.Specifications.Count > 0)
                    {
                        Dictionary<string, object> childData = CheckBomMaterial(item.Specifications, materLevel + 1, random, material.FID);
                        if (materLevel >= 1)
                        {
                            formulaList.Add(new TFS_Formula()
                            {
                                FID = -1,
                                FName = material.FName,
                                FType = material.FType,
                                FTestCode = material.FTestCode,
                                FVersionCode = material.FVersionCode,
                                FPlmCode = string.IsNullOrEmpty(material.FPlmCode) ? material.FCode : material.FPlmCode
                            });
                        }
                        mateList.AddRange((List<TFS_Material>)childData["mateList"]);
                        viewList.AddRange((List<TFS_ViewMaterial>)childData["viewList"]);
                        formulaList.AddRange((List<TFS_Formula>)childData["formulaList"]);
                        ids1 = ids1.Trim(',') + "," + childData["formulaIds"] + ",";
                        ids2 = ids2.Trim(',') + "," + childData["halfIds"] + ",";
                    }
                }
            }
            return new Dictionary<string, object>
            {
                { "mateList", mateList },
                { "viewList", viewList },
                { "formulaList", formulaList },
                { "formulaIds", ids1.Trim(',') },
                { "halfIds", ids2.Trim(',') }
            };
        }

        /// <summary>
        /// 获取JObject值
        /// </summary>
        private string GetValue(JObject item, string optStr)
        {
            string[] options = optStr.Split('&');
            for (int i = 0; i < options.Length; i++)
            {
                if (item.ContainsKey(options[i])) return item[options[i]].ToString();
            }
            return "";
        }

        /// <summary>
        /// 获取JObject值
        /// </summary>
        [HttpPost]
        public ApiResult UploadTeamworkFile()
        {
            ApiResult apiResult = new ApiResult();
            Dictionary<string, List<string>> result = null;
            string filePath = "";

            return ExceptionHelper.TryReturnException(() =>
            {
                var files = HttpContext.Current.Request.Files;
                if (files != null && files.Count > 0)
                {
                    ApiAuthInfo authInfo = Request.Properties["token"] as ApiAuthInfo;
                    string[] exts = ".xlsx,.xls".Split(',');
                    string saveBase = string.Format("/Upload/{0}/" + authInfo.FID + "/", "Teamwork");
                    saveBase = System.Web.Hosting.HostingEnvironment.MapPath(saveBase);
                    if (!Directory.Exists(saveBase)) Directory.CreateDirectory(saveBase);

                    for (int i = 0; i < files.Count; i++)
                    {
                        string ext = Path.GetExtension(files[i].FileName).ToLower();
                        if (Array.IndexOf(exts, ext) != -1)
                        {
                            filePath = saveBase + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + i + ext;
                            files[i].SaveAs(filePath);
                        }

                        ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;

                        result = ReadTeamworkExcel(filePath);
                        //apiResult.Data = CheckUploadFile(fileList, FFuncType, user.FID);
                    }

                    apiResult.Data = result;
                }

            }, apiResult, Request);
        }

        /// <summary>
        /// 批量上传协同信息
        /// </summary>
        private Dictionary<string, List<string>> ReadTeamworkExcel(string file)
        {
            Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
            List<string> okList = new List<string>();
            List<string> errorList = new List<string>();

            result.Add("ok", okList);
            result.Add("error", errorList);

            Workbook wb = new Workbook(file);
            Worksheet ws = wb.Worksheets[0];

            // 遍历工作表中的所有单元格，读取其中的数据
            for (int row = 1; row <= ws.Cells.MaxDataRow; row++)
            {
                string okStr = row + ":ok";
                string errStr = row + ":";
                bool isOk = true;
                //ws.Cells[row, 0].Value;

                Dictionary<string, object> inParam = new Dictionary<string, object>();
                var saleCode = ws.Cells[row, 0].Value; // 新增销售号
                var packCode = ws.Cells[row, 1].Value; // 包规
                var factoryName = ws.Cells[row, 2].Value; // 模式 要变化为工厂ID
                var materialGroup = ws.Cells[row, 3].Value; // 物料组 要变换为物料组ID
                var weightUnit = ws.Cells[row, 4].Value; // 计量单位
                var testCode = ws.Cells[row, 5].Value == null ? "" : ws.Cells[row, 5].Value; // 试验号 要跟版本号一起查询出配方
                var versionCode = ws.Cells[row, 6].Value; // 版本号
                var state = ws.Cells[row, 7].Value; // 创建方式（新增/暂存）

                if (state != null && state.ToString().Equals("新增"))
                {
                    state = 1;
                }
                else
                {
                    state = 0;
                }

                // 新增时进行非空校验
                if (state.ToString().Equals("1"))
                {
                    if (saleCode == null || string.IsNullOrEmpty(saleCode.ToString()))
                    {
                        errStr = errStr + "新增销售号不能为空;";
                        isOk = false;
                    }

                    if (packCode == null || string.IsNullOrEmpty(packCode.ToString()))
                    {
                        errStr = errStr + "包规不能为空;";
                        isOk = false;
                    }

                    if (factoryName == null || string.IsNullOrEmpty(factoryName.ToString()))
                    {
                        errStr = errStr + "模式不能为空;";
                        isOk = false;
                    }

                    if (materialGroup == null || string.IsNullOrEmpty(materialGroup.ToString()))
                    {
                        errStr = errStr + "物料组不能为空;";
                        isOk = false;
                    }

                    if (weightUnit == null || string.IsNullOrEmpty(weightUnit.ToString()))
                    {
                        errStr = errStr + "计量单位不能为空;";
                        isOk = false;
                    }

                    if (testCode == null || string.IsNullOrEmpty(testCode.ToString()))
                    {
                        errStr = errStr + "试验号不能为空;";
                        isOk = false;
                    }

                    if (versionCode == null || string.IsNullOrEmpty(versionCode.ToString()))
                    {
                        errStr = errStr + "版本号不能为空;";
                        isOk = false;
                    }
                }

                // 校验未通过，继续下一条
                if (!isOk)
                {
                    errorList.Add(errStr);
                    continue;
                }

                // 获取需要转换的值
                // 获取工厂ID
                var createFactoryId = -1;
                TFS_Factory factory = TeamworkBll.GetFactoryIdByName(factoryName.ToString());
                if (factory == null)
                {
                    errStr = errStr + "模式不正确;";
                    isOk = false;
                }
                else
                {
                    createFactoryId = factory.FID;
                }                

                // 获取物料组Id
                if (!materialGroup.ToString().Contains("+"))
                {
                    errStr = errStr + "物料组不正确;";
                    isOk = false;
                }
                var materialGroupId = materialGroup.ToString().Split('+')[0];

                // 获取配方
                var formulaName = "";
                var formulaId = -1;
                if (!string.IsNullOrEmpty(testCode.ToString()) && !string.IsNullOrEmpty(versionCode.ToString()))
                {
                    double dVersion;
                    bool isVersionNum = double.TryParse(versionCode.ToString(), out dVersion);

                    if (isVersionNum)
                    {
                        versionCode = string.Format("{0:F4}", dVersion);
                    }

                    TFS_Formula formula = TeamworkBll.GetFormulaByTestCodeAndVersion(testCode.ToString(), versionCode.ToString());
                    if (formula == null)
                    {
                        errStr = errStr + "试验号或版本号不正确;";
                        isOk = false;
                    }
                    else
                    {
                        formulaName = formula.FName + "+" + formula.FTestCode + "+" + formula.FVersionCode;
                        formulaId = formula.FID;
                    }
                }
                

                // 校验未通过，继续下一条
                if (!isOk)
                {
                    errorList.Add(errStr);
                    continue;
                }

                inParam.Add("FMaterialType", "ZMAT");
                inParam.Add("FSaleCode", saleCode);
                inParam.Add("FPackCode", packCode);
                inParam.Add("FCreateFactoryID", createFactoryId);
                inParam.Add("FMaterialGroup", materialGroupId);
                inParam.Add("FTestCode", testCode);
                inParam.Add("FWeightUnit", weightUnit);
                inParam.Add("FFormulaName", formulaName);
                inParam.Add("FState", state);
                inParam.Add("FFormulaID", formulaId);
                inParam.Add("FVersionCode", versionCode);
                inParam.Add("FFormulaTestCode", testCode);

                string addTeamResult = AddTeam(inParam);

                if (!string.IsNullOrEmpty(addTeamResult))
                {
                    errStr = errStr + addTeamResult + ";";
                    errorList.Add(errStr);
                    continue;
                }

                okList.Add(okStr);
            }

            return result;
        }

        private string AddTeam(Dictionary<string, object> inParam)
        {
            string result = "";
            //对接获取
            inParam.Add("FMdmCode", GetMdmCode(inParam));
            //var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //inParam.Add("FMdmCode", ts.TotalSeconds.ToString("F0"));
            if (!inParam.ContainsKey("FMdmCode") || string.IsNullOrEmpty(inParam["FMdmCode"].ToString().Trim()))
            {
                result = "获取MDM失败";
            }
            else if (TeamworkBll.CheckTeamName(inParam["FSaleCode"].ToString()))
            {
                result = "销售号已存在";
            }
            else
            {
                inParam.TryGetValue("FState", out object state);
                if (null == state)
                {
                    inParam["FState"] = state = 1;
                }
                inParam.Remove("FID");
                ApiAuthInfo user = Request.Properties["token"] as ApiAuthInfo;
                if (inParam.ContainsKey("FAddUser"))
                {
                    inParam["FAddUser"] = user.FID;
                }
                else
                {
                    inParam.Add("FAddUser", user.FID);
                }
                if (inParam.ContainsKey("FEditUser"))
                {
                    inParam["FEditUser"] = user.FID;
                }
                else
                {
                    inParam.Add("FEditUser", user.FID);
                }
                if (inParam.ContainsKey("FEditDate"))
                {
                    inParam["FEditDate"] = DateTime.Now;
                }
                else
                {
                    inParam.Add("FEditDate", DateTime.Now);
                }
                //TUser tUser = BaseBll.GetTempModel<TUser>(user.FID);
                TFS_Factory factory = BaseBll.GetTempModel<TFS_Factory>(int.Parse(inParam["FCreateFactoryID"].ToString()));
                if (inParam.ContainsKey("FCreateFactoryID"))
                {
                    inParam.Remove("FCreateFactoryID");
                }
                inParam.Add("FCreateFactoryID", factory.FID);
                inParam.Add("FCreateFactoryCode", factory.FCode);
                inParam.Add("FCreateFactoryType", factory.FType);
                if (factory.FType != (int)Constant.FactoryType.单工厂)
                {
                    factory = BaseBll.GetTempModel<TFS_Factory>(factory.FFactoryID);
                    inParam.Add("FProdFactoryID", factory.FID);
                    inParam.Add("FProdFactoryCode", factory.FCode);
                }
                else
                {
                    inParam.Add("FProdFactoryID", factory.FID);
                    inParam.Add("FProdFactoryCode", factory.FCode);
                }
                //创建 TFS_FTeamwork 
                int teamId = BaseBll.InsertDataModel(inParam, "TFS_FTeamwork");
                //apiResult.Data = teamId;
                if (teamId > 0)
                {
                    inParam.Add("FID", teamId);
                    //创建流程
                    int resultProcessCreate = TeamworkBll.CreateProcessData(teamId, user.FID);
                    if (resultProcessCreate > 0)
                    {
                        //直接走下一步
                        if (state.ToString().Contains("1"))
                        {
                            TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
                            List<TFS_Material> materialList = TeamworkBll.CheckMaterialListByTest(teamwork.FFormulaTestCode, teamwork.FVersionCode);
                            if (materialList.Count == 0)
                            {
                                TeamworkBll.CreateProductView(teamwork, null, user.FID);

                                // 20230726 不论新增或暂存，都在创建协同时生成成品事项
                                BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                                BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);

                                //开始BOM下载
                                DockGetBomData(teamwork.FID, user.FID);
                            }
                            else
                            {
                                TeamworkBll.CreateProductView(teamwork, materialList, user.FID);

                                // 20230726 不论新增或暂存，都在创建协同时生成成品事项
                                BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                                BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);

                                TeamworkBll.HasMaterialTestCode(teamwork);

                                /**
                                * 20230414 需求变更
                                * 在创建各类事项前，先创建物料分类事项
                                * 此处创建各类事项流程中断，转移至物料分类事项提交后进行
                                * **/
                                BaseBll.CreateTaskData(teamwork.FID, user.FID, "15"); //新增物料分类事项
                                BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.物料分类, 2, 1); // 更新物料分类流程
                            }
                        }
                        else
                        {
                            // 20230726 不论新增或暂存，都在创建协同时生成成品事项
                            TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>(teamId);
                            TeamworkBll.CreateProductView(teamwork, null, user.FID);
                            BaseBll.CreateTaskData(teamwork.FID, user.FID, "3", teamwork.FCreateFactoryID + "," + teamwork.FProdFactoryID);
                            BaseBll.UpdateTeamProcess(teamwork.FID, (int)Constant.ProcessType.成品视图, 2, 1);

                            BaseBll.CreateTaskData(teamId, user.FID, ((int)Constant.TaskType.配方选择).ToString());
                            BaseBll.UpdateTeamProcess(teamId, (int)Constant.ProcessType.协同发起, 1, 1);
                        }
                    }
                    else
                    {
                        BaseBll.DeleteDataById(teamId, "TFS_FTeamwork", true);
                        result = "流程创建失败，请稍后重试";
                    }
                    TeamworkBll.ChangeTeamProcess(teamId);
                }
            }

            return result;
        }

        #endregion

        #region 内部方法

        /// <summary>
        /// 创建Excel文件
        /// </summary>
        private void CreateExeclFile(int intType, string savePath, string selectSql, string whereSql, string joinSql, string teamId, string halfId)
        {
            List<TFS_ViewFieldInfo> filedList = TeamworkBll.GetTeamworkViewField(intType);
            foreach (TFS_ViewFieldInfo field in filedList)
            {
                if (string.IsNullOrEmpty(field.FField))
                {
                    selectSql += string.Format("'{0}' as '{1}'", string.IsNullOrEmpty(field.FDefault) ? "" : field.FDefault, field.FName);
                }
                else
                {
                    if (field.FName == "基本数量")
                    {
                        selectSql += string.Format("isnull({0},(select TFS_PackageMain.FBomUnit*1000 from TFS_PackageMain where TFS_PackageMain.FID =(select top 1 FPackID from TFS_FTeamwork where FID=@FTeamID@))) as '{1}'", field.FField, field.FName);
                    }
                    else if (field.FName == "组件数量") 
                    {
                        selectSql += string.Format(@"isnull( ( CASE WHEN TFS_ViewMaterial.FExtraQuantity IS NULL OR  TFS_ViewMaterial.FExtraQuantity= '' THEN TFS_PackageChild.FCount ELSE TFS_ViewMaterial.FExtraQuantity END ), (select TFS_PackageMain.FBomUnit*1000 from TFS_PackageMain where TFS_PackageMain.FID =(select top 1 FPackID from TFS_FTeamwork where FID=@FTeamID@))  ) AS '组件数量'");
                    }
                    else
                    {
                        selectSql += string.Format("isnull({0},'') as '{1}'", field.FField, field.FName);
                    }
                }
                selectSql += ",";
            }
            selectSql = selectSql.Replace("@FTeamID@", teamId);
            selectSql = selectSql.Replace("@FMaterialID@", halfId);
            DataTable dataList = new DataTable();
            if (intType == (int)Constant.TeamViewType.组装BOM视图)
            {
                dataList = TeamworkBll.GetTeamworkViewData2(selectSql.Trim(','), whereSql, joinSql);
                dataList.Columns.Remove("FMaterialID");
                DataTable dataList2 = dataList.Copy();
                List<bool> hasField = new List<bool>();
                hasField.Add(dataList.Columns.Contains("BOM用途"));
                hasField.Add(dataList.Columns.Contains("子项序号"));
                hasField.Add(dataList.Columns.Contains("组件损耗率"));
                hasField.Add(dataList.Columns.Contains("固定损耗数量"));
                int rowCount = dataList.Rows.Count;

                //生产组装BOM处理
                for (int i = 0; i < rowCount; i++)
                {
                    if (hasField[0]) dataList.Rows[i]["BOM用途"] = "Y";
                    if (hasField[1]) dataList.Rows[i]["子项序号"] = (i + 1) * 10;
                    if (hasField[2]) dataList.Rows[i]["组件损耗率"] = "";
                    if (hasField[3]) dataList.Rows[i]["固定损耗数量"] = "";
                    dataList.Rows[i]["可选文本"] = "生产组装BOM";
                }
                NPOIHelper.ExportDTtoExcel(dataList, "Sheet1", savePath.Replace(".xlsx", "1.xlsx"));

                //计划组装BOM处理
                DataTable dataList3 = dataList2.Copy();
                for (int i = 0; i < rowCount; i++)
                {
                    if (hasField[1])
                    {
                        dataList2.Rows[i]["子项序号"] = (i + 1) * 10;
                    }
                    if (hasField[3] && !string.IsNullOrEmpty(dataList2.Rows[i]["固定损耗数量"].ToString()) && !dataList2.Rows[i]["固定损耗数量"].ToString().Equals("0")) 
                    {
                        dataList3.Rows[i]["组件数量"] = "";
                        dataList3.Rows[i]["组件损耗率"] = "";
                        dataList3.Rows[i]["固定损耗数量"] = "X";
                        if (hasField[1]) dataList3.Rows[i]["子项序号"] = (i + rowCount + 1) * 10;
                        dataList3.Rows[i]["可选文本"] = "计划组装BOM";
                        dataList2.ImportRow(dataList3.Rows[i]);
                    }
                    dataList2.Rows[i]["固定损耗数量"] = "";
                    dataList2.Rows[i]["可选文本"] = "计划组装BOM";
                }
                NPOIHelper.ExportDTtoExcel(dataList2, "Sheet1", savePath.Replace(".xlsx", "2.xlsx"));
                for (int i = 0; i < dataList2.Rows.Count; i++)
                {
                    if (i == 0) dataList.Rows.Add("[换色]");
                    dataList.ImportRow(dataList2.Rows[i]);
                }
            }
            else if (intType == (int)Constant.TeamViewType.配方视图)
            {
                //原始配方
                DataTable dataList1 = TeamworkBll.GetTeamworkViewData2(selectSql.Trim(','), whereSql);
                TFS_FTeamwork teamwork = BaseBll.GetTempModel<TFS_FTeamwork>("FID=" + teamId);
                List<BomFormulaDto> bfList = JsonConvert.DeserializeObject<List<BomFormulaDto>>(teamwork.FBomFormula);
                //SetBFData(null, bfList, dataList1);
                List<string> forIdList = teamwork.FMaterialFormulaIDs.Split(',').ToList();

                DataTable tempTable = dataList1.Copy();
                tempTable.Rows.Clear();
                DataTable totalTable = tempTable.Copy();

                List<DataRow> rowList = SetXHData(null, bfList, dataList1, forIdList, 1);
                foreach (var item in rowList)
                {
                    tempTable.Rows.Add(item.ItemArray);
                    totalTable.Rows.Add(item.ItemArray);
                }
                tempTable.Columns.Remove("FMaterialID");
                NPOIHelper.ExportDTtoExcel(tempTable, "Sheet1", savePath.Replace(".xlsx", "1.xlsx"));
                tempTable = dataList1.Copy();
                tempTable.Rows.Clear();

                rowList = SetXHData(null, bfList, dataList1, forIdList, 2);
                totalTable.Rows.Add("[换色]");
                foreach (var item in rowList)
                {
                    tempTable.Rows.Add(item.ItemArray);
                    totalTable.Rows.Add(item.ItemArray);
                }
                tempTable.Columns.Remove("FMaterialID");
                NPOIHelper.ExportDTtoExcel(tempTable, "Sheet1", savePath.Replace(".xlsx", "2.xlsx"));
                tempTable = dataList1.Copy();
                tempTable.Rows.Clear();

                rowList = SetXHData(null, bfList, dataList1, forIdList, 3);
                totalTable.Rows.Add("[换色]");
                foreach (var item in rowList)
                {
                    tempTable.Rows.Add(item.ItemArray);
                    totalTable.Rows.Add(item.ItemArray);
                }
                tempTable.Columns.Remove("FMaterialID");
                NPOIHelper.ExportDTtoExcel(tempTable, "Sheet1", savePath.Replace(".xlsx", "3.xlsx"));
                tempTable.Rows.Clear();

                dataList = totalTable;
                dataList.Columns.Remove("FMaterialID");

                /*dataList1.Columns.Remove("FMaterialID");
                List<bool> hasField = new List<bool>
                {
                    dataList1.Columns.Contains("BOM用途"),
                    dataList1.Columns.Contains("子项序号"),
                    dataList1.Columns.Contains("组件损耗率"),
                    dataList1.Columns.Contains("固定损耗数量"),
                    dataList1.Columns.Contains("BOM项目文本2")
                };
                int rowCount = dataList1.Rows.Count;
                for (int i = 0; i < rowCount; i++)
                {
                    //if (hasField[0]) dataList1.Rows[i]["BOM用途"] = "1";
                    if (hasField[1]) dataList1.Rows[i]["子项序号"] = (i + 1) * 10;
                    if (hasField[2]) dataList1.Rows[i]["组件损耗率"] = "";
                    if (hasField[3]) dataList1.Rows[i]["固定损耗数量"] = "";
                    if (hasField[4]) dataList1.Rows[i]["BOM项目文本2"] = "";
                    dataList1.Rows[i]["可选文本"] = "原始BOM配方";
                    dataList.ImportRow(dataList1.Rows[i]);
                }
                NPOIHelper.ExportDTtoExcel(dataList1, "Sheet1", savePath.Replace(".xlsx", "1.xlsx"));
                dataList = dataList1.Copy();
                //生产配方
                DataTable dataList2 = TeamworkBll.GetTeamworkViewData2(selectSql.Trim(','), joinSql.Trim(','));
                SetBFData(null, bfList, dataList2);
                dataList2.Columns.Remove("FMaterialID");
                DataTable dataList3 = dataList2.Copy();
                string fuIds = "";
                dataList.Rows.Add("[换色]");
                rowCount = dataList2.Rows.Count;
                for (int i = 0; i < rowCount; i++)
                {
                    if (hasField[0]) dataList2.Rows[i]["BOM用途"] = "Y";
                    if (hasField[1]) dataList2.Rows[i]["子项序号"] = (i + 1) * 10;
                    if (hasField[2]) dataList2.Rows[i]["组件损耗率"] = "";
                    if (hasField[3]) dataList2.Rows[i]["固定损耗数量"] = "";
                    if (hasField[4])
                    {
                        if (!string.IsNullOrEmpty(dataList3.Rows[i]["BOM项目文本2"].ToString()))
                        {
                            fuIds += dataList3.Rows[i]["BOM项目文本2"].ToString() + ",";
                        }
                        dataList2.Rows[i]["BOM项目文本2"] = "";
                    }
                    dataList2.Rows[i]["可选文本"] = "生产BOM配方";
                    dataList.ImportRow(dataList2.Rows[i]);
                }
                if (!string.IsNullOrEmpty(fuIds))
                {
                    joinSql = string.Format("TFS_ViewMaterial.FMaterialID in({0}) and ", fuIds.Trim(',')) + joinSql.Substring(joinSql.IndexOf("TFS_ViewMaterial.FFactoryID"));
                    DataTable tempList = TeamworkBll.GetTeamworkViewData2(selectSql.Trim(','), joinSql.Trim(','));
                    tempList.Columns.Remove("FMaterialID");
                    foreach (DataRow dr in tempList.Rows)
                    {
                        dataList2.ImportRow(dr);
                        dataList3.ImportRow(dr);
                        if (hasField[0])
                        {
                            dataList2.Rows[dataList2.Rows.Count - 1]["BOM用途"] = "Y";
                            dataList3.Rows[dataList3.Rows.Count - 1]["BOM用途"] = "1";
                        }
                        if (hasField[1])
                        {
                            dataList2.Rows[dataList2.Rows.Count - 1]["子项序号"] = dataList2.Rows.Count * 10;
                            dataList3.Rows[dataList3.Rows.Count - 1]["子项序号"] = dataList2.Rows.Count * 10;
                        }
                        if (hasField[2])
                        {
                            dataList2.Rows[dataList2.Rows.Count - 1]["组件损耗率"] = "";
                            dataList3.Rows[dataList3.Rows.Count - 1]["组件损耗率"] = "";
                        }
                        if (hasField[3])
                        {
                            dataList2.Rows[dataList2.Rows.Count - 1]["固定损耗数量"] = "";
                        }
                        if (hasField[4])
                        {
                            dataList2.Rows[dataList2.Rows.Count - 1]["BOM项目文本2"] = "";
                            dataList3.Rows[dataList3.Rows.Count - 1]["BOM项目文本2"] = "";
                        }
                        dataList2.Rows[dataList2.Rows.Count - 1]["可选文本"] = "生产BOM配方";
                        dataList3.Rows[dataList3.Rows.Count - 1]["可选文本"] = "计划BOM配方";
                        dataList.ImportRow(dataList2.Rows[dataList2.Rows.Count - 1]);
                    }
                }
                NPOIHelper.ExportDTtoExcel(dataList2, "Sheet1", savePath.Replace(".xlsx", "2.xlsx"));
                //计划配方
                dataList.Rows.Add("[换色]");
                rowCount = dataList3.Rows.Count;
                for (int i = 0; i < rowCount; i++)
                {
                    if (hasField[0]) dataList3.Rows[i]["BOM用途"] = "1";
                    if (hasField[1]) dataList3.Rows[i]["子项序号"] = (i + 1) * 10;
                    if (hasField[3])
                    {
                        if (!string.IsNullOrEmpty(dataList3.Rows[i]["固定损耗数量"].ToString()))
                        {
                            DataRow dr = dataList3.Copy().Rows[i];
                            dr["组件数量"] = dataList3.Rows[i]["固定损耗数量"];
                            dr["组件损耗率"] = "";
                            dr["固定损耗数量"] = "X";
                            if (hasField[4]) dr["BOM项目文本2"] = "";
                            if (hasField[1]) dr["子项序号"] = (dataList3.Rows.Count + 1) * 10;
                            dr["可选文本"] = "计划BOM配方";
                            dataList3.ImportRow(dr);
                        }
                        dataList3.Rows[i]["固定损耗数量"] = "";
                        if (hasField[4]) dataList3.Rows[i]["BOM项目文本2"] = "";
                    }
                    dataList3.Rows[i]["可选文本"] = "计划BOM配方";
                }
                NPOIHelper.ExportDTtoExcel(dataList3, "Sheet1", savePath.Replace(".xlsx", "3.xlsx"));
                rowCount = dataList3.Rows.Count;
                for (int i = 0; i < rowCount; i++) { dataList.ImportRow(dataList3.Rows[i]); }*/
            }
            else
            {
                dataList = TeamworkBll.GetTeamworkViewData2(selectSql.Trim(','), whereSql, joinSql);
                dataList.Columns.Remove("FMaterialID");
                if (intType == (int)Constant.TeamViewType.生产版本视图)
                {
                    NPOIHelper.ExportDTtoExcel(dataList, "Sheet1", savePath.Replace(".xlsx", "1.xlsx"));
                    int rowCount = dataList.Rows.Count;
                    bool isChange = dataList.Columns.Contains("BOM用途");

                    DataTable dataList2 = dataList.Copy();
                    for (int i = 0; i < rowCount; i++)
                    {
                        if (isChange && dataList2.Rows[i]["BOM用途"].ToString() == "1")
                        {
                            dataList2.Rows[i]["BOM用途"] = "Y";
                        }
                    }
                    NPOIHelper.ExportDTtoExcel(dataList2, "Sheet1", savePath.Replace(".xlsx", "2.xlsx"));
                    for (int i = 0; i < rowCount; i++)
                    {
                        if (i == 0) dataList.Rows.Add("[换色]");
                        dataList.ImportRow(dataList2.Rows[i]);
                    }
                }
            }
            if (intType == (int)Constant.TeamViewType.物料视图)
            {
                NPOIHelper.ExportDTtoExcel(dataList, "Sheet1", savePath);
                //處理名字點
                dataList.Columns["组织级别.行业领域"].ColumnName = "行业领域\n（Industry Sector）";
                dataList.Columns["组织级别.物料类型"].ColumnName = "物料类型\n(Material Type)";
                dataList.Columns["组织级别.工厂"].ColumnName = "工厂\n(Plant)";
                dataList.Columns["组织级别.库存地点"].ColumnName = "库存地点\n(Stock Location)";
                dataList.Columns["组织级别.销售组织"].ColumnName = "销售组织\n(Sales Organization)";
                dataList.Columns["组织级别.分销渠道"].ColumnName = "分销渠道\n(distribution Channel)";
                dataList.Columns["基本视图.物料编号"].ColumnName = "物料编号\n(Material NO.)";
                dataList.Columns["基本视图.试验号"].ColumnName = "试验号\n(Test NO.)";
                dataList.Columns["基本视图.基本计量"].ColumnName = "基本计量\n(Base Unit of Measure)";
                dataList.Columns["基本视图.物料描述"].ColumnName = "物料描述\n（Material Description）";
                dataList.Columns["基本视图.物料组"].ColumnName = "物料组\n(Material Group)";
                dataList.Columns["基本视图.大小/量纲(规格)"].ColumnName = "大小/量纲（规格）\n(Specifications)";
                dataList.Columns["基本视图.物料长文本"].ColumnName = "物料长文本\n(Basic Data Text)";
                dataList.Columns["基本视图.标识符:固体/液体"].ColumnName = "实验室办公室（标识符:固体/液体/乳化）\n(In bulk/liquid)";
                dataList.Columns["基本视图.体积单位"].ColumnName = "体积单位\n(Volume Unit)";
                dataList.Columns["基本视图.毛重"].ColumnName = "毛重\n(Gross weight)";
                dataList.Columns["基本视图.净重"].ColumnName = "净重\n(Net weight)";
                dataList.Columns["基本视图.重量单位"].ColumnName = "重量单位\n(Weight unit)";
                dataList.Columns["基本视图.fame号"].ColumnName = "生产备忘录（fame号）";
                dataList.Columns["基本视图.业务量"].ColumnName = "业务量\n(Volume)";
                dataList.Columns["采购视图.采购组"].ColumnName = "采购组\n(Purchasing Group)";
                dataList.Columns["采购视图.采购单位"].ColumnName = "采购单位\n(Order Unit)";
                dataList.Columns["采购视图.采购单位数量"].ColumnName = "采购单位数量\n(Quantity Conversion of procument)";
                dataList.Columns["采购视图.采购基本单位数量"].ColumnName = "基本单位数量(Quantity Conversion of basic unit of measure)";
                dataList.Columns["采购视图.采购价值码"].ColumnName = "采购价值码\n(Purchasing value key)";
                dataList.Columns["采购视图.工厂特定状态"].ColumnName = "工厂特定状态\n(Plant-Specific Material Status)";
                dataList.Columns["采购视图.自动采购单标识"].ColumnName = "自动采购订单\n（automatic purchase order allowed）";
                dataList.Columns["采购视图.货源清单"].ColumnName = "货源清单\n（Source list requirement）";
                dataList.Columns["分类视图.类别种类"].ColumnName = "类别种类\n（Class Type）";
                dataList.Columns["分类视图.类别"].ColumnName = "类别\n（Class）";
                dataList.Columns["销售视图.交货工厂"].ColumnName = "交货工厂\n(Delivering Plant)";
                dataList.Columns["销售视图.税金分类"].ColumnName = "税金分类\n(Tax classification material)";
                dataList.Columns["销售视图.物料统计组"].ColumnName = "物料统计组\n(Material statistics group)";
                dataList.Columns["销售视图.销售单位"].ColumnName = "销售单位\n(Sales unit)";
                dataList.Columns["销售视图.基本单位数量"].ColumnName = "基本单位数量\n(Quantity Conversion of basic unit of measure)";
                dataList.Columns["销售视图.销售单位数量"].ColumnName = "销售单位数量\n(Quantity Conversion of Sales)";
                dataList.Columns["销售视图.科目设置组"].ColumnName = "科目设置组\n(Account Assignment Group for Material)";
                dataList.Columns["销售视图.普通项目类别组"].ColumnName = "普通项目类别组\n(General item category group)";
                dataList.Columns["销售视图.项目类别组"].ColumnName = "项目类别组\n(Item Category Group)";
                dataList.Columns["销售视图.可用性检查"].ColumnName = "可用性检查\n(Availability check)";
                dataList.Columns["销售视图.装载组"].ColumnName = "装载组\n(Loading Group)";
                dataList.Columns["销售视图.旧物料号"].ColumnName = "旧物料号\n（old material number）\n";
                dataList.Columns["仓储视图.存储条件"].ColumnName = "存储条件\n（Storage conditions）";
                dataList.Columns["仓储视图.批次管理"].ColumnName = "批次管理\n（Batch Management Requirement Indicator）";
                dataList.Columns["仓储视图.最大存储期间"].ColumnName = "最大存储期间\n（Maximum Storage Period）";
                dataList.Columns["仓储视图.时间单位"].ColumnName = "时间单位\n（Time unit）";
                dataList.Columns["仓储视图.最小剩余货架寿命"].ColumnName = "最小剩余货架寿命(Minimum Remaining Shelf Life)";
                dataList.Columns["仓储视图.总货架寿命"].ColumnName = "总货架寿命\n(Total shelf life)";
                dataList.Columns["仓储视图.SLED期间标识"].ColumnName = "SLED期间标识\n(Period Indicator for Shelf Life Expiration Date)";
                dataList.Columns["MRP1.MRP类型"].ColumnName = "MRP类型\n(MRP Type)";
                dataList.Columns["MRP1.再订货点"].ColumnName = "再订货点";
                dataList.Columns["MRP1.固定批量大小"].ColumnName = "固定批量大小";
                dataList.Columns["MRP1.最大库存水平"].ColumnName = "最大库存水平";
                dataList.Columns["MRP1.MRP控制者"].ColumnName = "MRP\n控制者\nMRP Controller";
                dataList.Columns["MRP1.批量大小"].ColumnName = "批量大小\nLot Sizing Procedure within Materials Planning";
                dataList.Columns["MRP1.最小批量大小"].ColumnName = "最小批\n量大小\nMaximum Lot Size";
                dataList.Columns["MRP1.最大批量大小"].ColumnName = "最大批\n量大小\nMinimum Lot Size";
                dataList.Columns["MRP1.MRP组"].ColumnName = "MRP组\nMRP Group";
                dataList.Columns["MRP1.舍入值"].ColumnName = "舍入值\nRounding value for purchase order quantity";
                dataList.Columns["MRP1.产品分类"].ColumnName = "产品分类\nProduct classification";
                dataList.Columns["MRP1.客户代码"].ColumnName = "客户代码";
                dataList.Columns["MRP1.大小料"].ColumnName = "大小料";
                dataList.Columns["MRP1.不计算缺料"].ColumnName = "不计算缺料     ";
                dataList.Columns["MRP1.压膜"].ColumnName = "压膜";
                dataList.Columns["MRP1.安全库存带小样"].ColumnName = "安全库存带小样";
                dataList.Columns["MRP1.需求计算不考虑前置物料库存"].ColumnName = "需求计算不考虑前置物料库存";
                dataList.Columns["MRP1.小料标准（小于）"].ColumnName = " 小料标准（小于）";
                dataList.Columns["MRP2.采购类型"].ColumnName = "采购类型\nProcurement Type";
                dataList.Columns["MRP2.计划边际码"].ColumnName = "计划\n边际码\nSchedMargin key";
                dataList.Columns["MRP2.特殊采购类"].ColumnName = "特殊\n采购类\nSpecial procurement";
                dataList.Columns["MRP2.反冲"].ColumnName = "反冲\nBackflush";
                dataList.Columns["MRP2.自制生产时间"].ColumnName = "自制\n生产时间\nIn-house production time";
                dataList.Columns["MRP2.计划交货时间"].ColumnName = "计划交\n货时间\nPlanned Delivery Time in Days";
                dataList.Columns["MRP2.收货处理时间"].ColumnName = "收货处\n理时间\nGoods receipt processing time in days";
                dataList.Columns["MRP2.安全库存"].ColumnName = "安全库存\nSafety Stock";
                dataList.Columns["MRP2.发货库存地点"].ColumnName = "发货库\n存地点\nIssue Storage Location";
                dataList.Columns["MRP2.外部采购仓储地点"].ColumnName = "外部采购\n仓储地点\nDefault storage location for external procurement";
                dataList.Columns["MRP3.策略组"].ColumnName = "策略组\nStrategy Group";
                dataList.Columns["MRP3.消耗模式"].ColumnName = "消耗模式\nConsumption Mode";
                dataList.Columns["MRP3.向前消耗期间"].ColumnName = "向前消\n耗期间\n（Consumption period: forward）";
                dataList.Columns["MRP3.逆向消耗期"].ColumnName = "逆向\n消耗期\n（Consumption period: backward）";
                dataList.Columns["MRP3.混合MRP"].ColumnName = "混合MRP\nMixed MRP indicator";
                dataList.Columns["MRP3.可用性检查"].ColumnName = "可用性检查\n\nAvailability check";
                dataList.Columns["MRP4.单独或集中"].ColumnName = "单独或集中\nIndividual requirements/Collective requirements";
                dataList.Columns["MRP4.非连续标识"].ColumnName = "非连续标识";
                dataList.Columns["MRP4.生效期"].ColumnName = "生效期";
                dataList.Columns["MRP4.后续的物料"].ColumnName = "后续的物料";
                dataList.Columns["工作计划视图.生产计划参数文件"].ColumnName = "生产计划参数文件\nProduction Scheduling Profile";
                dataList.Columns["工作计划视图.无限制过量交货"].ColumnName = "无限制过\n量交货\n（Indicator: Unlimited Overdelivery Allowed）";
                dataList.Columns["工作计划视图.不足交货允差"].ColumnName = "不足交\n货允差\nUnderdelivery tolerance limit";
                dataList.Columns["工作计划视图.过度交货允差"].ColumnName = "过度交\n货允差\nOverdelivery tolerance limit";
                dataList.Columns["工作计划视图.发货单位"].ColumnName = "发货单位\nUnit of issue";
                dataList.Columns["工作计划视图.发货单位数量"].ColumnName = "发货单位数量\n(Quantity Conversion of Delivery)";
                dataList.Columns["工作计划视图.发货基本单位数量"].ColumnName = "基本单位数量\n\n(Quantity Conversion of basic unit of measure)";
                dataList.Columns["质检视图.检验类型1"].ColumnName = "检验类型1\nInspection Type 1";
                dataList.Columns["质检视图.检验类型2"].ColumnName = "检验类型2\nInspection Type 2";
                dataList.Columns["质检视图.检验类型3"].ColumnName = "检验类型3\nInspection Type 3";
                dataList.Columns["质检视图.检验类型4"].ColumnName = "检验类型4\nInspection Type 4";
                dataList.Columns["质检视图.检验类型5"].ColumnName = "检验类型5\nInspection Type 5";
                dataList.Columns["质检视图.检验类型6"].ColumnName = "检验类型6\nInspection Type 6";
                dataList.Columns["会计视图.价格控制"].ColumnName = "价格控制\n(Price control indicator)";
                dataList.Columns["会计视图.价格确定"].ColumnName = "价格确定\n(Material Price Determination: Control)";
                dataList.Columns["会计视图.价格单位"].ColumnName = "价格单位\n(Price Unit)";
                dataList.Columns["会计视图.评估分类"].ColumnName = "评估分类\nValuation Class";
                dataList.Columns["会计视图.VC: 销售订单库存"].ColumnName = "VC: 销售订单库存\nValuation Class for Sales Order Stock";
                dataList.Columns["会计视图.标准价格"].ColumnName = "标准价格\nStandard Price";
                dataList.Columns["会计视图.利润中心"].ColumnName = "利润中心\nProfit Center";
                dataList.Columns["会计视图.成本核算批量"].ColumnName = "成本核算批量\nLot Size for Product Costing";
                NPOIHelper.ExportDTtoExcel(dataList, "Sheet1", savePath.Replace(Constant.TeamViewType.物料视图.ToString(), "SAP视图"));
            }
            else
            {
                NPOIHelper.ExportDTtoExcel(dataList, "Sheet1", savePath);
            }            
        }

        /// <summary>
        /// 梳理父项
        /// </summary>
        private void SetBFData(TFS_ViewMaterial parent, List<BomFormulaDto> bfList, DataTable dtList)
        {
            if (bfList != null && bfList.Count > 0)
            {
                foreach (var item in bfList)
                {
                    if (parent != null)
                    {
                        DataRow[] rows = dtList.Select("FMaterialID=" + item.mId);
                        foreach (var row in rows)
                        {
                            row["父项编码"] = parent.FBaseMaterialCode;
                            row["父项描述"] = parent.FBaseMaterialDesc;
                            row["基本数量"] = parent.FExtraQuantity;
                        }
                    }
                    if (item.childs.Count > 0)
                    {
                        SetBFData(BaseBll.GetTempModel<TFS_ViewMaterial>("FMaterialID=" + item.mId), item.childs, dtList);
                    }
                }
            }
        }

        /// <summary>
        /// 梳理序号（type：1原始，2生产，3计划）
        /// </summary>
        private List<DataRow> SetXHData(BomFormulaDto parent, List<BomFormulaDto> bfList, DataTable dtList, List<string> forIdList, int type)
        {
            if (bfList != null && bfList.Count > 0)
            {
                //物料、替代、副产、固损
                List<List<DataRow>> rowList = new List<List<DataRow>>() { new List<DataRow>(), new List<DataRow>(), new List<DataRow>(), new List<DataRow>() };
                foreach (BomFormulaDto item in bfList)
                {
                    DataRow[] rows = dtList.Select("FMaterialID=" + item.mId);
                    if (rows != null && rows.Length > 0)
                    {
                        string mId = rows[0]["FMaterialID"].ToString();
                        if (forIdList.IndexOf(mId) != -1)
                        {
                            DataRow main = dtList.Copy().Select("FMaterialID=" + item.mId)[0];
                            if (parent != null)
                            {
                                TFS_ViewMaterial temp = BaseBll.GetTempModel<TFS_ViewMaterial>("FMaterialID=" + parent.mId);
                                if (temp != null)
                                {
                                    main["父项编码"] = temp.FBaseMaterialCode;
                                    main["父项描述"] = temp.FBaseMaterialDesc;
                                    main["基本数量"] = temp.FExtraQuantity;
                                }
                            }
                            main["BOM项目文本2"] = "";
                            //固定损耗
                            if (type == 3 && !string.IsNullOrEmpty(main["固定损耗数量"].ToString()))
                            {
                                DataRow drGu = dtList.Copy().Select("FMaterialID=" + item.mId)[0];
                                drGu["组件数量"] = main["固定损耗数量"];
                                drGu["组件损耗率"] = "";
                                drGu["固定损耗数量"] = "X";
                                drGu["BOM项目文本2"] = "";
                                drGu["可选文本"] = "计划BOM配方";
                                rowList[3].Add(drGu);
                            }
                            if (type > 1)
                            {
                                {
                                    //副产物判断
                                    TFS_Material mTi = BaseBll.GetTempModel<TFS_Material>(string.Format("FID=(select a.FFuProductsID from TFS_Material a where a.FID={0})", mId));
                                    if (mTi != null)
                                    {
                                        DataRow drFu = dtList.Copy().Select("FMaterialID=" + item.mId)[0];
                                        TFS_ViewMaterial vTi = BaseBll.GetTempModel<TFS_ViewMaterial>(string.Format("FMaterialID={0}", mTi.FID));
                                        TFS_MaterialInfo iTi = BaseBll.GetTempModel<TFS_MaterialInfo>(string.Format("FType=2 and FDataID={0}", mTi.FID));
                                        if (iTi == null) iTi = new TFS_MaterialInfo();
                                        DataRow drTi = dtList.Copy().Select("FMaterialID=" + item.mId)[0];
                                        drFu["子项编码"] = vTi == null ? mTi.FCode : vTi.FBaseMaterialCode;
                                        drFu["子件描述"] = vTi == null ? mTi.FName : vTi.FBaseMaterialDesc;
                                        drFu["组件数量"] = vTi == null ? drTi["组件数量"] : vTi.FExtraQuantity;
                                        drFu["计量单位"] = vTi == null ? mTi.FBaseUnit : vTi.FBaseBasicMeter;
                                        drFu["物料供应标识符"] = mTi == null ? iTi.FCustomerCode : mTi.FSupplyCode;
                                        drFu["生产仓储地点"] = vTi == null ? iTi.FStoreHouse : vTi.FMRP2ExternalStoragePlace;
                                        drFu["成本核算标识相关"] = (mTi != null ? mTi.FSupplyCode : drTi["物料供应标识符"].ToString()) == "K" ? "" : "X";
                                        drFu["固定损耗数量"] = mTi == null ? iTi.FFixedLoss : mTi.FFixedLoss;
                                        if (type == 3) drFu["BOM用途"] = "Y";
                                        rowList[2].Add(drFu);
                                    }
                                }
                                {
                                    //替代料判断
                                    TFS_Material mTi = BaseBll.GetTempModel<TFS_Material>(string.Format("FID=(select a.FSuccedaneumID from TFS_Material a where a.FID={0})", mId));
                                    if (mTi != null)
                                    {
                                        TFS_ViewMaterial vTi = BaseBll.GetTempModel<TFS_ViewMaterial>(string.Format("FMaterialID={0}", mTi.FID));
                                        TFS_MaterialInfo iTi = BaseBll.GetTempModel<TFS_MaterialInfo>(string.Format("FType=2 and FDataID={0}", mTi.FID));
                                        if (iTi == null) iTi = new TFS_MaterialInfo();
                                        DataRow drTi = dtList.Copy().Select("FMaterialID=" + item.mId)[0];
                                        drTi["子项编码"] = vTi == null ? mTi.FCode : vTi.FBaseMaterialCode;
                                        drTi["子件描述"] = vTi == null ? mTi.FName : vTi.FBaseMaterialDesc;
                                        drTi["组件数量"] = vTi == null ? drTi["组件数量"] : vTi.FExtraQuantity;
                                        drTi["计量单位"] = vTi == null ? mTi.FBaseUnit : vTi.FBaseBasicMeter;
                                        drTi["物料供应标识符"] = mTi == null ? iTi.FCustomerCode : mTi.FSupplyCode;
                                        drTi["生产仓储地点"] = vTi == null ? iTi.FStoreHouse : vTi.FMRP2ExternalStoragePlace;
                                        drTi["成本核算标识相关"] = (mTi != null ? mTi.FSupplyCode : drTi["物料供应标识符"].ToString()) == "K" ? "" : "X";
                                        drTi["固定损耗数量"] = mTi == null ? iTi.FFixedLoss : mTi.FFixedLoss;
                                        main = drTi;
                                    }
                                }
                            }
                            if (type == 2) main["BOM用途"] = "Y";
                            rowList[0].Add(main);
                        }
                    }
                }
                if (type != 1) { rowList[0].AddRange(rowList[1]); rowList[0].AddRange(rowList[2]); }
                if (type == 3) rowList[0].AddRange(rowList[3]);
                for (int i = 0; i < rowList[0].Count; i++)
                {
                    rowList[0][i]["子项序号"] = (i + 1) * 10;
                    switch (type)
                    {
                        case 1: rowList[0][i]["可选文本"] = "原始BOM配方"; break;
                        case 2: rowList[0][i]["可选文本"] = "生产BOM配方"; break;
                        case 3: rowList[0][i]["可选文本"] = "计划BOM配方"; break;
                    }
                }
                foreach (BomFormulaDto item in bfList)
                {
                    if (item.childs != null && item.childs.Count > 0)
                    {
                        List<DataRow> temps = SetXHData(item, item.childs, dtList, forIdList, type);
                        if (temps.Count > 0) rowList[0].AddRange(temps);
                    }
                }
                return rowList[0];
            }
            return new List<DataRow>();
        }

        #endregion
    }
}
