Ejemplo n.º 1
0
        /// <summary>
        /// 获取滚动排期表数据
        /// </summary>
        /// <param name="factoryID">工厂id</param>
        /// <param name="poCode">生产单号</param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="orderType">Eric添加 生产单类型:实单1,非实单0 </param>
        private void InitData(int factoryID, string poCode, DateTime startDate, DateTime endDate, int orderType, string lotNO)
        {
            //客户信息
            this.DicAllCustomers = Customer.GetDictionary(null);
            //产品分类
            this.DicProductType = ProductType.GetDictionary(null);
            this.InitLstReportSetting();

            //返回选中的工厂ID字符串
            /// 多个用逗号隔开,默认全选
            /// 格式:"1,2,3,4,5,6"
            //string FactorySelectIDsStr = "1,2,3,12,14,15,16,17";
            string FactorySelectIDsStr = factoryID.ToString();

            this.DicSimulation.Clear();
            this.DicVirProdEvent.Clear();

            // 目标生产线集合
            Filter filter = new Filter();

            filter.AddSort("FactoryID");
            filter.AddSort("ID");
            //if (!string.IsNullOrEmpty(groupNames))
            //    filter.Add("GroupName", groupNames, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
            filter.Add("FactoryID", FactorySelectIDsStr, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);

            List <Facility> lstFacility = Facility.GetList(filter);

            this.LstVirtualFacility = new List <VirtualFacility>();
            List <int> ids = new List <int>();

            //
            // 相关的生产计划
            foreach (Facility fa in lstFacility)
            {
                if (!AMOData.Settings.ImpSetting.IsOutsourcedScheduling && fa.IsSubCon)//外发不排产需过滤外发线
                {
                    continue;
                }
                ids.Add(fa.ID);
                LstVirtualFacility.Add(new VirtualFacility(fa));
            }
            string wherein = string.Join(",", (from p in ids.Distinct() select p.ToString()).ToArray());

            if (string.IsNullOrEmpty(wherein))
            {
                return;
            }

            filter = new Filter();
            filter.Add(AMODataHelper.GetStringFromList(ids, 1000, "FacilityID"), LOGIC_TYPE.AND);
            filter.Add("StartTime", endDate.Date.AddDays(1), RELEATTION_TYPE.LESS, LOGIC_TYPE.AND);
            filter.Add("EndTime", startDate.Date, RELEATTION_TYPE.GREATEREQUAL, LOGIC_TYPE.AND);

            /*
             * if (orderType > -1)
             *  filter.Add("ISFIRMORDER", orderType, RELEATTION_TYPE.EQUAL, LOGIC_TYPE.AND);
             */
            if (orderType > -1)
            {
                filter.AddFrom("productioneventdetail", "ProductionEvent.ID=productioneventdetail.ProductionEventID", JOIN_TYPE.LEFT);
                filter.AddFrom("PO", "PO.ID = productioneventdetail.POID", JOIN_TYPE.LEFT);
                filter.Add("PO.ISFIRMORDER", orderType, RELEATTION_TYPE.EQUAL, LOGIC_TYPE.AND);
            }
            if (string.IsNullOrEmpty(lotNO) == false)
            {
                string sql = string.Format("(select id from po where LotNO like '%{0}%')", lotNO);
                filter.Add("ProductionEvent.POID", sql, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
            }
            filter.AddSort("StartTime");
            this.LstProdEvent   = ProductionEvent.GetList(filter);
            this.DicFaProdEvent = new Dictionary <int, IEnumerable <ProductionEvent> >();
            foreach (var g in this.LstProdEvent.GroupBy(x => x.FacilityID))
            {
                this.DicFaProdEvent[g.Key] = g.ToList();
            }
            //获取计划完成日期
            var peFilter = new Filter();

            peFilter.Add(AMODataHelper.GetStringFromList(ids, 1000, "PRODUCTIONEVENT.FacilityID"), LOGIC_TYPE.AND);
            peFilter.Add("PRODUCTIONEVENT.StartTime", endDate.Date.AddDays(1), RELEATTION_TYPE.LESS, LOGIC_TYPE.AND);
            peFilter.Add("PRODUCTIONEVENT.EndTime", startDate.Date, RELEATTION_TYPE.GREATEREQUAL, LOGIC_TYPE.AND);
            peFilter.Add("PRODUCTIONEVENT.STATUS", 1, RELEATTION_TYPE.EQUAL, LOGIC_TYPE.AND);
            this.DicProdFinishDates = ProductionSchedule.GetProductionFinishedDate(peFilter);

            //动态人数
            Filter fwnFilter = new Filter();
            string idStr     = string.Join(",", (from p in ids.Distinct() select p.ToString()).ToArray());

            fwnFilter.Add("FacilityID", idStr, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
            var lstFwn = FacilityWorkerNumber.GetList(fwnFilter);

            this.DicFwn = new Dictionary <int, IEnumerable <FacilityWorkerNumber> >();
            foreach (var g in lstFwn.GroupBy(x => x.FacilityID))
            {
                DicFwn[g.Key] = g.ToList();
            }
            //ids = new List<int>();
            //ids = (from item in this.LstProdEvent select item.POID).ToList();
            //this.LstProdEvent = ProductionEvent.GetList(filter);

            if (this.LstProdEvent.Count > 0)
            {
                var mylist = this.LstProdEvent.Where(x => !string.IsNullOrEmpty(x.GroupID));
                if (mylist.Any())
                {
                    var gids = mylist.Select(x => x.GroupID).Distinct();
                    var lst  = gids.ToList();
                    groupIdCodes = AMO.BLL.ProductionEvent.GetAboutGroupIdList(lst); //获取与组ID关联的POCODE列表
                }
            }



            //生产计划细分
            ids    = new List <int>();
            filter = new Filter();
            ids    = (from item in this.LstProdEvent select item.ID).ToList();
            this.DicProdEventDetail = new Dictionary <int, List <ProductionEventDetail> >();
            List <ProductionEventDetail> lstProdEventDetail = new List <ProductionEventDetail>();

            if (ids.Count > 0)
            {
                filter.Add(AMODataHelper.GetStringFromList(ids, 1000, "ProductionEventID"), LOGIC_TYPE.AND);
                if (!string.IsNullOrEmpty(poCode))
                {
                    filter.Add("POID", string.Format("SELECT id FROM dbo.PO WHERE CODE LIKE '%{0}%'", poCode), RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
                }

                lstProdEventDetail = ProductionEventDetail.GetList(filter);
                foreach (var g in lstProdEventDetail.GroupBy(x => x.ProductionEventID))
                {
                    this.DicProdEventDetail[g.Key] = g.ToList();
                }
            }

            //生产单信息
            ids    = new List <int>();
            filter = new Filter();
            ids    = (from item in lstProdEventDetail select item.POID).Distinct().ToList();
            string sokeySql = string.Empty;

            if (ids.Count > 0)
            {
                filter.Add(AMODataHelper.GetStringFromList(ids, 1000, "ID"), LOGIC_TYPE.AND);
                if (!string.IsNullOrEmpty(poCode))
                {
                    filter.Add("Code", poCode, RELEATTION_TYPE.LIKE, LOGIC_TYPE.AND);
                }
                string poidSql = DBHelper.GetDistinctSql("PO", "ID", filter);
                sokeySql   = DBHelper.GetDistinctSql("PO", "SoKeyID", filter);
                this.DicPO = PO.GetDictionary(filter);
                filter     = new Filter();
                filter.Add("POID", poidSql, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
                this.LstPODetail = PODetail.GetList(filter, false);

                //关键事件(物料ETA)日期,有实际区实际,没实际区预计
                var eventFilter = new Filter();
                eventFilter.AddFrom("EVENTFLOWNODE", "EVENTFLOWNODE.ID=POEVENT.EVENTFLOWNODEID", JOIN_TYPE.INNER);
                eventFilter.Add("EVENTFLOWNODE.CRITICALEVENTID", AMOData.Settings.SysSetting.Rpt_ActualMaterialETA, RELEATTION_TYPE.EQUAL, LOGIC_TYPE.AND);
                eventFilter.Add("POEVENT.POID", poidSql, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
                List <POEvent> lstPOEvent = POEvent.GetList(eventFilter);
                this.DicPOEvents = new Dictionary <int, POEvent>();
                foreach (POEvent model in lstPOEvent)
                {
                    if (DicPOEvents.ContainsKey(model.POID) == false)
                    {
                        DicPOEvents.Add(model.POID, model);
                    }
                }
            }
            else
            {
                this.DicPO       = new Dictionary <int, PO>();
                this.LstPODetail = new List <PODetail>();
            }



            //
            if (!string.IsNullOrEmpty(sokeySql))
            {
                Filter sokeyFilter = new Filter();
                sokeyFilter.Add("SoKeyID", sokeySql, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
                sokeyFilter.Add("MaterialStyle", 6, RELEATTION_TYPE.NOTEQUAL, LOGIC_TYPE.AND);
                LstPOMaterialRequest = POMaterialRequest.GetListOnlySample(sokeyFilter);
                LstPOMaterialRequest.Sort(POMaterialRequest.ComparerByDate);
            }

            #region 用于计算 计划的每日计划产量
            List <VirtualProdEvent> lstVirProdEvent = this.CreateVirtualProdEvent(this.LstProdEvent, lstProdEventDetail);
            this.DicVirProdEvent = lstVirProdEvent.ToDictionary(x => x.ID);

            if (this.LstReportSetting.Find(x => x.ColumnName == "AreaPlanQty" || x.ColumnName == "AreaOutput") != null)//AMOHB-3684 增加区间排单数、区间产值
            {
                var gsVpe = lstVirProdEvent.GroupBy(x => x.FacilityID);
                foreach (var g in gsVpe)
                {
                    var virFacility = this.LstVirtualFacility.Find(x => x.ID == g.Key);
                    if (virFacility != null)
                    {
                        foreach (var vpe in g.ToList())
                        {
                            vpe.FactoryID = virFacility.FactoryID;
                        }
                    }
                }

                //按工厂生产simulation对象
                var gsFacility = this.LstVirtualFacility.GroupBy(x => x.FactoryID);
                foreach (var g in gsFacility)
                {
                    if (!DicSimulation.ContainsKey(g.Key))
                    {
                        //Simulation sim = this.CreateSimulation(g.Key, lstVirProdEvent.Where(x => x.FactoryID == g.Key).ToList());
                        var lstVirProdEventFinded = lstVirProdEvent.Where(x => x.FactoryID == g.Key);
                        if (lstVirProdEventFinded != null && lstVirProdEventFinded.Count() > 0)
                        {
                            Simulation sim = this.CreateSimulation(g.Key, lstVirProdEventFinded.ToList());
                            DicSimulation.Add(g.Key, sim);
                        }
                    }
                }
            }
            #endregion
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 生成报表数据
        /// </summary>
        /// <returns></returns>
        private DataTable CreateData(string strFacilityIDs, DateTime dFrom, DateTime dTo, string code, string pattern, bool showByPlan, SortOrders sortOrder)
        {
            #region get data

            Filter filter1 = new Filter();
            filter1.Add("StartTime", dTo.Date.AddDays(1), RELEATTION_TYPE.LESSEQUAL, LOGIC_TYPE.AND);
            filter1.Add("EndTime", dFrom.Date, RELEATTION_TYPE.GREATEREQUAL, LOGIC_TYPE.AND);

            //拿取指定的生产线
            //string strFacilityIDs = this.GetFacilityID();
            List <Facility> lstFacility = AMO.BLL.Facility.GetList(strFacilityIDs);

            //ProductionEvent
            Filter filter = new Filter();
            filter.Add("FacilityID", strFacilityIDs, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
            filter.Add(filter1, LOGIC_TYPE.AND);


            List <ProductionEvent> lstProductionEvent = ProductionEvent.GetList(filter);
            DicProdEvent = lstProductionEvent.ToDictionary(x => x.ID);

            ////拿取指定时间段内指定生产线的生产计划
            string ProductionEventIDSql = DBHelper.GetDistinctSql("ProductionEvent", "ID", filter);

            //ProductionEventDetail
            filter = new Filter();
            filter.Add("ProductionEventID", ProductionEventIDSql, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
            List <ProductionEventDetail> lstProductionEventDetail = ProductionEventDetail.GetList(filter);
            DicProdEventDetails = new Dictionary <int, List <ProductionEventDetail> >();
            var gsPED = lstProductionEventDetail.GroupBy(x => x.ProductionEventID);
            foreach (var g in gsPED)
            {
                DicProdEventDetails.Add(g.Key, g.ToList());
            }

            //PO
            string distPOIDSql = DBHelper.GetDistinctSql("ProductionEventDetail", "POID", filter);

            //增加生产单&&款号过滤
            if (!string.IsNullOrEmpty(code))
            {
                if (code.Length >= AMOData.Settings.SysSetting.PoCodeLength)
                {
                    distPOIDSql += string.Format(@" and code = '{0}' ", code);
                }
                else
                {
                    distPOIDSql += string.Format(@" and code like '%{0}%' ", code);
                }
            }
            if (!string.IsNullOrEmpty(pattern))
            {
                if (pattern.Length >= AMOData.Settings.SysSetting.PatternLength)
                {
                    distPOIDSql += string.Format(@" and PATTERN ='{0}' ", pattern);
                }
                else
                {
                    distPOIDSql += string.Format(@" and PATTERN like '%{0}%' ", pattern);
                }
            }

            filter = new Filter();

            filter.Add("ID", distPOIDSql, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);

            DicPO = PO.GetDictionary(filter);

            //ProductionSchedule
            Filter filterProcess = new Filter();
            filterProcess.Add("IsPrimary", 1, RELEATTION_TYPE.EQUAL, LOGIC_TYPE.AND);
            string distProcessSQL = DBHelper.GetDistinctSql("Process", "ID", filterProcess);

            Filter filterPS = new Filter();
            filterPS.Add("ProductionDate", dFrom.Date, RELEATTION_TYPE.GREATEREQUAL, LOGIC_TYPE.AND);
            filterPS.Add("ProductionDate", dTo.Date, RELEATTION_TYPE.LESSEQUAL, LOGIC_TYPE.AND);
            filterPS.Add("ProcessID", distProcessSQL, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
            List <AMOData.ProductionSchedule> lstProdSchedule = ProductionSchedule.GetList(filterPS);
            //var qPS = from g in lstProdSchedule
            //          group g by g.POID;

            //生产线的动态人数
            Filter dyFilter = new Filter();
            dyFilter.Add("FacilityID", strFacilityIDs, RELEATTION_TYPE.IN, LOGIC_TYPE.AND);
            var lstDyWrorkers = FacilityWorkerNumber.GetList(dyFilter);
            if (lstDyWrorkers.Count > 0)
            {
                lstDyWrorkers = lstDyWrorkers.OrderByDescending(x => x.BeginDate).ToList();//开始日期大到小排序
            }
            DicFacilityWorkerNumber = new Dictionary <int, List <FacilityWorkerNumber> >();
            var gs = lstDyWrorkers.GroupBy(x => x.FacilityID).ToList();
            foreach (var g in gs)
            {
                DicFacilityWorkerNumber[g.Key] = g.ToList();
            }
            //
            #endregion

            #region create data structure

            lstActualAmount.Clear();

            List <DailyProdAmount> lstPlanAmount = new List <DailyProdAmount>();

            List <LineRate> lstLineRate = new List <LineRate>();

            //结果表
            DataTable dtResult = new DataTable();
            dtResult.Columns.Add("SpecLineID", typeof(int));//生产线ID
            foreach (ReportSetting rptSet in LstReportSetting)
            {
                //switch (rptSet.DataType.ToLower())
                //{
                //    case "int":
                //        dtResult.Columns.Add(rptSet.HeaderText, typeof(int));
                //        break;
                //    case "datetime":
                //        dtResult.Columns.Add(rptSet.HeaderText, typeof(DateTime));
                //        break;
                //    case "string":
                //    default:
                dtResult.Columns.Add(rptSet.HeaderText);
                //        break;
                //}
            }

            dtResult.Columns.Add("SpecCol", typeof(string));//特殊列

            DateTime dayDate = dFrom.Date;
            while (dayDate <= dTo.Date)
            {
                DataColumn dc = new DataColumn(dayDate.ToString("MM-dd"), typeof(string));
                dc.DefaultValue = 0;
                dtResult.Columns.Add(dc);
                dayDate = dayDate.AddDays(1);
            }

            DataColumn dcRowSum = new DataColumn("RowSum", typeof(string));
            dcRowSum.DefaultValue = 0;
            dtResult.Columns.Add(dcRowSum);//行 sum 列

            DataColumn dcRowSpan = new DataColumn("RowSpan", typeof(int));
            dcRowSpan.DefaultValue = 1;
            dtResult.Columns.Add(dcRowSpan);

            #endregion

            #region put data to lstPlanAmount

            Simulation oSimulation = new Simulation(true);
            oSimulation.LoadSettings();
            oSimulation.LoadFacility(true);
            oSimulation.LoadCalendar(false, true);
            oSimulation.LoadLnCurveData();
            //外发不排产需过滤外发线
            if (!AMOData.Settings.ImpSetting.IsOutsourcedScheduling)
            {
                lstFacility = lstFacility.Where(m => m.IsSubCon == false).ToList();
            }
            //join lstProductionEvent & lstFacility
            var query = (from xEvent in lstProductionEvent
                         join xFacility in lstFacility
                         on xEvent.FacilityID equals xFacility.ID
                         orderby xFacility.Name, xEvent.StartTime
                         select new { xEvent, xFacility }).ToList(); //

            foreach (var obj in query)                               //遍历每条生产线上每个计划
            {
                VirtualProdEvent vProdEvent = new VirtualProdEvent(obj.xEvent, oSimulation.DateNow);
                List <int>       lstPOIDs   = null;
                if (DicProdEventDetails.ContainsKey(obj.xEvent.ID))
                {
                    List <ProductionEventDetail> queryDetail = DicProdEventDetails[obj.xEvent.ID];
                    foreach (ProductionEventDetail detail in queryDetail)
                    {
                        VirtualProdEventDetail vDetail = new VirtualProdEventDetail(detail, string.Empty, string.Empty, string.Empty);
                        vProdEvent.AddDetail(vDetail);
                    }
                    lstPOIDs = queryDetail.Select(x => x.POID).Distinct().ToList();
                }

                if (lstPOIDs == null)
                {
                    lstPOIDs = new List <int>();
                }

                //学习曲线
                LnCurveApply oLnCurveApply = oSimulation.LearningCurve.GetInLncApply(vProdEvent);
                if (oLnCurveApply != null)
                {
                    vProdEvent.LncApplyID    = oLnCurveApply.ID;
                    vProdEvent.LncTemplateID = oLnCurveApply.LnCurveTemplateID;
                }

                foreach (int pid in lstPOIDs)
                {
                    if (DicPO.ContainsKey(pid))
                    {
                        // double poqty = vProdEvent.AllDetails.Where(p => p.POID == pid).Sum(p => p.PlanAmount);//PO排单总数
                        //
                        Dictionary <DateTime, int> dicAmount = vProdEvent.CalculateCanFinishedQty(oSimulation, true, -1, pid);//计算某个计划每天应该完成的数量
                        dayDate = dFrom.Date;
                        while (dayDate <= dTo.Date)
                        {
                            int amount = 0;
                            if (dicAmount.ContainsKey(dayDate.Date))
                            {
                                amount = dicAmount[dayDate.Date];
                            }

                            DailyProdAmount pAmount = new DailyProdAmount();
                            pAmount.LineID      = obj.xFacility.ID;
                            pAmount.ProdEventID = obj.xEvent.ID;
                            pAmount.POID        = pid;    //po.ID;
                            pAmount.ProdDate    = dayDate;
                            pAmount.Amount      = amount; // (poqty == vpqty ? amount : (int)Math.Round(amount * poqty / vpqty, 0));//考虑合单情况
                            lstPlanAmount.Add(pAmount);

                            dayDate = dayDate.AddDays(1);
                        }
                    }
                }
            }

            #endregion

            #region put data to lstActualAmount

            //join lstProdSchedule ,lstProductionEvent, lstFacility
            var query2 = (from xPS in lstProdSchedule
                          join xProdEv in lstProductionEvent on xPS.ProductionEventID equals xProdEv.ID
                          join xFacility in lstFacility on xProdEv.FacilityID equals xFacility.ID
                          orderby xFacility.ID
                          select new { xPS, xFacility }).ToList(); //

            foreach (var obj in query2)                            //遍历每条生产线上每个计划 实际产量
            {
                DailyProdAmount aAmount = new DailyProdAmount();
                aAmount.LineID      = obj.xFacility.ID;
                aAmount.ProdEventID = obj.xPS.ProductionEventID;
                aAmount.POID        = obj.xPS.POID;
                aAmount.ProdDate    = obj.xPS.ProductionDate;
                if (obj.xPS.Amount == 0)
                {
                    aAmount.HasZeroAmount = true;
                }
                if (!DicPO.Keys.Contains(aAmount.POID))
                {
                    continue;
                }
                aAmount.PoCode = DicPO[aAmount.POID].Code;
                aAmount.Amount = Convert.ToInt32(obj.xPS.Amount);//Ben 等于0时表示有进度,但数量为0

                lstActualAmount.Add(aAmount);
            }
            #endregion

            #region put data to lstLineRate
            var        lineIDs            = lstPlanAmount.Select(p => p.LineID).Distinct();
            List <int> prodtingFaciltyids = DicProdEvent.Values.Select(x => x.FacilityID).Distinct().ToList();
            foreach (int lineid in lineIDs)
            {
                if (!prodtingFaciltyids.Contains(lineid))
                {
                    continue;
                }
                int pAmount = lstPlanAmount.Where(p => p.LineID == lineid).ToList().Sum(p => p.Amount);
                if (pAmount > 0)
                {
                    int      aAmount = lstActualAmount.Where(p => p.LineID == lineid).ToList().Sum(p => p.Amount);
                    LineRate lr      = new LineRate();
                    lr.LineID       = lineid;
                    lr.CompleteRate = Math.Round(((double)aAmount / pAmount), 3);
                    Facility facility = lstFacility.First(m => m.ID == lineid);
                    lr.FacilityName = facility.Name;
                    lr.GroupName    = facility.GroupName;
                    lstLineRate.Add(lr);
                }
            }
            if (sortOrder == SortOrders.ByRanking)
            {
                lstLineRate = lstLineRate.OrderByDescending(p => p.CompleteRate).ToList();
            }
            else
            {//生产线,排序顺序同排产器
                lstLineRate = lstLineRate.OrderBy(p => p.GroupName).ThenBy(m => m.FacilityName).ToList();
            }

            #endregion

            #region put data to dtResult

            DataRow drTempTotalPlan = dtResult.NewRow();          //最后一行(总计行)
            DataRow drTempTotalActual = dtResult.NewRow();
            int     tempRowTotalPlan = 0, tempRowTotalActual = 0; //总计列累计
            int     mc = 0;                                       //名次

            #region insert 数据行&小计行
            foreach (LineRate lr in lstLineRate)//按完成率倒序
            {
                Facility oFacility = lstFacility.Find(f => f.ID == lr.LineID);
                if (oFacility == null)
                {
                    continue;
                }
                int lineid = lr.LineID;

                #region insert 生产线分组行
                DataRow drLine = dtResult.NewRow();
                drLine["SpecLineID"] = -1;

                string strSpecialCol = string.Empty;
                string leader        = string.Empty;
                if (string.IsNullOrEmpty(oFacility.Leader) == false)
                {
                    leader = string.Format(",{0}", oFacility.Leader);
                }
                //if (sortOrder == SortOrders.ByRanking)
                //{

                //    strSpecialCol = string.Format("{0} {1} ( {2}: {3} )", oFacility.Name, leader, CText.TextOrderName, ++mc);
                //}
                //else
                //{
                strSpecialCol = string.Format("{0} {1} ", oFacility.Name, leader);
                //}
                //增加code&pattern过滤条件的显示
                if (!string.IsNullOrEmpty(code.Trim()))
                {
                    strSpecialCol += " , " + code;
                }
                if (!string.IsNullOrEmpty(pattern.Trim()))
                {
                    strSpecialCol += " , " + pattern;
                }

                drLine["SpecCol"] = strSpecialCol;
                dtResult.Rows.Add(drLine);//insert facility summary row
                #endregion

                #region insert 数据行

                //生产线最后一行(小计行)
                DataRow drTempPlanSum = dtResult.NewRow();
                DataRow drTempActualSum = dtResult.NewRow();
                int     tempRowSumPlan = 0, tempRowSumActual = 0;//小计列累计

                var linePlanIDs = lstPlanAmount.Where(p => p.LineID == lineid).ToList().Select(p => p.ProdEventID).Distinct();
                foreach (int peid in linePlanIDs)//循环产线上的每一个计划
                {
                    if (!showByPlan)
                    {
                        SetContentRow(dtResult, peid, lineid, lstPlanAmount, oFacility, dFrom, dTo,
                                      ref tempRowSumPlan, ref tempRowSumActual, ref tempRowTotalPlan, ref tempRowTotalActual,
                                      drTempPlanSum, drTempActualSum, drTempTotalPlan, drTempTotalActual);
                    }
                    else
                    {
                        SetContentRow22(dtResult, peid, lineid, lstPlanAmount, oFacility, dFrom, dTo,
                                        ref tempRowSumPlan, ref tempRowSumActual, ref tempRowTotalPlan, ref tempRowTotalActual,
                                        drTempPlanSum, drTempActualSum, drTempTotalPlan, drTempTotalActual);
                    }
                }//end foreach plans

                #endregion

                #region insert 小计行
                DataRow drLineTotal = dtResult.NewRow();
                drLineTotal["SpecLineID"] = -2;
                drLineTotal["SpecCol"]    = "目标达成(小计)";// "目标达成(小计)";

                dayDate = dFrom.Date;
                while (dayDate <= dTo.Date)
                {
                    string colName       = dayDate.ToString("MM-dd");
                    int    planAmountSum = Convert.ToInt32(drTempPlanSum[colName]);
                    if (planAmountSum == 0)
                    {
                        drLineTotal[colName] = "";
                    }
                    else
                    {
                        drLineTotal[colName] = (Convert.ToDouble(drTempActualSum[colName]) / planAmountSum).ToString("p1");
                    }
                    dayDate = dayDate.AddDays(1);
                }

                if (tempRowSumPlan == 0)
                {
                    drLineTotal["RowSum"] = "";
                }
                else
                {
                    drLineTotal["RowSum"] = (Convert.ToDouble(tempRowSumActual) / tempRowSumPlan).ToString("p1");
                }

                drTempActualSum = null;
                drTempPlanSum   = null;
                dtResult.Rows.Add(drLineTotal);//insert 小计行
                #endregion
            }
            #endregion

            #region insert 总计行
            if (dtResult.Rows.Count > 0)
            {
                DataRow drAllTotal = dtResult.NewRow();
                drAllTotal["SpecLineID"] = -3;
                drAllTotal["SpecCol"]    = "目标达成(总计)";// "目标达成(总计)";

                dayDate = dFrom.Date;
                while (dayDate <= dTo.Date)
                {
                    string colName         = dayDate.ToString("MM-dd");
                    int    planAmountTotal = Convert.ToInt32(drTempTotalPlan[colName]);
                    if (planAmountTotal == 0)
                    {
                        drAllTotal[colName] = "";
                    }
                    else
                    {
                        drAllTotal[colName] = (Convert.ToDouble(drTempTotalActual[colName]) / planAmountTotal).ToString("p1");
                    }
                    dayDate = dayDate.AddDays(1);
                }

                if (tempRowTotalPlan == 0)
                {
                    drAllTotal["RowSum"] = "";
                }
                else
                {
                    drAllTotal["RowSum"] = (Convert.ToDouble(tempRowTotalActual) / tempRowTotalPlan).ToString("p1");
                }

                drTempTotalActual = null;
                drTempTotalPlan   = null;
                dtResult.Rows.Add(drAllTotal);//insert 总计行

                #region 汇总所有数量

                DataRow drSumPlan = dtResult.NewRow();
                drSumPlan["SpecLineID"] = -1;
                drSumPlan["SpecCol"]    = "汇总计划产量 : " + tempRowTotalPlan; //汇总计划产量
                dtResult.Rows.Add(drSumPlan);                             //insert 汇总计划数量

                DataRow drSumActual = dtResult.NewRow();
                drSumActual["SpecLineID"] = -1;
                drSumActual["SpecCol"]    = "汇总实际产量 : " + tempRowTotalActual; //汇总实际产量
                dtResult.Rows.Add(drSumActual);                               //insert 汇总实际产量
                #endregion
            }
            #endregion

            #endregion

            return(dtResult);
        }