using LinqToDB; using log4net; using MasaBlazorApp3.DataAccess.Dao; using MasaBlazorApp3.Pages; using MasaBlazorApp3.Pojo; using MasaBlazorApp3.Pojo.Config; using MasaBlazorApp3.Pojo.Vo; using MasaBlazorApp3.Port; using Microsoft.Extensions.Options; using Mysqlx.Crud; using System.Collections.Generic; using static LinqToDB.Common.Configuration; namespace MasaBlazorApp3.DataAccess.Impl { public class MachineRecordDao : IMachineRecordDao { private readonly AppDataConnection _connection; private readonly SettingConfig _setting; private readonly ILog logger = LogManager.GetLogger(typeof(MachineRecordDao)); private readonly PortUtil _portUtil; private GlobalStateService _globalStateService; //public UserDao(MyContext context) //{ // Context = context; //} public MachineRecordDao(AppDataConnection connection, IOptions setting, PortUtil portUtil, GlobalStateService globalStateService) { _connection = connection; _setting = setting.Value; _portUtil = portUtil; _globalStateService = globalStateService; } public async Task> GetChannelStockByDrugId(string DrugId, String ManuNo) { var query = _connection.ChannelStock.AsQueryable(); query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1) .Where(cs => cs.Quantity > 0) .Where(cs => cs.DrugId.Equals(DrugId)) .Where(cs => cs.ManuNo.Equals(ManuNo)); return await query.OrderBy((cs) => cs.EffDate) .ThenBy((cs) => cs.DrawerNo) .ThenBy((cs) => cs.ColNo) .ToListAsync(); } //还药时有库位即可,不需要库存大于0的条件 public async Task> GetChannelStockByDrugIdForReturn(string DrugId, String ManuNo) { var query = _connection.ChannelStock.AsQueryable(); query = query.Where(cs => cs.MachineId.Equals(_setting.machineId)).Where(cs => cs.DrawerType == 1) //.Where(cs => cs.Quantity > 0) .Where(cs => cs.DrugId.Equals(DrugId)) .Where(cs => cs.ManuNo.Equals(ManuNo)); return await query.OrderBy((cs) => cs.EffDate) .ThenBy((cs) => cs.DrawerNo) .ThenBy((cs) => cs.ColNo) .ToListAsync(); } public async Task> GetCanReturnRecords(DateTime start, DateTime end, int operatorId, string drugId, int? take, int? skip) { var query = _connection.MachineRecord.AsQueryable().Where(it => it.MachineId.Equals(_setting.machineId)&&it.InvoiceId.StartsWith("DRAWER_")); if (start != null && start != DateTime.MinValue) { query = query.Where(mr => mr.OperationTime > start); } if (end != null && end != DateTime.MinValue) { query = query.Where(mr => mr.OperationTime < end.AddDays(1)); } if (operatorId != 0) { query = query.Where(mr => mr.Operator == operatorId); } query = query.Where(mr => mr.Type == 2); query = query.Where(mr => mr.Status < 2); if (!String.IsNullOrEmpty(drugId)) { query = query.Where(mr => mr.DrugId == drugId); } int pagedData = await query.CountAsync(); List MachineRecords = await query.LoadWith(mr => mr.Drug) .LoadWith(mr => mr.OperatorUser) .OrderByDescending(mr => mr.OperationTime) .Skip((int)skip) .Take((int)take) .ToListAsync(); return new PageData() { Desserts = MachineRecords, TotalDesserts = pagedData }; } public async Task> GetMachineRecordAsync(DateTime start, DateTime end, int operatorId, string drugId, int type, int? take, int? skip) { var query = from mr in _connection.MachineRecord select mr ; if (start != null && start != DateTime.MinValue) { query = query.Where(mr => mr.OperationTime > start); } if (end != null && end != DateTime.MinValue) { query = query.Where(mr => mr.OperationTime < end.AddDays(1)); } if (operatorId != 0) { query = query.Where(mr => mr.Operator == operatorId); } if (type != 0) { query = query.Where(mr => mr.Type == type); } if (!String.IsNullOrEmpty(drugId)) { query = query.Where(mr => mr.DrugId == drugId); } query = query.OrderByDescending(mr => mr.OperationTime); query =from mr in query from dr in _connection.DrugInfo.Where(d => d.DrugId == mr.DrugId) from us in _connection.User.Where(u => u.Id == mr.Operator) select MachineRecord.Build(mr, dr, us); int pagedData = await query.CountAsync(); List MachineRecords = await query //.OrderByDescending(mr => mr.OperationTime) .Skip((int)skip) .Take((int)take) .ToListAsync(); //var query = _connection.MachineRecord.AsQueryable().Where(it => it.MachineId.Equals(_setting.machineId)); //if (start != null && start != DateTime.MinValue) //{ // query = query.Where(mr => mr.OperationTime > start); //} //if (end != null && end != DateTime.MinValue) //{ // query = query.Where(mr => mr.OperationTime < end.AddDays(1)); //} //if (operatorId != 0) //{ // query = query.Where(mr => mr.Operator == operatorId); //} //if (type != 0) //{ // query = query.Where(mr => mr.Type == type); //} //if (!String.IsNullOrEmpty(drugId)) //{ // query = query.Where(mr => mr.DrugId == drugId); //} //int pagedData = await query.CountAsync(); //List MachineRecords = await query.LoadWith(mr => mr.Drug) // .LoadWith(mr => mr.OperatorUser) // .OrderByDescending(mr => mr.OperationTime) // .Skip((int)skip) // .Take((int)take) // .ToListAsync(); return new PageData() { Desserts = MachineRecords, TotalDesserts = pagedData }; } public int InsertMachineRecord(MachineRecord record) { record.MachineId = _setting.machineId; return _connection.InsertWithInt32Identity(record); } public async Task>>> getReturnDrugInfoByRecords(List records) { List>> list = new(); for (int i = 0; i < records.Count; i++) { var record = records[i]; //var index = list.FindIndex(it => it.Drug.DrugId == record.DrugId && it.data.Count > 0 && it.data.First().ManuNo == record.ManuNo); var index = list.FindIndex(it => it.Drug.DrugId == record.DrugId && it.data.First().ManuNo == record.ManuNo); if (index > -1) { list[index].Quantity += record.CurrentReturnQuantity; list[index].data.Add(record); if (list[index].ChannelStocks.Count > 0) { list[index].ChannelStocks.First().ReturnQuantity += record.CurrentReturnQuantity; } } else { //List stockList = await this.GetChannelStockByDrugId(record.DrugId, record.ManuNo); List stockList = await this.GetChannelStockByDrugIdForReturn(record.DrugId, record.ManuNo); // 当前药品的库存总量 var total = stockList.Sum(current => current.Quantity); if (stockList.Count > 0) { stockList.First().ReturnQuantity = record.CurrentReturnQuantity; } list.Add(new OperationVo>() { Drug = record.Drug, ChannelStocks = stockList, data = new List { record }, Quantity = record.CurrentReturnQuantity, StockQuantity = total, }); } } return list; } public async Task ReturnDrugFinish(List>> datas) { //throw new NotImplementedException(); //还药完成 try { _connection.BeginTransaction(); if (datas.Count > 0) { datas = datas.Select(it => { it.ChannelStocks = it.ChannelStocks.Where(cs => cs.ReturnQuantity > 0).ToList(); return it; }).ToList(); if (datas.Count > 0) { foreach (var data in datas) { int sumQuantity = data.data.Sum(mr => mr.CurrentReturnQuantity); //更新 库存 foreach (ChannelStock record in data.ChannelStocks) { record.Quantity = record.Quantity + record.ReturnQuantity; record.Id = record.Id; _connection.Update(record); // 保存数据 还药记录 int acid = _connection.InsertWithInt32Identity(new MachineRecord() { MachineId = record.MachineId, DrawerNo = record.DrawerNo, ColNo = record.ColNo, DrugId = record.DrugId, ManuNo = record.ManuNo, EffDate = !String.IsNullOrEmpty(record.EffDate) ? DateTime.ParseExact(record.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, Operator = data.data.First().Operator, OperationTime = DateTime.Now, Quantity = record.ReturnQuantity, Type = 31, InvoiceId = data.data.First().InvoiceId, GetId = data.data.First().GetId }); //称重计数或称重+智能显示+管控药盒 类型需要 发26指令 if (record.BoardType == 5 || record.BoardType == 6) { //计数数量设置,发送称重26指令 _portUtil.SetNumCount(record.DrawerNo, record.ColNo, record.ReturnQuantity); Thread.Sleep(80); } // 获取更新完库存之后的药品库存 List 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(record.DrugId)) .ToListAsync(); //账册添加入库记录 int accountID = _connection.InsertWithInt32Identity(new AccountBook() { MachineId = _setting.machineId, DrugId = record.DrugId, ManuNo = record.ManuNo, EffDate = !String.IsNullOrEmpty(record.EffDate) ? DateTime.ParseExact(record.EffDate, "yyyy-MM-dd", System.Globalization.CultureInfo.CurrentCulture) : null, OperationTime = DateTime.Now, Type = 31, AddQuantity = record.ReturnQuantity, Operator = _globalStateService.Operator.Id, Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, ManuStock = list.Where(it => it.ManuNo == record.ManuNo).Sum(it => it.Quantity), TotalStock = list.Sum(it => it.Quantity), InvoiceId = data.data.First().InvoiceId, }); } // 更新 取药记录 设置还药数量、状态 foreach (MachineRecord record in data.data) { record.ReturnQuantity1 = record.ReturnQuantity1 + record.CurrentReturnQuantity; record.Id = record.Id; record.Status = (record.Quantity - (record.ReturnQuantity1 + record.ReturnQuantity2 + sumQuantity)) <= 0 ? 2 : 1; _connection.Update(record); //更新药盒库存(原库存减已还药数) if(record.BoxDrawer>0) { //查询药盒库位中对应的药品信息 ChannelStock csBox = _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.boxMachineId) && cs.DrugId == record.DrugId && cs.ManuNo == record.ManuNo && cs.DrawerNo == record.BoxDrawer && cs.ColNo == record.BoxColNo).FirstOrDefault(); if(csBox!=null) { csBox.Quantity = csBox.Quantity - sumQuantity; int iUpdateBox= _connection.Update(csBox); if(iUpdateBox<=0) { logger.Info("更新药品库存失败"); } } else { logger.Info($"未查询到药品{record.DrugId}批次{record.ManuNo}在库位{record.BoxDrawer}-{record.BoxColNo}中信息"); } } } } _connection.CommitTransaction(); } } else { _connection.RollbackTransaction(); return false; } return true; } catch (Exception ex) { logger.Error("还药完成保存数据库失败,错误:" + ex.Message); _connection.RollbackTransaction(); return false; } } #region 还空瓶 public async Task> GetReturnEmpty() { List channelStocks = new(); var query = _connection.ChannelStock.AsQueryable().Where(it => it.MachineId == _setting.machineId && it.DrawerType == 2); channelStocks= await query.LoadWith(cs => cs.Drug).ToListAsync(); //获取可归还数量 return channelStocks; //if (start != null && start != DateTime.MinValue) //{ // query = query.Where(mr => mr.OperationTime > start); //} //if (end != null && end != DateTime.MinValue) //{ // query = query.Where(mr => mr.OperationTime < end); //} //if (operatorId != 0) //{ // query = query.Where(mr => mr.Operator == operatorId); //} //query = query.Where(mr => mr.Type == 2); //query = query.Where(mr => mr.Status < 2); //if (!String.IsNullOrEmpty(drugId)) //{ // query = query.Where(mr => mr.DrugId == drugId); //} //int pagedData = await query.CountAsync(); //List MachineRecords = await query.LoadWith(mr => mr.Drug) // .LoadWith(mr => mr.OperatorUser) // .OrderByDescending(mr => mr.OperationTime) // .Skip((int)skip) // .Take((int)take) // .ToListAsync(); //return new PageData() { Desserts = MachineRecords, TotalDesserts = pagedData }; } public async Task> getReturnEmptyInfoByRecords(ChannelStock records) { List machineRecords = new(); int pagedData = 0; if (records != null && !string.IsNullOrEmpty(records.DrugId)) { var query = _connection.MachineRecord.Where(it => it.DrugId == records.DrugId && it.MachineId == _setting.machineId && it.Type == 2 && it.Status != 2).AsQueryable(); machineRecords = await query.LoadWith(cs => cs.OperatorUser).ToListAsync(); pagedData = await query.CountAsync(); } return new PageData() { Desserts = machineRecords, TotalDesserts = pagedData }; } public async Task ReturnEmptyFinish(List datas, ChannelStock channelStock) { try { _connection.BeginTransaction(); // 更新数据 库存信息 channelStock.Quantity = channelStock.Quantity+ datas.Sum(it => it.CurrentReturnQuantity); int iStock = _connection.Update(channelStock); for (int i = 0; i < datas.Count; i++) { MachineRecord _MachineRecord = datas[i]; _MachineRecord.ReturnQuantity2 = _MachineRecord.ReturnQuantity2+ _MachineRecord.CurrentReturnQuantity; _MachineRecord.Status = _MachineRecord.ReturnQuantity2 + _MachineRecord.ReturnQuantity1 >= _MachineRecord.Quantity ? 2 : 1; // 更新数据 取药记录 设置还药数量、状态 _connection.Update(_MachineRecord); // 保存数据 还药空瓶记录 int iMachineRecord = _connection.InsertWithInt32Identity(new MachineRecord() { MachineId= channelStock.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 = _MachineRecord.Operator, OperationTime = DateTime.Now, Quantity = _MachineRecord.CurrentReturnQuantity, Type = 32, InvoiceId = _MachineRecord.InvoiceId, GetId = _MachineRecord.GetId }); ////称重计数或称重+智能显示+管控药盒 类型需要 发26指令 //if (channelStock.BoardType == 5 || channelStock.BoardType == 6) //{ // //计数数量设置,发送称重26指令 // _portUtil.SetNumCount(channelStock.DrawerNo, channelStock.ColNo, channelStock.ReturnQuantity); // Thread.Sleep(80); //} if (channelStock.BoardType.ToString().Contains("5")) { await _portUtil.WriteQuantityMethod(channelStock.Quantity + datas.Sum(it => it.CurrentReturnQuantity), channelStock.DrawerNo, channelStock.ColNo); } } // 更新屏显库存 if (channelStock.BoardType == 5 || channelStock.BoardType == 35) { _portUtil.WriteQuantity(channelStock.DrawerNo, channelStock.ColNo, channelStock.Quantity); } _connection.CommitTransaction(); return true; } catch (Exception ex) { logger.Error("还空瓶完成保存数据库失败,错误:" + ex.Message); _connection.RollbackTransaction(); return false; } } public async Task> GetReturnEmptyWithCanReturnQuantiy() { List channelStocks = new(); var queryStock = _connection.ChannelStock.Where(cs => cs.DrawerType == 2 && cs.MachineId == _setting.machineId); var queryMachineRecord = _connection.MachineRecord.Where(dm => dm.Type == 2 && dm.Status != 2); var query = from cs in queryStock join other in queryMachineRecord on cs.DrugId equals other.DrugId where cs.MachineId==other.MachineId group other by cs.DrugId into g select new { ChannelStockId = g.Key, SumValue = g.Sum(x => x.Quantity-x.ReturnQuantity1-x.ReturnQuantity2) }; var results = await query.ToListAsync(); channelStocks= await queryStock.LoadWith(cs => cs.Drug).ToListAsync(); foreach (var itemStock in channelStocks) { foreach (var itemResult in results) { if(itemStock.DrugId==itemResult.ChannelStockId) { itemStock.CanReturnQuantity = itemResult.SumValue; } } } return channelStocks; } #endregion } }