using DistributionApi.IRepositories;
using MadRunFabric.Common;
using MadRunFabric.Common.Options;
using MadRunFabric.Model;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using DistributionApi.Model.Dto;
using DistributionApi.Model;

namespace DistributionApi.Repositories
{
    public class Distri_WorkorderRepository : BaseRepository<Distri_Workorder, string>, IDistri_WorkorderRepository
    {
        protected readonly ILogger<BaseRepository<Distri_Workorder, string>> _logger;
        protected readonly IMongoCollection<Distri_Workorder_PlanTask> _collection_distri_workorder_planworkorder;
        protected readonly IMongoCollection<Sys_DictionaryValue> _collection_sys_dictionaryvalue;
        protected readonly IMongoCollection<Pro_Project_Info> _collection_pro_project_info;
        protected readonly IMongoCollection<Distri_Workorder_PlanTask> _collection_distri_workorder_plantask;
        protected readonly IMongoCollection<Distri_Workorder_Plan> _collection_distri_workorder_plan;
        protected readonly IMongoCollection<Distri_Workorder_Exception> _collection_distri_workorder_exception;
        protected readonly IMongoCollection<Distri_Workorder_OffenceRecord> _collection_distri_workorder_offencerecord;
        protected readonly IMongoCollection<Distri_Workorder_UpdateRecord> _collection_distri_workorder_updaterecord;
        protected readonly IMongoCollection<Sys_ClassGroup> _collection_sys_classgroup;
        protected readonly IMongoCollection<Sys_ClassGroup_User_Map> _collection_sys_classgroup_user_map;
        protected readonly IMongoCollection<Sys_SystemConfig> _collection_sys_systemconfig;
        public Distri_WorkorderRepository(IOptions<MongodbOptions> settings, ILogger<BaseRepository<Distri_Workorder, string>> logger) : base(settings, logger)
        {
            _collection_distri_workorder_planworkorder = _context.GetCollection<Distri_Workorder_PlanTask>();  //获取集合
            _collection_sys_dictionaryvalue = _context.GetCollection<Sys_DictionaryValue>();  //获取集合
            _collection_pro_project_info = _context.GetCollection<Pro_Project_Info>();  //获取集合
            _collection_distri_workorder_plantask = _context.GetCollection<Distri_Workorder_PlanTask>();  //获取集合
            _collection_distri_workorder_plan = _context.GetCollection<Distri_Workorder_Plan>();  //获取集合
            _collection_distri_workorder_exception = _context.GetCollection<Distri_Workorder_Exception>();  //获取集合
            _collection_distri_workorder_offencerecord = _context.GetCollection<Distri_Workorder_OffenceRecord>();  //获取集合
            _collection_distri_workorder_updaterecord = _context.GetCollection<Distri_Workorder_UpdateRecord>();  //获取集合
            _collection_sys_classgroup = _context.GetCollection<Sys_ClassGroup>();  //获取集合
            _collection_sys_classgroup_user_map = _context.GetCollection<Sys_ClassGroup_User_Map>();  //获取集合
            _collection_sys_systemconfig = _context.GetCollection<Sys_SystemConfig>();
            _logger = logger;
        }

        /// <summary>
        /// 列表 -  Linq 关联查询 分页
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        public IEnumerable<object> GetListsByPage(string keyword, string projectid,int wosorts, int wostate, int wxstate, string stime, string etime,string rolecode,string usercode, UserAccountInfoModel userinfo, int pageIndex, int pageSize, out int recordCount)
        {
            //关联查询
            var query =
                 from goods in _collection.AsQueryable()
                 join proje in _collection_pro_project_info.AsQueryable() on goods.projectid equals proje.id into proje_Defa
                 join exception in _collection_distri_workorder_exception.AsQueryable() on goods.id equals exception.woid into exception_Defa
                 join offencerecord in _collection_distri_workorder_offencerecord.AsQueryable() on goods.id equals offencerecord.woid into offencerecord_Defa
                 join updaterecord in _collection_distri_workorder_updaterecord.AsQueryable() on goods.id equals updaterecord.woid into updaterecord_Defa
                 join plan in _collection_distri_workorder_plan.AsQueryable() on goods.planid equals plan.id into plan_Defa
                 where goods.isdelete == 0
                 orderby goods.createtime descending
                 select new
                 {
                     goods.id,
                     goods.wocode,
                     goods.wosorts,
                     goods.planid,
                     goods.channel,
                     goods.emergencyid,
                     goods.projectid,
                     projectname = proje_Defa != null && proje_Defa.Count() > 0 ? proje_Defa.First().project_name : null,
                     planname = plan_Defa != null && plan_Defa.Count() > 0 ? plan_Defa.First().planname : null,
                     goods.wostate,
                     goods.detail,
                     exceptions = exception_Defa != null && exception_Defa.Count() > 0 ? exception_Defa.First().content : null,
                     sended = exception_Defa != null && exception_Defa.Count() > 0 ? exception_Defa.First().isback_sended : 0,
                     goods.goodslist,
                     goods.receiverlist,
                     goods.deliverylist,
                     goods.deliveryname,
                     goods.deliverytel,
                     goods.assigtime,
                     goods.assigtime_elevator,
                     goods.touser_elevator,
                     goods.touser,
                     goods.dealby,
                     goods.dealtime,
                     goods.islast,
                     goods.isoffence,
                     isaudit_offence = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? offencerecord_Defa.First().isaudit : 0,
                     content_offence = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? offencerecord_Defa.First().content : "",
                     isagree = updaterecord_Defa != null && updaterecord_Defa.Count() > 0 ? updaterecord_Defa.First().isagree : 0,
                     isupdate = updaterecord_Defa != null && updaterecord_Defa.Count() > 0 ? updaterecord_Defa.First().isupdate : 0,
                     isupdatetype = updaterecord_Defa != null && updaterecord_Defa.Count() > 0 ? updaterecord_Defa.First().isupdatetype : 0,
                     goods.isexceptions,
                     goods.signbypic,
                     goods.planwopic,
                     goods.createtby,
                     goods.createname,
                     goods.createtime,
                     goods.isdelete,
                     goods.apptype
                 };
            #region 查询条件
            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(it => it.wocode.Contains(keyword) || it.touser.Contains(keyword));     //工单编号     
            if (!string.IsNullOrEmpty(projectid))
                query = query.Where(it => it.projectid == projectid);
            if (!string.IsNullOrEmpty(stime))
                query = query.Where(it => it.createtime >= Convert.ToDateTime(stime + " 00:00:00"));
            if (!string.IsNullOrEmpty(etime))
                query = query.Where(it => it.createtime <= Convert.ToDateTime(etime + " 23:59:59"));

            //我的工单（已完结/已评价）
            if (wostate >= 0)
            {
                //if (wostate == 44)
                //    query = query.Where(it => it.wostate == 4 || it.wostate == 9);
                //else
                query = query.Where(it => it.wostate == wostate);
            }
            //微信工单状态:1未完成，2待评价，3已评价
            if (wxstate >= 0)
            {                
                switch (wxstate)
                {
                    case 1:
                        query = query.Where(it => it.wostate < (int)EnumDistributionState.finish || it.wostate == (int)EnumDistributionState.backed);
                        break;
                    case 2:
                        query = query.Where(it => it.wostate == (int)EnumDistributionState.finish);
                        break;
                    case 3:
                        query = query.Where(it => it.wostate == (int)EnumDistributionState.evaluated);
                        break;
                }
                //只有微信看自己的
                if (userinfo.isallproject == 1)
                {
                    query = query.Where(it => (it.createtby.Contains(usercode)));
                }
            }
            if (wosorts >= 0)
                query = query.Where(it => it.wosorts == wosorts);            
            if (userinfo.isallproject == 0) {
                query = query.Where(it => userinfo.projectlist.Contains(it.projectid));
                //运维员工只能看到自己的工单
                if (string.IsNullOrWhiteSpace(rolecode))
                {
                    if (rolecode.Equals("SSY_PSG") || rolecode.Equals("SSY_DTG"))
                    {
                        //配送岗 和 电梯岗
                        query = query.Where(it => it.touser.Contains(usercode) || it.touser_elevator == usercode);
                    }
                }
            }

            #endregion
            //var lists = query.ToList();
            recordCount = query.Count();
            var list = query.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return list;
        }

        /// <summary>
        /// Linq 关联查询详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public object GetDetails(string id)
        {
            //关联查询
            var query =
                 from goods in _collection.AsQueryable()
                 join proje in _collection_pro_project_info.AsQueryable() on goods.projectid equals proje.id into proje_Defa
                 join exception in _collection_distri_workorder_exception.AsQueryable() on goods.id equals exception.woid into exception_Defa
                 join offencerecord in _collection_distri_workorder_offencerecord.AsQueryable() on goods.id equals offencerecord.woid into offencerecord_Defa
                 join updaterecord in _collection_distri_workorder_updaterecord.AsQueryable() on goods.id equals updaterecord.woid into updaterecord_Defa
                 join plan in _collection_distri_workorder_plan.AsQueryable() on goods.planid equals plan.id into plan_Defa
                 where goods.isdelete == 0 && goods.id == id
                 orderby goods.createtime descending
                 select new
                 {
                     goods.id,
                     goods.wocode,
                     goods.wosorts,
                     goods.planid,
                     goods.channel,
                     goods.emergencyid,
                     goods.projectid,
                     projectname = proje_Defa != null && proje_Defa.Count() > 0 ? proje_Defa.First().project_name : null,
                     planname = plan_Defa != null && plan_Defa.Count() > 0 ? plan_Defa.First().planname : null,
                     goods.wostate,
                     goods.detail,
                     //exceptions = exception_Defa != null && exception_Defa.Count() > 0 ? exception_Defa.First(x => x.type == 1).content : null,
                     //sended = exception_Defa != null && exception_Defa.Count() > 0 ? exception_Defa.First().isback_sended : 0,
                     goods.goodslist,
                     goods.receiverlist,
                     goods.deliverylist,
                     goods.deliveryname,
                     goods.deliverytel,
                     goods.assigtime,
                     goods.assigtime_elevator,
                     goods.touser,
                     goods.dealby,
                     goods.dealtime,
                     goods.islast,
                     goods.isoffence,
                     isaudit_offence = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? offencerecord_Defa.First().isaudit : 0,
                     content_offence = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? offencerecord_Defa.First().content : "",
                     isagree = updaterecord_Defa != null && updaterecord_Defa.Count() > 0 ? updaterecord_Defa.First().isagree : 0,
                     isupdate = updaterecord_Defa != null && updaterecord_Defa.Count() > 0 ? updaterecord_Defa.First().isupdate : 0,
                     isupdatetype = updaterecord_Defa != null && updaterecord_Defa.Count() > 0 ? updaterecord_Defa.First().isupdatetype : 0,
                     goods.isexceptions,
                     goods.signbypic,
                     goods.planwopic,
                     goods.createtby,
                     goods.createname,
                     goods.createtime,
                     goods.isdelete,
                     goods.apptype
                 };
            var model = query.FirstOrDefault();
            if (model != null)
            {
                return model;
            }
            return null;
        }

        /// <summary>
        /// 获取累积待配送量最大值
        /// </summary>
        /// <param name="usercode"></param>
        /// <returns></returns>
        public int GetLimitMaxCount(string usercode)
        {
            int n = 0;
            //	配送岗 累积待配送量最大值 5个（超过这个数值不能进行抢单）
            var model = _collection_sys_systemconfig.Find(p => p.paramcode == "Distribution_MaxNum").FirstOrDefault();
            if (model != null)
            {
                int m = Int32.Parse(model.paramvalue);
                if (m != 0)
                {
                    long num = _collection.Count(p => p.touser.Contains(usercode) && p.wosorts == (int)EnumDistributionWoSorts.random && p.wostate == (int)EnumDistributionState.assign && p.isdelete == 0);
                    if (num >= m) n = Int32.Parse(num.ToString());
                }
            }
            return n;
        }

        /// <summary>
        /// 获取评价规定时间间隔
        /// </summary>
        /// <returns></returns>
        public int GetEvaluateHour()
        {
            int n = 0;
            var model = _collection_sys_systemconfig.Find(p => p.paramcode == "Evaluate_TimeoutNum").FirstOrDefault();
            if (model != null)
            {
                int m = Int32.Parse(model.paramvalue);
                if (m > 0)
                {
                    n = m;
                }
            }
            return n;
        }

        /// <summary>
        /// 获取用户当前角色 - 根据排班
        /// </summary>
        /// <returns></returns>
        public string GetUserCodeByClassMap(string usercode)
        {
            #region 获取用户符合条件的用户
            DateTime dtnow = DateTime.Now;
            string nowDay = dtnow.ToString("yyyy-MM-dd");

            //关联查询
            var query =
                 from user_map in _collection_sys_classgroup_user_map.AsQueryable()
                 where user_map.isdelete == 0 && user_map.isstatus == 1 && user_map.date == nowDay
                 orderby user_map.createtime descending
                 select user_map;


            //班别列表
            var query_Class = from classgroup in _collection_sys_classgroup.AsQueryable()
                              where classgroup.isdelete == 0
                              orderby classgroup.createtime descending
                              select classgroup;

            //获取当天排班列表
            var rolecode_ByUserMap = string.Empty;    //排班后 角色
            var listClassUser = query.ToList();
            var listClass = query_Class.ToList();

            //var listUser = (await _sys_user_accountrepository.Get(x => x.delete_flag == false && x.lock_flag == false)).ToList();
            List<string> listUserCode_ByPlan = new List<string>();
            List<string> listUserCode = new List<string>();
            foreach (var item in listClassUser)
            {
                //获取条件 - 日期和班别code                           
                var list_code = new List<string> { };   //班别code
                var dayone = item.date;
                var list_r = item.classgroupList.ToList();
                foreach (var item_r in list_r)
                {
                    if (item_r.roleList != null && item_r.roleList.Count > 0)
                    {
                        //角色 - 班别
                        var mode_r = item_r.roleList.FirstOrDefault(x => x.ischeck == true);    // && x.rolecode == rolecode  // && x.rolecode == "SSY_PSG"
                        if (mode_r != null)
                        {
                            list_code.Add(item_r.code);     //班次list
                            rolecode_ByUserMap = mode_r.rolecode;     //当前角色code
                        }
                    }
                }
            }
            #endregion
            return rolecode_ByUserMap;
        }

        #region 所有我的任务工单 - 随机工单 和 计划分送工单 - App

        /// <summary>
        /// 抢单时效 / 待配送工单滞留时效 
        /// </summary>
        /// <param name="code">编号</param>
        /// <returns></returns>
        public int GetLimitCount(string code)
        {
            int m = 0;
            //1、配送岗 抢单时效  3分钟（某单子此时间内没人抢，系统强制分配）
            var model = _collection_sys_systemconfig.Find(p => p.paramcode == code).FirstOrDefault();
            if (model != null)
            {
                m = Int32.Parse(model.paramvalue);
            }
            return m;
        }

        /// <summary>
        /// 列表 -  Linq 关联查询 分页
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        public IEnumerable<Distri_PlanAndOrderDto> GetPlanAndTaskListByPage(string keyword, string projectid, int isfinish,int wosorts, int wostate, string stime, string etime, string rolecode,string usercode, UserAccountInfoModel userinfo, int pageIndex, int pageSize, out int recordCount)
        {           
            //关联查询 - 随机工单和分送工单
            var query =
                 from woder in _collection.AsQueryable()
                 join proje in _collection_pro_project_info.AsQueryable() on woder.projectid equals proje.id into proje_Defa
                 join exception in _collection_distri_workorder_exception.AsQueryable() on woder.id equals exception.woid into exception_Defa
                 where woder.isdelete == 0 //&& woder.wostate <= 2
                 orderby woder.createtime descending
                 select new Distri_WorkorderDto
                 {
                     id = woder.id,
                     wocode=woder.wocode,
                     wosorts = woder.wosorts,
                     planid=woder.planid,
                     plantaskid=woder.plantaskid,
                     emergencyid=woder.emergencyid,
                     projectid=woder.projectid,
                     projectname = proje_Defa != null && proje_Defa.Count() > 0 ? proje_Defa.First().project_name : null,
                     wostate=woder.wostate,
                     touser=woder.touser,
                     touser_elevator=woder.touser_elevator,
                     wostate_elevator=woder.wostate_elevator,
                     assigtime= woder.assigtime,
                     assigtime_elevator=woder.assigtime_elevator,
                     dealtime=woder.dealtime,
                     goodslist=woder.goodslist,
                     receiverlist=woder.receiverlist,
                     deliverylist=woder.deliverylist,
                     exceptions = exception_Defa != null && exception_Defa.Count() > 0 ? exception_Defa.First().content : null,
                     sended = exception_Defa != null && exception_Defa.Count() > 0 ? exception_Defa.First().isback_sended : 0,
                     isoffence=woder.isoffence,
                     isexceptions=woder.isexceptions,
                     createtby=woder.createtby,
                     createtime= woder.createtime,
                     isdelete= woder.isdelete
                     //woder.apptype
                 };
            
            //关联查询 - 计划工单
            var query_planorder =
                 from plan_woder in _collection_distri_workorder_planworkorder.AsQueryable()
                 join proje in _collection_pro_project_info.AsQueryable() on plan_woder.projectid equals proje.id into proje_Defa
                 where plan_woder.isdelete == 0     //&& plan_woder.planwostate <= 1
                 orderby plan_woder.createtime descending
                 select new Distri_Workorder_TaskDto
                 {
                     id=plan_woder.id,
                     wocode=plan_woder.wocode,
                     name=plan_woder.name,
                     planid=plan_woder.planid,
                     projectid=plan_woder.projectid,
                     projectname = proje_Defa != null && proje_Defa.Count() > 0 ? proje_Defa.First().project_name : null,
                     planwostate=plan_woder.planwostate,
                     statetime=plan_woder.statetime,
                     dealtime=plan_woder.dealtime,
                     joinuserlist=plan_woder.joinuserlist,
                     goodslist=plan_woder.goodslist,
                     receiverlist=plan_woder.receiverlist,
                     deliverylist= plan_woder.deliverylist,
                     createtby=plan_woder.createtby,
                     createtime=plan_woder.createtime,
                     isdelete=plan_woder.isdelete
                     //plan_woder.apptype
                 };
            //班次
            var query_classgroup = from classgroup in _collection_sys_classgroup.AsQueryable()
                           where classgroup.isdelete == 0
                           select classgroup;
            //排班
            var query_usermap = from usermap in _collection_sys_classgroup_user_map.AsQueryable()
                                where usermap.isdelete == 0 && usermap.isstatus == 1
                                select usermap;

            //1、配送岗 抢单时效  3分钟（某单子此时间内没人抢，系统强制分配）
            //抢单时效 - 分钟数
            int receive_Time = GetLimitCount("ReceiveOrder_Time");
            ////累积待配送量最大值
            //int limit_Max = GetLimitCount("Distribution_MaxNum");
            //待配送工单滞留时效 - 分钟数
            int stuck_Time = GetLimitCount("StuckOrder_Time");

            List<Distri_PlanAndOrderDto> list = new List<Distri_PlanAndOrderDto>();


            #region 查询条件
            // 随机工单 / 计划工单
            if (!string.IsNullOrEmpty(keyword))
            {
                query = query.Where(it => it.wocode.Contains(keyword));                         //工单       
                query_planorder = query_planorder.Where(it => it.wocode.Contains(keyword));     //工单       
            }
            if (!string.IsNullOrEmpty(projectid))
            {
                query = query.Where(it => it.projectid == projectid);
                query_planorder = query_planorder.Where(it => it.projectid == projectid);
            }
            if (userinfo.isallproject == 0)
            {
                query = query.Where(it => userinfo.projectlist.Contains(it.projectid));
                query_planorder = query_planorder.Where(it => userinfo.projectlist.Contains(it.projectid));
            }


            #region 排班条件
            var rolecode_ByUserMap = string.Empty;    //排班后 角色
            //随机工单
            DateTime dtnow = DateTime.Now;
            string nowDay = dtnow.ToString("yyyy-MM-dd");
            var listClassUser = query_usermap.Where(x => x.date == nowDay).ToList();     //.Where(x=>x.date == nowDay)
            var query_result = new List<Distri_WorkorderDto>();
            var query_planorder_result = new List<Distri_Workorder_TaskDto>();

            //此法写的原因是要查询对应时间段的工单，需要或||拼接 ----------------------------------------------
            var query1 = new List<Distri_WorkorderDto>();
            var query_planorder1 = new List<Distri_Workorder_TaskDto>();
            ////条件拼接（时间段查询） -----------------
            var listClass = query_classgroup.ToList();
            if (rolecode.Equals("SSY_DTG"))
                listClass = query_classgroup.ToList().Where(x => x.iswork == false).ToList();

            if (listClass != null && listClass.Count > 0)
            {
                #region 获取新工单 by 排班/班次  - 电梯岗 -----------------------------------------
                //获取新工单
                var query_zero = query.Where(x => x.wostate == (int)EnumDistributionState.create).ToList();
                var ddd = query_planorder.ToList();
                var query_planorder_zero = query_planorder.Where(x => x.planwostate == (int)EnumDistriWorkOrderPlanWOstate.create && x.joinuserlist.Count <= 0).ToList();
                var model_ClassUser = listClassUser.FirstOrDefault(x => x.usercode == usercode);
                if (model_ClassUser != null)
                {
                    #region 调用条件 - 日期和班别code
                    //获取条件 - 日期和班别code                           
                    var list_code = new List<string> { };   //班别code
                    var dayone = model_ClassUser.date;
                    var list_r = model_ClassUser.classgroupList.ToList();
                    foreach (var item_r in list_r)
                    {
                        if (item_r.roleList != null && item_r.roleList.Count > 0)
                        {
                            //角色 - 班别
                            var mode_r = item_r.roleList.FirstOrDefault(x => x.ischeck == true);  //rolecode SSY_DTG    // && x.rolecode == rolecode
                            if (mode_r != null)
                            {
                                list_code.Add(item_r.code);     //班次list
                                rolecode_ByUserMap = mode_r.rolecode;     //当前角色code
                            }
                        }
                    }

                    if (list_code != null && list_code.Count > 0)
                    {
                        listClass = listClass.Where(x => list_code.Contains(x.code)).ToList();
                        var model_Class = listClass.FirstOrDefault(x => dtnow >= DateTime.Parse(dayone + " " + x.starttime) && dtnow <= DateTime.Parse(dayone + " " + x.endtime));
                        if (model_Class != null)
                        {
                            query1 = query1.Union(query_zero.Where(x => x.createtime >= DateTime.Parse(dayone + " " + model_Class.starttime) && x.createtime <= DateTime.Parse(dayone + " " + model_Class.endtime))).ToList();
                            query_planorder1 = query_planorder1.Union(query_planorder_zero.Where(x => x.createtime >= DateTime.Parse(dayone + " " + model_Class.starttime) && x.createtime <= DateTime.Parse(dayone + " " + model_Class.endtime))).ToList();
                        }
                        //foreach (var item_Class in listClass)
                        //{
                        //    query1 = query1.Union(query_zero.Where(x => x.createtime >= DateTime.Parse(dayone + " " + item_Class.starttime) && x.createtime <= DateTime.Parse(dayone + " " + item_Class.endtime))).ToList();
                        //    query_planorder1 = query_planorder1.Union(query_planorder_zero.Where(x => x.createtime >= DateTime.Parse(dayone + " " + item_Class.starttime) && x.createtime <= DateTime.Parse(dayone + " " + item_Class.endtime))).ToList();
                        //}
                    }
                    #endregion
                }
                else
                {
                    //没有打卡或者排班，不让看到新建的随机工单和计划工单
                    query = query.Where(it => it.touser.Contains(usercode) || it.touser_elevator == usercode);      //配送岗 和 电梯岗 修改-------------------     
                    query_planorder = query_planorder.Where(it => it.joinuserlist.Contains(usercode));
                }
                #endregion
            }
            #endregion

            if (isfinish >= -1)
            {
                //isfinish 1未完成（任务中心），2已完成(我的工单)
                if (isfinish == 1)
                {
                    if (rolecode_ByUserMap.Equals("SSY_DTG"))
                    {
                        //我的未完成工单 - App任务中心
                        query = query.Where(it => it.wostate <= 2 && it.wostate_elevator <= 1);  //修改--------------------- 配送状态必须为未完成 it.wostate <= 2 || 
                    }
                    else
                    {
                        //我的未完成工单 - App任务中心
                        query = query.Where(it => it.wostate <= 2);
                    }
                    query_planorder = query_planorder.Where(it => it.planwostate <= 1);
                }
                else {
                    if (rolecode_ByUserMap.Equals("SSY_DTG"))
                    {
                        //我的已完成工单 - App工单管理
                        query = query.Where(it => it.wostate == 3 ||  it.wostate == 4 || it.wostate == 9 || it.wostate_elevator == 2);  //修改---------------------
                    }
                    else
                    {
                        //我的已完成工单 - App工单管理
                        query = query.Where(it => it.wostate == 4 || it.wostate == 9);
                    }
                    query_planorder = query_planorder.Where(it => it.planwostate == 2);
                }
            }
            
            if (wostate >= 0)
            {
                if (rolecode_ByUserMap.Equals("SSY_PSG"))
                {
                    if (wostate == 0)
                    {
                        query1 = query1.Where(x => x.wostate == 0).ToList();
                        query = query.Where(it => it.wostate == wostate);
                    }
                    else
                    {
                        query1 = query1.Where(x => x.wostate == wostate).ToList();
                        query = query.Where(it => it.wostate == wostate);
                    }
                }
                else if (rolecode_ByUserMap.Equals("SSY_DTG"))
                {
                    //配送接单人为此用户时，视为配送任务-------------
                    //电梯接单人为此用户时，视为电梯任务-------------
                    //query = query.Where(it => ((it.touser.Contains(usercode) && it.wostate == wostate) || (it.touser_elevator == usercode && it.wostate_elevator == wostate)));
                    //query = query.Where(it => (it.wostate == wostate || it.wostate_elevator == wostate));
                    if (wostate == 0)
                        query1 = query1.Where(x => x.wostate == 0).ToList();
                    else
                        query = query.Where(it => ((it.wostate_elevator == (int)EnumDistributionState_elevator.delivery) && it.wostate == wostate) || (it.wostate_elevator <= (int)EnumDistributionState_elevator.accept && it.wostate_elevator == wostate));
                }
                else
                    query = query.Where(it => it.wostate == wostate);
                //新创建和开始的计划工单，都要展示再 0新任务 中
                if (wostate == 0)
                {
                    query_planorder1 = query_planorder1.Where(x => x.planwostate == (int)EnumDistriWorkOrderPlanWOstate.create || x.planwostate == (int)EnumDistriWorkOrderPlanWOstate.start).ToList();
                    query_planorder = query_planorder.Where(it => it.planwostate == (int)EnumDistriWorkOrderPlanWOstate.create || it.planwostate == (int)EnumDistriWorkOrderPlanWOstate.start);
                }
                else
                {
                    query_planorder1 = query_planorder1.Where(x => x.planwostate == (int)EnumDistriWorkOrderPlanWOstate.finish).ToList();
                    query_planorder = query_planorder.Where(it => it.planwostate == (int)EnumDistriWorkOrderPlanWOstate.finish);
                }
            }
            if (!string.IsNullOrEmpty(stime))
            {
                query = query.Where(it => it.createtime >= Convert.ToDateTime(stime + " 00:00:00"));
                query_planorder = query_planorder.Where(it => it.createtime >= Convert.ToDateTime(stime + " 00:00:00"));
            }
            if (!string.IsNullOrEmpty(etime))
            {
                query = query.Where(it => it.createtime <= Convert.ToDateTime(etime + " 23:59:59"));
                query_planorder = query_planorder.Where(it => it.createtime <= Convert.ToDateTime(etime + " 23:59:59"));
            }

            bool isUnion = true;
            //query = query.Where(x => x.wostate > (int)EnumDistributionState.create);
            //电梯岗，配送岗看到自己的工单
            if (rolecode_ByUserMap.Equals("SSY_PSG"))
            {
                query = query.Where(it => (it.touser.Contains(usercode)));      //配送岗 和 电梯岗 ,新创建工单  || it.wostate == (int)EnumDistributionState.create
                query_planorder = query_planorder.Where(it => it.joinuserlist.Contains(usercode));
            }
            else if (rolecode_ByUserMap.Equals("SSY_DTG"))
            {
                query = query.Where(it => it.touser.Contains(usercode) || it.touser_elevator == usercode);      //配送岗 和 电梯岗 修改-------------------     
                query_planorder = query_planorder.Where(it => it.joinuserlist.Contains(usercode));
            }
            else
            {
                //未完成，主管等其他用户不让看（看自己的一般没有信息）
                if (isfinish == 1)
                {
                    isUnion = false;
                    query = query.Where(it => it.wosorts == (int)EnumDistributionWoSorts.random && it.wostate == (int)EnumDistributionState.create);    //主管和其他高级角色 看到随机，新建工单  - 转派
                    query_planorder = query_planorder.Where(it => it.joinuserlist.Contains(usercode));  //加条件就是不让其他角色看到
                }
            }
            if (isUnion)
            {
                query_result = (query.Where(x => x.wostate > (int)EnumDistributionState.create).ToList()
                    .Union(query1)).ToList();    //配送岗 和 电梯岗 ,新创建工单
                query_planorder_result = (query_planorder.Where(x => (x.planwostate > (int)EnumDistributionState.create) || (x.planwostate == (int)EnumDistributionState.create && x.joinuserlist != null && x.joinuserlist.Count > 0)).ToList()
                    .Union(query_planorder1)).ToList();    //新计划工单 和 已接单和已开始
                                                           //query_planorder_result = (query_planorder.Where(x => x.planwostate > (int)EnumDistributionState.create).ToList()
                                                           //    .Union(query_planorder1)).ToList();    //配送岗 和 电梯岗 ,新创建工单
            }
            else
            {
                query_result = query.ToList();
                query_planorder_result = query_planorder.ToList();
            }
            #endregion
            foreach (var item in query_result)
            {
                //剩余时间
                double timeout_receive_Seconds = 0;
                double timeout_Seconds = 0;
                //抢单倒计时剩余时间（秒）
                if (item.wostate == (int)EnumDistributionState.create)
                {
                    //抢单
                    var receivetime = item.createtime.AddMinutes(receive_Time);
                    TimeSpan ts_re = receivetime.Subtract(dtnow);
                    timeout_receive_Seconds = ts_re.TotalSeconds > 0 ? ts_re.TotalSeconds : 0;
                }
                //违规倒计时剩余时间（分钟）
                if (item.wostate > (int)EnumDistributionState.create && item.wostate < (int)EnumDistributionState.finish)
                {
                    //配送
                    var stucktime = item.assigtime.AddMinutes(stuck_Time);
                    TimeSpan ts = stucktime.Subtract(dtnow);
                    timeout_Seconds = ts.TotalSeconds > 0 ? ts.TotalSeconds : 0;
                }

                var model = new Distri_PlanAndOrderDto();
                model.id = item.id;
                model.planid = item.planid;
                model.plantaskid = item.plantaskid;
                model.wocode = item.wocode;
                model.emergencyid = item.emergencyid;
                model.projectid = item.projectid;
                model.planname = "";
                model.planandorder_state = item.wostate;
                model.wostate_elevator = item.wostate_elevator;
                model.wosorts = item.wosorts;   //(int)EnumDistributionWoSorts.random; 包含随机工单，分送工单
                model.touser = item.touser;
                model.assigtime = item.assigtime;
                model.dealtime = item.dealtime;
                model.receiverlist = item.receiverlist;
                model.deliverylist = item.deliverylist;

                #region 生成物品信息 - 主要是设置剩余数值
                List<DistributionGoodsListByTask> list_task = new List<DistributionGoodsListByTask>();
                foreach (var item_wo in item.goodslist)
                {
                    var model_task = new DistributionGoodsListByTask();
                    model_task.goodsid = item_wo.goodsid;
                    model_task.goodsname = item_wo.goodsname;
                    model_task.typeid = item_wo.typeid;
                    model_task.isremind = item_wo.isremind;
                    model_task.remark = item_wo.remark;
                    model_task.num = item_wo.num;
                    model_task.usednum = 0;     //使用数量 - 主要是设置剩余数值，为了统一计划工单
                    list_task.Add(model_task);
                }
                #endregion

                model.goodslist = list_task;     //item.goodslist
                model.sended = item.sended;
                model.isoffence = item.isoffence;
                model.isexceptions = item.isexceptions;
                model.exceptions = item.exceptions;
                model.timeout = (int)timeout_Seconds;
                model.timeout_receive = (int)timeout_receive_Seconds;
                model.createtby = item.createtby;
                model.createtime = item.createtime;
                list.Add(model);
            }            

            //计划工单
            foreach (var item_plan in query_planorder_result)
            {
                var model = new Distri_PlanAndOrderDto();
                model.id = item_plan.id;
                model.planid = item_plan.planid;
                model.plantaskid = item_plan.id;
                model.wocode = item_plan.wocode;
                //model.emergencyid = item.emergencyid; //默认为0
                model.projectid = item_plan.projectid;
                model.planname = item_plan.name;
                model.planandorder_state = item_plan.planwostate;  // item_plan.planwostate == 1 ? 0 : (int)EnumDistriWorkOrderPlanWOstate.create;
                model.wostate_elevator = 9;
                model.wosorts = (int)EnumDistributionWoSorts.plantask;
                model.touser = item_plan.joinuserlist;
                model.assigtime = item_plan.statetime;
                model.dealtime = item_plan.dealtime;
                model.receiverlist = item_plan.receiverlist;
                model.deliverylist = item_plan.deliverylist;
                model.goodslist = item_plan.goodslist;
                model.sended = 0;
                model.isoffence = 0;
                model.isexceptions = 0;
                model.exceptions = "";
                model.timeout = 0;
                model.timeout_receive = 0;
                model.createtby = item_plan.createtby;
                model.createtime = item_plan.createtime;
                list.Add(model);
            }
            //查询条件
            if (wosorts > 0)
                list = list.Where(it => it.wosorts == wosorts).ToList();     //已完成工单中之展示随机工单，分送工单在计划工单详情中展示

            recordCount = list.Count();
            var lists = list.OrderByDescending(x=>x.createtime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return lists;
        }

        /// <summary>
        /// 违规工单列表分页 - 随机工单 -  Linq 关联查询 分页
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="stime"></param>
        /// <param name="etime"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        public IEnumerable<object> GetOffenceWOListByPageAsync(string keyword, string projectid, string stime, string etime, string rolecode, string usercode, UserAccountInfoModel userinfo,int isappeal, int pageIndex, int pageSize, out int recordCount)
        {
            //关联查询
            var query =
                 from woder in _collection.AsQueryable()
                 join proje in _collection_pro_project_info.AsQueryable() on woder.projectid equals proje.id into proje_Defa
                 join offencerecord in _collection_distri_workorder_offencerecord.AsQueryable() on woder.id equals offencerecord.woid into offencerecord_Defa
                 where woder.isdelete == 0 && (woder.isoffence == 1 || woder.isexceptions == 1)
                 orderby woder.createtime descending
                 select new
                 {
                     id = woder.id,
                     wocode = woder.wocode,
                     planid = woder.planid,
                     plantaskid = woder.plantaskid,
                     emergencyid = woder.emergencyid,
                     projectid = woder.projectid,
                     projectname = proje_Defa != null && proje_Defa.Count() > 0 ? proje_Defa.First().project_name : null,
                     wostate = woder.wostate,
                     wosorts = woder.wosorts,
                     touser = woder.touser,
                     touser_elevator = woder.touser_elevator,
                     wostate_elevator = woder.wostate_elevator,
                     assigtime = woder.assigtime,
                     assigtime_elevator = woder.assigtime_elevator,
                     dealtime = woder.dealtime,
                     goodslist = woder.goodslist,
                     receiverlist = woder.receiverlist,
                     deliverylist = woder.deliverylist,
                     isoffence = woder.isoffence,
                     isappeal = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? 1 : 0,  //是否申诉（0没有申诉 1已申诉）
                     isaudit_offence = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? offencerecord_Defa.First().isaudit : 0,   //是否审核 0无操作 1不通过 2通过
                     content_offence = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? offencerecord_Defa.First().content : "",
                     content_rejectreason = offencerecord_Defa != null && offencerecord_Defa.Count() > 0 ? offencerecord_Defa.First().content_rejectreason : "",
                     isexceptions = woder.isexceptions,
                     createtime = woder.createtime,
                     createtby = woder.createtby,
                     isdelete = woder.isdelete
                 };
            #region 查询条件
            if (!string.IsNullOrEmpty(keyword))
                query = query.Where(it => it.wocode.Contains(keyword));     //工单编号     
            if (!string.IsNullOrEmpty(projectid))
                query = query.Where(it => it.projectid == projectid);
            if (!string.IsNullOrEmpty(stime))
                query = query.Where(it => it.createtime >= Convert.ToDateTime(stime + " 00:00:00"));
            if (!string.IsNullOrEmpty(etime))
                query = query.Where(it => it.createtime <= Convert.ToDateTime(etime + " 23:59:59"));
            
            if (userinfo.isallproject == 0)
            {
                query = query.Where(it => userinfo.projectlist.Contains(it.projectid));
            }
            //已申诉，异常
            query = query.Where(it => it.isappeal == 1 || it.isexceptions == 1);

            #endregion
            var lists = query.ToList();
            recordCount = lists.Count();
            var list = lists.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return list;

            #region 注释
            ////关联查询
            //var query =
            //     from offencerecord in _collection_distri_workorder_offencerecord.AsQueryable()
            //     join goods in _collection.AsQueryable() on offencerecord.woid equals goods.id into goods_Defa
            //     where offencerecord.isdelete == 0
            //     orderby offencerecord.createtime descending
            //     select new
            //     {
            //         offencerecord.id,  //违规表id
            //         woid = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().id : null,
            //         wocode = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().wocode : null,
            //         channel = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().channel : 0,
            //         emergencyid = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().emergencyid : 0,
            //         projectid = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().projectid : null,
            //         wostate = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().wostate : 0,
            //         wostate_elevator = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().wostate_elevator : 0,
            //         goodslist = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().goodslist : null,
            //         receiverlist = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().receiverlist : null,
            //         deliverylist = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().deliverylist : null,
            //         touser_elevator = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().touser_elevator : null,
            //         touser = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().touser : null,
            //         dealby = goods_Defa != null && goods_Defa.Count() > 0 ? goods_Defa.First().dealby : null,
            //         offencerecord.isaudit,
            //         offencerecord.content,
            //         offencerecord.content_rejectreason,
            //         offencerecord.createby,
            //         offencerecord.createtime,
            //         offencerecord.isdelete,
            //     };
            //#region 查询条件
            //if (!string.IsNullOrEmpty(keyword))
            //    query = query.Where(it => it.wocode.Contains(keyword));     //工单编号     
            //if (!string.IsNullOrEmpty(projectid))
            //    query = query.Where(it => it.projectid == projectid);
            //if (!string.IsNullOrEmpty(stime))
            //    query = query.Where(it => it.createtime >= Convert.ToDateTime(stime + " 00:00:00"));
            //if (!string.IsNullOrEmpty(etime))
            //    query = query.Where(it => it.createtime <= Convert.ToDateTime(etime + " 23:59:59"));

            //if (userinfo.isallproject == 0)
            //{
            //    query = query.Where(it => userinfo.projectlist.Contains(it.projectid));               
            //}

            //#endregion
            //var lists = query.ToList();
            //recordCount = lists.Count();
            //var list = lists.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            //return list;

            #endregion
        }

        #endregion

    }
}
