using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.IMSRepository.Entities;
using Siger.Middlelayer.IMSRepository.Repositories.Interface;
using Siger.Middlelayer.IMSRepository.Response;
using Siger.Middlelayer.WmsRepository.Entities;
using Siger.Middlelayer.WmsRepository.Request;

namespace Siger.Middlelayer.IMSRepository.Repositories
{
    internal class ToolReplaceReturnRepository : IMSRepositoryBase<siger_project_ims_tool_replace_return>, IToolLifeReplaceReturnRepository
    {
        private readonly object _lockObj = new object();
        private readonly ApiIMSDbContext _context;
        public ToolReplaceReturnRepository(ApiIMSDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ResponseGetReplaceReturn> GetPagedList(int workorder_id, string workorder_code, int material_id, int operate_mid
            , int starttime, int endtime, int page, int pagesize, int projectId, int toexcel)
        {
            var querylist = from q in _context.siger_project_ims_tool_replace_return
                join m in _context.siger_tr_materials on q.material_id equals m.id
                join u in _context.siger_project_user on q.operate_mid equals  u.mid
                join b in _context.siger_wms_bussinese_contacts on q.supplier_id equals b.id
                where q.status == (int)RowState.Valid && q.project_id == projectId
                select new ResponseGetReplaceReturn
                {
                    id = q.id,
                    workorder_id = q.workorder_id,
                    workorder_code = q.workorder_code,
                    material_id = q.material_id,
                    material_name = m.name ?? "",
                    status = q.status,
                    part_no = q.part_no,
                    ctime = q.operate_time,
                    quantity = q.quantity,
                    operate_mid = q.operate_mid,
                    operate_user = u.name??"",
                    operate_time = UnixTimeHelper.ConvertIntDateTime(q.operate_time),
                    operate_type = q.operate_type,
                    supplier = b.name??"",
                    install_code=q.install_code,
                };
            Expression<Func<ResponseGetReplaceReturn, bool>> orderIdExpression = q => true;
            if (workorder_id != 0)
            {
                orderIdExpression = q => q.workorder_id == workorder_id;
            }
            Expression<Func<ResponseGetReplaceReturn, bool>> orderCodeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(workorder_code))
            {
                orderCodeExpression = q => q.workorder_code == workorder_code;
            }
            Expression<Func<ResponseGetReplaceReturn, bool>> timeExpression = q => true;
            if (starttime > 0 && endtime>0)
            {
                timeExpression = q => (q.ctime <= endtime && q.ctime >= starttime);
            }
            Expression<Func<ResponseGetReplaceReturn, bool>> partNoExpression = q => true;
            if (material_id>0)
            {
                partNoExpression = q => q.material_id == material_id;
            }
            Expression<Func<ResponseGetReplaceReturn, bool>> operatorExpression = q => true;
            if (operate_mid > 0)
            {
                operatorExpression = q => q.operate_mid == operate_mid;
            }

            var predicate = orderIdExpression.And(timeExpression).And(partNoExpression).And(orderCodeExpression).And(operatorExpression);

            if (toexcel == 0)
            {
                var totalCount = querylist.Count(predicate);
                var entities = querylist.Where(predicate).OrderByDescending(t => t.id).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
                foreach (var item in entities)
                {
                    var install = _context.siger_project_ims_tool_install.OrderBy(o => o.id).Where(f => f.status != 0 && f.project_id == projectId && f.install_code == item.install_code).ToList();
                    item.life = install.FirstOrDefault(f => !string.IsNullOrEmpty(f.lastLife))?.lastLife ?? "";
                    item.reason = install.FirstOrDefault(f => !string.IsNullOrEmpty(f.uninstall_reason))?.uninstall_reason ?? "";
                }
                return new PagedCollectionResult<ResponseGetReplaceReturn>(entities, totalCount);
            }
            else
            {
                var entities = querylist.Where(predicate).AsNoTracking().ToList();
                foreach (var item in entities)
                {
                    var install = _context.siger_project_ims_tool_install.OrderBy(o=>o.id).Where(f => f.status != 0 && f.project_id == projectId && f.install_code == item.install_code).ToList();
                    item.life = install.FirstOrDefault(f => !string.IsNullOrEmpty(f.lastLife))?.lastLife ?? "";
                    item.reason = install.FirstOrDefault(f => !string.IsNullOrEmpty(f.uninstall_reason))?.uninstall_reason ?? "";
                }
                return new PagedCollectionResult<ResponseGetReplaceReturn>(entities, 0);
            }
        }

        public bool OutStock(IEnumerable<int> ReplaceIds, int projectId, int userId, int operator_mid)
        {
            var stocks = from s in _context.siger_project_ims_tool_replace_return
                         join t in _context.siger_project_ims_tool on s.material_id equals t.material_id
                         join sk in _context.siger_wms_stock on s.material_id equals sk.material_id
                         join lo in _context.siger_wms_storage_location on sk.storage_location_id equals lo.id
                         join st in _context.siger_wms_storage on s.storage_id equals st.id
                         where ReplaceIds.Contains(s.id) && s.project_id == projectId && sk.stock_state == (int)StockEnum.InWavehouse
                         select new
                         {
                             s.id,
                             pn = t.part_no,
                             s.supplier_id,
                             sk.storage_location_id,
                             st.name,
                             wareHouseId = s.storage_id,
                             s.quantity,
                             s.stock_number
                         };
            var replaces = stocks.GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();
            if (!replaces.Any())
            {
                throw new BadRequestException(RequestEnum.StockNotExist);
            }

            var orderDetails = new List<siger_wms_stock_access_order_detail>();
            foreach (var wareHouseId in replaces.Select(m => m.wareHouseId).Distinct())
            {
                var billCode = GetBillId("1", projectId);
                var entity = new siger_wms_stock_access_order
                {
                    contactid = 0,                   
                    category_code = (int)WaveHousingType.ProductionOut,
                    category = EnumHelper.GetEnumDesc(WaveHousingType.ProductionOut),
                    storageid = wareHouseId,
                    access_type = (int)WaveHouseType.Out,
                    order_number = billCode,
                    origin_order_number = billCode,
                    order_status = (int)WaveHousingState.Checked,
                    auditor = userId,
                    audit_time = DateTime.Now,
                    creator = userId,
                    create_time = DateTime.Now,
                    update_time = DateTime.Now,
                    updator = userId,
                    projectid = projectId,
                    status = (int)RowState.Valid,
                    picker = operator_mid > 0 ? operator_mid : userId                    
                };
                _context.siger_wms_stock_access_order.Add(entity);
                if (_context.SaveChanges() < 0)
                {
                    return false;
                }
                
                var wareChoices = replaces.Where(q => q.wareHouseId == wareHouseId);
                foreach (var stock in wareChoices)
                {
                    var material = _context.siger_tr_materials.FirstOrDefault(f =>
                        f.pn == stock.pn && f.projectId == projectId && f.status == (int)RowState.Valid);
                    if (material == null)
                    {
                        continue;
                    }

                    var stockTrace = GetStockTrace(stock.stock_number, 0, projectId);

                    var detail = new siger_wms_stock_access_order_detail
                    {
                        orderid = entity.id,
                        material_id = material.id,
                        material_name = material.name,
                        material_pn = material.pn,
                        material_spec = material.spec,
                        manage_mode = material.manage_mode,
                        unit = GetUnitName(material.unit, projectId),
                        quantity = stock.quantity,
                        creator = userId,
                        create_time = DateTime.Now,
                        update_time = DateTime.Now,
                        updator = userId,
                        projectid = projectId,
                        businessid = stock.supplier_id,
                        status = (int)RowState.Valid,                        
                        serial_number = stockTrace.serial_number,
                        batch_number = stockTrace.batch_number
                    };                    

                    _context.siger_wms_stock_access_order_detail.Add(detail);

                    //用于出库
                    detail.stock_number = stockTrace.id.ToString();
                    orderDetails.Add(detail);
                }
            }

            if (_context.SaveChanges() > 0)
            {
                //出库
                foreach (var orderId in orderDetails.Select(t=>t.orderid).Distinct())
                {
                    var details = orderDetails.Where(t => t.orderid == orderId).ToList();
                    if (details.Any())
                    {
                        var detail = details.FirstOrDefault();
                        var managemode = (managemodel)detail.manage_mode.ToInt();
                        var code = string.IsNullOrEmpty(detail.serial_number) ? detail.batch_number : detail.serial_number;
                        var stockList = details.Select(t => new Stock
                        {
                            count = t.quantity,
                            stockid = t.stock_number.ToInt()
                        }).ToList();
                        CheckOut(detail.id, stockList, userId, projectId, managemode, code);
                    }                                        
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        public void CheckOut(int id, List<Stock> inventories, int userId, int projectId, managemodel type, string code)
        {
            int totalCount = 0;

            switch (type)
            {
                case managemodel.Batch:
                    break;
                case managemodel.No:
                    //totalCount = 1;
                    break;
                case managemodel.Group:
                    break;
                default:
                    throw new BadRequestException(RequestEnum.ManageModeNotMatching);
            }
            if (_context.siger_wms_stock_access_order_detail.Count(f => f.id == id && f.status == (int)RowState.Valid && f.projectid == projectId) == 0)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            //类型为出库单
            siger_wms_stock_access_order_detail orderdetail = _context.siger_wms_stock_access_order_detail.FirstOrDefault(f => f.id == id && f.status == (int)RowState.Valid && f.projectid == projectId);
            switch (type)
            {
                case managemodel.Batch:
                    if (!string.IsNullOrEmpty(code))
                    {
                        if (_context.siger_wms_stock.Count(f => f.batch_number == code) < 0)
                        {
                            throw new BadRequestException(RequestEnum.BatchNull);
                        }
                    }
                    break;
                case managemodel.No:
                    if (!string.IsNullOrEmpty(code))
                    {
                        if (_context.siger_wms_stock.Count(f => f.serial_number == code) < 0)
                        {
                            throw new BadRequestException(RequestEnum.NoNull);
                        }
                    }
                    break;
                case managemodel.Group:
                    break;
                default:
                    throw new BadRequestException(RequestEnum.ManageModeNotMatching);
            }
            if (orderdetail == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var orderData = _context.siger_wms_stock_access_order.FirstOrDefault(f => f.status == (int)RowState.Valid && f.id == orderdetail.orderid &&
                                            f.access_type == (int)WaveHouseType.Out && f.projectid == projectId);
            if (orderData == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            if (orderData.order_status != (int)WaveHousingState.Checked && orderData.order_status != (int)WaveHousingState.WaveHousingOut)
            {
                throw new BadRequestException(RequestEnum.ErrorState);
            }

            foreach (var item in inventories)
            {
                totalCount += item.count;
                if (_context.siger_wms_stock.Count() < 0)
                {
                    throw new BadRequestException(RequestEnum.StockNotExist);
                }
            }
            if (orderdetail.quantity - orderdetail.access_quantity - totalCount < 0)
            {
                //count error
                throw new BadRequestException(RequestEnum.CountInsufficient);
            }
            var stockOuts = new List<int>();//出库的物料id列表
            if (type == managemodel.No)
            {
                var stock = _context.siger_wms_stock.FirstOrDefault(f => f.status == (int)RowState.Valid && f.serial_number == code &&
                                                                                    f.stock_state == (int)StockEnum.InWavehouse && f.projectid == projectId);
                if (stock == null)
                {
                    throw new BadRequestException(RequestEnum.StockNotExist);
                }
                if (orderdetail.material_id != stock.material_id)
                {
                    throw new BadRequestException(RequestEnum.MaterialeError);
                }
                if (orderdetail.businessid != stock.businessid)
                {
                    throw new BadRequestException(RequestEnum.BusinessNotMatch);
                }
                //检测是否为出库单上的仓库
                var locationdata = _context.siger_wms_storage_location.FirstOrDefault(f => f.id == stock.storage_location_id && f.status == (int)RowState.Valid);
                if (locationdata == null)
                {
                    throw new BadRequestException(RequestEnum.LocationError);
                }
                if (locationdata.storageid != orderData.storageid)
                {
                    throw new BadRequestException(RequestEnum.LocationError);
                }
                //check管理模式
                var entity = _context.siger_tr_materials.FirstOrDefault(f => f.id == stock.material_id && f.status == (int)RowState.Valid && f.projectId == projectId);
                if (entity == null)
                {
                    throw new BadRequestException(RequestEnum.MaterialNotExist);
                }
                if (int.TryParse(entity.manage_mode, out int mode))
                {
                    if ((int)type != mode)
                    {
                        throw new BadRequestException(RequestEnum.ManageModeNotMatching);
                    }
                }
                var location = _context.siger_wms_storage_location.FirstOrDefault(f => f.status == (int)RowState.Valid && f.projectid == projectId &&
                            f.id == stock.storage_location_id);
                if (location == null)
                {
                    throw new BadRequestException(CommonEnum.NoData);
                }
                //添加trace
                var user = GetProjectUser(userId, projectId);
                //供应商信息
                var supplier = GetSupplier(stock.businessid, projectId);
                var tracedata = new siger_wms_stock_detail
                {
                    type = (int) traceType.WaveHousingOut,
                    billID = orderData.order_number,
                    inventory = stock.material_id,
                    inventorySN = stock.material_pn,
                    inventoryName = orderdetail.material_name,
                    allqty = orderdetail.quantity,
                    qty = 1,
                    userid = userId,
                    username = user?.name ?? "",
                    updatetime = DateTime.Now,
                    state = (int) RowState.Valid,
                    locationid = stock.storage_location_id,
                    locationname = location.name,
                    inventorySpec = stock.material_spec,
                    projectid = projectId,
                    no = code,
                    businessid = stock.businessid,
                    businessName = supplier?.name ?? ""
                };

                _context.siger_wms_stock_detail.Add(tracedata);


                //更新stock中的数量
                stock.quantity -= 1;
                //更新状态为出库
                if (stock.quantity == 0)
                {
                    stock.stock_state = (int)StockEnum.OutWavehouse;
                }
                stockOuts.Add(stock.material_id);
                _context.siger_wms_stock.Update(stock);
            }
            else
            {
                //更新orderdetail中的数量
                foreach (var item in inventories)
                {
                    var stock = _context.siger_wms_stock.FirstOrDefault(f => f.status == (int)RowState.Valid && f.id == item.stockid &&
                                                                                    f.stock_state == (int)StockEnum.InWavehouse && f.projectid == projectId);
                    if (stock == null)
                    {
                        throw new BadRequestException(RequestEnum.StockNotExist);
                    }

                    //检测是否为出库单上的仓库
                    var locationdata = _context.siger_wms_storage_location.FirstOrDefault(f => f.id == stock.storage_location_id && f.status == (int)RowState.Valid);
                    if (locationdata == null)
                    {
                        throw new BadRequestException(RequestEnum.LocationError);
                    }
                    if (locationdata.storageid != orderData.storageid)
                    {
                        throw new BadRequestException(RequestEnum.LocationError);
                    }

                    if (item.count > stock.quantity)
                    {
                        throw new BadRequestException(RequestEnum.CountInsufficient);
                    }
                    //check管理模式
                    var entity = _context.siger_tr_materials.FirstOrDefault(f => f.id == stock.material_id && f.status == (int)RowState.Valid && f.projectId == projectId);
                    if (entity == null)
                    {
                        throw new BadRequestException(RequestEnum.MaterialNotExist);
                    }
                    if (int.TryParse(entity.manage_mode, out int mode))
                    {
                        if ((int)type != mode)
                        {
                            throw new BadRequestException(RequestEnum.ManageModeNotMatching);
                        }
                    }

                    //添加trace
                    var user = GetProjectUser(userId, projectId);
                    //供应商信息
                    var supplier = GetSupplier(stock.businessid, projectId);
                    var tracedata = new siger_wms_stock_detail
                    {
                        type = (int) traceType.WaveHousingOut,
                        billID = orderData.order_number,
                        inventory = stock.material_id,
                        inventorySN = stock.material_pn,
                        inventoryName = orderdetail.material_name,
                        allqty = orderdetail.quantity,
                        qty = item.count,
                        userid = userId,
                        username = user?.name ?? "",
                        updatetime = DateTime.Now,
                        state = (int) RowState.Valid,
                        locationid = locationdata.id,
                        locationname = locationdata.name,
                        inventorySpec = stock.material_spec,
                        projectid = projectId,
                        businessid = stock.businessid,
                        businessName = supplier?.name ?? ""
                    };
                    if (type == managemodel.Batch)
                    {
                        tracedata.batch = code;
                    }
                    _context.siger_wms_stock_detail.Add(tracedata);

                    //更新stock中的数量
                    stock.quantity -= item.count;
                    //更新状态为出库
                    if (stock.quantity == 0)
                    {
                        stock.stock_state = (int)StockEnum.OutWavehouse;
                    }
                    stockOuts.Add(stock.material_id);
                    _context.siger_wms_stock.Update(stock);
                }
            }
            //更新单据详情数量
            orderdetail.access_quantity += totalCount;
            orderData.auditor = userId;
            orderData.audit_time = DateTime.Now;
            orderData.audit_desc = "";
            orderData.audit_fail_reason = "";
            orderdetail.update_time = DateTime.Now;
            orderdetail.updator = userId;
            _context.siger_wms_stock_access_order_detail.Update(orderdetail);

            //汇总库存
            SubtractStockChange(orderData.storageid, orderdetail.material_id, totalCount, projectId);


            if (_context.SaveChanges() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            //更新单据状态
            if (orderData.order_status == (int)WaveHousingState.Checked)
            {
                orderData.order_status = (int)WaveHousingState.WaveHousingOut;
            }
            if (_context.siger_wms_stock_access_order_detail.FirstOrDefault(f => f.orderid == orderData.id && f.status == (int)RowState.Valid && f.projectid == projectId && f.quantity != f.access_quantity) ==null)
            {
                orderData.order_status = (int)WaveHousingState.WaveHousingOutFinish;
            }

            orderData.updator = userId;
            orderData.update_time = DateTime.Now;
            _context.siger_wms_stock_access_order.Update(orderData);

            if (_context.SaveChanges() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            else
            {
                var materialids = new List<int>();
                foreach (var material_id in stockOuts)
                {
                    if (materialids.Contains(material_id))
                    {
                        continue;
                    }
                    materialids.Add(material_id);
                    var material = GetMaterial(material_id, "", projectId);
                    if (material == null)
                    {
                        continue;
                    }
                    var stock_Alarm = _context.siger_wms_stock_alarm.FirstOrDefault(t => t.material_id == material.id && t.projectid == projectId
                        && t.status == (int)AlarmStatus.Operating);
                    if (stock_Alarm != null)
                    {
                        stock_Alarm.trigger_time = UnixTimeHelper.GetNow();
                        _context.siger_wms_stock_alarm.Update(stock_Alarm);
                        _context.SaveChanges();
                        continue;
                    }
                    var stockTotal = _context.siger_wms_stock.Where(t => t.material_id == material.id && t.status == (int)RowState.Valid &&
                        t.projectid == projectId && t.stock_state == (int)StockEnum.InWavehouse).Sum(t => t.quantity);
                    if (stockTotal < material.min_stock || (material.min_stock == 0 && stockTotal == material.min_stock))
                    {
                        var alarm = new siger_wms_stock_alarm
                        {
                            material_id = material.id,
                            material_pn = material.pn,
                            information_type = (int)AlarmInfoType.StockAlarm,
                            creator = userId,
                            create_time = UnixTimeHelper.GetNow(),
                            projectid = projectId,
                            status = (int)RowState.Valid,
                            trigger_time = UnixTimeHelper.GetNow()
                        };
                        _context.siger_wms_stock_alarm.Add(alarm);
                        _context.SaveChanges();
                    }
                }
            }
        }

        /// <summary>
        /// 库存汇总-减少数量
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="inventoryid"></param>
        /// <param name="count"></param>
        /// <param name="projectid"></param>
        public void SubtractStockChange(int storage, int inventoryid, int count, int projectid)
        {
            var start = DateTime.Now.Date;
            var entity = _context.siger_wms_stock_change.FirstOrDefault(f => f.time >= start && f.state == (int)RowState.Valid && f.projectid == projectid && f.storageid == storage && f.inventoryid == inventoryid);
            if (entity == null)
            {
                int tmpCount = 0;
                entity = _context.siger_wms_stock_change.Where(f => f.state == (int)RowState.Valid && f.projectid == projectid && f.storageid == storage &&
                f.inventoryid == inventoryid).OrderByDescending(f => f.time).FirstOrDefault();
                if (entity == null)
                {
                    return;
                }
                else
                {
                    tmpCount = entity.count - count;
                    if (tmpCount < 0)
                    {
                        return;
                    }
                    entity = new siger_wms_stock_change
                    {
                        storageid = storage,
                        inventoryid = inventoryid,
                        count = tmpCount,
                        time = DateTime.Now,
                        projectid = projectid,
                        state = (int)RowState.Valid
                    };
                    _context.siger_wms_stock_change.Add(entity);
                }
            }
            else
            {
                entity.count -= count;
                if (entity.count < 0)
                {
                    return;
                }
                _context.siger_wms_stock_change.Update(entity);
            }
        }

        public bool InStock(IEnumerable<siger_project_ims_tool_replace_return> returns, int storage_id, int projectId, int userId)
        {
            var stocks = from s in returns
                         select new
                         {
                             s.id,
                             pn = s.part_no,
                             s.quantity,
                             s.supplier_id
                         };
            var sendbackList = stocks.ToList();
            if (!sendbackList.Any())
            {
                throw new BadRequestException(RequestEnum.StockNotExist);
            }

            var billCode = GetBillId("0", projectId);
            var entity = new siger_wms_stock_access_order
            {
                contactid = 0,
                category = EnumHelper.GetEnumDesc(WaveHousingType.WholeToolIn),
                storageid = storage_id,
                access_type = (int)WaveHouseType.In,
                order_number = billCode,
                origin_order_number = billCode,
                order_status = (int)WaveHousingState.Waiting,
                creator = userId,
                create_time = DateTime.Now,
                update_time = DateTime.Now,
                updator = userId,
                projectid = projectId,
                status = (int)RowState.Valid
            };
            _context.siger_wms_stock_access_order.Add(entity);
            if (_context.SaveChanges() < 0)
            {
                return false;
            }

            //按照料号和供应商分组入库
            foreach (var supplierId in sendbackList.Select(m => m.supplier_id).Distinct())
            {
                var supplierChoices = sendbackList.Where(q => q.supplier_id == supplierId).ToList();
                foreach (var pn in supplierChoices.Select(m => m.pn).Distinct())
                {
                    var material = _context.siger_tr_materials.FirstOrDefault(f => f.pn == pn && f.projectId == projectId && f.status == (int)RowState.Valid);
                    if (material == null)
                    {
                        continue;
                    }

                    var quantity = supplierChoices.Count(m => m.pn == pn);
                    var detail = new siger_wms_stock_access_order_detail
                    {
                        orderid = entity.id,
                        material_id = material.id,
                        material_name = material.name,
                        material_pn = material.pn,
                        material_spec = material.spec,
                        manage_mode = material.manage_mode,
                        unit = GetUnitName(material.unit, projectId),
                        quantity = quantity,
                        creator = userId,
                        create_time = DateTime.Now,
                        update_time = DateTime.Now,
                        updator = userId,
                        projectid = projectId,
                        businessid = supplierId,
                        status = (int)RowState.Valid
                    };

                    _context.siger_wms_stock_access_order_detail.Add(detail);
                }
            }

            return _context.SaveChanges() > 0;
        }

        private string GetUnitName(string unit, int projectId)
        {
            var entity = Queryable.FirstOrDefault<SigerTrDict>(_context.siger_tr_dict, f => f.status == (int)RowState.Valid
                                                                    && f.cat == DictUnitType.meterunits.ToString()
                                                                    && f.dkey == unit && f.projectId == projectId);
            return entity?.dval;
        }

        private string GetBillId(string key, int projectid)
        {
            var tmp = _context.siger_wms_settings.FirstOrDefault(f => f.key == key && f.projectid == projectid);
            var value = "";
            switch (key)
            {
                case "0":
                    value = tmp == null ? "SC" : tmp.value;
                    break;
                case "1":
                    value = tmp == null ? "SH" : tmp.value;
                    break;
            }

            siger_wms_id t;
            lock (_lockObj)
            {
                t = new siger_wms_id
                {
                    day = DateTime.Now,
                    type = 1
                };
                _context.siger_wms_id.Add(t);
                _context.SaveChanges();

                var count = _context.siger_wms_id.Count(f => f.day > DateTime.Now.Date && f.day <= DateTime.Now.AddDays(1).Date && f.type == 1);
                t.code = $"{count:D6}";
                _context.siger_wms_id.Update(t);
                _context.SaveChanges();
            }

            var result = $"{value}{DateTime.Now:yyyyMMdd}{t.code}";
            return result;
        }

        public int GetIdMax()
        {
            var count = Queryable.Count<siger_project_ims_tool_replace_return>(_context.siger_project_ims_tool_replace_return);
            return count > 0 ? Queryable.Max<siger_project_ims_tool_replace_return, int>(_context.siger_project_ims_tool_replace_return, t => t.id) : 0;
        }
    }
}
