using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Repository.Paged;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Linq.Expressions;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Common;

namespace Siger.Middlelayer.QmsRepository.Repositories
{
    internal class QmsReworkDataRepository : QMSRepositoryBase<siger_qms_rework_data>, IQmsReworkDataRepository
    {
        private readonly ApiQmsDbContext _context;
        public QmsReworkDataRepository(ApiQmsDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ResponseRepairData> GetRepairPagedList(List<int> sectionId, int materialId, int productId, int preRoute, int route, int section, string sn, DateTime begin, DateTime end, int reworkType, int projectId, int page, int pagesize)
        {
            Expression<Func<ResponseRepairData, bool>> funpid = f => true;
            Expression<Func<ResponseRepairData, bool>> funmid = f => true;
            Expression<Func<ResponseRepairData, bool>> funpreRoute = f => true;
            Expression<Func<ResponseRepairData, bool>> funroute = f => true;
            Expression<Func<ResponseRepairData, bool>> funpn = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialName = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSpec = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSection = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialDate = f => true;

            if (materialId != 0)
                funmid = f => f.MaterailId == materialId;
            if (productId != 0)
                funpid = f => f.ProductId == productId;
            if (preRoute != 0)
                funpreRoute = f => f.PreRoute == preRoute;
            if (route != 0)
                funroute = f => f.Route == route;
            if (sectionId.Any())
                funmaterialSection = f => sectionId.Contains(f.SectionId);
            if (!string.IsNullOrEmpty(sn))
                funpn = f => f.Sn.Contains(sn);
            if (begin != DateTime.MinValue)
                funmaterialDate = f => f.Datetime >= begin && f.Datetime <= end;

            var predicates = funpid.And(funmid).And(funpreRoute).And(funroute).And(funpn).And(funmaterialName).And(funmaterialSpec).And(funmaterialSection).And(funmaterialDate);

            var query = from rw in _context.siger_qms_rework_data
                        join l in _context.siger_project_level_section on rw.Route_Id equals l.id
                        join u in _context.siger_project_user on rw.User_Id equals u.mid

                        join o in _context.siger_qms_inspection_standard on rw.OQC_Id equals o.id into otemp
                        from oqc in otemp.DefaultIfEmpty()
                        join m in _context.siger_tr_materials on rw.Material_Id equals m.id into tempMater
                        from mt in tempMater.DefaultIfEmpty()
                        join p in _context.siger_project_product on rw.Product_Id equals p.id
                        where rw.projectid == projectId && rw.Type == reworkType
                        select new ResponseRepairData
                        {
                            Id = rw.id,
                            ProductId = rw.Product_Id,
                            ProductCode = p.code,
                            ProductName = p.name,
                            SectionId = rw.Section_Id,
                            SectionParentId = l.parentid,
                            Pn = mt != null ? mt.pn : "",
                            MaterailId = rw.Material_Id,
                            MaterialName = mt != null ? mt.name : "",
                            MaterialSpec = mt != null ? mt.spec : "",
                            Sn = rw.Sn,
                            Type = rw.Type,
                            TypeDesc = rw.SnType == 1 ? "单件" : "整箱",
                            PreRoute = rw.preroute_id,
                            Route = rw.Route_Id,
                            Datetime = rw.DateTime,
                            Remark = rw.Remark,
                            User = u.name,
                            Count = rw.Count,
                            OItemId = oqc != null ? oqc.id : 0,
                            OItem = oqc != null ? oqc.item : ""
                        };
            var total = query.Count(predicates);
            var entities = query.GroupBy(g => g.Id).Select(g => g.FirstOrDefault()).OrderByDescending(d => d.Datetime).Where(predicates).Skip((page - 1) * pagesize).Take(pagesize).ToList();

            return new PagedCollectionResult<ResponseRepairData>(entities, total);
        }


        /// <summary>
        /// 返工到 工艺记录
        /// </summary>
        /// <param name="sn"></param>
        /// <param name="productId"></param>
        /// <param name="projectId"></param>
        /// <returns></returns>
        IEnumerable<ResponseProductRoute> IQmsReworkDataRepository.GetRouteBySn(string sn, int productId, int projectId)
        {
            Expression<Func<ResponseProductRoute, bool>> funsn = f => true;
            Expression<Func<ResponseProductRoute, bool>> funpid = f => true;
            var query = from st in _context.siger_qms_rework_setting
                        join r in _context.siger_project_product_route on st.Preroute_Id equals r.id
                        join s in _context.siger_check_sn_list on r.productId equals s.ProductID into stemp
                        from snt in stemp.DefaultIfEmpty()
                        where st.projectid == projectId
                        select new ResponseProductRoute
                        {
                            Id = r.id,
                            Name = r.name,
                            ProductId = st.Product_Id,
                            Sn = snt != null ? snt.SN : ""
                        };
            if (!string.IsNullOrEmpty(sn))
                funsn = f => f.Sn == sn;
            if (productId != 0)
                funpid = f => f.ProductId == productId;
            var predicates = funsn.And(funpid);
            return query.Where(predicates).GroupBy(g => g.Id).Select(s => s.FirstOrDefault()).ToList();
        }

        /// <summary>
        /// 返工前 工艺记录
        /// </summary>
        /// <param name="sn"></param>
        /// <param name="productId"></param>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public IEnumerable<ResponseProductRoute> GetPreRouteBySn(string sn, int productId, int projectId)
        {
            Expression<Func<ResponseProductRoute, bool>> funsn = f => true;
            Expression<Func<ResponseProductRoute, bool>> funpid = f => true;

            var query = from st in _context.siger_qms_rework_setting
                        join r in _context.siger_project_product_route on st.Preroute_Id equals r.id
                        join s in _context.siger_check_sn_list on r.productId equals s.ProductID into stemp
                        from snt in stemp.DefaultIfEmpty()
                        select new ResponseProductRoute
                        {
                            Id = r.id,
                            Name = r.name,
                            ProductId = st.Product_Id,
                            Sn = snt != null ? snt.SN : ""
                        };
            if (!string.IsNullOrEmpty(sn))
                funsn = f => f.Sn == sn;
            if (productId != 0)
                funpid = f => f.ProductId == productId;
            var predicates = funsn.And(funpid);

            return query.Where(predicates).GroupBy(g => g.Id).Select(s => s.FirstOrDefault()).ToList();
        }

        public ResponseSnMaterial GetSnList(string Sn, int projectId)
        {
            var query = from s in _context.siger_check_sn_list
                        join p in _context.siger_project_product on s.ProductID equals p.id
                        join m in _context.siger_tr_materials on s.MaterialID equals m.id into temp
                        from t in temp.DefaultIfEmpty()
                        where s.projectid == projectId && s.SN == Sn
                        select new ResponseSnMaterial
                        {
                            Sn = s.SN,
                            ProductId = s.ProductID,
                            ProductName = p.name,
                            MaterialId = t != null ? t.id : 0,
                            MaterialName = t != null ? t.name : "",
                            MaterialSpec = t != null ? t.spec : "",
                            Pn = t != null ? t.pn : ""
                        };
            return query.FirstOrDefault();
        }

        public IEnumerable<ResponseRepairData> GetRepairAllData(List<int> sectionId, int materialId, int productId, int preRoute, int route, int section, string sn, DateTime begin, DateTime end, int reworkType, int projectId)
        {
            Expression<Func<ResponseRepairData, bool>> funpid = f => true;
            Expression<Func<ResponseRepairData, bool>> funmid = f => true;
            Expression<Func<ResponseRepairData, bool>> funpreRoute = f => true;
            Expression<Func<ResponseRepairData, bool>> funroute = f => true;
            Expression<Func<ResponseRepairData, bool>> funpn = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialName = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSpec = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSection = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialDate = f => true;

            if (materialId != 0)
                funmid = f => f.MaterailId == materialId;
            if (productId != 0)
                funpid = f => f.ProductId == productId;
            if (preRoute != 0)
                funpreRoute = f => f.PreRoute == preRoute;
            if (route != 0)
                funroute = f => f.Route == route;
            if (sectionId.Any())
                funmaterialSection = f => sectionId.Contains(f.SectionId);
            if (!string.IsNullOrEmpty(sn))
                funpn = f => f.Sn.Contains(sn);
            if (begin != DateTime.MinValue)
                funmaterialDate = f => f.Datetime >= begin && f.Datetime <= end;

            var predicates = funpid.And(funmid).And(funpreRoute).And(funroute).And(funpn).And(funmaterialName).And(funmaterialSpec).And(funmaterialSection).And(funmaterialDate);

            var query = from rw in _context.siger_qms_rework_data
                        join l in _context.siger_project_level_section on rw.Section_Id equals l.id
                        join u in _context.siger_project_user on rw.User_Id equals u.mid
                        join o in _context.siger_qms_inspection_standard on rw.OQC_Id equals o.id into otemp
                        from oqc in otemp.DefaultIfEmpty()
                        join m in _context.siger_tr_materials on rw.Material_Id equals m.id into tempMater
                        from mt in tempMater.DefaultIfEmpty()
                        join p in _context.siger_project_product on rw.Product_Id equals p.id
                        where rw.projectid == projectId && rw.Type == reworkType
                        select new ResponseRepairData
                        {
                            Id = rw.id,
                            ProductId = rw.Product_Id,
                            ProductCode = p.code,
                            ProductName = p.name,
                            SectionId = l.id,
                            Section = l.title,
                            Pn = mt != null ? mt.pn : "",
                            MaterailId = rw.Material_Id,
                            MaterialName = mt != null ? mt.name : "",
                            MaterialSpec = mt != null ? mt.spec : "",
                            Sn = rw.Sn,
                            Type = rw.Type,
                            TypeDesc = rw.SnType == 1 ? "单件" : "整箱",
                            PreRoute = rw.preroute_id,
                            Route = rw.Route_Id,
                            Datetime = rw.DateTime,
                            Remark = rw.Remark,
                            User = u.name,
                            Count = rw.Count,
                            OItem = oqc.item
                        };
            return query.Where(predicates).ToList();
        }

        /// <summary>
        /// 报废分析数据源
        /// </summary>
        /// <param name="materialId"></param>
        /// <param name="productId"></param>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public IEnumerable<ResponseWasteInfo> GetWasteAnalysisData(int materialId, int productId, DateTime begin, DateTime end, int projectId)
        {
            Expression<Func<ResponseWasteInfo, bool>> funmaterial = f => true;
            Expression<Func<ResponseWasteInfo, bool>> funproduct = f => true;
            var query = from r in _context.siger_qms_rework_data
                        join p in _context.siger_project_product on r.Product_Id equals p.id
                        join m in _context.siger_tr_materials on r.Material_Id equals m.id
                        where r.projectid == productId && r.DateTime >= begin && r.DateTime < end &&
                        r.Type == (int)ReworkDataType.Waste
                        select new ResponseWasteInfo
                        {
                            Id = r.id,
                            ProductId = p.id,
                            Material = materialId,
                            SectionId = r.Section_Id,
                            Sn = r.Sn,
                            Amount = m.price,
                            Year = r.DateTime.Year,
                            Month = r.DateTime.Month,

                        };
            if (materialId != 0)
                funmaterial = f => f.Material == materialId;
            if (productId != 0)
                funproduct = f => f.ProductId == productId;
            var predicates = funmaterial.And(funproduct);
            return query;
        }

        public IEnumerable<ResponseProductItem> GetOQCItemBysn(int projectId, string sn)
        {
            var query = from s in _context.siger_check_sn_list
                        join p in _context.siger_project_product on s.ProductID equals p.id
                        where s.projectid == projectId && s.SN == sn && s.status == (int)RowState.Valid
                        select new ResponseProductItem
                        {
                            productId = p.id,
                            productName = p.name
                        };
            return query.ToList();

        }



        public IPagedCollectionResult<ResponseRepairData> GetReworkPagedList(List<int> sectionId, int materialId, int productId, int preRoute, int route, int section, string sn, DateTime begin, DateTime end, int projectId, int page, int pagesize)
        {
            Expression<Func<ResponseRepairData, bool>> funpid = f => true;
            Expression<Func<ResponseRepairData, bool>> funmid = f => true;
            Expression<Func<ResponseRepairData, bool>> funpreRoute = f => true;
            Expression<Func<ResponseRepairData, bool>> funroute = f => true;
            Expression<Func<ResponseRepairData, bool>> funpn = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialName = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSpec = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSection = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialDate = f => true;

            if (materialId != 0)
                funmid = f => f.MaterailId == materialId;
            if (productId != 0)
                funpid = f => f.ProductId == productId;
            if (preRoute != 0)
                funpreRoute = f => f.PreRoute == preRoute;
            if (route != 0)
                funroute = f => f.Route == route;
            if (sectionId.Any())
                funmaterialSection = f => sectionId.Contains(f.SectionId);
            if (!string.IsNullOrEmpty(sn))
                funpn = f => f.Sn.Contains(sn);
            if (begin != DateTime.MinValue)
                funmaterialDate = f => f.Datetime >= begin && f.Datetime <= end;

            var predicates = funpid.And(funmid).And(funpreRoute).And(funroute).And(funpn).And(funmaterialName).And(funmaterialSpec).And(funmaterialSection).And(funmaterialDate);

            var query = from rw in _context.siger_qms_rework_data
                        join s in _context.siger_project_level_section on rw.Section_Id equals s.id
                        join sp in _context.siger_project_level_section on s.parentid equals sp.id
                        join l in _context.siger_project_level_section on rw.Route_Id equals l.id
                        join lp in _context.siger_project_level_section on l.parentid equals lp.id
                        join u in _context.siger_project_user on rw.User_Id equals u.mid
                        join o in _context.siger_qms_inspection_standard on rw.OQC_Id equals o.id into otemp
                        from oqc in otemp.DefaultIfEmpty()
                        join m in _context.siger_tr_materials on rw.Material_Id equals m.id into tempMater
                        from mt in tempMater.DefaultIfEmpty()
                        join p in _context.siger_project_product on rw.Product_Id equals p.id
                   
                        where rw.projectid == projectId && rw.Type == 1
                        select new ResponseRepairData
                        {
                            Id = rw.id,
                            ProductId = rw.Product_Id,
                            ProductCode = p.code,
                            ProductName = p.name,
                            SectionId = rw.Section_Id,
                            SectionParentId = l.parentid,
                            Pn = mt != null ? mt.pn : "",
                            MaterailId = rw.Material_Id,
                            MaterialName = mt != null ? mt.name : "",
                            MaterialSpec = mt != null ? mt.spec : "",
                            Sn = rw.Sn,
                            Type = rw.Type,
                            TypeDesc = rw.SnType == 1 ? "单件" : "整箱",
                            PreRoute = rw.preroute_id,
                            Route = rw.Route_Id,
                            Datetime = rw.DateTime,
                            Remark = rw.Remark,
                            User = u.name,
                            Count = rw.Count,
                            Qty = rw.Count,
                            OItemId = oqc != null ? oqc.id : 0,
                            OItem = oqc != null ? oqc.item : "",
                            Section=$"{sp.title}-{s.title}",
                            RouteDesc=$"{lp.title}-{l.title}"
                        };
            var total = query.Count(predicates);
            var entities = query.GroupBy(g => g.Id).Select(g => g.FirstOrDefault()).OrderByDescending(d => d.Datetime).Where(predicates).Skip((page - 1) * pagesize).Take(pagesize).ToList();
            foreach(var d in entities)
            {
                var st = _context.siger_qms_rework_postion_setting.FirstOrDefault(f => f.projectid == projectId && f.Prestation == d.SectionId && f.Station == d.Route);
                d.SettingId = st != null ? st.id : 0;
            }
            return new PagedCollectionResult<ResponseRepairData>(entities, total);
        }

        public IPagedCollectionResult<ResponseRepairData> GetWastePagedList(List<int> sectionId, int materialId, int productId, int preRoute, int route, int section, string sn, DateTime begin, DateTime end, int projectId, int page, int pagesize)
        {
            Expression<Func<ResponseRepairData, bool>> funpid = f => true;
            Expression<Func<ResponseRepairData, bool>> funmid = f => true;
            Expression<Func<ResponseRepairData, bool>> funpreRoute = f => true;
            Expression<Func<ResponseRepairData, bool>> funroute = f => true;
            Expression<Func<ResponseRepairData, bool>> funpn = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialName = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSpec = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialSection = f => true;
            Expression<Func<ResponseRepairData, bool>> funmaterialDate = f => true;

            if (materialId != 0)
                funmid = f => f.MaterailId == materialId;
            if (productId != 0)
                funpid = f => f.ProductId == productId;
            if (preRoute != 0)
                funpreRoute = f => f.PreRoute == preRoute;
            if (route != 0)
                funroute = f => f.Route == route;
            if (sectionId.Any())
                funmaterialSection = f => sectionId.Contains(f.SectionId);
            if (!string.IsNullOrEmpty(sn))
                funpn = f => f.Sn.Contains(sn);
            if (begin != DateTime.MinValue)
                funmaterialDate = f => f.Datetime >= begin && f.Datetime <= end;

            var predicates = funpid.And(funmid).And(funpreRoute).And(funroute).And(funpn).And(funmaterialName).And(funmaterialSpec).And(funmaterialSection).And(funmaterialDate);

            var query = from rw in _context.siger_qms_rework_data
                        join rwd in _context.siger_qms_rework_data_material on rw.id equals rwd.reworkid
                        join l in _context.siger_project_level_section on rw.Route_Id equals l.id
                        join lp in _context.siger_project_level_section on l.parentid equals lp.id
                        join u in _context.siger_project_user on rw.User_Id equals u.mid
                        join mt in _context.siger_tr_materials on rwd.material_id equals mt.id
                        join p in _context.siger_project_product on rw.Product_Id equals p.id
                        join o in _context.siger_qms_inspection_standard on rw.OQC_Id equals o.id into otemp
                        from oqc in otemp.DefaultIfEmpty()
                        where rw.projectid == projectId && rw.Type == 2
                        select new ResponseRepairData
                        {
                            Id = rw.id,
                            ProductId = rw.Product_Id,
                            ProductCode = p.code,
                            ProductName = p.name,
                            Qty = rw.Count,
                            SectionId = rw.Section_Id,
                            SectionParentId = l.parentid,
                            Pn = mt != null ? mt.pn : "",
                            MaterailId = rwd.material_id,
                            MaterialName = mt.name,
                            MaterialSpec = mt.spec,
                            Sn = rw.Sn,
                            Type = rw.Type,
                            TypeDesc = rw.SnType == 1 ? "单件" : "整箱",
                            PreRoute = rw.preroute_id,
                            Route = rw.Route_Id,
                            RouteDesc=$"{lp.title}-{l.title}",
                            Datetime = rw.DateTime,
                            Remark = rw.Remark,
                            User = u.name,
                            Count = rwd.qty,
                            OItemId = oqc != null ? oqc.id : 0,
                            OItem = oqc != null ? oqc.item : "",
                            DetailsId = rwd.id
                        };
            var total = query.Count(predicates);
            var entities = query.Where(predicates).OrderByDescending(d => d.Datetime).Where(predicates).Skip((page - 1) * pagesize).Take(pagesize).ToList();

            return new PagedCollectionResult<ResponseRepairData>(entities, total);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sections"></param>
        /// <param name="productId"></param>
        /// <param name="projectId"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <returns></returns>
        public IEnumerable<ResponseWasteData> GetResponseWaste(List<int> sections, int productId, int projectId, DateTime starttime, DateTime endtime)
        {
            Expression<Func<ResponseWasteData, bool>> funcProduct = f => true;
            Expression<Func<ResponseWasteData, bool>> funcDate = f => true;
            var query = from r in _context.siger_qms_rework_data
                        join d in _context.siger_qms_rework_data_material on r.id equals d.reworkid
                        join m in _context.siger_tr_materials on d.material_id equals m.id
                        join l in _context.siger_project_level_section on r.Route_Id equals l.id
                        join lp in _context.siger_project_level_section on l.parentid equals lp.id
                        join o in _context.siger_qms_inspection_standard on r.OQC_Id equals o.id into otemp
                        from oqc in otemp.DefaultIfEmpty()
                        join rf in _context.siger_qms_rework_reference on r.Remark equals rf.Remark into rtemp
                        from rf in rtemp.DefaultIfEmpty()
                        join rt in _context.siger_qms_rework_type on rf.ReferType equals rt.type  into ttemp
                        from rt in ttemp.DefaultIfEmpty()
                        where r.projectid == projectId && r.Type == 2 && sections.Contains(r.Route_Id) && r.status == (int)RowState.Valid
                        select new ResponseWasteData
                        {
                            Id = r.id,
                            DtsId = d.id,
                            DateTime = r.DateTime,
                            Section = r.Route_Id,
                            SectionDesc = l.title,
                            SectionParent = l.parentid,
                            SectionParentDesc = lp.title,
                            Year = r.DateTime.Year,
                            Month = $"{r.DateTime.Year}-{r.DateTime.Month}",
                            Date = $"{r.DateTime.Year}-{r.DateTime.Month}-{r.DateTime.Day}",
                            Item = r.OQC_Id,
                            ItemDesc = oqc != null ? oqc.item : "",
                            Cause = r.Remark,
                            ProductId = r.Product_Id,
                            Qty = r.Count,
                            Material = d.material_id,
                            Count = d.qty,
                            Price = m.price,
                            level_sectionid= lp.id,
                            ReferDesc = r.Remark,
                            Refer=rf!=null?rf.id:0,
                            ReferType=rf!=null?rf.ReferType:0,
                            ReferTypeDesc=rt!=null?rt.name:""
                        };

            if (productId != 0)
            {
                funcProduct = f => f.ProductId == productId;
            }

            if (starttime != DateTime.MinValue && endtime != DateTime.MinValue)
            {
                funcDate = f => f.DateTime >= starttime && f.DateTime <= endtime;
            }

            var predicates = funcProduct.And(funcDate);
            var result = query.Where(predicates).GroupBy(g => g.DtsId).Select(s => s.FirstOrDefault()).ToList();
            foreach (var item in result)
            {
                var addition = _context.siger_qms_product_addition.FirstOrDefault(f => f.productid == item.ProductId && f.sectionid == item.level_sectionid);
                item.AddPrice = addition?.addval ?? 0d;
                var warehousing = _context.siger_qms_product_warehousing.Where(f => f.productid == item.ProductId
                                                                                    && f.section == item.level_sectionid
                                                                                    && f.createtime >= starttime
                                                                                    && f.createtime <= endtime
                                                                                    && f.type == 1 && f.createtime.Date == item.DateTime.Date).ToList();
                foreach (var items in warehousing)
                {
                    item.Warehorue += items.qty;
                }
            }
            return result;
        }
        /// <summary>
        /// Dashboard Rework Data
        /// </summary>
        /// <param name="sections"></param>
        /// <param name="projectId"></param>
        /// <param name="starttime"></param>
        /// <param name="endtime"></param>
        /// <returns></returns>
        public List<ResponseReworkData> GetReworkData(List<int> sections, int projectId, DateTime starttime, DateTime endtime)
        {
            var ret = new List<ResponseReworkData>();
            var reworks = _context.siger_qms_rework_data.Where(f => f.projectid == projectId && f.status != 0 && sections.Contains(f.Route_Id) && f.DateTime >= starttime && f.DateTime <= endtime).ToList();
            var levelSections = _context.siger_project_level_section.Where(f => f.projectid == projectId && f.status != 0).ToList();
            foreach (var rework in reworks)
            {
                //var count = _context.siger_qms_rework_data_material.Where(f => f.status != 0 && f.reworkid == rework.id).Sum(s => s.qty);
                var productRouteHour = _context.siger_project_product_route.Where(f => f.productId == rework.Product_Id && f.status != 0 && f.projectId == projectId).OrderByDescending(o => o.serialNumber).FirstOrDefault()?.working_hours ?? 0;
                var product = _context.siger_project_product.FirstOrDefault(f => f.id == rework.Product_Id && f.status != 0 && f.projectid == projectId);
                var section= GetParentSelfLevelSections(rework.Section_Id, projectId, levelSections).OrderBy(o=>o.id);
                var lastsections = section.Reverse().Take(2).Reverse().ToList();
                ret.Add(new ResponseReworkData
                {
                    SectionName = string.Join("-", lastsections.Select(s=>s.title)),
                    Count = rework.Count,
                    Operator = _context.siger_project_user.FirstOrDefault(f => f.projectid == projectId && f.status != 0 && f.mid == rework.User_Id)?.name ?? "",
                    ProductName = product?.name ?? "",
                    ProductCode = product?.code ?? "",
                    Loss = rework.Count * productRouteHour,
                    Reason=rework.Remark,
                    ReworkTime=rework.DateTime,
                });
            }
            return ret;
        }

    }
}
