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

namespace Siger.ApiTLM.Controllers
{
    public class ToolReplaceReturnController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IToolLifeToolGrindRepository _grindRepository;
        private readonly IToolLifeToolRepository _toolRepository;
        private readonly IToolLifeReplaceReturnRepository _replaceReturnRepository;
        private readonly IToolLifeWorkorderRepository _workorderRepository;
        private readonly IToolLifeToolScrapRepository _scrapRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly Isiger_wms_storage_locationRepository _sigerWmsStorageLocationRepository;
        private readonly IToolLifeToolInstallRepository _installRepository;
        private readonly IToollifeCabinetReceiveRepository _cabinetReceiveRepository;
        private readonly Isiger_wms_stock_access_orderRepository _stock_Access_OrderRepository;
        private readonly Isiger_wms_settingsRepository _wms_SettingsRepository;
        private readonly Isiger_wms_stockRepository _stockRepository;

        public ToolReplaceReturnController(IUnitOfWork unitOfWork, IToolLifeToolGrindRepository grindRepository, IToolLifeToolRepository toolRepository,
            IToolLifeReplaceReturnRepository replaceReturnRepository, IToolLifeWorkorderRepository workorderRepository, IToolLifeToolScrapRepository scrapRepository,
            ISigerProjectUserRepository projectUserRepository, Isiger_wms_storage_locationRepository sigerWmsStorageLocationRepository, IToolLifeToolInstallRepository installRepository,
            IToollifeCabinetReceiveRepository cabinetReceiveRepository, Isiger_wms_stock_access_orderRepository stock_Access_OrderRepository, Isiger_wms_settingsRepository wms_SettingsRepository
            ,Isiger_wms_stockRepository stockRepository)
        {
            _unitOfWork = unitOfWork;
            _grindRepository = grindRepository;
            _toolRepository = toolRepository;
            _replaceReturnRepository = replaceReturnRepository;
            _workorderRepository = workorderRepository;
            _scrapRepository = scrapRepository;
            _projectUserRepository = projectUserRepository;
            _sigerWmsStorageLocationRepository = sigerWmsStorageLocationRepository;
            _installRepository = installRepository;
            _cabinetReceiveRepository = cabinetReceiveRepository;
            _stock_Access_OrderRepository = stock_Access_OrderRepository;
            _wms_SettingsRepository = wms_SettingsRepository;
            _stockRepository = stockRepository;
        }

        [HttpPost]
        public IActionResult GetPagedList([FromBody]RequestGetToolReplaceReturn request)
        {
            var stime = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Parse(request.starttime));
            var etime = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Parse(request.endtime));
            var data = _replaceReturnRepository.GetPagedList(0, request.workorder_id, request.material_id.ToInt(),
                request.operate_mid.ToInt(), stime, etime, request.page,
                request.pagesize, ProjectId, 0);
            return new PagedObjectResult(data.Data, data.Total, request.page, request.pagesize);
        }

        /// <summary>
        /// 更换
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Replace([FromBody]RequestToolReplace request)
        {
            if (request.storage_id.ToInt() == 0)
            {
                throw new BadRequestException(RequestEnum.SelectData);
            }
            var user = _replaceReturnRepository.GetProjectUser(request.operate_mid.ToInt(), ProjectId);
            if (user == null)
            {
                throw new BadRequestException(RequestEnum.UserNotFound);
            }

            var material = _replaceReturnRepository.GetMaterial(request.material_id.ToInt(), "", ProjectId);
            if (material == null)
            {
                throw new BadRequestException(RequestEnum.MaterialNotExist);
            }

            var workorder = _workorderRepository.Get(t =>
                t.workorder_code == request.workorder_id && t.project_id == ProjectId &&
                t.status == (int)RowState.Valid);
            if (workorder == null)
            {
                //throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }

            var dic = GetSerialNumber().FirstOrDefault();
            var serial_number = request.serial_number;
            if (string.IsNullOrWhiteSpace(request.serial_number))
            {
                serial_number = dic.Value;
            }
            var replace = new siger_project_toollife_tool_replace_return
            {
                workorder_id = workorder?.id ?? 0,
                workorder_code = workorder?.workorder_code ?? "",
                material_id = material.id,
                part_no = material.pn,
                operate_time = UnixTimeHelper.GetNow(),
                operate_mid = user.mid,
                operate_type = (int)ReplaceReturnTypeStatus.Replace,
                project_id = ProjectId,
                status = request.status.ToInt(),
                quantity = request.quantity.ToInt(),
                stock_number = serial_number,
                supplier_id = request.supplier_id.ToInt(),
                storage_id = request.storage_id.ToInt(),
                create_mid = UserId,
                create_time = UnixTimeHelper.GetNow()
            };
            _replaceReturnRepository.Insert(replace);
            if (request.status.ToInt() == (int)StorageCategory.Grinding)
            {
                var tool = _toolRepository.Get(t =>
                    t.material_id == material.id && t.project_id == ProjectId &&
                    t.status == (int)RowState.Valid);
                if (tool == null)
                {
                    throw new BadRequestException(RequestEnum.ToolNotFound);
                }

                var grindCount = _grindRepository.GetList(t =>
                    (t.status == (int)ToolGrindStatus.Completed || t.status == (int)ToolGrindStatus.Apply)
                    && t.project_id == ProjectId && t.material_id == material.id).Count();
                var remain_count = tool.grind_times - grindCount > 0 ? tool.grind_times - grindCount : 0;
                var entity = new siger_project_toollife_tool_grind
                {
                    material_id = material.id,
                    part_no = material.pn,
                    remain_times = remain_count > 0 ? remain_count : 0,
                    recycling_time = UnixTimeHelper.GetNow(),
                    apply_time = 0,
                    cutter_number = tool.number,
                    grind_time = 0,
                    status = (int)ToolGrindStatus.UnGrind,
                    project_id = ProjectId,
                    stock_number = serial_number,
                    supplier_id = request.supplier_id.ToInt(),
                    source_id = dic.Key,
                    source_type = (int)ScrapGrindSourceStatus.ReplaceReturn,
                    create_mid = UserId,
                    create_time = UnixTimeHelper.GetNow()
                };
                _grindRepository.Insert(entity);
            }
            else if (request.status.ToInt() == (int)StorageCategory.Abandonment)
            {
                var tool = _toolRepository.Get(t =>
                    t.material_id == material.id && t.project_id == ProjectId &&
                    t.status == (int)RowState.Valid);
                if (tool == null)
                {
                    throw new BadRequestException(RequestEnum.ToolNotFound);
                }

                var scrap = new siger_project_toollife_tool_scrap
                {
                    material_id = material.id,
                    part_no = material.pn,
                    review_time = 0,
                    reason = "",
                    review_remark = "",
                    review_mid = 0,
                    cutter_number = tool.number,
                    create_mid = UserId,
                    create_time = UnixTimeHelper.GetNow(),
                    project_id = ProjectId,
                    stock_number = serial_number,
                    supplier_id = request.supplier_id.ToInt(),
                    source_id = dic.Key,
                    source_type = (int)ScrapGrindSourceStatus.ReplaceReturn
                };
                _scrapRepository.Insert(scrap);
            }
            else if (request.status.ToInt() == (int)StorageCategory.Recovery)
            {

            }
            else
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            if (_unitOfWork.Commit() > 0)
            {
                _replaceReturnRepository.OutStock(new List<int> { replace.id }, ProjectId, UserId, request.operate_mid.ToInt());
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 返还
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SendBack([FromBody]RequestToolReturn request)
        {
            if (request.sendbacks == null || !request.sendbacks.Any())
            {
                throw new BadRequestException(RequestEnum.InputValueError);
            }
            var user = _replaceReturnRepository.GetProjectUser(request.operate_mid.ToInt(), ProjectId);
            if (user == null)
            {
                throw new BadRequestException(RequestEnum.UserNotFound);
            }

            var workorder = _workorderRepository.Get(t =>
                t.workorder_code == request.workorder_id && t.project_id == ProjectId &&
                t.status == (int)RowState.Valid);
            if (workorder == null)
            {
                throw new BadRequestException(RequestEnum.ToolWorkorderNotFound);
            }

            var sendBackList = new List<siger_project_toollife_tool_replace_return>();
            var k = 0;
            foreach (var sendback in request.sendbacks)
            {
                var material = _replaceReturnRepository.GetMaterial(sendback.material_id.ToInt(), "", ProjectId);
                if (material == null)
                {
                    throw new BadRequestException(RequestEnum.MaterialNotExist);
                }

                var dic = GetSerialNumber().FirstOrDefault();
                var serial_number = sendback.serial_number;
                if (string.IsNullOrWhiteSpace(sendback.serial_number))
                {
                    serial_number = dic.Value;
                }
                var entity = new siger_project_toollife_tool_replace_return
                {
                    id = dic.Key + k,
                    workorder_id = workorder.id,
                    workorder_code = workorder.workorder_code,
                    material_id = material.id,
                    part_no = material.pn,
                    operate_time = UnixTimeHelper.GetNow(),
                    operate_mid = user.mid,
                    operate_type = (int)ReplaceReturnTypeStatus.SendBack,
                    project_id = ProjectId,
                    status = sendback.status.ToInt(),
                    quantity = sendback.quantity.ToInt(),
                    stock_number = serial_number,
                    supplier_id = sendback.supplier_id.ToInt(),
                    create_mid = UserId,
                    create_time = UnixTimeHelper.GetNow()
                };
                _replaceReturnRepository.Insert(entity);
                sendBackList.Add(entity);

                var tool = _toolRepository.Get(t =>
                    t.material_id == material.id && t.project_id == ProjectId &&
                    t.status == (int)RowState.Valid);
                if (tool == null)
                {
                    throw new BadRequestException(RequestEnum.ToolNotFound);
                }


                if (sendback.status.ToInt() == (int)StorageCategory.Grinding)
                {
                    var grindCount = _grindRepository.GetList(t =>
                        (t.status == (int)ToolGrindStatus.Completed || t.status == (int)ToolGrindStatus.Apply)
                        && t.project_id == ProjectId && t.material_id == material.id).Count();
                    var remain_count = tool.grind_times - grindCount > 0 ? tool.grind_times - grindCount : 0;
                    var grind = new siger_project_toollife_tool_grind
                    {
                        material_id = material.id,
                        part_no = material.pn,
                        remain_times = remain_count > 0 ? remain_count : 0,
                        recycling_time = UnixTimeHelper.GetNow(),
                        apply_time = 0,
                        cutter_number = tool.number,
                        grind_time = 0,
                        status = (int)ToolGrindStatus.UnGrind,
                        project_id = ProjectId,
                        stock_number = serial_number,
                        supplier_id = sendback.supplier_id.ToInt(),
                        source_id = dic.Key,
                        source_type = (int)ScrapGrindSourceStatus.ReplaceReturn,
                        create_mid = UserId,
                        create_time = UnixTimeHelper.GetNow()
                    };
                    _grindRepository.Insert(grind);
                }
                else if (sendback.status.ToInt() == (int)StorageCategory.Abandonment)
                {
                    var scrapModel = new siger_project_toollife_tool_scrap
                    {
                        material_id = material.id,
                        part_no = material.pn,
                        review_time = 0,
                        reason = "",
                        review_remark = "",
                        review_mid = 0,
                        cutter_number = tool.number,
                        create_mid = UserId,
                        create_time = UnixTimeHelper.GetNow(),
                        project_id = ProjectId,
                        stock_number = serial_number,
                        supplier_id = sendback.supplier_id.ToInt(),
                        source_id = dic.Key,
                        source_type = (int)ScrapGrindSourceStatus.ReplaceReturn
                    };
                    _scrapRepository.Insert(scrapModel);
                }
                else if (sendback.status.ToInt() == (int)StorageCategory.Recovery)
                {

                }
                else
                {
                    throw new BadRequestException(CommonEnum.Fail);
                }
                k++;
            }
            //生成入库单
            if (sendBackList.All(f => f.status == (int)StorageCategory.Recovery))
            {
                var model = new RequestAddBill();
                var bill = _wms_SettingsRepository.GetBillIDs(Settings.WaveHousingPre, ProjectId);
                model.billID = bill;
                model.rowBillID = bill;
                model.billType = WaveHouseType.In;
                model.businessid = 0;
                model.wavehousingtype = WaveHousingType.Recycling;
                model.waveHouseID = request.waveHouseID;
                model.inventories = sendBackList.Select(s => new Inventory { InventoryID = s.material_id, Count = s.quantity }).ToList();
                _stock_Access_OrderRepository.AddBill(ProjectId, UserId, model);
            }
            if (_unitOfWork.Commit() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpPost]
        public IActionResult ReplaceReturn([FromBody]RequestReplaceReturn request)
        {
            var replaceData = _replaceReturnRepository.Get(f => f.project_id == ProjectId && f.status != 0 && f.id == request.id);
            if (replaceData == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var dic = GetSerialNumber().FirstOrDefault();
            var tool = _toolRepository.Get(t =>
                    t.material_id == replaceData.material_id && t.project_id == ProjectId &&
                    t.status == (int)RowState.Valid);
            if (tool == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var status= (int)RowState.Invalid;
            switch (request.storagecategory)
            {
                case StorageCategory.Recovery:
                    status = (int)StorageCategory.Recovery;
                    var bill = _wms_SettingsRepository.GetBillIDs(Settings.WaveHousingPre, ProjectId);
                    var model = new RequestAddBill
                    {
                        billID = bill,
                        rowBillID = bill,
                        billType = WaveHouseType.In,
                        businessid = 0,
                        wavehousingtype = WaveHousingType.Recycling,
                        waveHouseID = request.waveHouseID,
                        inventories = new List<Inventory> { new Inventory { InventoryID = replaceData.material_id, Count = replaceData.quantity,storage_location_id=request.locationId } },
                    };
                    _stock_Access_OrderRepository.AddBill(ProjectId, UserId, model);
                    break;
                case StorageCategory.Grinding:
                    status = (int)StorageCategory.Grinding;
                    var grindCount = _grindRepository.GetList(t =>
                        (t.status == (int)ToolGrindStatus.Completed || t.status == (int)ToolGrindStatus.Apply)
                        && t.project_id == ProjectId && t.material_id == replaceData.material_id).Count();
                    var remain_count = tool.grind_times - grindCount > 0 ? tool.grind_times - grindCount : 0;
                    var grind = new siger_project_toollife_tool_grind
                    {
                        material_id = replaceData.material_id,
                        part_no = replaceData.part_no,
                        remain_times = remain_count > 0 ? remain_count : 0,
                        recycling_time = UnixTimeHelper.GetNow(),
                        apply_time = 0,
                        cutter_number = tool.number,
                        grind_time = 0,
                        status = (int)ToolGrindStatus.UnGrind,
                        project_id = ProjectId,
                        stock_number = replaceData.stock_number,
                        supplier_id = replaceData.supplier_id,
                        source_id = dic.Key,
                        source_type = (int)ScrapGrindSourceStatus.ReplaceReturn,
                        create_mid = UserId,
                        create_time = UnixTimeHelper.GetNow(),
                    };
                    _grindRepository.Insert(grind);
                    break;
                case StorageCategory.Abandonment:
                    status = (int)StorageCategory.Abandonment;
                    var scrapModel = new siger_project_toollife_tool_scrap
                    {
                        material_id = replaceData.material_id,
                        part_no = replaceData.part_no,
                        review_time = 0,
                        reason = "",
                        review_remark = "",
                        review_mid = 0,
                        cutter_number = tool.number,
                        create_mid = UserId,
                        create_time = UnixTimeHelper.GetNow(),
                        project_id = ProjectId,
                        stock_number = replaceData.stock_number,
                        supplier_id = replaceData.supplier_id,
                        source_id = dic.Key,
                        source_type = (int)ScrapGrindSourceStatus.ReplaceReturn,
                    };
                    _scrapRepository.Insert(scrapModel);
                    break;
                default:
                    throw new BadRequestException(CommonEnum.Fail);
            }
            replaceData.status = status;
            _replaceReturnRepository.Update(replaceData);
            if (_unitOfWork.Commit() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }
        /// <summary>
        /// 修模归还
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ReplaceReturnAfterGrind([FromBody] RequestReplaceReturnAfterGrind request)
        {
            var grindData = _grindRepository.Get(f => f.project_id == ProjectId && f.status != 0 && f.id == request.id);
            if (grindData==null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var bill = _wms_SettingsRepository.GetBillIDs(Settings.WaveHousingPre, ProjectId);
            var model = new RequestAddBill
            {
                billID = bill,
                rowBillID = bill,
                billType = WaveHouseType.In,
                businessid = 0,
                wavehousingtype = WaveHousingType.Recycling,
                waveHouseID = request.waveHouseID,
                inventories = new List<Inventory> { new Inventory { InventoryID = request.materialId, Count = request.count ,storage_location_id=request.storage_location_id } },
            };
            _stock_Access_OrderRepository.AddBill(ProjectId, UserId, model);
            grindData.status = 0;
            _grindRepository.Update(grindData);
            if (_unitOfWork.Commit() <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        private Dictionary<int, string> GetSerialNumber()
        {
            try
            {
                var id = _replaceReturnRepository.GetIdMax() + 1;
                var sn = "XM-" + (id.ToString().Length > 6 ? id.ToString() : id.ToString("000000"));
                return new Dictionary<int, string> { { id, sn } };
            }
            catch
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
        }

        [HttpGet]
        public IActionResult GetRecieveInfo(string sn)
        {
            if (string.IsNullOrWhiteSpace(sn))
            {
                throw new BadRequestException(RequestEnum.SNEmpty);
            }

            var res = new ResponseGetRecieveInfo();
            var stock = _replaceReturnRepository.GetStockTrace(sn, (int)StockEnum.InWavehouse, ProjectId);
            if (stock != null)
            {
                res.part_no = stock.material_pn;
                var material = _replaceReturnRepository.GetMaterial(0, res.part_no, ProjectId);
                res.material_name = material?.name ?? "";
                res.quantity = stock.quantity;
                res.IsSerial = stock.serial_number == sn ? 1 : 0;

                if (res.quantity <= 0)
                {
                    throw new BadRequestException(RequestEnum.StockUnEnough);
                }
                return new ObjectResult(res);
            }
            throw new BadRequestException(RequestEnum.StockNotExist);
        }

        /// <summary>
        /// 领用
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Recieve([FromBody]RequestRecieve req)
        {
            if (string.IsNullOrWhiteSpace(req.sn))
            {
                throw new BadRequestException(RequestEnum.SNEmpty);
            }
            var picker = _projectUserRepository.Get(t => t.mid == req.picker.ToInt() && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (picker == null)
            {
                throw new BadRequestException(RequestEnum.UserNotFound);
            }

            var stock = _replaceReturnRepository.GetSerialNoStock(req.sn, (int)StockEnum.InWavehouse, ProjectId);
            //GetStockTrace(req.sn, (int)StockEnum.InWavehouse, ProjectId);//改成只能填序号
            if (stock == null)
            {
                throw new BadRequestException(RequestEnum.StockDataNotNull);
            }

            var tool = _toolRepository.Get(t => t.material_id == stock.material_id && t.project_id == ProjectId && t.status == (int)RowState.Valid);
            if (tool == null)
            {
                throw new BadRequestException(RequestEnum.ToolNotFound);
            }
            var storage = _sigerWmsStorageLocationRepository.Get(t =>
                t.id == stock.storage_location_id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            if (storage == null)
            {
                throw new BadRequestException(RequestEnum.StorageError);
            }

            if (req.quantity.ToInt() == 0)
            {
                throw new BadRequestException(RequestEnum.CountError);
            }

            if (stock.quantity < req.quantity.ToInt())
            {
                throw new BadRequestException(RequestEnum.StockUnEnough);
            }
            var recieve = new siger_project_toollife_tool_replace_return
            {
                workorder_id = 0,
                workorder_code = string.Empty,
                material_id = stock.material_id,
                part_no = stock.material_pn,
                operate_time = UnixTimeHelper.GetNow(),
                operate_mid = picker.mid,
                operate_type = (int)ReplaceReturnTypeStatus.Recieve,
                project_id = ProjectId,
                status = (int)StorageCategory.Use,
                quantity = req.quantity.ToInt(),
                stock_number = req.sn,
                supplier_id = stock.businessid,
                storage_id = storage.storageid,
                create_mid = UserId,
                create_time = UnixTimeHelper.GetNow()
            };
            _replaceReturnRepository.Insert(recieve);

            if (_unitOfWork.Commit() > 0)
            {
                _replaceReturnRepository.OutStock(new List<int> { recieve.id }, ProjectId, UserId, picker.mid);
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 查询刀具报废，修磨，领用量
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetToolAmount([FromBody]RequestGetToolAmount req)
        {
            var res = new ResponseGetUnInstallImage();

            var stime = UnixTimeHelper.GetUnixByDate(req.starttime);
            var etime = UnixTimeHelper.GetUnixByDate(req.endtime);

            var dates = DateTimeHelper.GetDateTimes(req.starttime.ToDateTime(), req.endtime.ToDateTime(), 0);

            switch (req.stype.ToInt())
            {
                case (int)ToolAmountStatus.AbandonmentAmount:
                    var scrapList = _replaceReturnRepository.GetList(t =>
                        t.create_time >= stime && t.create_time <= etime && t.project_id == ProjectId && t.status == (int)StorageCategory.Abandonment).ToList();
                    foreach (var date in dates)
                    {
                        var sDatetime = UnixTimeHelper.GetUnixByDate(date.ToString(ParameterConstant.DateTimeFormat));
                        var eDatetime = UnixTimeHelper.GetUnixByDate(date.AddDays(1).AddSeconds(-1).ToString(ParameterConstant.DateTimeFormat));
                        res.x.Add(date.ToString(ParameterConstant.MonthDayFormay));
                        res.y.Add(scrapList.Count(t => t.create_time <= eDatetime && t.create_time >= sDatetime));
                    }
                    break;
                case (int)ToolAmountStatus.GrindingAmount:
                    var gridList = _replaceReturnRepository.GetList(t =>
                        t.create_time >= stime && t.create_time <= etime && t.project_id == ProjectId && t.status == (int)StorageCategory.Grinding).ToList();
                    foreach (var date in dates)
                    {
                        var sDatetime = UnixTimeHelper.GetUnixByDate(date.ToString(ParameterConstant.DateTimeFormat));
                        var eDatetime = UnixTimeHelper.GetUnixByDate(date.AddDays(1).AddSeconds(-1).ToString(ParameterConstant.DateTimeFormat));
                        res.x.Add(date.ToString(ParameterConstant.MonthDayFormay));
                        res.y.Add(gridList.Count(t => t.create_time <= eDatetime && t.create_time >= sDatetime));
                    }
                    break;
                case (int)ToolAmountStatus.UseAmount:
                    var useList = _installRepository.GetList(t => t.install_category == InstallCategory.Install &&
                            t.create_time >= req.starttime.ToDateTime() && t.create_time <= req.endtime.ToDateTime() && t.project_id == ProjectId && t.status == (int)RowState.Valid).ToList();
                    foreach (var date in dates)
                    {
                        var sDatetime = date;
                        var eDatetime = date.AddDays(1).AddSeconds(-1);
                        res.x.Add(date.ToString(ParameterConstant.MonthDayFormay));
                        res.y.Add(useList.Count(t => t.create_time <= eDatetime && t.create_time >= sDatetime));
                    }
                    break;
            }

            return new ObjectResult(res);
        }

        /// <summary>
        /// 人员用刀分析
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetToolUseCount([FromBody]RequestGetToolUseCount req)
        {
            var res = new List<ResponseGetToolUseCount>();
            var users = new List<siger_project_user>();
            if (string.IsNullOrEmpty(req.name))
            {
                users = _projectUserRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
            }
            else
            {
                users = _projectUserRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid && t.name.Contains(req.name)).ToList();
            }

            var count = users.Count;
            if (req.toexcel.ToInt() == 0)
            {
                users = users.Skip((req.page - 1) * req.pagesize).Take(req.pagesize).ToList();
            }

            if (!users.Any())
            {
                return new PagedObjectResult(res, count, req.page, req.pagesize);
            }

            var stime = req.starttime.ToDateTime();
            var etime = req.endtime.ToDateTime();
            var sUnix = UnixTimeHelper.ConvertDataTimeLong(stime);
            var eUnix = UnixTimeHelper.ConvertDataTimeLong(etime);
            var userIds = users.Select(t => t.mid).ToList();
            var cabinets = _cabinetReceiveRepository.GetCabinetReceiveDetailData(stime, etime, userIds, ProjectId).ToList();
            var recieves = _replaceReturnRepository.GetList(t =>
                t.operate_type == (int)ReplaceReturnTypeStatus.Recieve && t.status == (int)StorageCategory.Use &&
                t.project_id == ProjectId && userIds.Contains(t.operate_mid)
                && t.create_time <= eUnix && t.create_time >= sUnix).ToList();
            var installs = _installRepository.GetList(t =>
                t.project_id == ProjectId && t.status == (int)RowState.Valid &&
                t.install_category == InstallCategory.Install && userIds.Contains(t.install_userid) &&
                t.create_time <= etime && t.create_time >= stime).ToList();
            var material_ids=installs.Select(s => s.material_id);
            var tools = _toolRepository.GetList(f => material_ids.Contains(f.material_id) && f.category == TlmSettingCategory.Cutter).Select(s=>s.material_id).ToList();
            foreach (var user in users)
            {
                var cabinet = cabinets.Where(t => t.Uid == user.mid).ToList();
                var recieve = recieves.Where(t => t.operate_mid == user.mid).ToList();
                var install = installs.Where(t => t.install_userid == user.mid && tools.Contains(t.material_id)).ToList();
                var cabinetNumber = cabinet.Sum(t => t.quantity);
                var collarNumber = cabinetNumber + recieve.Sum(t => t.quantity);



                res.Add(new ResponseGetToolUseCount
                {
                    cabinet_number = cabinetNumber,
                    collar_number = collarNumber,
                    name = user.name,
                    install_number = install.Count,
                    work_code = user.work_code,
                    proportion = collarNumber > 0 ? Math.Round(install.Count / (double)collarNumber * 100, 2) : 0
                });
            }

            if (req.toexcel.ToInt() == 0)
            {
                return new PagedObjectResult(res, count, req.page, req.pagesize);
            }

            return ExportTools(res);
        }

        private IActionResult ExportTools(IEnumerable<ResponseGetToolUseCount> responses)
        {
            if (!responses.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var temporaryFileName = $"ToolUseCount{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusExcelHelper<ToolUseCountTemplate>();
            try
            {
                var list = new List<ToolUseCountTemplate>();
                var index = 1;
                foreach (var tool in responses)
                {
                    var entity = new ToolUseCountTemplate
                    {
                        No = index,
                        Name = tool.name,
                        CabinetNumber = tool.cabinet_number,
                        CollarNumber = tool.collar_number,
                        InstallNumber = tool.install_number,
                        WorkCode = tool.work_code,
                        Proportion = tool.proportion + "%"
                    };
                    list.Add(entity);
                    index++;
                }

                helper.GenerateExcel(list, fileName);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ExportToolUseCount failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }
        }
    }
}