using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Filters;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.CncRepository.Response;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.CncRepository.Request;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Dapper;

namespace Siger.ApiCNC.Controllers
{
    /// <summary>
    /// 计划内派工控制器
    /// </summary>
    public class ProductPlanDispatchController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IProductPlanRepository _planRepository;
        private readonly IProjectProductPlanDispatchReponsitory _projectProductPlanDispatchReponsitory;
        private readonly IProductPlanDetailRepository _planDetailRepository;
        private readonly IProductRouteRepository _routeRepository;
        private readonly ISigerProjectProductReport _sigerProjectProductReport;
        private readonly ISigerProjectUserRepository _sigerProjectUserRepository;
        private readonly ISigerProjectPlanMachineRouteRepository _planMachineRoute;
        private readonly ISigerProjectUserRepository _userRepository;
        private readonly ISigerProjectProductReport _productionReportRepository;
        private readonly IWorkingGroupRepository _workingGroup;
        private readonly ISigerProjectShiftRepository _sigerProjectShift;
        private readonly ISigerProjectMachineAttributionRepository _machineAttributionRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectLevelSectionRepository _levelSectionRepository;

        public ProductPlanDispatchController(IUnitOfWork unitOfWork,IProductPlanRepository planRepository, IProjectProductPlanDispatchReponsitory projectProductPlanDispatchReponsitory, ISigerProjectPlanMachineRouteRepository planMachineRoute,
            IProductPlanDetailRepository planDetailRepository, IProductRouteRepository routeRepository, ISigerProjectProductReport sigerProjectProductReport,ISigerProjectUserRepository sigerProjectUserRepository
            , ISigerProjectProductReport productionReportRepository, ISigerProjectUserRepository userRepository, IWorkingGroupRepository workingGroup, ISigerProjectShiftRepository sigerProjectShift, ISigerProjectMachineAttributionRepository machineAttributionRepository,
             ISigerProjectMachineRepository machineRepository, ISigerProjectLevelSectionRepository levelSectionRepository)
        {
            _unitOfWork = unitOfWork;
            _planRepository = planRepository;
            _projectProductPlanDispatchReponsitory = projectProductPlanDispatchReponsitory;
            _planDetailRepository = planDetailRepository;
            _routeRepository = routeRepository;
            _sigerProjectProductReport = sigerProjectProductReport;
            _sigerProjectUserRepository = sigerProjectUserRepository;
            _planMachineRoute = planMachineRoute;
            _userRepository = userRepository;
            _productionReportRepository = productionReportRepository;
            _workingGroup = workingGroup;
            _sigerProjectShift = sigerProjectShift;
            _machineAttributionRepository = machineAttributionRepository;
            _machineRepository = machineRepository;
            _levelSectionRepository = levelSectionRepository;

        }

        /// <summary>
        /// 计划内派工查询
        /// </summary>
        /// <param name="ordernumber">订单号</param>
        /// <param name="product_name">产品名称</param>
        /// <param name="code">工单号</param>
        /// <param name="page">第几页</param>
        /// <param name="pagesize">每页条数</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetDataList(string ordernumber, string product_name, string code, int page, int pagesize)
        {
            var data = _projectProductPlanDispatchReponsitory.GetPagedProductPlanDispatch(ordernumber, product_name, code, ProjectId, page, pagesize);
            var response = new List<ResponseProductPlanDispatch>();

            foreach (var plan in data.Data)
            {
                var planDts = _planDetailRepository.GetList(m =>
                    m.planId == plan.planid && m.status != (int)PlanDispatch.Stop && m.projectId == ProjectId);

                var planInfo = Mapper<ResponseProductPlanDispatch, ResponseProductPlanDispatch>.Map(plan);
                planInfo.batches_number = planDts.Count();
                planInfo.scheduled_quantity = planDts.Sum(s => s.quantity);//已排产数量
                var deliveryDate = plan.delivery_time.ToDateTime(); // UnixTimeHelper.ConvertStringDateTime(plan.delivery_time.ToString());
                planInfo.days_remaining = deliveryDate.Date.Subtract(DateTime.Now.Date).Days;
                //var productReport = _sigerProjectProductReport.GetList(f => f.plan_id == plan.id);
                //if (productReport.Any())
                //{
                //    planInfo.workorder_status = (int)PlanDispatch.Producing;
                //}
              
                double planCount = plan.install_count;
                double  planRate = planDts.Sum(s => s.producted_number) / planCount;
                var rate = Math.Round(planRate * 100, 2);
                planInfo.completion_rate = rate;
                response.Add(planInfo);
            }
            return new PagedObjectResult(response, data.Total, page, pagesize);
        }

        /// <summary>
        /// 计划内派工生成工令单和派工数量
        /// </summary>
        /// <param name="id">数据id</param>
        /// <param name="num">批次</param>
        /// <param name="total">数量</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetDispatchDetails(int id, int num, int total)
        {
            if (num == 0)
            {
                throw new BadRequestException(CncEnum.BatchMustGreaterZero);
            }
            var plan = _planRepository.Get(id);
            if (plan == null)
            {
                throw new BadRequestException(CncEnum.PlanNotFound);
            }
            if (num > total)
            {
                num = total;
            }

            var startIndex = 0;
            var details = _planDetailRepository.GetList(q => q.planId == plan.id && q.projectId == ProjectId).ToList();
            if (details.Any())
            {
                var orderNumber = details.OrderByDescending(q => q.id).First().orderNumber;
                var orders = orderNumber.Split('-');
                startIndex = orders[orders.Length - 1].ToInt();
            }

            var batch = total / num;
            var residual = total % num;
            var response = new List<ResponseGetWorkOrders>();
            if (residual == 0)
            {
                for (var i = 1; i <= num; i++)
                {
                    response.Add(new ResponseGetWorkOrders
                    {
                        orderNumber = $"{plan.code}-{i + startIndex}",
                        count = batch
                    });
                }
            }
            else
            {
                var count = batch;
                for (var i = 1; i <= num; i++)
                {
                    if (i == num)
                    {
                        count = batch + residual;
                    }
                    response.Add(new ResponseGetWorkOrders
                    {
                        orderNumber = $"{plan.code}-{i + startIndex}",
                        count = count
                    });
                }

            }
            return new ObjectResult(response);
        }

        /// <summary>
        /// 派工
        /// </summary>
        /// <param name="request">参数</param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddSchedule([FromBody]RequestProductPlanDispatch request)
        {
            if (request.orders == null || !request.orders.Any())
            {
                throw new BadRequestException(CncEnum.RoutesNotFound);
            }

            var planObj = _planRepository.Get(f => f.id == request.planId);
            if (planObj == null)
            {
                throw new BadRequestException(CncEnum.PlanNotFound);
            }
            var planDts = _planDetailRepository.GetList(f => f.planId == request.planId && f.status == (int)RowState.Valid);
            var planCnt = planDts.Sum(f => f.quantity);
            var curCnt = request.orders.Sum(f => f.count);
            if (planCnt + curCnt > planObj.install_count)
            {
                throw new BadRequestException(CncEnum.MaxReportCount);
            }
            foreach (var r in request.orders)
            {
                _planDetailRepository.Insert(new siger_project_product_plan_detail
                {
                    addTime = DateTime.Now,
                    levelId = 0,
                    orderNumber = r.orderNumber,
                    planId = request.planId,
                    projectId = ProjectId,
                    quantity = r.count,
                    creator_mid = UserId,
                    status= (int)PlanDispatch.HasPlan
                });
            }
            planObj.status = (int)PlanDispatch.HasPlan;
            _planRepository.Update(planObj);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);

        }

        /// <summary>
        /// 获取终止弹框数据
        /// </summary>
        /// <param name="code">工单号</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetStopScheduleData(string code) 
        {
            var plan = _planRepository.Get(f => f.projectid == ProjectId && f.code == code);
            if (plan==null)
            {
                throw new BadRequestException(CncEnum.PlanNotFound);
            }
            if (plan.status== (int)PlanDispatch.UnIssue || plan.status>= (int)PlanDispatch.Finished)
            {
                throw new BadRequestException(CncEnum.PlanCannotStop);
            }
            var report = _sigerProjectProductReport.GetList(f => f.plan_id == plan.id);
            if (report.Any())
            {
                throw new BadRequestException(CncEnum.PlanCannotStop);
            }
            var result = new List<ResponseStopSchedule>();
            var planDts = _planDetailRepository.GetList(f => f.planId == plan.id);
            var total = planDts.Sum(s => s.quantity);
           
            foreach(var dts in planDts)
            {
                var state = "";
                if (dts.producted_number == 0)
                {
                    state= EnumHelper.GetEnumDesc(PlanDispatch.HasPlan);
                }
                if(dts.producted_number>0)
                {
                    state= EnumHelper.GetEnumDesc(PlanDispatch.Producing);
                }
                if (dts.producted_number>=dts.quantity)
                {
                    state= EnumHelper.GetEnumDesc(PlanDispatch.Finished);
                }
                if (dts.status== (int)PlanDispatch.Stop)
                {
                    state = EnumHelper.GetEnumDesc(PlanDispatch.Stop);
                }
                if (plan.delivery_time <= UnixTimeHelper.ConvertDataTimeLong(DateTime.Now.ToString()) && plan.status !=(int)PlanDispatch.Finished)
                {
                    state = EnumHelper.GetEnumDesc(PlanDispatch.Overdue);
                }
                var usr = _sigerProjectUserRepository.Get(f => f.mid == dts.creator_mid);
                result.Add(new ResponseStopSchedule
                {
                     install_count=plan.install_count,
                     name=usr!=null?usr.name:"",
                     id=dts.id,
                     orderNumber=dts.orderNumber,
                     producted_num=dts.producted_number,
                     ngCount=dts.nok_number,
                     last_number=dts.quantity-dts.producted_number,
                     quantiy=dts.quantity,
                     state= state,
                     time=dts.addTime.ToString()
                     
                });
            }
          //  var data = _projectProductPlanDispatchReponsitory.GetStopScheduleData(code,ProjectId);
            
            return new ObjectResult(result);
        }

        /// <summary>
        /// 终止
        /// </summary>
        /// <param name="idstr">数据要终止的工单id</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult StopSchedule(int planId)
        {

            var plan = _planRepository.Get(f => f.id == planId);
            if (plan==null)
            {
                throw new BadRequestException(CncEnum.PlanNotFound);
            }
            //1,5,6 
            if (plan.status==(int)PlanDispatch.UnIssue || plan.status == (int)PlanDispatch.Finished|| plan.status == (int)PlanDispatch.Stop)
            {
                throw new BadRequestException(CncEnum.PlanCannotStop);
            }
            plan.status = (int)PlanDispatch.Stop;

            var planDts = _planDetailRepository.GetList(s => s.planId == plan.id && s.projectId == ProjectId);
            foreach (var dts in planDts)
            {
               
                dts.status = (int)PlanDispatch.Stop;
                _planDetailRepository.Update(dts);
            }
            _planRepository.Update(plan);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 查看工单进度
        /// </summary>
        /// <param name="id">数据id</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetOrderProgress(int id)
        {

            var plan = _planRepository.Get(id);
            if (plan == null)
            {
                throw new BadRequestException(CncEnum.PlanNotFound);
            }
            var data = _planDetailRepository.GetPlanReports(ProjectId, plan.id,0);
            var plandts = data.GroupBy(g => g.code);
            var doneCnt = 0d;
            foreach(var dts in plandts)
            {
                doneCnt += dts.FirstOrDefault().quantity;
            }
            var result = new List<ResponseDispatchViewProgress>();
            var routeReport = data.GroupBy(g => g.route_id);
            foreach(var route in routeReport)
            {
                var obj = route.FirstOrDefault();
                var objlst = _sigerProjectProductReport.GetList(f => f.projectid == ProjectId && f.plan_id == obj.plan_id && f.route_id== obj.route_id);
                var stateDesc= EnumHelper.GetEnumDesc((PlanDispatch)obj.status);
                double okttl = objlst.Sum(f => f.actual_output);
                double ngttl = objlst.Sum(f => f.nok_number);
                double processPercent = (okttl + ngttl)  * 100 / plan.quantity;
                var productionschedule = Math.Round(processPercent,2);
                result.Add(new ResponseDispatchViewProgress
                {
                    producted_number=plan.install_count,
                    description=obj.route_name,
                    name=obj.route_name,
                    job_count= doneCnt,
                    ok_number= okttl,
                    nok_number= ngttl,
                    serialNumber= obj.route_serinum,
                    state= stateDesc,
                    productionschedule= productionschedule
                });

            }
            return new ObjectResult(result);
        }

        /// <summary>
        /// 计划下发
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="planstart">计划开始</param>
        /// <param name="planend">计划结束</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult PlanDistribution(int id, string planstart, string planend)
        {
            var planData = _planRepository.Get(f => f.id == id && f.projectid == ProjectId);
            if (planData == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            // 工单状态: 1 = 未下发(生产计划使用); 2 = 未排产；3 = 已派工；4 = 生产中；5 = 已完工；6 = 已终止
            if (planData.status > 1)
            {
                throw new BadRequestException(CncEnum.ProductionPlanIssued);
            }
            planData.status = (int)PlanDispatch.UnPlan;
            planData.plan_starttime = UnixTimeHelper.GetUnixByShortDate(planstart);
            planData.plan_endtime = UnixTimeHelper.GetUnixByShortDate(planend);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 根据工位
        /// </summary>
        /// <param name="sectionId"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult WebScanMachine(int sectionId)
        {
            var machineAttr = _machineAttributionRepository.Get(f => f.station == sectionId && f.status == (int)RowState.Valid);
            if (machineAttr == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var machine = _machineRepository.Get(q => q.id == machineAttr.machine && q.status == (int)RowState.Valid && q.projectid == ProjectId);
            if (machine == null)
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            var title = "";
            title = _levelSectionRepository.GetList(q => q.id == sectionId && q.status == (int)RowState.Valid && q.projectid == ProjectId).ToList().Select(q => q.title).FirstOrDefault();
            
            var planMachine = _planMachineRoute.Get(q => q.machineId == machine.id && q.status != (int)RowState.Invalid && q.projectId == ProjectId);
            if (planMachine != null)
            {
                var details = _planDetailRepository.Get(q => q.id == planMachine.plandts_id && q.status != (int)RowState.Invalid && q.projectId == ProjectId);
                if (details == null)
                {
                    throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
                }
                var plan = _planRepository.Get(q => q.id == details.planId && q.status != (int)RowState.Invalid && q.projectid == ProjectId);
                if (plan == null)
                {
                    throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
                }
                var url = _planDetailRepository.GetDrawUrl(plan.product_id,ProjectId);
                var res = new RequestMachines()
                {
                    id = details.id,
                    machineId = machine.id,
                    circulation = details.orderNumber,
                    product_id = plan.product_id,
                    route_id = planMachine.route_id,
                    code = plan.code,
                    deliverytime = UnixTimeHelper.ConvertIntDateTime(plan.delivery_time),
                    drawnumber = plan.draw_number,
                    nok_number = planMachine.nok,
                    ok_number = planMachine.ok,
                    producename = plan.product_name,
                    quantity = plan.quantity,
                    title = title,
                    route_ordernumber = planMachine.route_code,
                    sectionId = machineAttr.station,
                    route_name = planMachine.routename,
                    number = planMachine.nok + planMachine.ok,
                    draw_url = url != null ? url : "",
                    state = 1,
                    section = planMachine != null ? planMachine.sectionid : 0,
                    status = planMachine.status
                };

                return new ObjectResult(res);
            }
            var ret = new RequestMachine()
            {
                sectionId = sectionId,
                machineId = machine.id,
                section=0,
                title = title,
                state = 0,
            };

            return new ObjectResult(ret);
        }

        /// <summary>
        /// 根据工单和工序查询数据
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult WebScanMachines(string code)
        {
            var str = code.Split('|');
            if (str.Length!=2)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }
            var details = _planDetailRepository.Get(q => q.orderNumber == str[0] && q.status != (int)RowState.Invalid && q.projectId == ProjectId);
            if (details == null)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }
            var plan = _planRepository.Get(q => q.id == details.planId && q.status != (int)RowState.Invalid && q.projectid == ProjectId);
            if (plan == null)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }
            var route = _routeRepository.Get(q => q.id.ToString() == str[1] && q.status == (int)RowState.Valid && q.projectId == ProjectId);
            if (route == null)
            {
                throw new BadRequestException(RequestEnum.RouteNotFound);
            }
            var machineRoute = _planMachineRoute.Get(f => f.route_code == code && f.status != (int)RowState.Invalid && f.projectId == ProjectId);
            
            var url = _planDetailRepository.GetDrawUrl(plan.product_id, ProjectId);
            var res = new RequestMachines()
            {
                id = details.id,
                circulation = details != null ? details.orderNumber : "",
                code = plan.code,
                deliverytime = UnixTimeHelper.ConvertIntDateTime(plan.delivery_time),
                drawnumber = plan.draw_number,
                product_id = plan.product_id,
                route_id = route.id,
                nok_number = 0,
                ok_number =0,
                producename = plan.product_name,
                quantity = plan.quantity,
                route_ordernumber = code,
                route_name = route.name,
                number = machineRoute!=null?machineRoute.ok+machineRoute.nok:0,
                section= machineRoute != null ? machineRoute.sectionid  : 0,
                draw_url = url != null ? url : "",
                state=0,
                status = machineRoute != null ? machineRoute.status : 3
            };
            return new ObjectResult(res);
        }

        /// <summary>
        /// 开始调机
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult WebStartProduct([FromBody] RequestStart request)
        {
            var str = request.route_code.Split('|');
            if (str.Length != 2)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }
            var planDetail = _planDetailRepository.Get(q => q.orderNumber == str[0] && q.status != (int)RowState.Invalid && q.projectId == ProjectId);
            if (planDetail == null)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }
            var plan = _planRepository.Get(q => q.id == planDetail.planId && q.status != (int)RowState.Invalid && q.projectid == ProjectId);
            if (plan == null)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }
            var route = _routeRepository.Get(q => q.id.ToString() == str[1] && q.status == (int)RowState.Valid && q.projectId == ProjectId);
            if (route == null)
            {
                throw new BadRequestException(RequestEnum.RouteNotFound);
            }
            var machineRoute1 = _planMachineRoute.Get(f => f.projectId == ProjectId && f.route_code == request.route_code);
            if (machineRoute1 != null)
            {
                machineRoute1.machineId = request.machineId;
                machineRoute1.sectionid = request.sectionId;
                machineRoute1.status = (int)PlanDispatch.Debugging;
                _planMachineRoute.Update(machineRoute1);
            }
            else
            {
                var machineRoute = new siger_projectId_plan_machine_route()
                {
                    projectId = ProjectId,
                    plandts_id = planDetail.id,
                    routename = route.name,
                    route_code = request.route_code,
                    serialnum = route.serialNumber.ToString(),
                    machineId = request.machineId,
                    startTime = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Now),
                    route_id = route.id,
                    status= (int)PlanDispatch.Debugging,
                    sectionid = request.sectionId
                };
                _planMachineRoute.Insert(machineRoute);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 状态更改
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult WebStart(string route_code, int status)
        {
            var machineRoute1 = _planMachineRoute.Get(f => f.projectId == ProjectId && f.route_code == route_code);
            if (machineRoute1 != null)
            {
                if (status== (int)PlanDispatch.Producing)
                {
                    machineRoute1.debugEndTime = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Now);
                }
                machineRoute1.status = status;
                _planMachineRoute.Update(machineRoute1);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 生产报工 完工、确认接口
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult WebProductReportPreservation([FromBody] RequestReportPreservation request)
        {
            var user = _userRepository.Get(q =>
                q.mid == request.uid && q.projectid == ProjectId && q.status == (int)RowState.Valid);
            if (user == null)
            {
                throw new BadRequestException(RequestEnum.UserNotExists);
            }
            var planDetail = _planDetailRepository.Get(q => q.id == request.id && q.status != (int)RowState.Invalid && q.projectId == ProjectId);
            if (planDetail == null)
            {
                throw new BadRequestException(CncEnum.PlanNotFound);
            }
            var plan = _planRepository.Get(q => q.id == planDetail.planId && q.projectid == ProjectId && q.status != (int)RowState.Invalid);

            if (plan == null)
            {
                throw new BadRequestException(CncEnum.PlanNotFound);
            }
            var machineRoute = _planMachineRoute.Get(q => q.route_code == request.route_ordernumber && q.status != (int)RowState.Invalid && q.projectId == ProjectId);
            if (machineRoute == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var wprkGroup = _workingGroup.Get(f => f.midSplit.Contains(user.mid));
            var _shitid = 0;
            if (wprkGroup != null)
            {
                var dic = _sigerProjectShift.GetCurrentShit(wprkGroup.shiftSplit, user.mid);
                if (dic.Any())
                {
                    _shitid = dic.FirstOrDefault().Key;
                }
            }
            var entity = new siger_project_product_report
            {
                draw_number = plan.draw_number,
                plan_id = plan.id,
                product_name = plan.product_name,
                product_code = plan.product_code,
                code = planDetail.orderNumber,
                actual_output = request.ok_number,
                end_time = request.endTime != "" ? Convert.ToInt32(UnixTimeHelper.ConvertDataTimeLong(request.endTime.ToDateTime())) : 0,
                machineid = request.machineId,
                nok_number = request.nok_number,
                produced_program_number = request.ProgramCode,
                start_time = request.startTime != "" ? Convert.ToInt32(UnixTimeHelper.ConvertDataTimeLong(request.startTime.ToDateTime())) : 0,
                uid = user.mid,
                worker_code = user.work_code,
                worker_name = user.name,
                projectid = ProjectId,
                time = UnixTimeHelper.GetNow(),
                route_name = request.route_ordernumber,
                station = machineRoute.sectionid,
                route_id = machineRoute.route_id,
                shift_id = _shitid,
                output = request.ok_number + request.nok_number,
            };

            _productionReportRepository.InsertProductReportData(entity);

            machineRoute.ok += request.ok_number;
            machineRoute.nok += request.nok_number;
            machineRoute.producted_number = request.product_number;
            if (request.IsComplete == 0)
            {
                machineRoute.status = (int)PlanDispatch.Producing;
                _planMachineRoute.Update(machineRoute);
            }
            else if (request.IsComplete == 1)
            {
                machineRoute.endTime = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Now);
                machineRoute.machineId = 0;
                machineRoute.sectionid = 0;
                machineRoute.status = (int)PlanDispatch.Finished;
                _planMachineRoute.Update(machineRoute);
            }
            else if (request.IsComplete == 2)
            {
                machineRoute.endTime = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Now);
                machineRoute.machineId = 0;
                machineRoute.sectionid = 0;
                machineRoute.status = (int)PlanDispatch.HasPlan;
                _planMachineRoute.Update(machineRoute);
            }
            if (request.IsComplete != 2)
            {
                var lastRoute = _routeRepository.GetList(q => q.productId == plan.product_id && q.status == (int)RowState.Valid && q.projectId == ProjectId).OrderByDescending(q => q.serialNumber);
                if (lastRoute.Any())
                {
                    if (lastRoute.FirstOrDefault().id == machineRoute.route_id)
                    {
                        planDetail.ok_number = machineRoute.ok;
                        planDetail.nok_number = machineRoute.nok;
                        planDetail.producted_number = machineRoute.ok + machineRoute.nok;
                        if (request.IsComplete == 1)
                        {
                            planDetail.status = (int)PlanDispatch.Finished;
                            plan.status = (int)PlanDispatch.Finished;
                        }
                        else if (request.IsComplete == 0)
                        {
                            planDetail.status = (int)PlanDispatch.Producing;
                            plan.status = (int)PlanDispatch.Producing;
                        }
                        _planDetailRepository.Update(planDetail);
                        plan.producted_number = machineRoute.ok + machineRoute.nok;
                        plan.nok_number = machineRoute.nok;

                        _planRepository.Update(plan);
                    }
                    else
                    {
                        plan.status = (int)PlanDispatch.Producing;
                        _planRepository.Update(plan);
                        planDetail.status = (int)PlanDispatch.Producing;
                        _planDetailRepository.Update(planDetail);
                    }
                }

            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 获取程序产量信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetProgram([FromBody] RequestProgram request)
        {
            var entites = _planMachineRoute.Get(q => q.route_id == request.route_id && q.status != (int)RowState.Invalid && q.projectId == ProjectId);
            if (entites == null)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }
            var programList = new List<RequestPrograms>();
            var cncExceptionRepository = new ProductRepository(CompanyId, ProjectId);
            var exceptions = cncExceptionRepository.GetCncProductionTwo(request.machineId, UnixTimeHelper.ConvertIntDateTime(entites.startTime));
            if (exceptions.Any())
            {
                var pro = exceptions.Select(q => q.programCode).Distinct();
                foreach (var item in pro)
                {
                    var list = exceptions.Where(q => q.programCode == item);
                    var program = new RequestPrograms();
                    program.number = list.Sum(q => q.yield);
                    program.startTime = list.Min(q => q.StartTime).ToString();
                    program.endTime = list.Max(q => q.EndTime).ToString();
                    program.ProgramCode = list.FirstOrDefault().programCode;
                    programList.Add(program);
                }
            }
            return new ObjectResult(programList);
        }
    }
}
