using Microsoft.AspNetCore.Mvc;
using Siger.ApiCNC.Result;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.CncRepository.Request;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Log;
using Siger.Middlelayer.CncRepository.Response;
using Siger.ApiCommon.Filters;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common.ModuleEnum;
using System.Threading.Tasks;
using System.Linq.Expressions;
using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.Repository.Extensions;
namespace Siger.ApiCNC.Controllers
{
    /// <summary>
    /// 绩效统计控制器
    /// </summary>
    public class PerformanceStatisticsController : BaseController
    {
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectLevelSectionRepository _sigerProjectLevelSection;
        private readonly IProductPlanRepository _planRepository;
        private readonly IWorkingGroupRepository _workingGroupRepository;

        public PerformanceStatisticsController(IProductPlanRepository planRepository,ISigerProjectMachineRepository machineRepository, ISigerProjectLevelSectionRepository sigerProjectLevelSection,
            IWorkingGroupRepository workingGroupRepository)
        {
            _planRepository = planRepository;
            _machineRepository = machineRepository;
            _sigerProjectLevelSection = sigerProjectLevelSection;
            _workingGroupRepository = workingGroupRepository;
        }
        #region 工时统计分析

        /// <summary>
        /// 工时统计
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult WorkingHourStatistics([FromBody]RequestPerformanceStatistics request) //TODO此方法太长，需要优化,测试时优化
        {
            var startDate = UnixTimeHelper.ConvertDataTimeLong(request.starttime.ToDateTime());
            var endDate = UnixTimeHelper.ConvertDataTimeLong(request.endtime.ToDateTime().AddDays(1).AddMilliseconds(-1));
            var response = new WorkingHourStatisticsResult();
            //查时间内所有报工
            var reports = _planRepository.GetAllPassProductReports(request.sectionid, startDate, endDate, request.ordernumber, request.userid, ProjectId,(int)OrderReportApprovalStatus.Pass);
            if (!reports.Any())
            {
                if (request.toexcel == 0)
                {
                    return response;
                }
                else
                {
                    throw new BadRequestException(CommonEnum.NoDataForExport);
                }
            }


            if (request.type == 1) //订单号
            {
                var data = reports.GroupBy(g => g.ordernumber);
                foreach(var d in data)
                {
                    var obj = d.FirstOrDefault();
                    var orderDts = d.ToList();
                    //double actCnt = orderDts.Sum(s => s.actual_output);
                    response.xdata.Add(d.Key);
                    var ttwork = 0d;
                    var woCode = orderDts.GroupBy(g => g.gonglingdan);
                    foreach (var wo in woCode)
                    {
                        var woObj = wo.FirstOrDefault();
                        var woDts = wo.ToList();
                        var woCnt = woDts.Sum(s => s.actual_output);
                        var route = woDts.GroupBy(g => g.route_id);
                        foreach (var r in route)
                        {
                            var routeObj = r.FirstOrDefault();
                            var routelst = r.ToList();
                            var ttlOk = routelst.Sum(f => f.actual_output);
                            var ttlng = routelst.Sum(f => f.ngcount);
                            var workmin =(ttlOk+ ttlng) * routeObj.working_hour;
                            ttwork += workmin;
                            response.data.Add(new Result.WorkingHourListData
                            {
                                orderno=obj.ordernumber,
                                code = woObj.code,
                                workcode=woObj.gonglingdan,
                                productname= routeObj.product_name,
                                productdraw=routeObj.drawcode,
                                routename= routeObj.route_name,
                                machine=routeObj.machineTitle,
                                time=routeObj.time,
                                usercode=routeObj.worker_code,
                                username=routeObj.worker_name,
                                okcnt= ttlOk,
                                ngcnt= ttlng,
                                workingmin= workmin
                            });
                        }
                    }
                    response.ydata.Add(ttwork);

                }

            }
            else if (request.type == 2) //人员
            {
                var data = reports.GroupBy(g => g.user_mid);
                foreach (var d in data)
                {
                    var obj = d.FirstOrDefault();
                    var orderDts = d.ToList();
                    //double actCnt = orderDts.Sum(s => s.actual_output);
                    response.xdata.Add(obj.worker_name);
                  
                    var ttwork = 0d;
                    var woCode = orderDts.GroupBy(g => g.gonglingdan);
                    foreach (var wo in woCode)
                    {
                        var woObj = wo.FirstOrDefault();
                        var woDts = wo.ToList();
                        var woCnt = woDts.Sum(s => s.actual_output);
                        var route = woDts.GroupBy(g => g.route_id);
                        foreach (var r in route)
                        {
                            var routeObj = r.FirstOrDefault();
                            var routelst = r.ToList();
                            var ttlOk = routelst.Sum(f => f.actual_output);
                            var ttlng = routelst.Sum(f => f.ngcount);
                            var workmin = (ttlOk +ttlng) * routeObj.working_hour;
                            ttwork += workmin;
                            response.data.Add(new Result.WorkingHourListData
                            {
                                orderno = obj.ordernumber,
                                code = woObj.code,
                                workcode = woObj.gonglingdan,
                                productname = routeObj.product_name,
                                productdraw = routeObj.drawcode,
                                routename = routeObj.route_name,
                                machine = routeObj.machineTitle,
                                time = routeObj.time,
                                usercode = routeObj.worker_code,
                                username = routeObj.worker_name,
                                okcnt = ttlOk,
                                ngcnt = ttlng,
                                workingmin = workmin
                            });
                        }
                    }
                    response.ydata.Add(ttwork);
                }
            }
            else  //工单号
            {
                var data = reports.GroupBy(g => g.code);
                foreach (var d in data)
                {
                    var obj = d.FirstOrDefault();
                    var orderDts = d.ToList();
                    response.xdata.Add(d.Key);
                    var ttwork = 0d;
                    var woCode = orderDts.GroupBy(g => g.gonglingdan);
                    foreach (var wo in woCode)
                    {
                        var woObj = wo.FirstOrDefault();
                        var woDts = wo.ToList();
                        var woCnt = woDts.Sum(s => s.actual_output);
                        var route = woDts.GroupBy(g => g.route_id);
                        foreach (var r in route)
                        {
                            var routeObj = r.FirstOrDefault();
                            var routelst = r.ToList();
                            var ttlOk = routelst.Sum(f => f.actual_output);
                            var ttlng = routelst.Sum(f => f.ngcount);
                            var workmin =(ttlOk+ ttlng) * routeObj.working_hour;
                            ttwork += workmin;
                            response.data.Add(new Result.WorkingHourListData
                            {
                                orderno = obj.ordernumber,
                                code = woObj.code,
                                workcode = woObj.gonglingdan,
                                productname = routeObj.product_name,
                                productdraw = routeObj.drawcode,
                                routename = routeObj.route_name,
                                machine = routeObj.machineTitle,
                                time = routeObj.time,
                                usercode = routeObj.worker_code,
                                username = routeObj.worker_name,
                                okcnt = ttlOk,
                                ngcnt = ttlng,
                                workingmin = workmin
                            });
                        }
                    }
                    response.ydata.Add(ttwork);
                }
            }
            if (request.toexcel == 0)
            {
                return response;
            }
            return ExportWorkingHour(response.data, request.type, 0);
        }

        private IActionResult ExportWorkingHour(IList<WorkingHourListData> responses, int type, int language)
        {
            if (!responses.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var temporaryFileName = $"WorkingHour_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);
            var helper = new EpPlusExcelHelper<WorkingHourList>(language);
            try
            {
                var machineYields = new List<WorkingHourList>();
                var index = 1;
                foreach (var yield in responses)
                {
                    var machineYield = new WorkingHourList
                    {
                        No = index,
                        Abscissa = yield.orderno,
                        OrderNumber = yield.code,
                        ProductName = yield.productname,
                        Prepare = "",
                        WorkingHour = yield.workingmin.ToStr(),
                        Total = yield.okcnt.ToStr()
                    };
                    machineYields.Add(machineYield);
                    index++;
                }

                helper.GenerateExcel(machineYields, fileName);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ExportBarChart failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }

        }

        #endregion
        #region 质量合格率统计
        /// <summary>
        /// 质量合格率统计
        /// </summary>
        /// <param name="sectionid">产线层级</param>
        /// <param name="starttime">日期范围--开始</param>
        /// <param name="endtime">日期范围--结束</param>
        /// <param name="dimension">统计维度--工位或人员(1/2)</param>
        /// <param name="toexcel">是否是导出--1导出</param>
        /// <returns></returns>
        [HttpGet]
        [NoTokenValidateFilter]
        public IActionResult GetQualificationRate(int sectionid,string starttime,string endtime,int dimension,int toexcel=0) 
        {

            if (starttime==null|| endtime==null)
            {
                starttime = DateTimeHelper.FirstDayMoth(DateTime.Now).ToStr();
                endtime = DateTimeHelper.LastDayMonth(DateTime.Now).ToStr();
            }
            //得到时间范围的每天开始到结束时间
            Dictionary<long, long> dic = new Dictionary<long, long>();
            var monthStart =starttime.ToDateTime();
            var monthEnd = DateTimeHelper.LastDayMonth(monthStart);
           // var monthEnd = monthStart.AddMonths(1).AddDays(1).AddMinutes(1).AddSeconds(-1);
            var days = monthEnd.Day - monthStart.Day;
            var dayStart = monthStart;
            var dayEnd = monthEnd.AddDays(-days);
            dic.Add(UnixTimeHelper.ConvertDataTimeLong(dayStart), UnixTimeHelper.ConvertDataTimeLong(dayEnd));
            for (int i = 0; i < days; i++)
            {
                dayStart = dayStart.AddDays(+1);
                dayEnd = dayEnd.AddDays(+1);
                dic.Add(UnixTimeHelper.ConvertDataTimeLong(dayStart), UnixTimeHelper.ConvertDataTimeLong(dayEnd));
            }
    
            //查时间内所有报工
            var reports = _planRepository.GetAllPassProductReports(sectionid, UnixTimeHelper.ConvertDataTimeLong(monthStart), 
                UnixTimeHelper.ConvertDataTimeLong(monthEnd),ProjectId);

            var responseData= new ResponseQualificationRate();
            if (dimension == 1)//工位
            {
                var columKey = "base";
                var grpStation = reports.GroupBy(g => g.station_id);
                if (!grpStation.Any())
                {
                    DateTime dtDay;
                    for (dtDay = monthStart; dtDay.CompareTo(monthEnd) <= 0; dtDay = dtDay.AddDays(1))
                    {
                        var step = dtDay.Day;
                        var key = $"day{step}";
                        if (!responseData.xdata.Exists(f => f.key == columKey))
                        {
                            responseData.xdata.Add(new xdata
                            {
                                key = "base",
                                title = "工位"
                            });
                            responseData.xdata.Add(new xdata
                            {
                                key = key,
                                title = step.ToStr()
                            });
                        }
                    }
                }
                var row = 0;
                foreach (var station in grpStation)
                {
                    var stationObj = station.FirstOrDefault();
                    var stationDts = station.ToList();
                    if (!responseData.xdata.Exists(f => f.key == columKey))
                    {
                        responseData.xdata.Add(new xdata
                        {
                            key = "base",
                            title = "工位"
                        });
                    }
                    var ydata = new ydata
                    {
                        day = new List<ydatadetails>(),
                        stationperson = stationObj.station_name,
                        stationpersonid = stationObj.station_id
                    };
                    DateTime dtDay;
                    for (dtDay = monthStart; dtDay.CompareTo(monthEnd) <= 0; dtDay = dtDay.AddDays(1))
                    {
                       
                        var step = dtDay.Day;
                        var currData = stationDts.Where(f => f.day == step);
                        var key = $"day{step}";
                        if (row == 0)
                        {

                            responseData.xdata.Add(new xdata
                            {
                                key = key,
                                title = step.ToStr()
                            });
                        }
                        double okCnt = currData.Sum(s => s.actual_output);
                        double ngCnt = currData.Sum(s => s.nok_number);
                       
                        var total = okCnt + ngCnt;
                        var rate =total==0?0:okCnt * 100 / (okCnt + ngCnt);
                        ydata.day.Add(new ydatadetails
                        {
                            key= key,
                            percent= Math.Round(rate,2)
                        });
                    }
                    responseData.ydata.Add(ydata);
                    row += 1;
                }


            }
            else//人员
            {
                var columKey = "base";
                var grpUser = reports.GroupBy(g => g.uid);
                if (!grpUser.Any())
                {
                    DateTime dtDay;
                    for (dtDay = monthStart; dtDay.CompareTo(monthEnd) <= 0; dtDay = dtDay.AddDays(1))
                    {
                        var step = dtDay.Day;
                        var key = $"day{step}";
                        if (!responseData.xdata.Exists(f => f.key == columKey))
                        {
                            responseData.xdata.Add(new xdata
                            {
                                key = "base",
                                title = "人员"
                            });
                            responseData.xdata.Add(new xdata
                            {
                                key = key,
                                title = step.ToStr()
                            });
                        }
                    }
                }
                var row = 0;
                foreach (var usr in grpUser)
                {
                    var usrobj = usr.FirstOrDefault();
                    var usrobjDts = usr.ToList();
                    if (!responseData.xdata.Exists(f => f.key == columKey))
                    {
                        responseData.xdata.Add(new xdata
                        {
                            key = "base",
                            title = "人员"
                        });
                    }
                    var ydata = new ydata
                    {
                        day = new List<ydatadetails>(),
                        stationperson = usrobj.worker_name,
                        stationpersonid = usrobj.uid
                    };
                    DateTime dtDay;
                    for (dtDay = monthStart; dtDay.CompareTo(monthEnd) <= 0; dtDay = dtDay.AddDays(1))
                    {
                        var step = dtDay.Day;
                        var currData = usrobjDts.Where(f => f.day == step);
                        var key = $"day{step}";
                        if (row == 0)
                        {
                            responseData.xdata.Add(new xdata
                            {
                                key = key,
                                title = step.ToStr()
                            });
                        }
                        double okCnt = currData.Sum(s => s.actual_output);
                        double ngCnt = currData.Sum(s => s.nok_number);
                        var total = okCnt + ngCnt;
                        var rate = total == 0 ? 0 : okCnt / (okCnt + ngCnt);
                        ydata.day.Add(new ydatadetails
                        {
                            key = key,
                            percent =Math.Round( rate,2) * 100
                        });
                    }
                    responseData.ydata.Add(ydata);
                    row += 1;
                }

            }
            if (toexcel==1)
            {
               return  ExportQualificationRate(responseData, dimension);
            }
            return new ObjectResult(responseData);
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="responses"></param>
        /// <param name="type">工位/人员</param>
        /// <returns></returns>
        private IActionResult ExportQualificationRate(ResponseQualificationRate responses, int type)
        {
            if (responses==null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            //导出
        
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            //获取列名和所有值
            var tracking =GetNormal(responses,type);

            var importGeneralData = new List<ImportGeneralObj>();
            //循环body获取列名和对应的值
            foreach (var g in tracking.Bodys)
            {
                var items = new List<string>();
                var values = new List<string>();
                foreach (var dts in g.Items)
                {
                    items.Add(dts.Item);
                    values.Add(dts.Values);
                }
                importGeneralData.Add(new ImportGeneralObj
                {
                    Items = items,
                    Values = values
                });
            }
            EpPlusExcelTemplateHelper helper = null;
            try
            {
                helper = new EpPlusExcelTemplateHelper();
                var temporaryFileName = $"质量合格率统计-{DateTime.Now:yyyyMMddHHmmss}.xlsx";

                helper.GenerateAutoQualificationRate(importGeneralData, Path.Combine(rootDir, temporaryFileName));
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch
            {
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper?.Dispose();
            }
        }

        /// <summary>
        /// 获取列名和所有值
        /// </summary>
        /// <param name="response"></param>
        /// <param name="type">工位/人员(1/2)</param>
        /// <returns></returns>
        private PerformanceStatistic GetNormal(ResponseQualificationRate response, int type)
        {
            var tracking = new PerformanceStatistic { Heads = new PerformanceStatisticDetails(), Bodys = new List<PerformanceStatisticDetails>() };
            var head = new PerformanceStatisticDetails
            {
                Items = new List<ItemDetails>()
            };

            var stationItem = response.xdata;
            var stationTracelst = response.ydata;
            var trace = stationTracelst.FirstOrDefault();          
            if (trace != null)
            {
                foreach (var ydatas in stationTracelst)
                {
                    var body = new PerformanceStatisticDetails
                    {
                        Items = new List<ItemDetails>()
                    };
                    var num = 1;
                    foreach (var ydata in ydatas.day)
                    {
                        if (num == 1)
                        {
                            body.Items.Add(new ItemDetails { Item =EnumHelper.GetEnumDesc((PersonStation)type), Values = ydatas.stationperson });
                            num++;
                        }                                          
                        body.Items.Add(new ItemDetails { Item = ydata.key, Values = ydata.percent.ToStr() });
                    }
                    tracking.Bodys.Add(body);
                }
            }
            return tracking;
        }


        /// <summary>
        /// 查看某天的效率详情
        /// </summary>
        /// <param name="sectionid">产线层级</param>
        /// <param name="starttime">日期范围--开始</param>
        /// <param name="endtime">日期范围--结束</param>
        /// <param name="dimension">统计维度--工位或人员(1/2)</param>
        /// <param name="stationpersonid">工位或人员唯一标识</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetDataDetail(int sectionid, string starttime, string endtime, int dimension,int stationpersonid) 
        {

            var dayStart = starttime.ToDateTime();
            var dayEnd = endtime.ToDateTime().AddDays(1).AddMilliseconds(-1);

            //查时间内所有报工
            var reports = _planRepository.GetAllPassProductReports(sectionid, UnixTimeHelper.ConvertDataTimeLong(dayStart), UnixTimeHelper.ConvertDataTimeLong(dayEnd), ProjectId);
            if (dimension == 1)//工位
            {
                reports = reports.Where(f => f.station_id == stationpersonid);
            }
            else//人员
            {
                reports = reports.Where(f => f.uid == stationpersonid);
            }
            var result = new List<QualificationRate>();
            foreach(var d in reports)
            {
                d.name = "bb";
            }
            return new ObjectResult(reports);
        }

        #endregion

        #region 计划执行分析
        /// <summary>
        /// 计划执行分析 列表
        /// </summary>
        /// <param name="sectionid">产线层级</param>
        /// <param name="productid">产品名称id</param>
        /// <param name="starttime">时间范围--开始</param>
        /// <param name="endtime">时间范围--结束</param>
        /// <param name="page">第几页</param>
        /// <param name="pagesize">每页条数</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetPlanExecutionAnalysis(int sectionid,int productid,string starttime,string endtime,int page,int pagesize) 
        {
            var startDate = UnixTimeHelper.ConvertDataTimeLong(starttime.ToDateTime());
            var endDate = UnixTimeHelper.ConvertDataTimeLong(endtime.ToDateTime().AddDays(1).AddMilliseconds(-1));
            Expression<Func<siger_project_product_plan, bool>> pdExpression = q => true;
            if (productid != 0)
            {
                pdExpression = p => p.product_id == productid;
            }
            Expression<Func<siger_project_product_plan, bool>> TimeExpression = q => true;
            TimeExpression = q => q.projectid==ProjectId && q.create_time >= startDate && q.create_time <= endDate;
            var predicate = TimeExpression.And(pdExpression);
            var plan = _planRepository.GetPagedList(page,pagesize,predicate);

            var result = new List<ResponsePlanExecutionAnalysis>();
            foreach(var p in plan.Data.ToList())
            {
                double okCnt = p.producted_number - p.nok_number;
                double rate = p.producted_number > 0 ? Math.Round(okCnt *100  / p.producted_number,2):0d;
                if(p.delivery_time <= UnixTimeHelper.ConvertDataTimeLong(DateTime.Now.ToString()) && p.status!=(int)PlanDispatch.Finished)
                {
                    p.status = (int)PlanDispatch.Overdue;
                }
                result.Add(new ResponsePlanExecutionAnalysis
                {
                     id=p.id,
                     actual_completiontime= p.finish_time,
                     actual_number=p.producted_number,
                     delivery_time = p.delivery_time,
                     code=p.code,
                     nok_number=p.nok_number,
                     ok_number=p.producted_number -p.nok_number,
                     product_name=p.product_name,
                     plan_number=p.install_count,
                     product_id=p.product_id,
                     pass_rate=Math.Round( rate,2),
                     status=p.status
                });
            }
            return new PagedObjectResult(result, plan.Total, page, pagesize);

        }
        /// <summary>
        /// 计划执行分析数据汇总 
        /// </summary>
        /// <param name="sectionid">产线层级</param>
        /// <param name="productid">产品名称id</param>
        /// <param name="starttime">时间范围--开始</param>
        /// <param name="endtime">时间范围--结束</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetPlanSum(int sectionid, int productid, string starttime, string endtime)
        {

            var startDate = UnixTimeHelper.ConvertDataTimeLong(starttime.ToDateTime());
            var endDate = UnixTimeHelper.ConvertDataTimeLong(endtime.ToDateTime().AddDays(1).AddMilliseconds(-1));
            Expression<Func<siger_project_product_plan, bool>> pdExpression = q => true;
            if (productid!=0)
            {
                pdExpression = p => p.product_id == productid;
            }
            Expression<Func<siger_project_product_plan, bool>> TimeExpression = q => true;
            TimeExpression = q =>q.projectid==ProjectId && q.create_time>=startDate && q.create_time<=endDate;
            var predicate = TimeExpression.And(pdExpression);

            var plan = _planRepository.GetList(predicate);
            var plancount = plan.Count();
            var installPlan = plan.Sum(f => f.install_count); // 工单生产数量
      
            double ttlProductPlan = plan.Sum(f => f.producted_number); //ok+ng // 最后一道工序完成单子条数
            double okttlPlan= ttlProductPlan - plan.Sum(f => f.nok_number); //ok

            double planDelivery = plan.Where(f => f.finish_time > 0 && f.finish_time <= f.delivery_time).Count(); //完工时间<交货期的工单数量
            double achievementPdRate = installPlan>0? Math.Round(ttlProductPlan * 100 / installPlan,2):0d;
            double achievementPlanRate = plancount>0? Math.Round(planDelivery * 100/ plancount,2):0d;
            double passRate = ttlProductPlan > 0 ? Math.Round(okttlPlan * 100 / ttlProductPlan ,2): 0d;
            var data = new ResponsePlanSum
            {
                plannumber= installPlan,
                actualnumber= ttlProductPlan,
                total= plancount,
                productpercent= Math.Round(achievementPdRate,2),
                planpercent = Math.Round(achievementPlanRate,2),
                qualitypercent=Math.Round(passRate,2)
            };
            return new ObjectResult(data);
        }

        #endregion

        /// <summary>
        ///  报工明细
        /// </summary>
        /// <param name="section"></param>
        /// <param name="startdate"></param>
        /// <param name="enddate"></param>
        /// <param name="orderno"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetReportDetails(int section,string startdate,string enddate,string orderno)
        {
            var startDate = UnixTimeHelper.ConvertDataTimeLong(startdate.ToDateTime());
            var endDate = UnixTimeHelper.ConvertDataTimeLong(enddate.ToDateTime().AddDays(1).AddMilliseconds(-1));
            var reports = _planRepository.GetAllPassProductReports(section, startDate, endDate, orderno, UserId, ProjectId,0);
            if(!reports.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var result = new List<WorkingHourListData>();
            var data = reports.GroupBy(g => g.user_mid);
            foreach (var d in data)
            {
                var obj = d.FirstOrDefault();
                var orderDts = d.ToList();
                double actCnt = orderDts.Sum(s => s.actual_output);

                var woCode = orderDts.GroupBy(g => g.gonglingdan);
                foreach (var wo in woCode)
                {
                    var woObj = wo.FirstOrDefault();
                    var woDts = wo.ToList();
                    var woCnt = woDts.Sum(s => s.actual_output);
                    var route = woDts.GroupBy(g => g.route_id);
                    foreach (var r in route)
                    {
                        var routeObj = r.FirstOrDefault();
                        var routelst = r.ToList();
                        var ttlOk = routelst.Sum(f => f.actual_output);
                        var ttlng = routelst.Sum(f => f.ngcount);
                        var workmin = ttlOk * routeObj.working_hour;
                        result.Add(new Result.WorkingHourListData
                        {
                            orderno = wo.FirstOrDefault().ordernumber,
                            code = woObj.code,
                            workcode = woObj.gonglingdan,
                            productname = routeObj.product_name,
                            productdraw = routeObj.drawcode,
                            routename = routeObj.route_name,
                            machine = routeObj.machineTitle,
                            time = routeObj.time,
                            usercode = routeObj.worker_code,
                            username = routeObj.worker_name,
                            okcnt = ttlOk,
                            ngcnt = ttlng,
                            workingmin = workmin
                        });
                    }
                }
            }

            return new ObjectResult(result);
        }

        /// <summary>
        /// APP 生产进度详情
        /// </summary>
        /// <param name="section"></param>
        /// <param name="startdate"></param>
        /// <param name="enddate"></param>
        /// <param name="orderno"></param>
        /// <param name="planid"></param>
        /// <param name="userid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetReportDetailsPlanId(int section, string startdate, string enddate, string orderno, int planid,int userid)
        {
            var startDate = UnixTimeHelper.ConvertDataTimeLong(startdate.ToDateTime());
            var endDate = UnixTimeHelper.ConvertDataTimeLong(enddate.ToDateTime().AddDays(1).AddMilliseconds(-1));
            var reports = _planRepository.GetAllPassProductReports(section, startDate, endDate, orderno, userid, ProjectId,0);

            return new ObjectResult(reports);
        }
    }
}
