using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Request;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;
using Siger.ApiQMS.Utility;
using UploadFileModel = Siger.Middlelayer.QmsRepository.Response.UploadFileModel;
using Siger.Middlelayer.Repository.Entities;

namespace Siger.ApiQMS.Controllers
{
    public class SendTestCollectionController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IInspectStandardRepository _inspectStandard;
        private readonly ISigerProjectProductRepository _productRepository;
        private readonly ISigerProjectLevelSectionRepository _levelSectionRepository;
        private readonly ICheckSnTraceInspectionRepository _traceInspectionRepository;
        private readonly ISigerDict _sigerDict;
        private readonly ICheckSnListRepository _snListRepository;
        private readonly ISigerTrMaterialsRepository _materialsRepository;
        private readonly ISigerProjectLevelRepository _levelRepository;
        private readonly ICheckSnTraceFileRepository _traceFileRepository;
        private readonly ICheckMessageRepository _checkMessageRepository;
        private readonly IWorkingGroupCalendarRepository _calendarRepository;
        private readonly ISigerProjectShiftRepository _projectShiftRepository;
        private readonly ISigerProjectMachineAttributionRepository _machineAttributionRepository;
        private readonly ISendTestParameterRepository _parameterRepository;
        private readonly IQmsCheckParameterRepository _checkParameterRepository;
        private readonly ICheckSnTraceDetailRepository _traceDetailRepository;
        private readonly IQmsTypeCountSettingRepository _typeCountRepository;
        private readonly IAbnormalRuleRepository _abnormalRuleRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly IWorkingRelationMachineRepository _workingRelationMachine;
        private readonly IWorkingRelationUserRepository _workingRelationUser;

        //private readonly IWorkingMachineSetRepository _machineSetRepository;

        public SendTestCollectionController(IUnitOfWork unitOfWork, IInspectStandardRepository inspectStandard, 
            ISigerProjectProductRepository productRepository, ISigerProjectLevelSectionRepository levelSectionRepository,
            ICheckSnTraceInspectionRepository traceInspectionRepository, ISigerDict sigerDict, ICheckSnListRepository snListRepository,
            ISigerTrMaterialsRepository materialsRepository, ISigerProjectLevelRepository levelRepository,
            ICheckSnTraceFileRepository traceFileRepository, ICheckMessageRepository checkMessageRepository,
            IWorkingGroupCalendarRepository workingCalendarRepository, ISigerProjectShiftRepository sigerProjectShiftRepository,
            ISigerProjectMachineAttributionRepository machineAttributionRepository, ISendTestParameterRepository parameterRepository, 
            IQmsCheckParameterRepository checkParameterRepository, ICheckSnTraceDetailRepository traceDetailRepository,
            IQmsTypeCountSettingRepository typeCountRepository, IAbnormalRuleRepository abnormalRuleRepository,
            ISigerProjectUserRepository projectUserRepository, IWorkingRelationMachineRepository workingRelationMachine,IWorkingRelationUserRepository workingRelationUser /*IWorkingMachineSetRepository machineSetRepository*/)
        {
            _unitOfWork = unitOfWork;
            _inspectStandard = inspectStandard;
            _productRepository = productRepository;
            _levelSectionRepository = levelSectionRepository;
            _traceInspectionRepository = traceInspectionRepository;
            _sigerDict = sigerDict;
            _snListRepository = snListRepository;
            _materialsRepository = materialsRepository;
            _levelRepository = levelRepository;
            _traceFileRepository = traceFileRepository;
            _checkMessageRepository = checkMessageRepository;
            _calendarRepository = workingCalendarRepository;
            _projectShiftRepository = sigerProjectShiftRepository;
            _machineAttributionRepository = machineAttributionRepository;
            _parameterRepository = parameterRepository;
            _checkParameterRepository = checkParameterRepository;
            _traceDetailRepository = traceDetailRepository;
            _typeCountRepository = typeCountRepository;
            _abnormalRuleRepository = abnormalRuleRepository;
            _projectUserRepository = projectUserRepository;
            _workingRelationMachine = workingRelationMachine;
            _workingRelationUser = workingRelationUser;
            //_machineSetRepository = machineSetRepository;
        }

        [HttpGet]
        public IActionResult GetPageList(int sectionid, int productid, int routeid, int materialid, int checktype, string testroom, string result,
                int checkstatus, string sn, string starttime, string endtime, int page, int pagesize, string toexcel)
        {
            var sectionIds = new List<int>();
            if (sectionid > 0)
            {
                sectionIds = _levelSectionRepository.GetLevelSectionIds(sectionid, ProjectId).ToList();
            }
            var list = new List<ResponseSendTestCollection>();
            var datas = _traceInspectionRepository.GetPagedList(sectionIds, productid, routeid, materialid, checktype,
                testroom, result, checkstatus, sn, starttime, endtime, ProjectId, page, pagesize, toexcel);
            var levelSections = _levelSectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            var traceIds = datas.Data.Select(t => t.id).ToList();
            var fileList = _traceFileRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                traceIds.Contains(t.trace_id) && t.trace_type == (int)FileTraceType.SendTest).ToList();
            foreach (var data in datas.Data)
            {
                var model = Mapper<ResponseSendTestCollection, ResponseSendTestCollection>.Map(data);
                model.testroom_value = _sigerDict.GetDictValue(ProjectId, AccDictCost.TestRoom, model.testroom);
                model.sectionname = ChannelSectionHelper.GetChannelSection(data.sectionid, levelSections);
                var images = fileList.Where(t => t.file_type == (int)TraceFileType.Image && t.trace_id == data.id).ToList();
                var files = fileList.Where(t => t.file_type == (int)TraceFileType.File && t.trace_id == data.id).ToList();
                foreach (var image in images)
                {
                    model.images.Add(new UploadFileModel
                    {
                        url = image.url,
                        name = image.name,
                        size = image.size
                    });
                }
                foreach (var file in files)
                {
                    model.files.Add(new UploadFileModel
                    {
                        url = file.url,
                        name = file.name,
                        size = file.size
                    });
                }
                list.Add(model);
            }

            if(toexcel.ToInt() == 1)
            {
                return ExportExcel(list);
            }
            return new PagedLongTotalObjectResult(list, datas.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult SendTest([FromBody]RequestSendTest req)
        {
            var maxLevel = _levelRepository.GetList(t => t.status == (int)RowState.Valid && t.projectid == ProjectId).Max(q => q.id);
            var section = _levelSectionRepository.Get(t => t.status == (int)RowState.Valid && t.projectid == ProjectId && t.id == req.sectionid);
            if (section == null || section.levelid != maxLevel)
            {
                throw new ServerException(1052);
            }

            var product = _productRepository.Get(t => t.id == req.productid && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if(product == null)
            {
                throw new BadRequestException(RequestEnum.ProductNotFound);
            }

            var testRoom = _sigerDict.GetDictValue(ProjectId, AccDictCost.TestRoom, req.testroom);
            if(string.IsNullOrEmpty(testRoom))
            {
                throw new BadRequestException(RequestEnum.TestRoomNotFound);
            }

            var entity = new siger_check_sn_trace_inspection
            {
                testroom = req.testroom,
                productid = req.productid,
                materialid = req.materialid.ToInt(),
                sectionid = req.sectionid,
                sn = req.sn ?? "",
                routeid = req.routeid.ToInt(),
                check_type = req.checktype.ToInt(),
                check_status = (int)SendCheckStatus.Testing,
                projectid = ProjectId,
                result = "",
                send_mid = UserId,
                send_time = DateTime.Now,
                inspection_type = (int)InspectionType.SendTest,
                number = req.number.ToInt(),
                reason = req.reason ?? "",
                workorder = "",
            };
            var parameterList = new List<siger_qms_check_paramter>();
            var parameters = _parameterRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                req.parameters.Select(q => q.id).Contains(t.id)).ToList();            
            foreach(var param in req.parameters)
            {
                var parameter = parameters.FirstOrDefault(t => t.id == param.id);
                if(parameter == null)
                {
                    continue;
                }
                if(parameter.is_required == 1 && string.IsNullOrWhiteSpace(param.result))
                {
                    throw new BadRequestException(RequestEnum.ParameterMiss);
                }
                if (string.IsNullOrWhiteSpace(param.result))
                {
                    continue;
                }
                if(parameter.category == 2)
                {
                    var dict = _sigerDict.Get(t => t.projectId == ProjectId && t.status == (int)RowState.Valid &&
                            t.cat == AccDictCost.SendTestParameter && t.dkey == param.result);
                    if(dict == null)
                    {
                        throw new BadRequestException(RequestEnum.ParameterMiss);
                    }
                }
                parameterList.Add(new siger_qms_check_paramter
                {
                    parameterid = param.id,
                    result = param.result,
                    projectid = ProjectId
                });
            }
            _traceInspectionRepository.Insert(entity);

            if (_unitOfWork.Commit() > 0)
            {
                foreach(var parameter in parameterList)
                {
                    parameter.checkid = entity.id;
                    _checkParameterRepository.Insert(parameter);
                }
                _unitOfWork.Commit();
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult Edit([FromBody]RequestUpdateSendTest req)
        {
            var data = _traceInspectionRepository.Get(t => t.id == req.id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (data == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            if (data.check_status == (int)SendCheckStatus.Completed)
            {
                throw new BadRequestException(RequestEnum.HasCompletedDontOperate);
            }

            var maxLevel = _levelRepository.GetList(t => t.status == (int)RowState.Valid && t.projectid == ProjectId).Max(q => q.id);
            var section = _levelSectionRepository.Get(t => t.status == (int)RowState.Valid && t.projectid == ProjectId && t.id == req.sectionid);
            if (section == null || section.levelid != maxLevel)
            {
                throw new ServerException(1052);
            }

            var product = _productRepository.Get(t => t.id == req.productid && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (product == null)
            {
                throw new BadRequestException(RequestEnum.ProductNotFound);
            }

            var testRoom = _sigerDict.GetDictValue(ProjectId, AccDictCost.TestRoom, req.testroom);
            if (string.IsNullOrEmpty(testRoom))
            {
                throw new BadRequestException(RequestEnum.TestRoomNotFound);
            }

            data.testroom = req.testroom;
            data.productid = req.productid;
            data.materialid = req.materialid.ToInt();
            data.sectionid = req.sectionid;
            data.sn = req.sn ?? "";
            data.routeid = req.routeid.ToInt();
            data.check_type = req.checktype.ToInt();
            data.number = req.number.ToInt();
            _traceInspectionRepository.Update(data);

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

        [HttpPost]
        public IActionResult AddTrace([FromBody]RequestAddSendTestDataCollection req)
        {
            var sendTest = _traceInspectionRepository.Get(t => t.id == req.id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (sendTest == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            if (sendTest.check_status != (int)SendCheckStatus.Checking)
            {
                throw new BadRequestException(RequestEnum.NotChecking);
            }

            if (sendTest.check_status == (int)SendCheckStatus.Completed)
            {
                throw new BadRequestException(RequestEnum.HasCompletedDontOperate);
            }

            var testRoom = _sigerDict.GetDictValue(ProjectId, AccDictCost.TestRoom, req.testroom);
            if (string.IsNullOrEmpty(testRoom))
            {
                throw new BadRequestException(RequestEnum.TestRoomNotFound);
            }

            var result = req.result.ToInt();
            if (result <= 0)
            {
                throw new BadRequestException(RequestEnum.SelectCheckResult);
            }

            if (req.result == ((int)SendTestType.DeviationRelease).ToString() && (string.IsNullOrEmpty(req.quantity) || req.quantity.ToInt() < 1))
            {
                throw new BadRequestException(RequestEnum.DeviationReleaseQuantityNotNull);
            }

            var items = _inspectStandard.GetList(t => req.details.Select(q => q.itemid).Contains(t.id)).ToList();
            var indexs = req.details.Select(t => t.index).Distinct().ToList();
            foreach (var index in indexs)
            {
                var traceDetails = req.details.Where(t => t.index == index).OrderBy(t => t.index).ToList();
                if (traceDetails.Any())
                {
                    foreach (var detail in traceDetails)
                    {
                        var item = items.FirstOrDefault(t => t.id == detail.itemid);
                        if (item == null)
                        {
                            throw new BadRequestException(RequestEnum.ParameterMiss);
                        }
                        if (item.value_category == (int)ValueCategory.Maxmin && (detail.lowerlimit.HasValue &&
                                !detail.upperlimit.HasValue || detail.upperlimit.HasValue && !detail.lowerlimit.HasValue ||
                                (detail.upperlimit.HasValue && detail.lowerlimit.HasValue && detail.upperlimit.Value < detail.lowerlimit.Value)))
                        {
                            throw new BadRequestException(RequestEnum.MaxMinError);
                        }
                    }
                }
            }            

            var machine = _inspectStandard.GetMachineBySectionId(sendTest.sectionid, ProjectId);

            var insertDetailList = new List<SnTraceDetailList>();
            foreach (var index in indexs)
            {
                var traceDetails = req.details.Where(t => t.index == index).OrderBy(t => t.index).ToList();
                foreach (var detail in traceDetails)
                {
                    var item = items.FirstOrDefault(t => t.id == detail.itemid);
                    if (item == null)
                    {
                        continue;
                    }
                    if (item.value_type == (int)ValueTypeStatus.O)
                    {
                        if (string.IsNullOrWhiteSpace(detail.result))
                        {
                            continue;
                        }
                        insertDetailList.Add(new SnTraceDetailList
                        {
                            TraceID = "",
                            ItemID = detail.itemid,
                            Result = detail.result,
                            Value = detail.value,
                            ItemName = item.item_en,
                            SN = sendTest.sn ?? "",
                            NumberIndex = detail.index,
                            LowerLimit = detail.lowerlimit,
                            UpperLimit = detail.upperlimit,
                        });
                    }
                    else if (item.value_type == (int)ValueTypeStatus.V)
                    {
                        if (detail.value == null && item.value_category != (int)ValueCategory.Maxmin)
                        {
                            continue;
                        }
                        var detailResult = "";
                        if (item.value_category == (int)ValueCategory.Maxmin && !detail.upperlimit.HasValue && !detail.lowerlimit.HasValue)
                        {
                            continue;
                        }
                        if (item.value_category == (int)ValueCategory.Maxmin)
                        {
                            var range = detail.upperlimit.Value - detail.lowerlimit.Value;
                            detail.value = (detail.upperlimit.Value + detail.lowerlimit.Value) / 2;
                            detailResult = "OK";
                            if (detail.upperlimit.Value > item.max_value || detail.lowerlimit.Value < item.min_value ||
                                range > item.range || detail.value.Value > item.max_value || detail.value.Value < item.min_value ||
                                detail.upperlimit.Value < item.min_value || detail.lowerlimit.Value > item.max_value)
                            {
                                detailResult = "NG";
                            }
                        }
                        else
                        {
                            detailResult = (detail.value.Value <= item.max_value && detail.value.Value >= item.min_value) ? "OK" : "NG";
                        }
                        insertDetailList.Add(new SnTraceDetailList
                        {
                            TraceID = "",
                            ItemID = detail.itemid,
                            Result = detailResult,
                            Value = detail.value,
                            ItemName = item.item_en,
                            SN = sendTest.sn ?? "",
                            NumberIndex = detail.index,
                            LowerLimit = detail.lowerlimit,
                            UpperLimit = detail.upperlimit
                        });
                    }
                }
            }
            var traceId = Guid.NewGuid().ToString();
            var nowTime = DateTime.Now;
            var machineIds = _machineAttributionRepository.GetList(t => t.projectid == ProjectId && t.station == sendTest.sectionid &&
                t.status == (int)RowState.Valid && t.attribution == (int)MachineAttributionEnum.equipment).Select(t => t.machine).ToList();
            var userIds = GetPushUserId(UnixTimeHelper.GetNow(), machineIds);

            sendTest.result = req.result ?? "";
            sendTest.testroom = req.testroom;
            sendTest.trace_id = traceId;
            sendTest.check_mid = UserId;
            sendTest.check_status = (int)SendCheckStatus.Completed;
            sendTest.check_time = nowTime;
            sendTest.number = req.number.ToInt();
            sendTest.quantity = req.quantity.ToInt();
            _traceInspectionRepository.Update(sendTest);
            SaveFiles(req.files, req.images, sendTest.id);
            if(sendTest.send_mid != UserId)
            {
                userIds = userIds.Where(t => t != UserId).ToList();
            }
            else
            {
                userIds.Add(sendTest.send_mid);
            }
            userIds = userIds.Distinct().ToList();
            foreach(var userId in userIds)
            {
                var message = new siger_qms_check_message
                {
                    checkid = sendTest.id,
                    tomid = userId,
                    readstate = 0,
                    creator = UserId,
                    createtime = nowTime,
                    projectid = ProjectId
                };
                _checkMessageRepository.Insert(message);
            }

            foreach(var detail in insertDetailList)
            {
                var model = new siger_check_sn_trace_detail
                {
                    TraceID = traceId,
                    ItemID = detail.ItemID,
                    Result = detail.Result,
                    Value = detail.Value,
                    ItemName = detail.ItemName,
                    SN = sendTest.sn ?? "",
                    NumberIndex = detail.NumberIndex,
                    LowerLimit = detail.LowerLimit,
                    UpperLimit = detail.UpperLimit,
                    projectid = ProjectId,
                    CreateTime = nowTime
                };
                _traceDetailRepository.Insert(model);
            }

            if (_unitOfWork.Commit() > 0)
            {
                try
                {
                    AddSnList(sendTest);

                    var abnormalCheckHelper = new AbnormalCheckHelper(_unitOfWork, _abnormalRuleRepository, _projectUserRepository,
                        _traceDetailRepository, _inspectStandard, _traceInspectionRepository, _sigerDict, CompanyId, ProjectId, UserId);
                    abnormalCheckHelper.AbnomalRuleCheck(sendTest.number, traceId, sendTest.sectionid, machine?.id ?? 0, true, sendTest.check_type);
                }
                catch(Exception ex)
                {
                    Logger.WriteLineError(ex.ToString());
                }

                return new ObjectResult(CommonEnum.Succefull);
            }
            else
            {
                throw new BadRequestException(CommonEnum.Fail);
            }                           
        }

        private List<int> GetPushUserId(int time, List<int> machineids)
        {
            var userIds = new List<int>();
            var date = DateTime.Parse(UnixTimeHelper.ConvertIntDate(time));
            //var userMids = _machineSetRepository.GetList(q => machineids.Contains(q.machine_id) && q.project_id == ProjectId && q.status == (int)RowState.Valid).Select(q => q.user_mid)
            //    .Distinct().ToList();
            var machineRelation = _workingRelationMachine.Get(f => f.projectid == ProjectId && machineids.Contains(f.machine) && f.status == (int)RowState.Valid);
            var userMids = machineRelation != null ? machineRelation.employsSplit : new List<int>();

            var cals = _calendarRepository.GetList(q => userMids.Contains(q.user_mid) && q.status == (int)RowState.Valid
                                                        && q.date == date).ToList();
            if (cals.Any())
            {
                var nowDate = UnixTimeHelper.GetUnixByDate(date.ToShortDateString());
                foreach (var calendar in cals)
                {
                    var shift = _projectShiftRepository.Get(q => q.id == calendar.shift_id && q.status == (int)RowState.Valid);
                    if (shift == null)
                    {
                        continue;
                    }

                    //零点到零点的，全部都算
                    if (shift.start_time == 0 && shift.end_time == 0)
                    {
                        userIds.Add(calendar.user_mid);
                    }
                    //在时间范围内的
                    else if (nowDate + shift.start_time <= time && nowDate + shift.end_time >= time)
                    {
                        userIds.Add(calendar.user_mid);
                    }
                    //结束时间小于开始时间
                    else if (shift.end_time <= shift.start_time)
                    {
                        if (nowDate + shift.start_time <= time && nowDate + 86400 + shift.end_time >= time)
                        {
                            userIds.Add(calendar.user_mid);
                        }
                    }
                }
            }

            return userIds;
        }

        private void SaveFiles(List<InsertFileModel> files, List<InsertFileModel> images, int traceId)
        {
            var fileList = new List<siger_check_sn_trace_file>();
            foreach (var image in images)
            {
                fileList.Add(new siger_check_sn_trace_file
                {
                    trace_id = traceId,
                    url = image.url,
                    name = image.name,
                    size = image.size,
                    projectid = ProjectId,
                    file_type = (int)TraceFileType.Image,
                    trace_type = (int)FileTraceType.SendTest
                });
            }
            foreach (var file in files)
            {
                fileList.Add(new siger_check_sn_trace_file
                {
                    trace_id = traceId,
                    url = file.url,
                    name = file.name,
                    size = file.size,
                    projectid = ProjectId,
                    file_type = (int)TraceFileType.File,
                    trace_type = (int)FileTraceType.SendTest
                });
            }
            _traceFileRepository.Insert(fileList);
        }

        [HttpGet]
        public IActionResult ExportExcel(List<ResponseSendTestCollection> data)
        {
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            
            if (!data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var dataList = new List<SendTestCollectionList>();
            var dataDetailList = new List<SendTestCollectionDetailList>();
            int index = 1;
            var levelSections = _levelSectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            foreach (var item in data)
            {
                dataList.Add(new SendTestCollectionList
                {
                    No = index,
                    ProductCode = item.productcode,
                    ProductName = item.productname,
                    MaterialPn = item.materialpn,
                    MaterialName = item.materialname,
                    MaterialSpec = item.materialspec,
                    Section = ChannelSectionHelper.GetChannelSection(item.sectionid, levelSections),
                    TestRoom = item.testroom_value,
                    SN = item.sn,
                    CheckType = item.checktype,
                    CheckStatus = item.checkstatus,
                    Result = item.result,
                    SendUser = item.send_user,
                    SendTime = item.send_time,
                    CheckUser = item.check_user,
                    CheckTime = item.check_time,
                    Reason = item.reason,
                    Number = item.number.ToString(),
                    Quantity = (item.checkstatus == (int)SendCheckStatus.Completed &&
                        item.result == ((int)SendTestType.DeviationRelease).ToString()) ? item.quantity.ToString() : "",
                    RecieveUser = item.recieve_user,
                    RecieveTime = item.recieve_time,
                    CheckingUser = item.checking_user,
                    CheckingTime = item.checking_time
                });
                if (item.checkstatus == (int)SendCheckStatus.Completed)
                {
                    var dataDetails = _traceDetailRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                        t.TraceID == item.traceid).ToList();
                    var items = _inspectStandard.GetList(t => dataDetails.Select(q => q.ItemID).Contains(t.id)).ToList();
                    if (dataDetails.Any())
                    {
                        var detailIndex = 1;
                        foreach (var detail in dataDetails)
                        {
                            var standardItem = items.FirstOrDefault(t => t.id == detail.ItemID);
                            var minValue = standardItem != null ? (standardItem.value_type == (int)ValueTypeStatus.V ? standardItem.min_value.ToString() ?? "" : "") : "";
                            var maxValue = standardItem != null ? (standardItem.value_type == (int)ValueTypeStatus.V ? standardItem.max_value.ToString() ?? "" : "") : "";
                            if(minValue == QmsLimitValue.MinValue)
                            {
                                minValue = "";
                            }
                            if(maxValue == QmsLimitValue.MaxValue)
                            {
                                maxValue = "";
                            }
                            dataDetailList.Add(new SendTestCollectionDetailList
                            {
                                No = detailIndex,
                                Item = standardItem?.item ?? detail.ItemName,
                                Standard = standardItem?.standard ?? "",
                                MinValue = minValue,
                                MaxValue = maxValue,
                                DetailResult = detail.Result,
                                Value = detail.Value.HasValue ? detail.Value.ToString() : "",
                                Range = standardItem == null ? "" : standardItem.range.ToString(),
                                LowerLimit = detail.LowerLimit.HasValue ? detail.LowerLimit.Value.ToString() : "",
                                UpperLimit = detail.UpperLimit.HasValue ? detail.UpperLimit.Value.ToString() : "",
                                ActualRange = detail.LowerLimit.HasValue && detail.UpperLimit.HasValue ?
                                        Math.Round(detail.UpperLimit.Value - detail.LowerLimit.Value, 4).ToString() : ""
                            });
                            detailIndex++;
                        }
                    }
                }
                index++;
            }
            if (dataList.Any())
            {
                EpPlusExcelHelper<SendTestCollectionList> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<SendTestCollectionList>();
                    var temporaryFileName = $"送检检验数据_SendTestInspectionData_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                    helper.GenerateExcel(dataList, dataDetailList, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch (Exception e)
                {
                    Logger.WriteLineError("Export Send Test Inspection Data failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetTestRoomDict()
        {
            var dicts = _sigerDict.GetList(t => t.projectId == ProjectId && t.status == (int)RowState.Valid && t.cat == AccDictCost.TestRoom)
                .Select(t => new ResponseKeyValue(t.dkey, t.dval)).ToList();
            return new ObjectResult(dicts);
        }

        [HttpGet]
        public IActionResult GetParentSection(int sectionid)
        {
            var sectionIds = new List<int>();
            var ids = GetParentSections(sectionIds, sectionid);
            ids.Reverse();
            return new ObjectResult(ids);
        }

        private List<int> GetParentSections(List<int> sectionids, int parentid)
        {
            var section = _levelSectionRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid && t.id == parentid);
            if(section != null)
            {
                sectionids.Add(section.id);
                parentid = section.parentid;
                return GetParentSections(sectionids, parentid);
            }
            else
            {
                return sectionids;
            }
        }

        [HttpGet]
        public IActionResult GetTestItems(int id)
        {
            var data = _traceInspectionRepository.Get(t => t.id == id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (data == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            if (data.check_status != (int)SendCheckStatus.Checking)
            {
                throw new BadRequestException(RequestEnum.NotChecking);
            }
            if (data.check_status == (int)SendCheckStatus.Completed)
            {
                throw new BadRequestException(RequestEnum.HasCompletedDontOperate);
            }

            var tyepCount = _typeCountRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.type_code == data.check_type);
            var res = new ResponseGetTestItems
            {
                id = id,
                testroom = data.testroom,
                sn = data.sn,
                reason = data.reason ?? "",
                number = tyepCount?.check_count ?? 0
            };
            var typeOne = data.check_type.ToString(); var typeEnd = $",{typeOne}"; var typeStart = $"{typeOne},"; var typeTwo = $",{typeOne},";//精确匹配，避免类似12匹配到1的情况
            var standards = _inspectStandard.GetList(t =>
                    t.productid == data.productid && t.sectionid == data.sectionid && t.projectid == ProjectId
                    && t.status == (int)RowState.Valid && t.standard_type == (int)StandardType.SendTest &&
                    (t.checktype.Contains(",") ? (t.checktype.Contains(typeTwo) || t.checktype.StartsWith(typeStart) || t.checktype.EndsWith(typeEnd)) : (t.checktype == typeOne))).OrderBy(q => q.seq).ToList();
            foreach (var standard in standards)
            {
                var model = new ResponseDataCollectionDetail
                {
                    id = 0,
                    itemid = standard.id,
                    max_value = standard.max_value,
                    min_value = standard.min_value,
                    result = "",
                    value = null,
                    item = standard.item,
                    standard = standard.standard,
                    checktype = standard.value_type,
                    valuecategory = standard.value_category,
                    range = standard.range,                    
                };
                res.details.Add(model);
            }

            var checkParameters = _checkParameterRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.checkid == id).ToList();
            var parameters = _parameterRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                checkParameters.Select(q => q.parameterid).Contains(t.id)).ToList();
            foreach (var param in checkParameters)
            {
                var parameter = parameters.FirstOrDefault(t => t.id == param.parameterid);
                if (parameter == null)
                {
                    continue;
                }
                res.parameters.Add(new SendTestParameterDetails
                {
                    name = parameter.name,
                    result = parameter.category == 2 ?
                        _sigerDict.GetDictValue(ProjectId, AccDictCost.SendTestParameter, param.result) : param.result
                });
            }

            return new ObjectResult(res);
        }

        [HttpGet]
        public IActionResult GetParentSectionByItem(string itemid)
        {
            var item = _inspectStandard.Get(t => t.id == itemid.ToInt());
            if (item != null)
            {
                var sectionIds = new List<int>();
                var ids = GetParentSections(sectionIds, item.sectionid);
                ids.Reverse();
                return new ObjectResult(ids);
            }
            else
            {
                return new ObjectResult(new List<int>());
            }
        }

        [HttpGet]
        public IActionResult Delete(int id)
        {
            var data = _traceInspectionRepository.Get(t => t.id == id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if(data == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var details = _traceDetailRepository.GetList(t =>
                    t.TraceID == data.trace_id && t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();

            var files = _traceFileRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.trace_id == data.id && t.trace_type == (int)FileTraceType.SendTest).ToList();

            data.status = (int)RowState.Invalid;
            _traceInspectionRepository.Update(data);
            foreach (var file in files)
            {
                file.status = (int)RowState.Invalid;
                _traceFileRepository.Update(file);
            }
            foreach (var detail in details)
            {
                detail.status = (int)RowState.Invalid;
                _traceDetailRepository.Update(detail);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            else
            {
                throw new BadRequestException(CommonEnum.Fail);
            }            
        }

        [HttpPost]
        public IActionResult Update([FromBody]RequestAddSendTestDataCollection req)
        {
            var sendTest = _traceInspectionRepository.Get(t => t.id == req.id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (sendTest == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }            

            if (sendTest.check_status != (int)SendCheckStatus.Completed)
            {
                throw new ServerException(1950602);
            }

            var result = req.result.ToInt();
            if (result <= 0)
            {
                throw new BadRequestException(RequestEnum.SelectCheckResult);
            }

            if (req.result == ((int)SendTestType.DeviationRelease).ToString() && (string.IsNullOrEmpty(req.quantity) || req.quantity.ToInt() < 1))
            {
                throw new BadRequestException(RequestEnum.DeviationReleaseQuantityNotNull);
            }

            var items = _inspectStandard.GetList(t => req.details.Select(q => q.itemid).Contains(t.id)).ToList();
            var indexs = req.details.Select(t => t.index).Distinct().ToList();
            foreach (var index in indexs)
            {
                var traceDetails = req.details.Where(t => t.index == index).OrderBy(t => t.index).ToList();
                if (!traceDetails.Any())
                {
                    continue;
                }
                foreach (var detail in traceDetails)
                {
                    var item = items.FirstOrDefault(t => t.id == detail.itemid);
                    if (item == null)
                    {
                        throw new BadRequestException(RequestEnum.ParameterMiss);
                    }
                    if (item.value_category == (int)ValueCategory.Maxmin && (detail.lowerlimit.HasValue &&
                                !detail.upperlimit.HasValue || detail.upperlimit.HasValue && !detail.lowerlimit.HasValue ||
                                detail.upperlimit.HasValue && detail.lowerlimit.HasValue && detail.upperlimit.Value < detail.lowerlimit.Value))
                    {
                        throw new BadRequestException(RequestEnum.MaxMinError);
                    }
                }
            }

            var machine = _inspectStandard.GetMachineBySectionId(sendTest.sectionid, ProjectId);

            var delTraceDetails = _traceDetailRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.TraceID == sendTest.trace_id).ToList();

            var insertDetailList = new List<SnTraceDetailList>();
            foreach (var index in indexs)
            {
                var traceDetails = req.details.Where(t => t.index == index).OrderBy(t => t.index).ToList();
                foreach (var detail in traceDetails)
                {
                    var item = items.FirstOrDefault(t => t.id == detail.itemid);
                    if (item == null)
                    {
                        continue;
                    }
                    if (item.value_type == (int)ValueTypeStatus.O)
                    {
                        if (string.IsNullOrWhiteSpace(detail.result))
                        {
                            continue;
                        }
                        insertDetailList.Add(new SnTraceDetailList
                        {
                            TraceID = "",
                            ItemID = detail.itemid,
                            Result = detail.result,
                            Value = detail.value,
                            ItemName = item.item_en,
                            SN = sendTest.sn ?? "",
                            NumberIndex = detail.index,
                            LowerLimit = detail.lowerlimit,
                            UpperLimit = detail.upperlimit,
                        });
                    }
                    else if (item.value_type == (int)ValueTypeStatus.V)
                    {
                        if (detail.value == null && item.value_category != (int)ValueCategory.Maxmin)
                        {
                            continue;
                        }
                        var detailResult = "";
                        if (item.value_category == (int)ValueCategory.Maxmin && !detail.upperlimit.HasValue && !detail.lowerlimit.HasValue)
                        {
                            continue;
                        }
                        if (item.value_category == (int)ValueCategory.Maxmin)
                        {
                            var range = detail.upperlimit.Value - detail.lowerlimit.Value;
                            detail.value = (detail.upperlimit.Value + detail.lowerlimit.Value) / 2;
                            detailResult = "OK";
                            if (detail.upperlimit.Value > item.max_value || detail.lowerlimit.Value < item.min_value ||
                                range > item.range || detail.value.Value > item.max_value || detail.value.Value < item.min_value ||
                                detail.upperlimit.Value < item.min_value || detail.lowerlimit.Value > item.max_value)
                            {
                                detailResult = "NG";
                            }
                        }
                        else
                        {
                            detailResult = (detail.value.Value <= item.max_value && detail.value.Value >= item.min_value) ? "OK" : "NG";
                        }
                        insertDetailList.Add(new SnTraceDetailList
                        {
                            TraceID = "",
                            ItemID = detail.itemid,
                            Result = detailResult,
                            Value = detail.value,
                            ItemName = item.item_en,
                            SN = sendTest.sn ?? "",
                            NumberIndex = detail.index,
                            LowerLimit = detail.lowerlimit,
                            UpperLimit = detail.upperlimit,
                        });
                    }
                }
            }

            var traceId = Guid.NewGuid().ToString();
            sendTest.result = req.result ?? "";
            sendTest.trace_id = traceId;
            sendTest.number = req.number.ToInt();
            sendTest.quantity = req.quantity.ToInt();
            _traceInspectionRepository.Update(sendTest);

            var files = _traceFileRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.trace_id == sendTest.id && t.trace_type == (int)FileTraceType.SendTest).ToList();

            if (files.Any())
            {
                foreach (var file in files)
                {
                    file.status = (int)RowState.Invalid;
                    _traceFileRepository.Update(file);
                }
            }

            SaveFiles(req.files, req.images, sendTest.id);

            foreach(var delDetail in delTraceDetails)
            {
                delDetail.status = (int)RowState.Invalid;
                _traceDetailRepository.Update(delDetail);
            }

            foreach (var detail in insertDetailList)
            {
                var model = new siger_check_sn_trace_detail
                {
                    TraceID = traceId,
                    ItemID = detail.ItemID,
                    Result = detail.Result,
                    Value = detail.Value,
                    ItemName = detail.ItemName,
                    SN = sendTest.sn ?? "",
                    NumberIndex = detail.NumberIndex,
                    LowerLimit = detail.LowerLimit,
                    UpperLimit = detail.UpperLimit,
                    projectid = ProjectId,
                    CreateTime = sendTest.checking_time.HasValue ? sendTest.checking_time.Value : DateTime.Now
                };
                _traceDetailRepository.Insert(model);
            }

            if (_unitOfWork.Commit() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }

            return new ObjectResult(CommonEnum.Succefull);
        }

        private void AddSnList(siger_check_sn_trace_inspection sendTest)
        {
            var snEntity = _snListRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.SN == sendTest.sn && !string.IsNullOrWhiteSpace(sendTest.sn));
            var stateCode = "000";
            var eventNoObj = _snListRepository.GetEventNoByResult(sendTest.sn, ProjectId);
            if (eventNoObj != null)
            {
                //出站信息获取
                var outObj = _snListRepository.GetOutStationByEventNo(eventNoObj.EventNo, sendTest.sectionid, ProjectId);
                if (outObj != null)
                {
                    stateCode = outObj.ResultStatus;
                }
            }
            var product = _productRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.id == sendTest.productid);
            var material = _materialsRepository.Get(t => t.projectId == ProjectId && t.status == (int)RowState.Valid &&
                t.id == sendTest.materialid);
            var section = _levelSectionRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.id == sendTest.sectionid);
            if (snEntity == null)
            {                
                if (product != null && section != null)
                {
                    var snListObj = new siger_check_sn_list
                    {
                        SN = sendTest.sn ?? "",
                        BatchNumber = "",
                        ProductID = sendTest.productid,
                        ProductCode = product.code,
                        LineID = section.parentid,
                        WorkOrder = sendTest.workorder,
                        MaterialID = material?.id ?? 0,
                        PartNumber = material?.pn ?? "",
                        StateCode = stateCode,
                        CreateTime = DateTime.Now,
                        projectid = ProjectId
                    };
                    _snListRepository.Insert(snListObj);
                    _unitOfWork.Commit();
                }
            }
            else
            {
                snEntity.StateCode = stateCode;
                _snListRepository.Update(snEntity);
                _unitOfWork.Commit();
            }
        }

        /// <summary>
        /// 修改时获取数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetUpdateDetails(int id)
        {
            var data = _traceInspectionRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid && t.id == id
                && t.inspection_type == (int)InspectionType.SendTest);
            if (data == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            if(data.check_status != (int)SendCheckStatus.Completed)
            {
                throw new ServerException(1950602);
            }

            var tyepCount = _typeCountRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.type_code == data.check_type);
            var res = new ResponseGetUpdateSendTestDetails
            {
                result = data.result.ToInt(),
                testroom = data.testroom,
                sn = data.sn,
                number = data.number,
                quantity = tyepCount?.check_count ?? 0
            };

            var fileList = _traceFileRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.trace_type == (int)FileTraceType.SendTest && t.trace_id == data.id).ToList();
            var images = fileList.Where(t => t.file_type == (int)TraceFileType.Image).ToList();
            var files = fileList.Where(t => t.file_type == (int)TraceFileType.File).ToList();
            foreach (var image in images)
            {
                res.images.Add(new UploadFileModel
                {
                    url = image.url,
                    name = image.name,
                    size = image.size,
                });
            }
            foreach (var file in files)
            {
                res.files.Add(new UploadFileModel
                {
                    url = file.url,
                    name = file.name,
                    size = file.size,
                });
            }

            var details = _traceDetailRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.TraceID == data.trace_id).ToList();
            var typeOne = data.check_type.ToString(); var typeEnd = $",{typeOne}"; var typeStart = $"{typeOne},"; var typeTwo = $",{typeOne},";//精确匹配，避免类似12匹配到1的情况
            var items = _inspectStandard.GetList(t => details.Select(q => q.ItemID).Contains(t.id) && t.projectid == ProjectId &&
                t.status == (int)RowState.Valid && t.standard_type == (int)StandardType.SendTest &&
                (t.checktype.Contains(",") ? (t.checktype.Contains(typeTwo) || t.checktype.StartsWith(typeStart) || t.checktype.EndsWith(typeEnd)) : (t.checktype == typeOne))).ToList();
            foreach (var detail in details)
            {
                var item = items.FirstOrDefault(t => t.id == detail.ItemID);
                res.details.Add(new SendTestTraceDetails
                {
                    id = detail.ID,
                    itemid = detail.ItemID,
                    itmename = item?.item ?? detail.ItemName,
                    max_value = item?.max_value ?? 0,
                    min_value = item?.min_value ?? 0,
                    standard = item?.standard ?? "",
                    result = detail.Result,
                    value = detail.Value,
                    checktype = item?.value_type ?? 0,
                    index = detail.NumberIndex,
                    lowerlimit = detail.LowerLimit,
                    upperlimit = detail.UpperLimit,
                    range = (detail.LowerLimit.HasValue && detail.UpperLimit.HasValue) ?
                        (detail.UpperLimit.Value - detail.LowerLimit.Value).ToString() : "",
                    valuecategory = item?.value_category ?? 0,
                });
            }

            var checkParameters = _checkParameterRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.checkid == id).ToList();
            var parameters = _parameterRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                checkParameters.Select(q => q.parameterid).Contains(t.id)).ToList();
            foreach(var param in checkParameters)
            {
                var parameter = parameters.FirstOrDefault(t => t.id == param.parameterid);
                if(parameter == null)
                {
                    continue;
                }
                res.parameters.Add(new SendTestParameterDetails
                {
                    name = parameter.name,
                    result = parameter.category == 2 ?
                        _sigerDict.GetDictValue(ProjectId, AccDictCost.SendTestParameter, param.result) : param.result
                });
            }

            return new ObjectResult(res);
        }

        [HttpGet]
        public IActionResult GetSendTestUpdateItems(int id)
        {
            var data = _traceInspectionRepository.Get(t => t.id == id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (data == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var res = new ResponseGetTestItems();
            var typeOne = data.check_type.ToString(); var typeEnd = $",{typeOne}"; var typeStart = $"{typeOne},"; var typeTwo = $",{typeOne},";//精确匹配，避免类似12匹配到1的情况
            var standards = _inspectStandard.GetList(t =>
                    t.productid == data.productid && t.sectionid == data.sectionid && t.projectid == ProjectId
                    && t.status == (int)RowState.Valid && t.standard_type == (int)StandardType.SendTest &&
                    (t.checktype.Contains(",") ? (t.checktype.Contains(typeTwo) || t.checktype.StartsWith(typeStart) || t.checktype.EndsWith(typeEnd)) : (t.checktype == typeOne))).ToList();
            foreach (var standard in standards)
            {
                var model = new ResponseDataCollectionDetail
                {
                    id = 0,
                    itemid = standard.id,
                    max_value = standard.max_value,
                    min_value = standard.min_value,
                    result = "",
                    value = null,
                    item = standard.item,
                    standard = standard.standard,
                    checktype = standard.value_type,
                    range = standard.range,
                    valuecategory = standard?.value_category ?? 0,
                };
                res.details.Add(model);
            }

            return new ObjectResult(res);
        }

        [HttpGet]
        public IActionResult GetCheckTypeCount(int checktype)
        {
            var typeCount = _typeCountRepository.Get(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                t.type_code == checktype);
            return new ObjectResult(typeCount?.check_count ?? 0);
        }

        [HttpPost]
        public IActionResult Recieve([FromBody]RequestIds req)
        {
            if(req.ids == null || !req.ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }

            var models = _traceInspectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                req.ids.Contains(t.id)).ToList();
            if (!models.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            models = models.Where(t => t.check_status == (int)SendCheckStatus.Testing).ToList();

            if (models.Count != req.ids.Count)
            {
                throw new BadRequestException(RequestEnum.SelectWaitRecieve);
            }

            foreach(var model in models)
            {
                if(model.check_status != (int)SendCheckStatus.Testing)
                {
                    continue;
                }
                model.check_status = (int)SendCheckStatus.Recieved;
                model.recieve_mid = UserId;
                model.recieve_time = DateTime.Now;
                _traceInspectionRepository.Update(model);
            }

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

        [HttpPost]
        public IActionResult StartCheck([FromBody]RequestIds req)
        {
            if (req.ids == null || !req.ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }

            var models = _traceInspectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                req.ids.Contains(t.id)).ToList();
            if (!models.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            models = models.Where(t => t.check_status == (int)SendCheckStatus.Recieved).ToList();

            if (models.Count != req.ids.Count)
            {
                throw new BadRequestException(RequestEnum.SelectWaitCheck);
            }

            foreach (var model in models)
            {
                if (model.check_status != (int)SendCheckStatus.Recieved)
                {
                    continue;
                }
                model.check_status = (int)SendCheckStatus.Checking;
                model.checking_mid = UserId;
                model.checking_time = DateTime.Now;
                _traceInspectionRepository.Update(model);
            }

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


        [HttpGet]
        public IActionResult GetInspectionSectionTree(string inspectiontype, string iscompelete)
        {
            var itemSectionIds = new List<int>();
            var traceData = _traceInspectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (inspectiontype.ToInt() > 0)
            {
                traceData = traceData.Where(t => t.inspection_type == inspectiontype.ToInt());
            }
            if (iscompelete.ToInt() > 0)
            {
                traceData = traceData.Where(t => t.check_status == (int)SendCheckStatus.Completed);
            }
            itemSectionIds = traceData.Select(t => t.sectionid).Distinct().ToList();
            var levels = _levelRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            var maxLevel = levels.Max(q => q.id);
            var sections = _levelSectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid);
            var itemSections = sections.Where(t => itemSectionIds.Contains(t.id) && t.levelid == maxLevel).ToList();
            var inSections = new List<siger_project_level_section>();
            foreach (var section in itemSections)
            {
                var parentSections = new List<siger_project_level_section>();
                int pid = section.parentid;
                foreach (var level in levels)
                {
                    if (level.id == maxLevel)
                    {
                        parentSections.Add(section);
                        pid = section.parentid;
                    }
                    else
                    {
                        var parentSection = sections.FirstOrDefault(t => t.id == pid);
                        if (parentSection != null)
                        {
                            pid = parentSection.parentid;
                            parentSections.Add(parentSection);
                        }
                    }
                }
                inSections.AddRange(parentSections);
            }
            inSections = inSections.GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();

            var resp = ChannelSectionHelper.GetSectionChildren(0, ProjectId, maxLevel, inSections);
            return new ObjectResult(resp);
        }
        [HttpGet]
        public IActionResult GetInspectionProducts(string sectionid, string iscompelete)
        {
            var productIds = new List<int>();
            var sectionIds = new List<int>();
            if (sectionid.ToInt() > 0)
            {
                sectionIds = _levelSectionRepository.GetLevelSectionIds(sectionid.ToInt(), ProjectId).ToList();
            }
            var traceData = _traceInspectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (sectionid.ToInt() > 0)
            {
                traceData = traceData.Where(t => sectionIds.Contains(t.sectionid));
            }
            if (iscompelete.ToInt() > 0)
            {
                traceData = traceData.Where(t => t.check_status == (int)SendCheckStatus.Completed);
            }
            productIds = traceData.Select(t => t.productid).Distinct().ToList();
            var products = _productRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid &&
                productIds.Contains(t.id)).Select(t => new
                {
                    t.id,
                    t.name,
                    t.code
                }).ToList();

            return new ObjectResult(products);
        }
        [HttpGet]
        public IActionResult GetInspectionMaterials(string productid, string iscompelete)
        {
            var materialIds = new List<int>();
            var traceData = _traceInspectionRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (productid.ToInt() > 0)
            {
                traceData = traceData.Where(t => t.productid == productid.ToInt());
            }
            if (iscompelete.ToInt() > 0)
            {
                traceData = traceData.Where(t => t.check_status == (int)SendCheckStatus.Completed);
            }
            materialIds = traceData.Select(t => t.materialid).Distinct().ToList();
            var materials = _materialsRepository.GetList(t => t.projectId == ProjectId && t.status == (int)RowState.Valid &&
                materialIds.Contains(t.id)).Select(t => new
                {
                    t.id,
                    t.name,
                    t.pn,
                    t.spec
                }).ToList();

            return new ObjectResult(materials);
        }
    }
}