using Google.Protobuf;
using LinqToDB;
using LinqToDB.SqlQuery;
using log4net;
using log4net.Util;
using MasaBlazorApp3.DataAccess.Dao;
using MasaBlazorApp3.Pages;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Config;
using MasaBlazorApp3.Pojo.Vo;
using MasaBlazorApp3.Port;
using MasaBlazorApp3.Util;
using Microsoft.Extensions.Options;
using Mysqlx.Crud;
using Radzen;
using Radzen.Blazor.Rendering;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using static LinqToDB.Common.Configuration;
using static LinqToDB.Reflection.Methods.LinqToDB.Insert;

namespace MasaBlazorApp3.DataAccess.Impl
{
    public class OrderInfoDao : IOrderInfoDao
    {

        private readonly SettingConfig _setting;
        private AppDataConnection _connection;
        private GlobalStateService _globalStateService;
        private readonly ILog logger = LogManager.GetLogger(typeof(OrderInfoDao));
        private readonly PortUtil _portUtil;
        NotificationService _message;
        public OrderInfoDao(AppDataConnection connection, IOptions<SettingConfig> setting, GlobalStateService globalStateService, PortUtil portUtil, NotificationService message)
        {
            _connection = connection;
            _setting = setting.Value;
            _globalStateService = globalStateService;
            _portUtil = portUtil;
            _message = message;
        }

        public async Task<PageData<OrderInfo>> GetAllOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip)
        {

            //var query = _connection.OrderInfo.AsQueryable();

            //query.InnerJoin<OrderDetail>((oi, od) => oi.OrderNo == od.OrderNo);

            var query2 = from od in _connection.OrderDetail
                         from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.machineId).InnerJoin(c => c.DrugId == od.DrugId)
                         group od by od.OrderNo into temp
                         select new { temp.Key };
            var query = from oi in _connection.OrderInfo
                        from od in query2.InnerJoin(od => od.Key == oi.OrderNo)
                        select oi;

            if (!String.IsNullOrEmpty(OrderrNo))
            {
                query = query.Where(oi => oi.OrderNo.Equals(OrderrNo));
            }
            if (OrderDate != null && OrderDate != DateTime.MinValue)
            {
                query = query.Where(oi => oi.ChargeDate.Date.Equals(OrderDate.Date));
            }

            query = query.Where(oi => oi.Status == 0);
            query = query.Where(oi => oi.HisDispFlag == 0);
            query = query.Where(oi => oi.CancelFlag == 0);


            int pagedData = await query.CountAsync();

            List<OrderInfo> list = await query
                //.LoadWith(oi => oi.Detail)
                //.LoadWith(oi => oi.Detail.Drug)
                .OrderBy((oi) => oi.RecvDate)
                .ThenBy((oi => oi.OrderNo))
                .Skip((int)skip)
                .Take((int)take)
                .ToListAsync();


            return new PageData<OrderInfo>()
            {
                TotalDesserts = pagedData,
                Desserts = list
            };
        }
        public async Task<PageData<OrderInfo>> GetAllOrderInfoForImport(string name, string OrderrNo, DateTime OrderDate, BoxModel boxModel, int? take, int? skip)
        {

            //var query = _connection.OrderInfo.AsQueryable();

            //query.InnerJoin<OrderDetail>((oi, od) => oi.OrderNo == od.OrderNo);

            var query2 = from od in _connection.OrderDetail
                         from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.boxMachineId && c.DrawerNo != boxModel.BoxName && c.ColNo != boxModel.BoxNo).InnerJoin(c => c.DrugId == od.DrugId)
                         group od by od.OrderNo into temp
                         select new { temp.Key };
            var query = from oi in _connection.OrderInfo
                        from od in query2.InnerJoin(od => od.Key == oi.OrderNo)
                        select oi;
            if (!string.IsNullOrEmpty(name))
            {
                query = query.Where(oi => oi.PatientName.Equals(name));
            }
            if (!String.IsNullOrEmpty(OrderrNo))
            {
                query = query.Where(oi => oi.OrderNo.Equals(OrderrNo));
            }
            if (OrderDate != null && OrderDate != DateTime.MinValue)
            {
                query = query.Where(oi => oi.ChargeDate.Date.Equals(OrderDate.Date));
            }

            query = query.Where(oi => oi.Status == 0);
            query = query.Where(oi => oi.HisDispFlag == 0);
            query = query.Where(oi => oi.CancelFlag == 0);


            int pagedData = await query.CountAsync();

            List<OrderInfo> list = await query
                .LoadWith(oi => oi.DetailInfo)
                //.LoadWith(oi => oi.DetailInfo.Drug)
                .OrderBy((oi) => oi.RecvDate)
                .ThenBy((oi => oi.OrderNo))
                .Skip((int)skip)
                .Take((int)take)
                .ToListAsync();
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].DetailInfo != null && list[i].DetailInfo.Id > 0)
                {
                    list[i].DetailInfo.Drug = await _connection.DrugInfo.AsQueryable().Where(d => d.DrugId == list[i].DetailInfo.DrugId).FirstOrDefaultAsync();
                    list[i].SelectedOrderList = new List<OrderInfo>();
                    list[i].SelectedOrderList.Add(list[i]);
                }
            }

            return new PageData<OrderInfo>()
            {
                TotalDesserts = pagedData,
                Desserts = list
            };
        }

        public async Task<List<OrderDetail>> getDetailByOrderNo(string OrderrNo)
        {
            var query2 = from cl in _connection.ChannelStock
                         where cl.MachineId == _setting.machineId
                         group cl by cl.DrugId into temp
                         select new { temp.Key };
            ;


            var query = from od in _connection.OrderDetail.Where(od => od.OrderNo == OrderrNo)
                        from cl in query2.InnerJoin(c => c.Key == od.DrugId)
                        orderby od.DrugId
                        select od;

            query = query.LoadWith(od => od.Drug);

            return await query.ToListAsync();
        }

        public async Task<List<ChannelStock>> GetChannelStockByDrugId(string DrugId, String ManuNo, int quantity = 0)
        {
            var query = _connection.ChannelStock.AsQueryable();


            query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1)
               
                .Where(cs => cs.DrugId.Equals(DrugId));

            if (quantity > 0)
            {
                if (!String.IsNullOrEmpty(ManuNo))
                {
                    query = query.Where(cs => cs.ManuNo.Equals(ManuNo));
                }
                query = query.Where(cs => cs.Quantity > 0);
            }
            else
            {
                if (!String.IsNullOrEmpty(ManuNo))
                {
                    query = query.Where(cs => cs.ManuNo.Equals(ManuNo) || cs.Quantity == 0);
                }
            }


            return await query.OrderBy((cs) => cs.EffDate)
                        .ThenBy((cs) => cs.DrawerNo)
                        .ThenBy((cs) => cs.ColNo)
                        .ToListAsync();
        }

        public async Task<List<OrderTakeVo>> getTakeInfoByOrderNo(string OrderrNo)
        {
            List<OrderTakeVo> tempData = new();
            List<OrderTakeVo> tempData2 = new();
            List<OrderDetail> details = await this.getDetailByOrderNo(OrderrNo);
            var flag = true;
            for (var i = 0; i < details.Count; i++)
            {
                //List<IDictionary<string, object>> tempData = new();
                OrderDetail detail = details[i];
                // 当前detail取药数量
                var Quantity = detail.Quantity;
                List<ChannelStock> stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.SetManuNo, Quantity);

                // 当前药品的库存总量
                var total = stockList.Sum(current => current.Quantity);

                tempData2.Add(new OrderTakeVo()
                {
                    Drug = detail.Drug,
                    OrderDetail = detail,
                    StockQuantity = total,
                    Quantity = Quantity
                });

                if (flag)
                {
                    // 盘点库存是否足够
                    if (total > Quantity)
                    {

                        for (var j = 0; Quantity > 0; j++)
                        {
                            ChannelStock stock = stockList[j];
                            if (Quantity > stock.Quantity)
                            {
                                // 取药数量大于库存
                                tempData.Add(new OrderTakeVo()
                                {
                                    Drug = detail.Drug,
                                    OrderDetail = detail,
                                    ChannelStock = stock,
                                    StockQuantity = total,
                                    Quantity = stock.Quantity,
                                });
                                Quantity -= stock.Quantity;
                            }
                            else
                            {
                                //取药数量小于库存
                                tempData.Add(new OrderTakeVo()
                                {
                                    Drug = detail.Drug,
                                    OrderDetail = detail,
                                    ChannelStock = stock,
                                    StockQuantity = total,
                                    Quantity = Quantity,
                                });
                                Quantity = 0;
                            }
                        }
                    }
                    else
                    {
                        // 库存不足
                        flag = false;
                    }
                }

            }
            if (flag)
            {
                return tempData;
            }
            else
            {
                return tempData2;
            }
        }

        public async Task<bool> OrderTakeFinish(List<OrderTakeVo> datas)
        {

            try
            {
                _connection.BeginTransaction();
                var flag = true;
                // 更新处方状态
                int r1 = _connection.OrderInfo.Where(oi => oi.OrderNo == datas.First().OrderDetail.OrderNo)
                        .Set(oi => oi.Status, 1)
                        .Update();
                if (!(r1 > 0))
                {
                    flag = false;
                    logger.Error("处方取药完成更新处方状态失败");
                    _connection.RollbackTransaction();
                    return flag;
                }
                for (var i = 0; i < datas.Count; i++)
                {
                    var orderTakeVo = datas[i];
                    var EffDate = orderTakeVo.ChannelStock.EffDate;
                    if (!DateTime.TryParse(orderTakeVo.ChannelStock.EffDate, out DateTime dEffDate))
                    {
                        //效期转换出错
                        if (orderTakeVo.ChannelStock.EffDate != null)
                        {
                            string[] idate = orderTakeVo.ChannelStock.EffDate.Split('/');
                            foreach (string iS in idate)
                            {
                                if (!string.IsNullOrEmpty(iS.Trim()))
                                {
                                    switch (iS.Trim().Length)
                                    {
                                        case 4:
                                            EffDate = iS.Trim();
                                            break;
                                        case 2:
                                            EffDate += "-" + iS.Trim();
                                            break;
                                        case 1:
                                            EffDate += "-0" + iS.Trim();
                                            break;
                                    }
                                }
                            }


                        }
                    }
                    else
                    {
                        EffDate = dEffDate.ToString("yyyy-MM-dd");
                    }
                    // 出库记录
                    int mid = _connection.InsertWithInt32Identity(new MachineRecord()
                    {
                        MachineId = _setting.machineId,
                        DrawerNo = orderTakeVo.ChannelStock.DrawerNo,
                        ColNo = orderTakeVo.ChannelStock.ColNo,
                        DrugId = orderTakeVo.ChannelStock.DrugId,
                        ManuNo = orderTakeVo.ChannelStock.ManuNo,
                        EffDate = !String.IsNullOrEmpty(EffDate) ? DateTime.ParseExact(EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                        OperationTime = DateTime.Now,
                        Type = 2,
                        Quantity = orderTakeVo.GetQuantity,
                        Operator = _globalStateService.Operator.Id,
                        Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
                        InvoiceId = orderTakeVo.OrderDetail.Id.ToString(),
                    });
                    // 更新库存
                    int r = _connection.ChannelStock.Where(cs => cs.Id == orderTakeVo.ChannelStock.Id)
                        .Set(cs => cs.Quantity, orderTakeVo.ChannelStock.Quantity - orderTakeVo.GetQuantity)
                        .Update();
                    // 获取更新完库存之后的药品库存
                    List<ChannelStock> list = await _connection.ChannelStock.AsQueryable()
                         .InnerJoin(
                             _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1),
                             (cs, cl) => cs.ListId == cl.Id,
                             (cs, cl) => cs
                         )
                         .Where(cs => cs.DrugId.Equals(orderTakeVo.ChannelStock.DrugId))
                         .ToListAsync();
                    // 保存账册
                    int acid = _connection.InsertWithInt32Identity(new AccountBook()
                    {
                        MachineId = _setting.machineId,
                        DrugId = orderTakeVo.ChannelStock.DrugId,
                        ManuNo = orderTakeVo.ChannelStock.ManuNo,
                        EffDate = !String.IsNullOrEmpty(EffDate) ? DateTime.ParseExact(EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                        OperationTime = DateTime.Now,
                        Type = 2,
                        OutQuantity = orderTakeVo.GetQuantity,
                        AddQuantity = 0,
                        Operator = _globalStateService.Operator.Id,
                        Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
                        ManuStock = list.Where(it => it.ManuNo == orderTakeVo.ChannelStock.ManuNo).Sum(it => it.Quantity),
                        TotalStock = list.Sum(it => it.Quantity),
                        InvoiceId = orderTakeVo.OrderDetail.Id.ToString()
                    });
                    if (mid > 0 && r > 0 && acid > 0)
                    {
                        if (orderTakeVo.ChannelStock.BoardType.ToString().Contains("5"))
                        {
                            await _portUtil.WriteQuantityMethod(orderTakeVo.ChannelStock.Quantity - orderTakeVo.GetQuantity, orderTakeVo.ChannelStock.DrawerNo, orderTakeVo.ChannelStock.ColNo);
                        }

                    }
                    else
                    {
                        flag = false;
                        break;
                    }
                }
                if (flag)
                {
                    _connection.CommitTransaction();
                }
                else
                {
                    _connection.RollbackTransaction();
                }
                return flag;

            }
            catch (Exception ex)
            {
                logger.Error("处方取药完成保存数据库失败，错误：" + ex.Message);
                _connection.RollbackTransaction();
                return false;
            }
        }

        public async Task<PageData<OrderInfo>> GetAllCanReturnOrderInfo(string OrderrNo, DateTime OrderDate, int? take, int? skip)
        {
            var query2 = from od in _connection.OrderDetail
                         from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.machineId).InnerJoin(c => c.DrugId == od.DrugId)
                         group od by od.OrderNo into temp
                         select new { temp.Key };
            var query = from oi in _connection.OrderInfo
                        from od in query2.InnerJoin(od => od.Key == oi.OrderNo)
                        select oi;

            if (!String.IsNullOrEmpty(OrderrNo))
            {
                query = query.Where(oi => oi.OrderNo.Equals(OrderrNo));
            }
            if (OrderDate != null && OrderDate != DateTime.MinValue)
            {
                query = query.Where(oi => oi.ChargeDate.Date.Equals(OrderDate.Date));
            }

            query = query.Where(oi => oi.Status == 1);
            query = query.Where(oi => oi.CancelFlag == 1);


            int pagedData = await query.CountAsync();

            List<OrderInfo> list = await query
                .OrderBy((oi) => oi.RecvDate)
                .ThenBy((oi => oi.OrderNo))
                .Skip((int)skip)
                .Take((int)take)
                .ToListAsync();


            return new PageData<OrderInfo>()
            {
                TotalDesserts = pagedData,
                Desserts = list
            };
        }

        public async Task<List<MachineRecord>> GetMachineRecordByOrderNo(string OrderrNo)
        {
            var query = _connection.MachineRecord.AsQueryable();
            query = query.InnerJoin(
                    _connection.OrderDetail.Where(od => od.OrderNo.Equals(OrderrNo)),
                    (mr, od) => mr.InvoiceId.Equals(od.Id),
                    (mr, od) => mr
                    )
                    .Where(md => md.Type == 2)
                    .LoadWith(md => md.Drug)
                ;
            return await query.ToListAsync();
        }

        public async Task<List<OperationVo<MachineRecord>>> getReturnInfoByOrderNo(string OrderrNo)
        {
            List<OperationVo<MachineRecord>> tempData = new();
            List<MachineRecord> details = await this.GetMachineRecordByOrderNo(OrderrNo);
            for (var i = 0; i < details.Count; i++)
            {
                //List<IDictionary<string, object>> tempData = new();
                MachineRecord detail = details[i];
                List<ChannelStock> stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.ManuNo);


                // 当前药品的库存总量
                var total = stockList.Sum(current => current.Quantity);
                // 当前detail出库数量
                var Quantity = detail.Quantity;

                stockList.First().AddQuantity = Quantity;

                tempData.Add(new OperationVo<MachineRecord>()
                {
                    Drug = detail.Drug,
                    data = detail,
                    StockQuantity = total,
                    Quantity = Quantity,
                    ChannelStocks = stockList,
                });

            }
            return tempData;
        }

        public async Task<DrugManuNo> GetDrugManuNo(string drugId, string manuNo)
        {
            var query = _connection.DrugManuNo.AsQueryable();

            return await query.Where(m => m.DrugId.Equals(drugId))
                .Where(m => m.ManuNo.Equals(manuNo))
                .FirstAsync();
        }

        public async Task<bool> OrderReturnFinish(List<OperationVo<MachineRecord>> datas, string OrderNo)
        {
            try
            {
                _connection.BeginTransaction();
                var flag = true;
                // 更新处方状态
                int r1 = _connection.OrderInfo.Where(oi => oi.OrderNo == OrderNo)
                        .Set(oi => oi.Status, 0)
                        .Update();
                if (!(r1 > 0))
                {
                    flag = false;
                    logger.Error("处方取药完成更新处方状态失败");
                    _connection.RollbackTransaction();
                    return flag;
                }
                for (var i = 0; i < datas.Count; i++)
                {
                    var operationVo = datas[i];

                    List<ChannelStock> stocks = operationVo.ChannelStocks.Where(cs => cs.ReturnQuantity > 0).ToList();

                    // 更新取出记录状态
                    var r2 = _connection.MachineRecord.Where(cs => cs.Id == operationVo.data.Id)
                    .Set(cs => cs.Status, 2)
                    .Set(cs => cs.ReturnQuantity1, operationVo.data.Quantity).Update();

                    if (r2 > 0)
                    {

                    }
                    else
                    {
                        flag = false;
                        break;
                    }

                    for (var j = 0; j < stocks.Count; j++)
                    {
                        var channelStock = stocks[j];

                        // 更新库存
                        var q = _connection.ChannelStock.Where(cs => cs.Id == channelStock.Id)
                        .Set(cs => cs.Quantity, channelStock.Quantity + channelStock.ReturnQuantity);
                        if (String.IsNullOrEmpty(channelStock.ManuNo) || (channelStock.Quantity == 0 && !channelStock.ManuNo.Equals(operationVo.data.ManuNo)))
                        {
                            DrugManuNo drugManuNo = await GetDrugManuNo(channelStock.DrugId, operationVo.data.ManuNo);

                            channelStock.Dmnguid = drugManuNo.Id;
                            channelStock.ManuNo = drugManuNo.ManuNo;
                            channelStock.EffDate = drugManuNo.EffDate.ToString();

                            q = q.Set(cs => cs.Dmnguid, drugManuNo.Id)
                                .Set(cs => cs.ManuNo, drugManuNo.ManuNo)
                                .Set(cs => cs.EffDate, drugManuNo.EffDate.ToString());
                        }
                        int r = q.Update();
                        // 退回记录
                        int mid = _connection.InsertWithInt32Identity(new MachineRecord()
                        {
                            MachineId = _setting.machineId,
                            DrawerNo = channelStock.DrawerNo,
                            ColNo = channelStock.ColNo,
                            DrugId = channelStock.DrugId,
                            ManuNo = channelStock.ManuNo,
                            EffDate = !String.IsNullOrEmpty(channelStock.EffDate) ? DateTime.ParseExact(channelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                            OperationTime = DateTime.Now,
                            Type = 31,
                            Quantity = channelStock.ReturnQuantity,
                            Operator = _globalStateService.Operator.Id,
                            Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
                            InvoiceId = operationVo.data.InvoiceId.ToString(),
                            GetId = operationVo.data.Id
                        });

                        // 获取更新完库存之后的药品库存
                        List<ChannelStock> list = await _connection.ChannelStock.AsQueryable()
                             .InnerJoin(
                                 _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.machineId)).Where(cl => cl.DrawerType == 1),
                                 (cs, cl) => cs.ListId == cl.Id,
                                 (cs, cl) => cs
                             )
                             .Where(cs => cs.DrugId.Equals(channelStock.DrugId))
                             .ToListAsync();
                        // 保存账册
                        int acid = _connection.InsertWithInt32Identity(new AccountBook()
                        {
                            MachineId = _setting.machineId,
                            DrugId = channelStock.DrugId,
                            ManuNo = channelStock.ManuNo,
                            EffDate = !String.IsNullOrEmpty(channelStock.EffDate) ? DateTime.ParseExact(channelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                            OperationTime = DateTime.Now,
                            Type = 2,
                            OutQuantity = channelStock.ReturnQuantity,
                            AddQuantity = 0,
                            Operator = _globalStateService.Operator.Id,
                            Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id,
                            ManuStock = list.Where(it => it.ManuNo == channelStock.ManuNo).Sum(it => it.Quantity),
                            TotalStock = list.Sum(it => it.Quantity),
                            InvoiceId = operationVo.data.InvoiceId
                        });
                        if (mid > 0 && r > 0 && acid > 0)
                        {
                            if (channelStock.BoardType.ToString().Contains("5"))
                            {
                                await _portUtil.WriteQuantityMethod(channelStock.Quantity - channelStock.ReturnQuantity, channelStock.DrawerNo, channelStock.ColNo);
                            }
                        }
                        else
                        {
                            flag = false;
                            break;
                        }

                    }


                }
                if (flag)
                {
                    _connection.CommitTransaction();
                }
                else
                {
                    _connection.RollbackTransaction();
                }
                return flag;

            }
            catch (Exception ex)
            {
                logger.Error("处方取药完成保存数据库失败，错误：" + ex.Message);
                _connection.RollbackTransaction();
                return false;
            }
        }


        /// <summary>
        /// 获取药盒中的用药信息
        /// </summary>
        /// <param name="OrderrNo"></param>
        /// <param name="OrderDate"></param>
        /// <param name="take"></param>
        /// <param name="skip"></param>
        /// <returns></returns>
        public async Task<PageData<OrderInfo>> GetAllOrderInfoByBox(int box, string OrderrNo, DateTime OrderDate, int? take, int? skip)
        {
            var query2 = from od in _connection.OrderDetail
                         from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.boxMachineId).InnerJoin(c => c.DrugId == od.DrugId)
                         group od by od.OrderNo into temp
                         select new { temp.Key };
            var query = from oi in _connection.OrderInfo
                        from od in query2.InnerJoin(od => od.Key == oi.OrderNo)
                        where oi.Pharmacy == _setting.storage
                        select oi;
            if (!String.IsNullOrEmpty(OrderrNo))
            {
                query = query.Where(oi => oi.OrderNo.Equals(OrderrNo));
            }
            if (OrderDate != null && OrderDate != DateTime.MinValue)
            {
                query = query.Where(oi => oi.ChargeDate.Date.Equals(OrderDate.Date));
            }

            query = query.Where(oi => oi.Status == 0);
            query = query.Where(oi => oi.HisDispFlag == 0);
            query = query.Where(oi => oi.CancelFlag == 0);
            //query = query.Where(oi => oi.DoctorCode == box);

            int pagedData = await query.CountAsync();

            List<OrderInfo> list = await query
                .LoadWith(oi => oi.DetailInfo)
                .OrderBy((oi) => oi.RecvDate)
                .ThenBy((oi => oi.OrderNo))
                .Skip((int)skip)
                .Take((int)take)
                .ToListAsync();
            if (list != null && list.Count > 0)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    //for (int j = 0; j < list[i].DetailList.Count; j++)
                    //{
                    if (list[i].DetailInfo != null && list[i].DetailInfo.Id > 0)
                    {
                        list[i].DetailInfo.Drug = await _connection.DrugInfo.AsQueryable().Where(d => d.DrugId == list[i].DetailInfo.DrugId).FirstOrDefaultAsync();
                        if (list[i].DetailInfo.Drug != null)
                        {
                            list[i].DetailInfo.Drug.Manus = await _connection.DrugManuNo.AsQueryable().Where(m => m.DrugId == list[i].DetailInfo.DrugId).ToListAsync();
                        }
                    }
                    //}
                }
            }


            //var query2 = from od in _connection.OrderDetail
            //             from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.machineId).InnerJoin(c => c.DrugId == od.DrugId)
            //             group od by od.OrderNo into temp
            //             select new { temp.Key };
            //var query = from oi in _connection.OrderInfo
            //            from od in query2.InnerJoin(od => od.Key == oi.OrderNo)
            //            select oi;

            //if (!String.IsNullOrEmpty(OrderrNo))
            //{
            //    query = query.Where(oi => oi.OrderNo.Equals(OrderrNo));
            //}
            //if (OrderDate != null && OrderDate != DateTime.MinValue)
            //{
            //    query = query.Where(oi => oi.OrderDate.Date.Equals(OrderDate.Date));
            //}

            //query = query.Where(oi => oi.Status == 0);
            //query = query.Where(oi => oi.HisDispFlag == 0);
            //query = query.Where(oi => oi.CancelFlag == 0);
            ////query = query.Where(oi => oi.DoctorCode == box);

            //int pagedData = await query.CountAsync();

            //List<OrderInfo> list = await query
            //    .LoadWith(oi => oi.Detail)
            //    .LoadWith(oi => oi.Detail.Drug)
            //    .OrderBy((oi) => oi.RecvDate)
            //    .ThenBy((oi => oi.OrderNo))
            //    .Skip((int)skip)
            //    .Take((int)take)
            //    .ToListAsync();
            //if (list != null && list.Count > 0)
            //{
            //    for (int i = 0; i < list.Count; i++)
            //    {
            //        //list[i].Detail = await _connection.OrderDetail.AsQueryable()
            //        //    .Where(od => od.OrderNo == list[i].OrderNo)
            //        //    .LoadWith(od => od.Drug)
            //        //    .ToListAsync();
            //    }
            //}

            return new PageData<OrderInfo>()
            {
                TotalDesserts = pagedData,
                Desserts = list
            };
        }
        /// <summary>
        /// 获取待处理处方中的麻醉师
        /// </summary>
        /// <param name="OrderrNo"></param>
        /// <param name="OrderDate"></param>
        /// <param name="take"></param>
        /// <param name="skip"></param>
        /// <returns></returns>
        public async Task<PageData<OrderInfo>> GetAllOrderInfo(string Name, string BoxNum, string PatientName, string OrderrNo, DateTime? OrderDate, int? take, int? skip)
        {
            logger.Info($"GetAllOrderInfo开始:{DateTime.Now}");
            var query2 = from od in _connection.OrderDetail
                         from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.boxMachineId).InnerJoin(c => c.DrugId == od.DrugId)
                         group od by od.OrderNo into temp
                         select new { temp.Key };
            var query = from oi in _connection.OrderInfo
                        from od in query2.InnerJoin(od => od.Key == oi.OrderNo)
                        where oi.Pharmacy == _setting.storage
                        select oi;
            if (!string.IsNullOrEmpty(Name))
            {
                query = query.Where(oi => oi.anaesthetistName == Name);
            }
            if (!string.IsNullOrEmpty(BoxNum) && !BoxNum.Contains("99") && !BoxNum.Contains("111"))
            {
                query = query.Where(oi => oi.RoomName == BoxNum);
            }
            if (!string.IsNullOrEmpty(PatientName))
            {
                query = query.Where(oi => oi.PatientName.Contains(PatientName));
            }
            if (!String.IsNullOrEmpty(OrderrNo))
            {
                query = query.Where(oi => oi.OrderNo.Equals(OrderrNo));
            }
            if (OrderDate != null && OrderDate != DateTime.MinValue)
            {
                query = query.Where(oi => oi.ChargeDate.Date.Equals(((DateTime)OrderDate).Date));
            }
            query = query.Where(oi => oi.Status == 0);
            query = query.Where(oi => oi.HisDispFlag == 0);
            query = query.Where(oi => oi.CancelFlag == 0);

            int pagedData = await query.CountAsync();

            List<OrderInfo> list = await query
                .LoadWith(oi => oi.DetailInfo)
                .OrderBy((oi) => oi.DetailInfo.DrugId)
                .ThenBy((oi => oi.OrderNo))
                //.Skip((int)skip)
                //.Take((int)take)
                .ToListAsync();
            if (list != null && list.Count > 0)
            {

                var group = list.GroupBy(it => it.DetailInfo.DrugId)
                    .Select(it => new
                    {
                        drugId = it.Key,
                        totalQuantity = it.Sum(g => g.DetailInfo.Quantity)
                    });
                foreach (var item in group)
                {
                    OrderInfo oiGroup = list.Where(it => it.DetailInfo.DrugId == item.drugId).FirstOrDefault();
                    list.Where(it => it.OrderId == oiGroup.OrderId).ToList().ForEach(it => it.DetailInfo.TotalQuantity = item.totalQuantity);
                }
                for (int i = 0; i < list.Count; i++)
                {
                    if (list[i].DetailInfo != null && list[i].DetailInfo.Id > 0)
                    {
                        list[i].DetailInfo.Drug = await _connection.DrugInfo.AsQueryable().Where(d => d.DrugId == list[i].DetailInfo.DrugId).FirstOrDefaultAsync();
                        if (list[i].DetailInfo.Drug != null)
                        {
                            list[i].DetailInfo.Drug.Manus = await _connection.DrugManuNo.AsQueryable().Where(m => m.DrugId == list[i].DetailInfo.DrugId).ToListAsync();
                        }
                    }
                }
            }
            logger.Info($"GetAllOrderInfo结束:{DateTime.Now}");
            return new PageData<OrderInfo>()
            {
                TotalDesserts = pagedData,
                Desserts = list
            };

        }
        /// <summary>
        /// 获取待处理处方中的麻醉师
        /// </summary>
        /// <param name="OrderrNo"></param>
        /// <param name="OrderDate"></param>
        /// <param name="take"></param>
        /// <param name="skip"></param>
        /// <returns></returns>
        public async Task<PageData<ChannelStock>> GetAllOrderInfoDrugByBox(BoxModel boxNum, string roomName, DateTime? OrderDate)
        {
            List<ChannelStock> csList = await _connection.ChannelStock
                .Where(cs => cs.MachineId == _setting.boxMachineId && cs.DrawerNo == boxNum.BoxName && cs.ColNo == boxNum.BoxNo && cs.Quantity > 0)
                .LoadWith(cs => cs.Drug)
                .ToListAsync();
            if (csList != null && csList.Count > 0)
            {
                for (int i = 0; i < csList.Count; i++)
                {
                    List<OrderInfo> oiList = await _connection.OrderInfo.Where(oi => oi.RoomName == roomName && oi.Status == 0 && oi.HisDispFlag == 0 && oi.CancelFlag == 0 && oi.ChargeDate.Date.Equals(((DateTime)OrderDate).Date))
                        .LoadWith(oi => oi.DetailInfo).Where(oi => oi.DetailInfo.DrugId == csList[i].DrugId && oi.DetailInfo.SetManuNo == csList[i].ManuNo)
                        .ToListAsync();
                    csList[i].OrderList = oiList;
                    csList[i].SelectedOrderList = oiList;
                    csList[i].UseQuantity = oiList.Sum(oi => oi.DetailInfo.Quantity);
                    csList[i].OrderQuantity = oiList.Count;
                    csList[i].EmptyQuantity = oiList.Sum(oi => oi.DetailInfo.Quantity);
                    csList[i].TotalQuantity = csList.Where(c => c.DrugId == csList[i].DrugId).Sum(c => c.Quantity);
                    if ((String.IsNullOrEmpty(csList[i].ListId) && csList[i].Quantity > csList[i].UseQuantity) || (csList[i].Quantity > csList[i].BaseQuantity))
                    {
                        //药品未在套餐中绑定需要把药还到对应抽屉
                        List<ChannelStock> allDrugStock = await GetStockByDRrug(csList[i].DrugId, csList[i].ManuNo, 1);// await _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType == 1 && cs.DrugId == csList[i].DrugId && cs.ManuNo == csList[i].ManuNo).OrderBy(cs => cs.Quantity).ToListAsync();
                        if (allDrugStock != null && allDrugStock.Count > 0)
                        {
                            csList[i].DrawerChanneStockList = new();
                            int iReturnQuantity = csList[i].Quantity - csList[i].UseQuantity - csList[i].BaseQuantity;
                            for (int j = 0; j < allDrugStock.Count; j++)
                            {
                                if (allDrugStock[j].BoardType.ToString().Contains("2") && allDrugStock[j].Quantity >= 25)
                                    continue;
                                if (allDrugStock[j].BoardType.ToString().Contains("2") && allDrugStock[j].Quantity + csList[i].Quantity - csList[i].UseQuantity > 25)
                                {
                                    //if (iReturnQuantity <= allDrugStock.Sum(it => it.Quantity))
                                    if (allDrugStock[j].Quantity <= 25)
                                    {
                                        //有空位置可以放
                                        int canStockQuantity = 25 - allDrugStock[j].Quantity;
                                        if (canStockQuantity > iReturnQuantity)
                                        {
                                            allDrugStock[j].ReturnQuantity = iReturnQuantity;
                                            csList[i].DrawerChanneStockList.Add(allDrugStock[j]);
                                            break;
                                        }
                                        else
                                        {
                                            allDrugStock[j].ReturnQuantity = canStockQuantity;
                                            iReturnQuantity = iReturnQuantity - allDrugStock[j].ReturnQuantity;
                                            csList[i].DrawerChanneStockList.Add(allDrugStock[j]);
                                        }
                                        //iReturnQuantity = iReturnQuantity - allDrugStock[j].ReturnQuantity;
                                        //for (int q = 0; iReturnQuantity > 0; q++)
                                        //{

                                        //    allDrugStock[j].ReturnQuantity = 25 - allDrugStock[q].Quantity;
                                        //    csList[i].DrawerChanneStockList.Add(allDrugStock[q]);
                                        //    iReturnQuantity = iReturnQuantity - allDrugStock[q].ReturnQuantity;
                                        //    if (iReturnQuantity <= 0)
                                        //        break;
                                        //}

                                    }
                                    else
                                    {
                                        //库位不足，有药品无库位可放
                                        allDrugStock[j].ReturnQuantity = iReturnQuantity;
                                        csList[i].DrawerChanneStockList.Add(allDrugStock[j]);
                                        logger.Info($"还药品【{csList[i].Drug.DrugName}】库位不足，有药品无库位可放");
                                    }
                                }
                                else
                                {
                                    allDrugStock[j].ReturnQuantity = iReturnQuantity;
                                    csList[i].DrawerChanneStockList.Add(allDrugStock[j]);
                                    break;
                                }
                            }
                        }
                    }
                }

            }
            int pagedData = csList.Count;
            return new PageData<ChannelStock>()
            {
                TotalDesserts = pagedData,
                Desserts = csList.OrderBy(cs => cs.DrugId).OrderByDescending(cs => cs.UseQuantity).ToList()
            };
        }
        //public List<string> GetAnaesthetistName()
        //{
        //    List<string> strList = new List<string>();
        //    strList = _connection.OrderInfo.Where(it=>it.state==0&&it.HisDispFlag==0&&it.CancelFlag==0).Select(it => it.anaesthetistName).Distinct().ToList();
        //    return strList;

        //}
        /// <summary>
        /// 获取所有药盒号
        /// </summary>
        /// <param name="machineId"></param>
        /// <returns></returns>
        public async Task<List<ChannelStock>> GetDrawerNum(string machineId)
        {
            List<ChannelStock> stockList = _connection.ChannelStock
                .Where(cs => cs.MachineId == machineId)
                .GroupBy(cs => new { cs.DrawerNo, cs.ColNo })
                .Select(g => new ChannelStock
                {
                    DrawerNo = g.Key.DrawerNo,
                    ColNo = g.Key.ColNo,
                })
                .ToList();
            return stockList;
        }
        /// <summary>
        /// 获取指定药盒号
        /// </summary>
        /// <param name="machineId"></param>
        /// <returns></returns>
        public async Task<List<BoxModel>> GetDrawerNumByOperationNum(string machineId, int boxColor)
        {
            List<BoxModel> boxModelList = new List<BoxModel>();
            //var query = _connection.ChannelStock
            //    .Where(cs => cs.MachineId == machineId && operationNum.Contains(cs.DrawerNo)&&cs.Quantity>0);
            //boxModelList = await _connection.ChannelStock
            //    .Where(cs => cs.MachineId == machineId && cs.Quantity > 0 && (operationNum.Contains(cs.DrawerNo)))
            //    .Select(cs => new BoxModel { BoxName = cs.DrawerNo, BoxNo = Convert.ToInt32(cs.ColNo) }).Distinct().OrderBy(cs=>new { cs.BoxName, cs.BoxNo }).ToListAsync();
            //return boxModelList;
            var query = _connection.ChannelList.Where(cs => cs.MachineId == machineId).AsQueryable();
            if (boxColor > 0)
            {
                query.Where(cs => cs.ColNo == boxColor);
            }
            List<ChannelList> csList = query.OrderBy(cs => cs.DrawerNo).ToList();
            if (csList != null && csList.Count > 0)
            {
                for (int i = 0; i < csList.Count; i++)
                {
                    boxModelList.Add(new BoxModel { BoxName = csList[i].DrawerNo, BoxNo = csList[i].ColNo });
                }
            }

            return boxModelList;
        }
        //核对处方
        public async Task<bool> CheckOrderInfo(IList<OrderInfo> selectedOrderInfos, BoxModel boxModel)
        {
            try
            {
                _connection.BeginTransaction();
                bool bFlag = true;
                logger.Info($"管理员{_globalStateService.Operator.NickName}开始确认手麻单");


                string empChannelStock = string.Empty;

                for (int i = 0; i < selectedOrderInfos.Count; i++)
                {
                    OrderInfo oi = selectedOrderInfos[i];


                    int drawerNo = Convert.ToInt32(boxModel.BoxName);
                    if (oi.DetailInfo != null && oi.DetailInfo.Id > 0)
                    {
                        //ChannelStock? cs = _connection.ChannelStock.AsQueryable()
                        //                 .Where(cs => cs.DrugId == oi.DetailList[j].DrugId
                        //                       // && cs.ManuNo == oi.DetailList[j].SetManuNo
                        //                        // && cs.EffDate == oi._OrderDetail.SetEffDate
                        //                        && cs.MachineId.Equals(_setting.boxMachineId)
                        //                        && cs.DrawerNo == drawerNo
                        //                        && cs.Quantity >= oi.DetailList[j].Quantity).FirstOrDefault();
                        List<ChannelStock> cs = _connection.ChannelStock.AsQueryable()
                                        .Where(cs => cs.DrugId == oi.DetailInfo.DrugId
                                                && cs.ManuNo == oi.DetailInfo.drugManuNo.ManuNo
                                               //&& cs.EffDate == ((DateTime)oi.DetailInfo.drugManuNo.EffDate).ToString("yyyy-MM-dd")
                                               && cs.MachineId.Equals(_setting.boxMachineId)
                                               && cs.DrawerNo == drawerNo && cs.ColNo == boxModel.BoxNo).OrderBy(cs => cs.EffDate).ToList();
                        if (cs.Count <= 0)
                        {
                            logger.Info($"处方{oi.OrderNo}中药品{oi.DetailInfo.Drug.DrugName}在{drawerNo}号药盒无库存");
                            empChannelStock += $"处方{oi.OrderNo}中药品{oi.DetailInfo.Drug.DrugName}在{drawerNo}号药盒无库存 ";
                            continue;
                        }
                        int csQuantity = cs.Sum(cs => cs.Quantity);
                        if (csQuantity < oi.DetailInfo.Quantity)
                        {
                            logger.Info($"处方{oi.OrderNo}中药品{oi.DetailInfo.Drug.DrugName}在{drawerNo}号库存不足，需要核对数{oi.DetailInfo.Quantity}，库存总数{csQuantity}");
                            empChannelStock += $"处方{oi.OrderNo}中药品{oi.DetailInfo.Drug.DrugName}在{drawerNo}号库存不足，需要核对数{oi.DetailInfo.Quantity}，库存总数{csQuantity} ";
                            continue;
                        }
                        //更新处方状态
                        if (oi.Status == 0)
                        {
                            int iUpdate = _connection.OrderInfo.Where(o => o.OrderNo == oi.OrderNo).Set(o => o.Status, 2).Update();
                            int odUpdate = _connection.OrderDetail.Where(od => od.OrderNo == oi.OrderNo).Set(od => od.SetManuNo, oi.DetailInfo.drugManuNo.ManuNo).Set(od => od.Quantity, oi.DetailInfo.Quantity).Update();
                            _connection.Insert(new OrderFinish()
                            {
                                OrderNo = oi.OrderNo,
                                PatientId = oi.PatientId,
                                Pharmacy = oi.Pharmacy,
                                State = 1,
                                //WinNo = DrawerNo + 1 + "号手术间",
                                Operator = _globalStateService.Operator.NickName,
                            });
                        }
                        int Break = 0;
                        for (int k = 0; (k < cs.Count && Break == 0); k++)
                        {
                            int oldQuantity = cs[k].Quantity;
                            int useQuantity = 0; //实际使用数量
                            if (cs[k].Quantity >= oi.DetailInfo.Quantity)
                            {
                                cs[k].Quantity = cs[k].Quantity - oi.DetailInfo.Quantity;
                                Break = 1;//药品够取跳出循环
                                useQuantity = oi.DetailInfo.Quantity;
                            }
                            else
                            {
                                oi.DetailInfo.Quantity = oi.DetailInfo.Quantity - cs[k].Quantity;
                                useQuantity = cs[k].Quantity;
                                cs[k].Quantity = 0;
                            }
                            //cs.NeedNum = cs.NeedNum > 0 ? cs.NeedNum + oi._OrderDetail.Quantity : oi._OrderDetail.Quantity;
                            logger.Info($"更新药盒{cs[k].DrawerNo}药品{cs[k].DrugId}批次{cs[k].ManuNo}库存为{oldQuantity}，处方用药数量为{oi.DetailInfo.Quantity}");
                            // 更新数据 库存信息
                            _connection.Update(cs[k]);

                            //更新ChannelList对应的总库存
                            ChannelList? channelList = _connection.ChannelList.AsQueryable().Where(cl => cl.MachineId.Equals(cs[k].MachineId) && cl.Id.Equals(cs[k].ListId) && cl.DrawerNo.Equals(cs[k].DrawerNo)).FirstOrDefault();
                            if (channelList != null)
                            {
                                channelList.TotalQuantity = channelList.TotalQuantity - useQuantity;// oi.DetailList[j].Quantity;
                                _connection.Update(channelList);
                            }
                            // 获取更新完库存后的药品库存
                            List<ChannelStock> nowChannels = _connection.ChannelStock.AsQueryable()
                                .Where(it => it.MachineId.Equals(cs[k].MachineId) || it.MachineId.Equals(_setting.machineId))
                                .Where(it => it.DrugId.Equals(cs[k].DrugId))
                                .Where(it => it.ManuNo.Equals(cs[k].ManuNo))
                                .Where(it => it.DrawerType == 1)
                                .ToList();
                            _connection.Insert(new MachineRecord()
                            {
                                MachineId = _setting.machineId,
                                DrawerNo = cs[k].DrawerNo,
                                ColNo = cs[k].ColNo,
                                DrugId = cs[k].DrugId,
                                ManuNo = cs[k].ManuNo,
                                EffDate = !String.IsNullOrEmpty(cs[k].EffDate) ? DateTime.ParseExact(cs[k].EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                                Operator = _globalStateService.Operator?.Id,
                                Reviewer = _globalStateService.Reviewer?.Id,
                                OperationTime = DateTime.Now,
                                Quantity = useQuantity,// oi.DetailList[j].Quantity,
                                Type = 2,
                                InvoiceId = oi.OrderNo
                                //, StockQuantity = nowChannels.Sum(it => it.Quantity)
                            });


                            //查询上一条账册中的空瓶数
                            AccountBookG2? accountBookEmpty = _connection.AccountBookG2.AsQueryable()
                            .Where(ab => ab.MachineId.Equals(_setting.machineId))
                            .Where(ab => ab.Type == 1 || ab.Type == 2)
                            .Where(ab => ab.DrugId == oi.DetailInfo.DrugId)
                            .Where(ab => ab.ManuNo == cs[k].ManuNo).OrderByDescending(ab => ab.Id).FirstOrDefault();
                            //保存账册
                            int iInsertResult = _connection.Insert(new AccountBookG2()
                            {
                                DrugId = oi.DetailInfo.DrugId,
                                Type = 2,
                                Department = oi.DeptName,
                                OrderNo = oi.OrderNo,
                                ManuNo = cs[k].ManuNo,
                                EffDate = cs[k].EffDate,
                                OutQuantity = useQuantity,// oi.DetailList[j].Quantity,
                                UserId1 = _globalStateService.Operator?.Id,
                                UserId2 = _globalStateService.Reviewer?.Id,
                                MachineId = _setting.machineId,
                                CreateDate = DateTime.Now.ToString("yyyy-MM-dd"),
                                CreateTime = DateTime.Now,
                                InvoiceNo = oi.OrderNo,
                                ManuStock = nowChannels.Sum(it => it.Quantity),
                                TotalStock = (accountBookEmpty != null ? (accountBookEmpty.TotalStock > 0 ? accountBookEmpty.TotalStock : 0) : 0) + oi.DetailInfo.Quantity,
                                ShoushuJian = drawerNo.ToString()
                            });
                            //修改凌晨生成的日结存与总结存数据
                            AccountBookG2? accountBookG2Day = _connection.AccountBookG2.AsQueryable()
                            .Where(ab => ab.MachineId.Equals(_setting.machineId))
                            .Where(ab => ab.Type == 3)
                            .Where(ab => ab.DrugId == oi.DetailInfo.DrugId)
                            .Where(ab => ab.ManuNo == cs[k].ManuNo)
                            .Where(ab => ab.CreateDate == DateTime.Now.ToString("yyyy-MM-dd")).FirstOrDefault();
                            if (accountBookG2Day != null)
                            {
                                accountBookG2Day.ManuStock = accountBookG2Day.ManuStock - useQuantity;// oi.DetailList[j].Quantity;
                                _connection.Update(accountBookG2Day);
                            }
                            else
                            {
                                //生成日结存时可能没有该库位的绑定信息，需要写入日结存
                                int iDayResult = _connection.Insert(new AccountBookG2()
                                {
                                    DrugId = oi.DetailInfo.DrugId,
                                    Type = 3,
                                    ManuNo = cs[k].ManuNo,
                                    EffDate = cs[k].EffDate,
                                    YQuantity = 0,
                                    ManuStock = useQuantity,// oi.DetailList[j].Quantity,
                                    TotalStock = useQuantity,// oi.DetailList[j].Quantity,
                                    UserId1 = _globalStateService.Operator?.Id,
                                    UserId2 = _globalStateService.Reviewer?.Id,
                                    MachineId = _setting.machineId,
                                    CreateDate = DateTime.Now.ToString("yyyy-MM-dd"),
                                    InvoiceNo = "日结存"
                                });
                                if (iDayResult <= 0)
                                {
                                    logger.Info($"未写入日结存数据{oi.DetailInfo.DrugId}-{cs[k].ManuNo}-{cs[k].EffDate}-{useQuantity}");
                                    empChannelStock += $"未写入日结存数据{oi.DetailInfo.DrugId}-{cs[k].ManuNo}-{cs[k].EffDate}-{useQuantity} ";
                                }
                            }
                            //修改凌晨生成的日结存与总结存数据
                            AccountBookG2? accountBookG2Total = _connection.AccountBookG2.AsQueryable()
                            .Where(ab => ab.MachineId.Equals(_setting.machineId))
                            .Where(ab => ab.Type == 4)
                            .Where(ab => ab.DrugId == oi.DetailInfo.DrugId)
                            .Where(ab => ab.CreateDate == DateTime.Now.ToString("yyyy-MM-dd")).FirstOrDefault();
                            if (accountBookG2Total != null)
                            {
                                accountBookG2Total.TotalStock = accountBookG2Total.TotalStock - useQuantity;// oi.DetailList[j].Quantity;
                                _connection.Update(accountBookG2Total);
                            }
                            else
                            {
                                //生成总结存时可能没有该库位的绑定信息，需要写入总结存
                                int iTotalResult = _connection.Insert(new AccountBookG2()
                                {
                                    DrugId = oi.DetailInfo.DrugId,
                                    Type = 4,
                                    YQuantity = 0,
                                    ManuStock = useQuantity,//oi.DetailList[j].Quantity,
                                    TotalStock = useQuantity,// oi.DetailList[j].Quantity,
                                    UserId1 = _globalStateService.Operator?.Id,
                                    UserId2 = _globalStateService.Reviewer?.Id,
                                    MachineId = _setting.machineId,
                                    CreateDate = DateTime.Now.ToString("yyyy-MM-dd"),
                                    InvoiceNo = "总结存"
                                });
                                if (iTotalResult <= 0)
                                {
                                    logger.Info($"未写入总结存数据{oi.DetailInfo.DrugId}-{useQuantity}");
                                    empChannelStock += $"未写入总结存数据{oi.DetailInfo.DrugId}-{useQuantity} ";
                                }
                            }
                        }

                    }
                }
                logger.Info($"管理员{_globalStateService.Operator.NickName}结束确认手麻单");
                if (!string.IsNullOrEmpty(empChannelStock))
                {
                    _message.Notify(
                          new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"有未核对处方：{empChannelStock}", Duration = 4000 }
                      );
                    _connection.RollbackTransaction();
                    return false;
                }
                if (bFlag)
                {
                    _connection.CommitTransaction();
                    return true;
                }
                else
                {
                    _connection.RollbackTransaction();
                    logger.Info($"管理员{_globalStateService.Operator.NickName}确认手麻单失败");
                    return false;
                }
            }
            catch (Exception ex)
            {
                _connection.RollbackTransaction();
                logger.Info($"核对处方异常{ex.Message}");
                return false;
            }
        }
        int status;
        //核对处方
        public async Task<bool> CheckOrderInfoByChannelStock(IList<ChannelStock> csList, BoxModel boxModel)
        {
            try
            {
                _connection.BeginTransaction();
                bool bFlag = true;
                logger.Info($"管理员{_globalStateService.Operator.NickName}开始核对处方");


                string empChannelStock = string.Empty;

                for (int i = 0; i < csList.Count; i++)
                {
                    ChannelStock channelStock = csList[i];
                    if (channelStock != null && channelStock.SelectedOrderList != null && channelStock.SelectedOrderList.Count > 0)
                    {
                        List<OrderInfo> oiList = channelStock.SelectedOrderList.ToList();
                        for (int j = 0; j < oiList.Count; j++)
                        {
                            //修改选中的处方状态
                            int iUpdate = _connection.OrderInfo.Where(o => o.OrderNo == oiList[j].OrderNo).Set(o => o.Status, 2).Update();
                            _connection.Insert(new OrderFinish()
                            {
                                OrderNo = oiList[j].OrderNo,
                                PatientId = oiList[j].PatientId,
                                Pharmacy = oiList[j].Pharmacy,
                                State = 1,
                                //WinNo = DrawerNo + 1 + "号手术间",
                                Operator = _globalStateService.Operator.NickName,
                            });
                            //更新库存
                            channelStock.Quantity = channelStock.Quantity - oiList[j].DetailInfo.Quantity;
                            _connection.Update(channelStock);

                            //更新ChannelList对应的总库存
                            if (!string.IsNullOrEmpty(channelStock.ListId) && channelStock.ListId != "0")
                            {
                                ChannelList? channelList = _connection.ChannelList.AsQueryable().Where(cl => cl.Id == channelStock.ListId).FirstOrDefault();
                                if (channelList != null)
                                {
                                    channelList.TotalQuantity = channelList.TotalQuantity - oiList[j].DetailInfo.Quantity;
                                    _connection.Update(channelList);
                                }
                            }
                            //记录出库记录
                            _connection.Insert(new MachineRecord()
                            {
                                MachineId = _setting.machineId,
                                DrawerNo = channelStock.DrawerNo,
                                ColNo = channelStock.ColNo,
                                DrugId = channelStock.DrugId,
                                ManuNo = channelStock.ManuNo,
                                EffDate = !String.IsNullOrEmpty(channelStock.EffDate) ? DateTime.ParseExact(channelStock.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                                Operator = _globalStateService.Operator?.Id,
                                Reviewer = _globalStateService.Reviewer?.Id,
                                OperationTime = DateTime.Now,
                                Quantity = oiList[j].DetailInfo.Quantity,
                                Type = 2,
                                InvoiceId = oiList[j].OrderNo
                            });
                            //保存账册                
                            // 获取更新完库存后的药品库存
                            List<ChannelStock> nowChannels = _connection.ChannelStock.AsQueryable()
                                .Where(it => it.MachineId.Equals(_setting.machineId) || it.MachineId.Equals(_setting.boxMachineId))
                                .Where(it => it.DrugId.Equals(oiList[j].DetailInfo.DrugId))
                                .Where(it => it.ManuNo.Equals(oiList[j].DetailInfo.SetManuNo))
                                .Where(it => it.DrawerType == 1)
                                .ToList();
                            //查询上一条账册中的空瓶数
                            AccountBookG2? accountBookEmpty = _connection.AccountBookG2.AsQueryable()
                            .Where(ab => ab.MachineId.Equals(_setting.machineId))
                            .Where(ab => ab.Type == 1 || ab.Type == 2)
                            .Where(ab => ab.DrugId == oiList[j].DetailInfo.DrugId)
                            .Where(ab => ab.ManuNo == oiList[j].DetailInfo.SetManuNo).OrderByDescending(ab => ab.Id).FirstOrDefault();
                            //保存账册
                            int iInsertResult = _connection.Insert(new AccountBookG2()
                            {
                                DrugId = oiList[j].DetailInfo.DrugId,
                                Type = 2,
                                Department = oiList[j].DeptName,
                                OrderNo = oiList[j].OrderNo,
                                ManuNo = oiList[j].DetailInfo.SetManuNo,
                                EffDate = oiList[j].DetailInfo.SetEffDate,
                                OutQuantity = oiList[j].DetailInfo.Quantity,
                                UserId1 = _globalStateService.Operator?.Id,
                                UserId2 = _globalStateService.Reviewer?.Id,
                                MachineId = _setting.machineId,
                                CreateDate = DateTime.Now.ToString("yyyy-MM-dd"),
                                CreateTime = DateTime.Now,
                                InvoiceNo = oiList[j].OrderNo,
                                ManuStock = nowChannels.Sum(it => it.Quantity),
                                TotalStock = (accountBookEmpty != null ? (accountBookEmpty.TotalStock > 0 ? accountBookEmpty.TotalStock : 0) : 0) + oiList[j].DetailInfo.Quantity,
                                ShoushuJian = oiList[j].RoomName
                            });

                            //修改日结
                            //修改凌晨生成的日结存与总结存数据
                            AccountBookG2? accountBookG2Day = _connection.AccountBookG2.AsQueryable()
                            .Where(ab => ab.MachineId.Equals(_setting.machineId))
                            .Where(ab => ab.Type == 3)
                            .Where(ab => ab.DrugId == oiList[j].DetailInfo.DrugId)
                            .Where(ab => ab.ManuNo == oiList[j].DetailInfo.SetManuNo)
                            .Where(ab => ab.CreateDate == DateTime.Now.ToString("yyyy-MM-dd")).FirstOrDefault();
                            if (accountBookG2Day != null)
                            {
                                accountBookG2Day.ManuStock = accountBookG2Day.ManuStock - oiList[j].DetailInfo.Quantity;
                                _connection.Update(accountBookG2Day);
                            }
                            else
                            {
                                //生成日结存时可能没有该库位的绑定信息，需要写入日结存
                                int iDayResult = _connection.Insert(new AccountBookG2()
                                {
                                    DrugId = oiList[j].DetailInfo.DrugId,
                                    Type = 3,
                                    ManuNo = oiList[j].DetailInfo.SetManuNo,
                                    EffDate = oiList[j].DetailInfo.SetEffDate,
                                    YQuantity = 0,
                                    ManuStock = oiList[j].DetailInfo.Quantity,
                                    TotalStock = oiList[j].DetailInfo.Quantity,
                                    UserId1 = _globalStateService.Operator?.Id,
                                    UserId2 = _globalStateService.Reviewer?.Id,
                                    MachineId = _setting.machineId,
                                    CreateDate = DateTime.Now.ToString("yyyy-MM-dd"),
                                    InvoiceNo = "日结存"
                                });
                                if (iDayResult <= 0)
                                {
                                    logger.Info($"未写入日结存数据{oiList[j].DetailInfo.DrugId}-{oiList[j].DetailInfo.SetManuNo}-{oiList[j].DetailInfo.SetEffDate}-{oiList[j].DetailInfo.Quantity}");
                                    empChannelStock += $"未写入日结存数据{oiList[j].DetailInfo.DrugId}-{oiList[j].DetailInfo.SetManuNo}-{oiList[j].DetailInfo.SetEffDate}-{oiList[j].DetailInfo.Quantity} ";
                                }
                            }
                            //总结
                            //修改凌晨生成的日结存与总结存数据
                            AccountBookG2? accountBookG2Total = _connection.AccountBookG2.AsQueryable()
                            .Where(ab => ab.MachineId.Equals(_setting.machineId))
                            .Where(ab => ab.Type == 4)
                            .Where(ab => ab.DrugId == oiList[j].DetailInfo.DrugId)
                            .Where(ab => ab.CreateDate == DateTime.Now.ToString("yyyy-MM-dd")).FirstOrDefault();
                            if (accountBookG2Total != null)
                            {
                                accountBookG2Total.TotalStock = accountBookG2Total.TotalStock - oiList[j].DetailInfo.Quantity;// oi.DetailList[j].Quantity;
                                _connection.Update(accountBookG2Total);
                            }
                            else
                            {
                                //生成总结存时可能没有该库位的绑定信息，需要写入总结存
                                int iTotalResult = _connection.Insert(new AccountBookG2()
                                {
                                    DrugId = oiList[j].DetailInfo.DrugId,
                                    Type = 4,
                                    YQuantity = 0,
                                    ManuStock = oiList[j].DetailInfo.Quantity,
                                    TotalStock = oiList[j].DetailInfo.Quantity,
                                    UserId1 = _globalStateService.Operator?.Id,
                                    UserId2 = _globalStateService.Reviewer?.Id,
                                    MachineId = _setting.machineId,
                                    CreateDate = DateTime.Now.ToString("yyyy-MM-dd"),
                                    InvoiceNo = "总结存"
                                });
                                if (iTotalResult <= 0)
                                {
                                    logger.Info($"未写入总结存数据{oiList[j].DetailInfo.DrugId}-{oiList[j].DetailInfo.Quantity}");
                                    empChannelStock += $"未写入总结存数据{oiList[j].DetailInfo.DrugId}-{oiList[j].DetailInfo.Quantity} ";
                                }
                            }
                            //移出库位里是否有未绑套餐且库存为0的数据，有则删除
                            _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.boxMachineId) && (string.IsNullOrEmpty(cs.ListId)) && cs.DrawerNo == channelStock.DrawerNo && cs.ColNo == channelStock.ColNo && cs.Quantity <= 0).Delete();
                            //删除绑定套餐中同一药品多批次且库存为0的第一条数据
                            List<ChannelStock> delChannelStock = await _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.boxMachineId) && cs.DrawerNo == channelStock.DrawerNo && cs.ColNo == channelStock.ColNo && cs.DrugId == channelStock.DrugId).ToListAsync();
                            if (delChannelStock != null && delChannelStock.Count > 1)
                            {
                                //删除绑定套餐中库存为0的药的批次数据，只保留一条数据
                                List<ChannelStock> del = delChannelStock.Where(c => c.Quantity <= 0).ToList();
                                if (del != null && del.Count > 0)
                                {
                                    if (delChannelStock.Count == del.Count)
                                    {
                                        for (int d = 1; d < del.Count; d++)
                                        {
                                            _connection.ChannelStock.Where(cs => cs.Id == del[d].Id).Delete();
                                        }
                                    }
                                    else
                                    {
                                        for (int d = 0; d < del.Count; d++)
                                        {
                                            _connection.ChannelStock.Where(cs => cs.Id == del[d].Id).Delete();
                                        }
                                    }
                                }
                            }
                        }

                    }

                    List<OrderTakeVo> drawerNos = new();
                    List<ChannelStock> returnStock = new();
                    //if (csList.Any(c => c.DrawerChanneStockList?.Count > 0))

                    if (csList[i].DrawerChanneStockList != null && csList[i].DrawerChanneStockList.Count > 0)
                    {
                        List<ChannelStock> drawerChannelStockList = csList[i].DrawerChanneStockList;
                        for (int j = 0; j < drawerChannelStockList.Count; j++)
                        {
                            //还药将库存加入抽屉、从药盒中减库存
                            _connection.ChannelStock.Where(cs => cs.Id == csList[i].DrawerChanneStockList[j].Id).Set(cs => cs.Quantity, csList[i].DrawerChanneStockList[j].Quantity + csList[i].DrawerChanneStockList[j].ReturnQuantity).Update();
                            _connection.ChannelStock.Where(cs => cs.Id == csList[i].Id).Set(cs => cs.Quantity, csList[i].Quantity - csList[i].DrawerChanneStockList[j].ReturnQuantity).Update();
                            //药盒对应channel_list表总库存也要减
                            ChannelList clList = _connection.ChannelList.Where(cl => cl.MachineId.Equals(_setting.boxMachineId) && cl.DrawerNo == csList[i].DrawerNo && cl.ColNo == csList[i].ColNo).FirstOrDefault();
                            if (clList != null)
                            {
                                clList.TotalQuantity -= csList[i].DrawerChanneStockList[j].ReturnQuantity;
                                int iUpdate = await _connection.UpdateAsync(clList);
                                if (iUpdate <= 0)
                                {
                                    logger.Info($"抽屉还药记录药盒{boxModel.BoxName}-{boxModel.BoxNo}总库存失败，还药数量{csList[i].DrawerChanneStockList[j].ReturnQuantity}");
                                }
                            }
                            MachineRecord _MachineRecord = _connection.MachineRecord
                                .Where(dm => dm.MachineId.Equals(_setting.boxMachineId) && dm.DrugId == csList[i].DrugId && dm.ManuNo == csList[i].ManuNo && dm.BoxDrawer == csList[i].DrawerNo && dm.ColNo == csList[i].ColNo && dm.Type == 2 && dm.Status != 2).FirstOrDefault();
                            if (_MachineRecord != null)
                            {
                                _MachineRecord.ReturnQuantity2 = _MachineRecord.ReturnQuantity2 + _MachineRecord.CurrentReturnQuantity;
                                _MachineRecord.Status = _MachineRecord.ReturnQuantity2 + _MachineRecord.ReturnQuantity1 >= _MachineRecord.Quantity ? 2 : 1;
                                // 更新借药数据 取药记录 设置还药数量、状态
                                _connection.Update(_MachineRecord);
                            }
                            //添加还药记录
                            int acid = _connection.InsertWithInt32Identity(new MachineRecord()
                            {
                                MachineId = _setting.boxMachineId,
                                DrawerNo = csList[i].DrawerChanneStockList[j].DrawerNo,
                                ColNo = csList[i].DrawerChanneStockList[j].ColNo,
                                DrugId = csList[i].DrugId,
                                ManuNo = csList[i].DrawerChanneStockList[j].ManuNo,
                                // EffDate = !String.IsNullOrEmpty(record.EffDate) ? DateTime.ParseExact(record.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                                Operator = _globalStateService.Operator?.Id,
                                Reviewer = _globalStateService.Reviewer?.Id,
                                OperationTime = DateTime.Now,
                                Quantity = csList[i].DrawerChanneStockList[j].ReturnQuantity,
                                Type = 31,
                                InvoiceId = csList[i].Location,
                                GetId = _MachineRecord?.GetId
                            });
                        }


                    }
                    if (csList[i].EmptyStock != null && csList[i].EmptyStock.ReturnQuantity > 0)
                    {
                        //还空瓶，将空瓶数量加到空瓶库位 //还药将库存加入抽屉、从药盒中减库存
                        _connection.ChannelStock.Where(cs => cs.Id == csList[i].EmptyStock.Id).Set(cs => cs.Quantity, csList[i].EmptyStock.Quantity + csList[i].EmptyStock.ReturnQuantity).Update();

                        MachineRecord _MachineRecord = _connection.MachineRecord
                            .Where(dm => dm.MachineId.Equals(_setting.boxMachineId) && dm.DrugId == csList[i].DrugId && dm.ManuNo == csList[i].ManuNo && dm.BoxDrawer == csList[i].DrawerNo && dm.ColNo == csList[i].ColNo && dm.Type == 2 && dm.Status != 2).FirstOrDefault();
                        if (_MachineRecord != null)
                        {
                            _MachineRecord.ReturnQuantity2 = _MachineRecord.ReturnQuantity2 + _MachineRecord.CurrentReturnQuantity;
                            _MachineRecord.Status = _MachineRecord.ReturnQuantity2 + _MachineRecord.ReturnQuantity1 >= _MachineRecord.Quantity ? 2 : 1;
                            // 更新借药数据 取药记录 设置还药数量、状态
                            _connection.Update(_MachineRecord);
                        }
                        //添加还空瓶记录
                        int acid = _connection.InsertWithInt32Identity(new MachineRecord()
                        {
                            MachineId = _setting.boxMachineId,
                            DrawerNo = csList[i].EmptyStock.DrawerNo,
                            ColNo = csList[i].EmptyStock.ColNo,
                            DrugId = csList[i].DrugId,
                            ManuNo = csList[i].EmptyStock.ManuNo,
                            // EffDate = !String.IsNullOrEmpty(record.EffDate) ? DateTime.ParseExact(record.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null,
                            Operator = _globalStateService.Operator?.Id,
                            Reviewer = _globalStateService.Reviewer?.Id,
                            OperationTime = DateTime.Now,
                            Quantity = csList[i].EmptyStock.ReturnQuantity,
                            Type = 32,
                            InvoiceId = csList[i].Location,
                            GetId = _MachineRecord?.GetId
                        });
                    }
                }

                //将药盒中无绑定库位的药品且库存为0的删除
                _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.boxMachineId) && string.IsNullOrEmpty(cs.ListId) && cs.Quantity <= 0).Delete();
                logger.Info($"管理员{_globalStateService.Operator.NickName}结束确认手麻单");
                if (!string.IsNullOrEmpty(empChannelStock))
                {
                    _message.Notify(
                          new NotificationMessage { Severity = NotificationSeverity.Error, Summary = "提示", Detail = $"有未核对处方：{empChannelStock}", Duration = 4000 }
                      );
                    _connection.RollbackTransaction();
                    return false;
                }
                if (bFlag)
                {
                    _connection.CommitTransaction();
                    return true;
                }
                else
                {
                    _connection.RollbackTransaction();
                    logger.Info($"管理员{_globalStateService.Operator.NickName}确认手麻单失败");
                    return false;
                }
            }
            catch (Exception ex)
            {
                _connection.RollbackTransaction();
                logger.Info($"核对处方异常{ex.Message}");
                return false;
            }
        }

        void RestData()
        {
            //    PortUtil.speechSynthesizer.SpeakAsyncCancelAll();
            //    this.status = 0;
            //    data.ForEach(it =>
            //    {
            //        it.Status = 0;
            //        it.BeforeQuantity = new int[9];
            //        it.AfterQuantity = new int[9];
            //    });
            //    this.WeightFinnalQuantity = new int[9];
            //    DrawerNoColNoList.Clear();
        }
        public async Task<List<Anaesthetist>> GetAnaesthetistName()
        {
            List<Anaesthetist> strList = new List<Anaesthetist>();
            strList = await _connection.OrderInfo.Where(it => it.state == 0 && it.HisDispFlag == 0 && it.CancelFlag == 0).Select(it => new Anaesthetist { Name = it.anaesthetistName }).Distinct().ToListAsync();
            return strList;

        }

        //获取麻醉师单对应的手术间号
        public async Task<List<BoxModel>> GetOperationNum(int boxColor)
        {
            List<BoxModel> boxNumList = new List<BoxModel>();
            //List<int> roomNameList = await _connection.OrderInfo
            //    .Where(it => it.state == 0 && it.HisDispFlag == 0 && it.CancelFlag == 0&&it.anaesthetistName== anaesthetistName)
            //    .Select(it => Convert.ToInt32(it.RoomName.Substring(6, it.RoomName.Length - 6))).Distinct().ToListAsync();
            //roomNameList.Add(99);
            //roomNameList.Add(111);
            logger.Info($"开始查询药盒{DateTime.Now}");
            boxNumList = await GetDrawerNumByOperationNum(_setting.boxMachineId, boxColor);

            logger.Info($"结束查询药盒{DateTime.Now}");
            return boxNumList;
        }


        //获取麻醉师单对应的手术间号(查询全部手术间已绑套餐的手术间)
        public async Task<List<BoxModel>> GetAllBindOperationNum()
        {
            List<BoxModel> boxModelList = new List<BoxModel>();
            boxModelList = await _connection.ChannelList
                .Where(cs => cs.MachineId == _setting.boxMachineId && (!string.IsNullOrEmpty(cs.DrugId)))
                .Select(cs => new BoxModel { BoxName = cs.DrawerNo, BoxNo = Convert.ToInt32(cs.ColNo) }).Distinct().OrderBy(cs => new { cs.BoxName, cs.BoxNo }).ToListAsync();
            return boxModelList;
        }

        //查询药品对应的库位 drawerType=1药品库位，其他则是回收库位
        public async Task<List<ChannelStock>> GetStockByDRrug(string drugId, string manuNo, int drawerType)
        {
            if (drawerType == 1)
            {
                return await _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType == drawerType && cs.DrugId == drugId && cs.ManuNo == manuNo).OrderBy(cs => cs.Quantity).ToListAsync();
            }
            else
            {
                return await _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType != 1 && cs.DrugId == drugId).OrderBy(cs => cs.Quantity).ToListAsync();
            }
        }

        public Task<List<BoxModel>> GetDrawerNumByOperationNum(string machineId, List<int> operationNum)
        {
            throw new NotImplementedException();
        }
    }
}
