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 System; using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MasaBlazorApp3.DataAccess.Impl { public class InOutInvoiceDao : IInOutInvoiceDao { private AppDataConnection _connection; private readonly SettingConfig _setting; private readonly ILog logger = LogManager.GetLogger(typeof(InOutInvoiceDao)); private GlobalStateService _globalStateService; private readonly PortUtil _portUtil; public InOutInvoiceDao(AppDataConnection connection, IOptions setting, GlobalStateService globalStateService, PortUtil portUtil) { _connection = connection; _setting = setting.Value; _globalStateService = globalStateService; _portUtil = portUtil; } public async Task> GetAllInvoiceByType(string invoiceNo, DateTime invoiceDate, int? take, int? skip, int type = 1) { //var query2 = from cl in _connection.ChannelStock.Where(c => c.MachineId == _setting.machineId) // group cl by cl.DrugId into temp // select new { temp.Key }; //var query3 = from ioi in _connection.InOutInvoice // from od in query2.InnerJoin(od => od.Key == ioi.DrugId) // group ioi by ioi.InvoiceNo into temp // select new InOutInvoice{ // InvoiceNo= temp.First().InvoiceNo, // InPharmacyId = temp.First().InPharmacyId, // OutPharmacyId = temp.First().OutPharmacyId, // InvoiceDate = temp.First().InvoiceDate, // CreateTime = temp.First().CreateTime, // Type = temp.First().Type, // CancelFlag = temp.First().CancelFlag, // Status = temp.First().Status, // }; var query = _connection.FromSql($@" SELECT ioi.invoice_no,ioi.in_pharmacy_id, ioi.out_pharmacy_id, ioi.invoice_date, ioi.create_time, ioi.type, ioi.cancel_flag, ioi.status FROM in_out_invoice ioi INNER JOIN (SELECT drug_id FROM channel_stock WHERE machine_id = {_setting.machineId} GROUP BY drug_id) c ON c.drug_id = ioi.drug_id GROUP BY ioi.invoice_no"); if (!String.IsNullOrEmpty(invoiceNo)) { query = query.Where(ioi => ioi.InvoiceNo.Contains(invoiceNo)); //query3 = query3.Where(ioi => ioi.InvoiceNo.Contains(invoiceNo)); } if (invoiceDate != DateTime.MinValue) { query = query.Where(ioi => Convert.ToDateTime(ioi.InvoiceDate).Date.Equals(invoiceDate.Date)); //query3 = query3.Where(ioi => ioi.InvoiceNo.Contains(invoiceNo)); } if (!String.IsNullOrEmpty(_setting.inPharmacyId)) { if (type == 1) { query = query.Where(ioi => ioi.InPharmacyId.Equals(_setting.inPharmacyId)); //query = query.Where(ioi => ioi.OutPharmacyId.Equals(_setting.inPharmacyId)); //query3 = query3.Where(ioi => ioi.OutPharmacyId.Equals(_setting.storage)); } // 调拨出库 else if (type == 2) { query = query.Where(ioi => ioi.InPharmacyId.Equals(_setting.inPharmacyId)); //query3 = query3.Where(ioi => ioi.OutPharmacyId.Equals(_setting.storage)); } } // 调拨入库 if (type == 1) { query = query.Where(ioi => (ioi.Type == 2 && ioi.Status == 0)); //query3 = query3.Where(ioi => (ioi.Type == 0 && ioi.Status == 2) || (ioi.Type == 1 && ioi.Status == 0)); } // 调拨出库 else if (type == 2) { query = query.Where(ioi => new int[] { 0, 2 }.Contains(ioi.Type) && ioi.Status == 0); //query3 = query3.Where(ioi => new int[] { 0, 2 }.Contains(ioi.Type) && ioi.Status == 0); } query = query.Where(ioi => ioi.CancelFlag == 0); query = query.Select(ioi => new InOutInvoice() { InPharmacyId = ioi.InPharmacyId, OutPharmacyId = ioi.OutPharmacyId, InvoiceDate = ioi.InvoiceDate, InvoiceNo = ioi.InvoiceNo, CreateTime = ioi.CreateTime, Type = ioi.Type, Status = ioi.Status, CancelFlag = ioi.CancelFlag, }); //query3 = query3.Where(ioi => ioi.CancelFlag == 0); List list = await query .OrderByDescending(ioi => ioi.CreateTime) .Skip((int)skip) .Take((int)take) .ToListAsync(); int pagedData = await query.CountAsync(); return new PageData() { TotalDesserts = pagedData, Desserts = list }; } public async Task 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> 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) { query = query.Where(cs => cs.Quantity > 0); if (!String.IsNullOrEmpty(manuNo) && manuNo != "X") { query = query.Where(cs => cs.ManuNo.Equals(manuNo)); } } else { if (!String.IsNullOrEmpty(manuNo) && manuNo != "X") { query = query.Where(cs => cs.ManuNo.Equals(manuNo) || String.IsNullOrEmpty(cs.ManuNo) || cs.Quantity == 0); } } return await query.LoadWith(cl => cl.drugManuNo) .OrderBy((cs) => cs.EffDate) .ThenBy((cs) => cs.DrawerNo) .ThenBy((cs) => cs.ColNo) .ToListAsync(); } public async Task> getInvoiceByInvoiceNo(string invoiceNo) { var query = _connection.InOutInvoice.AsQueryable(); query = query.InnerJoin( _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.machineId)).GroupBy(cs => cs.DrugId).Select(cs => cs.Key), (ioi, key) => key == ioi.DrugId, (ioi, key) => ioi) .Where(ioi => ioi.InvoiceNo.Equals(invoiceNo)) .OrderBy(ioi => ioi.DrugId); return await query.ToListAsync(); } public async Task getDrugInfoById(string DrugId) { return await _connection.DrugInfo.Where(di => di.DrugId == DrugId).LoadWith(di => di.Manus).FirstOrDefaultAsync(); } public async Task> getTakeInfoByInvoiceNo(string invoiceNo) { List tempData = new(); var flag = true; List details = await this.getInvoiceByInvoiceNo(invoiceNo); for (var i = 0; i < details.Count; i++) { //List> tempData = new(); InOutInvoice detail = details[i]; DrugInfo Drug = await this.getDrugInfoById(detail.DrugId); // 当前detail取药数量 var Quantity = detail.quantity; List stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.DrugManuNo,Quantity); if (Drug != null && stockList != null && stockList.Count > 0) { stockList.ForEach(sl => sl.Drug = Drug); } if (stockList != null && stockList.Count > 0) { if (Drug != null && Drug.SmallUnit != detail.Units) { Quantity = detail.quantity * stockList[0].Drug.ConvertRatio; } } // 当前药品的库存总量 var total = stockList.Sum(cs => cs.Quantity); if (flag) { // 盘点库存是否足够 if (total >= Quantity) { for (var j = 0; Quantity > 0; j++) { ChannelStock stock = stockList[j]; if (Quantity > stock.Quantity) { // 取药数量大于库存 stock.TakeQuantity = stock.Quantity; Quantity -= stock.Quantity; } else { //取药数量小于库存 stock.TakeQuantity = Quantity; Quantity = 0; } } } else { // 库存不足 flag = false; } } tempData.Add(new InvoiceVo() { Drug = Drug, Invoice = detail, StockQuantity = total, Quantity = detail.quantity, ChannelStocks = stockList, }); } return tempData; } public async Task> getAddInfoByInvoiceNo(string invoiceNo) { List tempData = new(); List details = await this.getInvoiceByInvoiceNo(invoiceNo); for (var i = 0; i < details.Count; i++) { //List> tempData = new(); InOutInvoice detail = details[i]; List stockList = await this.GetChannelStockByDrugId(detail.DrugId, detail.DrugManuNo); DrugInfo Drug = await this.getDrugInfoById(detail.DrugId); if (Drug != null && stockList != null && stockList.Count > 0) { stockList.ForEach(sl => sl.Drug = Drug); } // 当前药品的库存总量 var total = stockList.Aggregate(0, (current, next) => current + next.Quantity); // 当前detail加药数量 var Quantity = detail.quantity; if(stockList!=null&&stockList.Count>0) { if (stockList[0].Drug != null && stockList[0].Drug.SmallUnit!=detail.Units) { Quantity = detail.quantity * stockList[0].Drug.ConvertRatio; } } stockList.First().AddQuantity = Quantity; tempData.Add(new InvoiceVo() { Drug = Drug, Invoice = detail, StockQuantity = total, Quantity = Quantity, ChannelStocks = stockList, }); } return tempData; } public async Task InvoiceOutFinish(List datas) { try { _connection.BeginTransaction(); var flag = true; // 更新处方状态 int r1 = _connection.InOutInvoice.Where(oi => oi.InvoiceNo == datas.First().Invoice.InvoiceNo) .Set(oi => oi.Status, 2) .Update(); if (!(r1 > 0)) { flag = false; logger.Error("调拨取药完成更新状态失败"); _connection.RollbackTransaction(); return flag; } for (var i = 0; i < datas.Count; i++) { var invoiceVo = datas[i]; List stocks = invoiceVo.ChannelStocks.Where(cs => cs.TakeQuantity > 0).ToList(); for (var j = 0; j < stocks.Count; j++) { var ChannelStock = stocks[j]; if (!DateTime.TryParse(ChannelStock.EffDate, out DateTime dEffDate)) { //效期转换出错 if (ChannelStock.EffDate != null) { string[] idate = ChannelStock.EffDate.Split('/'); foreach (string iS in idate) { if (!string.IsNullOrEmpty(iS.Trim())) { switch (iS.Trim().Length) { case 4: ChannelStock.EffDate = iS.Trim(); break; case 2: ChannelStock.EffDate += "-" + iS.Trim(); break; case 1: ChannelStock.EffDate += "-0" + iS.Trim(); break; } } } } } else { ChannelStock.EffDate = dEffDate.ToString("yyyy-MM-dd"); } // 出库记录 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 = 2, Quantity = ChannelStock.TakeQuantity, Operator = _globalStateService.Operator.Id, Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, InvoiceId = invoiceVo.Invoice.InvoiceNo, }); // 更新库存 int r = _connection.ChannelStock.Where(cs => cs.Id == ChannelStock.Id) .Set(cs => cs.Quantity, ChannelStock.Quantity - ChannelStock.TakeQuantity) .Update(); // 获取更新完库存之后的药品库存 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(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.TakeQuantity, 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 = invoiceVo.Invoice.InvoiceNo }); if (mid > 0 && r > 0 && acid > 0) { //根据抽屉类型判断是否需要写标签 if (ChannelStock.BoardType.ToString().Contains("5")) { await _portUtil.WriteQuantityMethod(ChannelStock.Quantity - ChannelStock.TakeQuantity, ChannelStock.DrawerNo, ChannelStock.ColNo); } } else { flag = false; break; } } if (!flag) { break; } } if (flag) { _connection.CommitTransaction(); } else { _connection.RollbackTransaction(); } return flag; } catch (Exception ex) { logger.Error("调拨取药完成保存数据库失败,错误:" + ex.Message); _connection.RollbackTransaction(); return false; } } public async Task InvoiceAddFinish(List datas) { try { _connection.BeginTransaction(); var flag = true; // 更新调拨单状态 int r1 = _connection.InOutInvoice.Where(oi => oi.InvoiceNo == datas.First().Invoice.InvoiceNo) .Set(oi => oi.Status, 4) .Update(); if (!(r1 > 0)) { flag = false; logger.Error("调拨加药完成更新状态失败"); _connection.RollbackTransaction(); return flag; } for (var i = 0; i < datas.Count; i++) { var invoiceVo = datas[i]; List stocks = invoiceVo.ChannelStocks.Where(cs => cs.AddQuantity > 0).ToList(); 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.AddQuantity); if (String.IsNullOrEmpty(ChannelStock.ManuNo) || (ChannelStock.Quantity == 0 && !ChannelStock.ManuNo.Equals(invoiceVo.Invoice.DrugManuNo))) { DrugManuNo drugManuNo = await GetDrugManuNo(ChannelStock.DrugId, ChannelStock.drugManuNo.ManuNo); ChannelStock.Dmnguid = drugManuNo.Id; ChannelStock.ManuNo = drugManuNo.ManuNo; ChannelStock.EffDate = drugManuNo.EffDate?.ToString("yyyy-MM-dd"); q = q.Set(cs => cs.Dmnguid, ChannelStock.Dmnguid) .Set(cs => cs.ManuNo, ChannelStock.ManuNo) .Set(cs => cs.EffDate, ChannelStock.EffDate); } int r = q.Update(); if (!DateTime.TryParse(ChannelStock.EffDate, out DateTime dEffDate)) { //效期转换出错 if (ChannelStock.EffDate != null) { string[] idate = ChannelStock.EffDate.Split('/'); foreach (string iS in idate) { if (!string.IsNullOrEmpty(iS.Trim())) { switch (iS.Trim().Length) { case 4: ChannelStock.EffDate = iS.Trim(); break; case 2: ChannelStock.EffDate += "-" + iS.Trim(); break; case 1: ChannelStock.EffDate += "-0" + iS.Trim(); break; } } } } } else { ChannelStock.EffDate = dEffDate.ToString("yyyy-MM-dd"); } // 入库记录 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 = 1, Quantity = ChannelStock.AddQuantity, Operator = _globalStateService.Operator.Id, Reviewer = _globalStateService.Reviewer?.Id ?? _globalStateService.Operator.Id, InvoiceId = invoiceVo.Invoice.InvoiceNo, }); //更新回收箱库存,入库后回收箱的空瓶库存减少 //List returnChannelStockList = _connection.ChannelStock.Where(cs => cs.MachineId == _setting.machineId && cs.DrawerType == 2 && cs.DrugId == ChannelStock.DrugId && cs.Quantity > 0).OrderBy(cs => cs.Quantity).ToList(); //if (returnChannelStockList != null && returnChannelStockList.Count > 0 && returnChannelStockList.Sum(rcs => rcs.Quantity) <= ChannelStock.AddQuantity) //{ // //空瓶数小于等于入库数量,直接清空所有回收箱中药品空瓶数 // returnChannelStockList.ForEach(rcs => rcs.Quantity = 0); // _connection.Update(returnChannelStockList); //} //else if(returnChannelStockList != null && returnChannelStockList.Count > 0) //{ // for (int rt = 0; rt < ChannelStock.AddQuantity; rt++) // { // int AddQuan = ChannelStock.AddQuantity; // int StockQuan = returnChannelStockList[rt].Quantity; // returnChannelStockList[rt].Quantity = (StockQuan - AddQuan) <= 0 ? 0 : (StockQuan - AddQuan); // ChannelStock.AddQuantity = AddQuan - StockQuan; // } // _connection.Update(returnChannelStockList); //} // 获取更新完库存之后的药品库存 List list = await _connection.ChannelStock.AsQueryable() .Where(cs => cs.MachineId.Equals(_setting.machineId)) .Where(cs => cs.DrawerType == 1) .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 = 1, OutQuantity = 0, AddQuantity = ChannelStock.AddQuantity, 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 = invoiceVo.Invoice.InvoiceNo }); if (mid > 0 && r > 0 && acid > 0) { //根据抽屉类型判断是否需要写标签 if (ChannelStock.BoardType.ToString().Contains("5")) { await _portUtil.WriteQuantityMethod(ChannelStock.Quantity - ChannelStock.TakeQuantity, ChannelStock.DrawerNo, ChannelStock.ColNo); } } else { flag = false; break; } } if (!flag) { break; } } if (flag) { _connection.CommitTransaction(); } else { _connection.RollbackTransaction(); } return flag; } catch (Exception ex) { logger.Error("调拨加药完成保存数据库失败,错误:" + ex.Message); _connection.RollbackTransaction(); return false; } } } }