using Aspose.Cells; using AutoMapper; using EyeSoft.Collections.Generic; using Newtonsoft.Json; using OASystem.Domain; using OASystem.Domain.Dtos.PersonnelModule; using OASystem.Domain.Entities.Groups; using OASystem.Domain.Entities.PersonnelModule; using OASystem.Domain.ViewModels.PersonnelModule; using OASystem.Infrastructure.Repositories.System; using OASystem.Infrastructure.Tools; namespace OASystem.Infrastructure.Repositories.PersonnelModule { /// /// 物品进销存 /// 仓储 /// public class GoodsRepository : BaseRepository { private readonly IMapper _mapper; private JsonView _jv; private string _url; private string _excelPath; private List _goodsTypeIds; //多部门审核物品类型Id private readonly ApprovalProcessRepository _approvalProcessRep; public GoodsRepository(SqlSugarClient sqlSugar, IMapper mapper, ApprovalProcessRepository approvalProcessRep) : base(sqlSugar) { _mapper = mapper; _jv = new JsonView() { Code = StatusCodes.Status400BadRequest, Msg = "操作失败!" }; _url = AppSettingsHelper.Get("ExcelBaseUrl"); _excelPath = $"{AppSettingsHelper.Get("ExcelBasePath")}"; if (!Directory.Exists(_excelPath)) { Directory.CreateDirectory(_excelPath); } _goodsTypeIds = new List() { 1423, //1423 贵重物品 }; _approvalProcessRep = approvalProcessRep; } /// /// 基础数据 /// /// public async Task InitDataSource() { var typeData = await _sqlSugar.Queryable() .Includes(x => x.SubTypeItems.Where(z => z.IsDel == 0) //.Select(z => new { // z.Id, // z.STid, // z.Name //}) .ToList()) .Where(x => x.IsDel == 0 && x.Remark.Equals("GoodsType")) //.Select(x => new { // x.Id, // x.Name, // x.SubTypeItems //}) .ToListAsync(); var groupData = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0) .Select(x => new { id = x.Id, groupName = x.TeamName }) .OrderByDescending(x => x.id) .ToListAsync(); groupData.Insert(0, new { id = 0, groupName = "其他物资(公司内部物资)" }); groupData.Insert(0, new { id = -1, groupName = "拜访客户所使用的物资" }); groupData.Insert(0, new { id = -2, groupName = "库存调整" }); groupData.Insert(0, new { id = -3, groupName = "全部团组" }); var userData = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0) .Select(x => new { x.Id, UserName = x.CnName, }) .ToListAsync(); //库存状态 var stockStatus = new List() { new { Value = -1, Text = "全部" }, new { Value = 0, Text = "待确认" }, new { Value = 1, Text = "部分确认" }, new { Value = 2, Text = "已确认" }, new { Value = 3, Text = "已拒绝" }, }; //领用出库状态 var receiveStatus = new List() { new { Value = -1, Text = "全部" }, new { Value = GoodsAuditEnum.Pending, Text = GoodsAuditEnum.Pending.GetEnumDescription() }, //new { Value = GoodsAuditEnum.Approved, Text = GoodsAuditEnum.Approved.GetEnumDescription() }, //new { Value = GoodsAuditEnum.UnApproved, Text = GoodsAuditEnum.UnApproved.GetEnumDescription() }, //new { Value = GoodsAuditEnum.OutPending, Text = GoodsAuditEnum.OutPending.GetEnumDescription() }, new { Value = GoodsAuditEnum.OutConfirming, Text = GoodsAuditEnum.OutConfirming.GetEnumDescription() }, new { Value = GoodsAuditEnum.OutConfirmed, Text = GoodsAuditEnum.OutConfirmed.GetEnumDescription() }, new { Value = GoodsAuditEnum.OutRejected, Text = GoodsAuditEnum.OutRejected.GetEnumDescription() }, }; _jv.Code = StatusCodes.Status200OK; _jv.Data = new { goodsTypeData = typeData, stockStatus, receiveStatus, groupNameData = groupData, userNameData = userData }; _jv.Msg = $"操作成功"; return _jv; } /// /// 物品列表 /// /// /// public async Task GoodsList(GoodsListDto dto) { var ids = new List(); if (!string.IsNullOrEmpty(dto.TypeIds)) { var strArray = dto.TypeIds.Split(','); foreach (var str in strArray) { if (int.TryParse(str, out int id)) { ids.Add(id); } } } var auditEnums = new List() { GoodsAuditEnum.Pending, GoodsAuditEnum.OutPending, GoodsAuditEnum.OutConfirming }; RefAsync total = 0; var data = await _sqlSugar.Queryable() //.Includes(glv => glv.Receives.Where(z1 => z1.IsDel == 0 && z1.AuditStatus == GoodsAuditEnum.Pending).ToList()) .Includes(glv => glv.Receives.Where(z1 => z1.IsDel == 0 && auditEnums.Contains(z1.AuditStatus)).ToList()) .Includes(glv => glv.TypeData) .Includes(glv => glv.UserData) .LeftJoin((glv, sd) => glv.Type == sd.Id) .LeftJoin((glv, sd, u) => glv.LastUpdateUserId == u.Id) .Where(glv => glv.IsDel == 0) .WhereIF(ids.Count > 0, glv => ids.Contains(glv.Type)) .WhereIF(!string.IsNullOrEmpty(dto.GoodsName), glv => glv.Name.Contains(dto.GoodsName)) .OrderByDescending(glv => glv.LastUpdateTime) .ToPageListAsync(dto.PageIndex, dto.PageSize, total); var view = data.Select(x => new { x.Id, x.Name, x.Type, TypeName = x.TypeData?.Name ?? string.Empty, LastUpdateUserName = x.UserData?.CnName ?? string.Empty, x.LastUpdateTime, StockQuantity = x.StockQuantity - x.WaitAuditQuantity, x.Unit, x.StockQuantityLabel, x.Remark }).ToList(); _jv.Code = StatusCodes.Status200OK; _jv.Data = view; _jv.Count = total; _jv.Msg = $"操作成功"; return _jv; } /// /// 物品Info /// /// /// /// public async Task GoodsInfo(int portType, int id) { var data = await _sqlSugar.Queryable() .LeftJoin((gi, sd) => gi.Type == sd.Id) .LeftJoin((gi, sd, u1) => gi.LastUpdateUserId == u1.Id) .LeftJoin((gi, sd, u1, u2) => gi.CreateUserId == u2.Id) .Where((gi, sd, u1, u2) => gi.IsDel == 0 && gi.Id == id) .Select((gi, sd, u1, u2) => new { gi.Id, gi.Name, ParentType = sd.STid, gi.Type, TypeName = sd.Name, gi.SQ_Total, gi.OQ_Total, gi.PriceTotal, gi.StockQuantity, gi.Unit, gi.Remark, LastUpdateUserName = u1.CnName, gi.LastUpdateTime, CreateUserName = u2.CnName, gi.CreateTime, }) .FirstAsync(); _jv.Code = StatusCodes.Status200OK; _jv.Data = data; _jv.Msg = $"操作成功"; return _jv; } /// /// 物品 OP(Create Or Edit) /// /// /// /// public async Task GoodsOp(GoodsOpDto dto, int currUserId) { var info = new Pm_GoodsInfo() { Id = dto.Id, Name = dto.Name, Type = dto.Type, SQ_Total = 0, OQ_Total = 0, PriceTotal = 0, StockQuantity = 0, Unit = dto.Unit, Remark = dto.Remark, LastUpdateUserId = currUserId, LastUpdateTime = DateTime.Now, CreateUserId = currUserId }; if (dto.Id > 0) //Edit { var upd = await _sqlSugar.Updateable(info) .UpdateColumns(x => new { x.Name, x.Type, x.Unit, x.Remark, x.LastUpdateUserId, x.LastUpdateTime, }) .ExecuteCommandAsync(); if (upd > 0) { _jv.Msg = $"修改成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } } else if (dto.Id < 1) //添加 { var selectInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Name.Equals(info.Name)); if (selectInfo != null) { _jv.Msg = $"“{info.Name}”该物品已存在,请勿重新添加!"; return _jv; } var add = await _sqlSugar.Insertable(info).ExecuteCommandAsync(); if (add > 0) { _jv.Msg = $"添加成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } } return _jv; } /// /// 物品 Del /// /// /// /// public async Task GoodsDel(int id, int currUserId) { _sqlSugar.BeginTran(); var goods = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsInfo() { IsDel = 1, DeleteUserId = currUserId, DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }) .Where(x => x.Id == id) .ExecuteCommandAsync(); if (goods < 1) { _sqlSugar.RollbackTran(); _jv.Msg = $"操作失败"; return _jv; } var goodsStorage = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsStorage() { IsDel = 1, DeleteUserId = currUserId, DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }) .Where(x => x.Id == id) .ExecuteCommandAsync(); var goodsReceive = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsReceive() { IsDel = 1, DeleteUserId = currUserId, DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }) .Where(x => x.Id == id) .ExecuteCommandAsync(); _sqlSugar.CommitTran(); _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"操作成功!"; return _jv; } /// /// 入库/出库 审核类型 /// 根据物品类型 处理审核是否需要多部门审核 /// /// 物品类型Id /// public bool GoodsAuditType(int goodsTypeId) { if (_goodsTypeIds.Contains(goodsTypeId)) { return true; } return false; } /// /// 物品入库列表(带审核) /// /// /// public async Task GoodsStorageList(GoodsStorageListDto dto) { string reqAuditLabel = dto.AuditLabel; var auditLabel = Array.Empty(); int userId = dto.CurrUserId; if (!string.IsNullOrEmpty(reqAuditLabel)) { if (!reqAuditLabel.Contains("-1")) { auditLabel = reqAuditLabel .Split(',') .Select(x => { if (int.TryParse(x, out var id)) return id; return id; }) .ToArray(); } } var auditList = GoodsStorageConfirmAuditDep(1); var hrAuditPer = false; var finAuditPer = false; var hrAuditInfo = auditList.FirstOrDefault(x => x.AuditDep == GoodsAuditDepEnum.Hr); var finAuditInfo = auditList.FirstOrDefault(x => x.AuditDep == GoodsAuditDepEnum.Financial); if (hrAuditInfo != null) { if (hrAuditInfo.AuditorIds.Any(x => x == userId)) hrAuditPer = true; } if (finAuditInfo != null) { if (finAuditInfo.AuditorIds.Any(x => x == userId)) finAuditPer = true; } RefAsync total = 0; var data = await _sqlSugar.Queryable() .LeftJoin((gs, gi) => gs.GoodsId == gi.Id) .LeftJoin((gs, gi, u) => gs.CreateUserId == u.Id) .LeftJoin((gs, gi, u, u1) => gs.StorageUserId == u1.Id) .Where((gs, gi, u, u1) => gs.IsDel == 0) .WhereIF(dto.GoodsId > 0, (gs, gi, u, u1) => gs.GoodsId == dto.GoodsId) .WhereIF(auditLabel.Length > 0, (gs, gi, u, u1) => auditLabel.Contains((int)gs.ConfirmStatus)) .WhereIF(!string.IsNullOrEmpty(dto.GoodsName), (gs, gi, u, u1) => gi.Name.Contains(dto.GoodsName)) .WhereIF(!string.IsNullOrEmpty(dto.BatchNo), (gs, gi, u, u1) => gs.BatchNo.Contains(dto.BatchNo)) .WhereIF(finAuditPer, (gs, gi, u, u1) => _goodsTypeIds.Contains(gi.Type)) .Select((gs, gi, u, u1) => new GoodsStorageListView() { Id = gs.Id, GoodsId = gs.GoodsId, GoodsType = gi.Type, BatchNo = gs.BatchNo, GoodsName = gi.Name, Quantity = gs.Quantity, UnitPrice = gs.UnitPrice, TotalPrice = gs.TotalPrice, SupplierName = gs.SupplierName, SupplierTel = gs.SupplierTel, SupplierAddress = gs.SupplierAddress, SupplierSource = gs.SupplierSource, StorageUserName = u1.CnName, StorageTime = gs.StorageTime, CreateUserName = u.CnName, ConfirmStatus = gs.ConfirmStatus, StatusDesc = gs.StatusDesc, CreateTime = gs.CreateTime, Remark = gs.Remark }) .OrderByDescending(gs => gs.CreateTime) .ToPageListAsync(dto.PageIndex, dto.PageSize, total); foreach (var item in data) { var auditDeps = new List { new() { AuditPer = hrAuditPer, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr.GetEnumDescription() } }; var auditPer = GoodsAuditType(item.GoodsType); if (auditPer) { auditDeps.Add(new() { AuditPer = finAuditPer, AuditDep = GoodsAuditDepEnum.Financial, ButtonText = GoodsAuditDepEnum.Financial.GetEnumDescription() }); } item.AuditPers = auditDeps.ToArray(); } _jv.Code = StatusCodes.Status200OK; _jv.Data = data; _jv.Count = total; _jv.Msg = $"操作成功"; return _jv; } /// /// 物品入库详情 /// /// /// public async Task GoodsStorageInfo(int portType, int id) { var data = await _sqlSugar.Queryable() .LeftJoin((gs, gi) => gs.GoodsId == gi.Id) .LeftJoin((gs, gi, u) => gs.CreateUserId == u.Id) .LeftJoin((gs, gi, u, u1) => gs.StorageUserId == u1.Id) .Where((gs, gi, u, u1) => gs.IsDel == 0) .WhereIF(id > 0, (gs, gi, u, u1) => gs.Id == id) .Select((gs, gi, u, u1) => new { gs.Id, gs.GoodsId, GoodsName = gi.Name, gs.Quantity, gs.UnitPrice, gs.TotalPrice, gs.SupplierName, gs.SupplierTel, gs.SupplierAddress, gs.SupplierSource, gs.ReceiveQuantity, gs.StorageUserId, StorageUser = u1.CnName, gs.StorageTime, CreateUserName = u.CnName, gs.CreateUserId, gs.CreateTime, gs.Remark, //gs.IsInConfirm }) .FirstAsync(); _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; _jv.Data = data; return _jv; } /// /// 物品入库 操作(Create Or Edit) /// /// /// /// public async Task GoodsStorageOp(GoodsStorageOpDto dto, int currUserId) { var info = _mapper.Map(dto); info.CreateUserId = currUserId; info.BatchNo = DateTime.Now.ToString("yyyyMMddHHmmssfff"); _sqlSugar.BeginTran(); if (info.Id > 0) //修改 { var selectInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == dto.Id); var auditStatus = selectInfo.ConfirmStatus; if (auditStatus == GoodsConfirmEnum.Confirmed || auditStatus == GoodsConfirmEnum.PartConfirmed) { _sqlSugar.RollbackTran(); _jv.Msg = $"该条入库信息已确认或部分确认审核,不可更改!如若更改请取消已确认或部分确认审核状态!"; return _jv; } var storageEdit = await _sqlSugar.Updateable(info) .UpdateColumns(x => new { x.Quantity, x.UnitPrice, x.TotalPrice, x.SupplierName, x.SupplierTel, x.SupplierAddress, x.SupplierSource, x.StorageUserId, x.StorageTime }) .Where(x => x.Id == dto.Id) .ExecuteCommandAsync(); if (storageEdit < 1) { _sqlSugar.RollbackTran(); _jv.Msg = $"修改失败!"; return _jv; } //入库确认默认状态 多条 or 单条 var auditInfos = await _sqlSugar.Queryable().Where(x => x.Type == 1 && x.DataId == dto.Id).ToListAsync(); if (auditInfos.Any()) { var isAuditPer = false; var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.IsDel == 0 && x.Id == dto.GoodsId); if (goodsInfo != null) { isAuditPer = GoodsAuditType(goodsInfo.Type); } if (!isAuditPer && auditInfos.Count == 1) { var auditInfo = new Pm_GoodsAudit(1, GoodsAuditDepEnum.Financial, dto.Id, GoodsConfirmEnum.WaitConfirm, currUserId); await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync(); } } } else if (info.Id < 1) //添加 { info.ConfirmStatus = GoodsConfirmEnum.WaitConfirm; var storageAddId = await _sqlSugar.Insertable(info).ExecuteReturnIdentityAsync(); if (storageAddId < 1) { _sqlSugar.RollbackTran(); _jv.Msg = $"添加失败!"; return _jv; } //入库确认默认状态 List auditInfos = GoodsStorageConfirm(1, storageAddId, info.CreateUserId); if (auditInfos.Any()) { //验证添加多条或者单条审核状态 var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.IsDel == 0 && x.Id == dto.GoodsId); if (goodsInfo != null) { var isAuditPer = GoodsAuditType(goodsInfo.Type); if (!isAuditPer) auditInfos = auditInfos.Where(x => x.Dep == GoodsAuditDepEnum.Hr).ToList(); } await _sqlSugar.Insertable(auditInfos).ExecuteCommandAsync(); } } _sqlSugar.CommitTran(); _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } /// /// 物品入库 确认操作-默认审核部门 /// /// /// 审核类型 /// 1.入库 2.出库 /// /// dataId /// 审核人 /// public List GoodsStorageConfirm(int auditType, int dataId, int currUserId) { var goodsAuditList = new List { new(auditType, GoodsAuditDepEnum.Hr, dataId, GoodsConfirmEnum.WaitConfirm, currUserId), new(auditType, GoodsAuditDepEnum.Financial, dataId, GoodsConfirmEnum.WaitConfirm, currUserId) }; return goodsAuditList; } /// /// 物品入库 确认操作 /// /// /// public async Task GoodsStorageConfirmStatusChange(GoodsStorageConfirmDto dto, int currUserId) { int gsId = dto.Id; var auditDep = dto.AuditDep; if (gsId < 1) { _jv.Msg = string.Format("{0}", MsgTips.Id); return _jv; } if (currUserId < 1) { _jv.Msg = string.Format("{0}", MsgTips.UserId); return _jv; } //验证审核部门 (bool auditPer, GoodsAuditDepEnum goodsAuditDep) = GoodsAuditDep(currUserId, auditDep, 1); if (!auditPer) { _jv.Msg = string.Format("未分配入库确认权限!"); return _jv; } //入库确认 更改审核状态 _sqlSugar.BeginTran(); var info = await _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.Id == gsId).FirstAsync(); if (info == null) { _jv.Msg = string.Format("入库信息不存在!"); return _jv; } var goodsInfo = await _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.Id == info.GoodsId).FirstAsync(); if (goodsInfo == null) { _jv.Msg = string.Format("物品信息不存在!"); return _jv; } int goodsTypeId = goodsInfo.Type; var preChangeStatus = info.ConfirmStatus; if (preChangeStatus == dto.ConfirmStatus) { _jv.Msg = string.Format("“{0}”已操作,请勿重复该操作!", dto.ConfirmStatus.GetEnumDescription()); return _jv; } var preInfos = await _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.DataId == gsId).ToListAsync(); //验证是否需要多级确认 var isAuditPer = GoodsAuditType(goodsTypeId); //单部门审核时默认人事部审核 if (!isAuditPer) goodsAuditDep = GoodsAuditDepEnum.Hr; var auditInfo = preInfos.FirstOrDefault(x => x.Dep == goodsAuditDep); if (auditInfo != null) { //移除部门审核状态 preInfos.Remove(auditInfo); auditInfo.AuditStatus = dto.ConfirmStatus; auditInfo.AuditUserId = currUserId; auditInfo.AuditTime = DateTime.Now; var updStatus = await _sqlSugar.Updateable(auditInfo) .UpdateColumns(x => new { x.AuditStatus, x.AuditUserId, x.AuditTime }) .ExecuteCommandAsync(); if (updStatus < 1) { _sqlSugar.RollbackTran(); _jv.Msg = string.Format("入库确认失败!"); return _jv; } } else { auditInfo = new Pm_GoodsAudit(1, goodsAuditDep, gsId, dto.ConfirmStatus, currUserId, currUserId); var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync(); if (addStatus < 1) { _sqlSugar.RollbackTran(); _jv.Msg = string.Format("入库确认失败!"); return _jv; } } preInfos.Add(auditInfo); //入库确认 更改入库状态及扣或增加除库存数、金额 var confirmStatus = GoodsConfirmEnum.WaitConfirm; if (isAuditPer) //多级审核确认 { if (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() >= 2) { confirmStatus = GoodsConfirmEnum.Confirmed; } else if (preInfos.Count(x => x.AuditStatus == GoodsConfirmEnum.Confirmed) >= 1) { confirmStatus = GoodsConfirmEnum.PartConfirmed; } else if (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.UnApproved).Count() > 0) { confirmStatus = GoodsConfirmEnum.UnApproved; } else if (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.PartConfirmed).Count() > 0) { confirmStatus = GoodsConfirmEnum.PartConfirmed; } } else //人事部审核确认 { confirmStatus = GoodsConfirmEnum.Confirmed; confirmStatus = dto.ConfirmStatus; preInfos = preInfos.Where(x => x.Dep == GoodsAuditDepEnum.Hr).ToList(); } //入库状态描述 var statusDesc = new StringBuilder(); foreach (var preInfo in preInfos) { string depName = preInfo.Dep.GetEnumDescription(), auditStatus = preInfo.AuditStatus.GetEnumDescription(), auditUserName = preInfo.AuditUserId > 0 ? _sqlSugar.Queryable().First(x => x.Id == preInfo.AuditUserId)?.CnName ?? "-" : "-", auditTime = preInfo.AuditUserId > 0 ? preInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-"; statusDesc.Append(string.Format("{0}:状态:{1} 审核人:{2} 审核时间:{3};
", depName, auditStatus, auditUserName, auditTime)); } //更改入库状态及描述 info.ConfirmStatus = confirmStatus; info.StatusDesc = statusDesc.ToString(); var goodsStorageUpd = await _sqlSugar.Updateable(info) .UpdateColumns(x => new { x.ConfirmStatus, x.StatusDesc, }) .Where(x => x.Id == info.Id) .ExecuteCommandAsync(); if (goodsStorageUpd < 1) { _sqlSugar.RollbackTran(); _jv.Msg = $"入库确认状态更改失败!"; return _jv; } //入库审核通过数量、金额 decimal auditQuantity = info.Quantity, auditTotalPrice = info.TotalPrice; goodsInfo.LastUpdateUserId = currUserId; goodsInfo.LastUpdateTime = DateTime.Now; if (confirmStatus == GoodsConfirmEnum.Confirmed) // 确认状态 { //更改后的状态和更改前的状态不一致时 更改库存数、金额 if (preChangeStatus != confirmStatus) // { goodsInfo.SQ_Total += auditQuantity; goodsInfo.StockQuantity += auditQuantity; goodsInfo.PriceTotal += auditTotalPrice; } } else //其他状态 拒绝、部分确认、等待确认 { //更改前状态为确认状态时,减库存数、金额 if (preChangeStatus == GoodsConfirmEnum.Confirmed) { goodsInfo.SQ_Total -= auditQuantity; goodsInfo.StockQuantity -= auditQuantity; goodsInfo.PriceTotal -= auditTotalPrice; } } var goodsUpd = await _sqlSugar.Updateable(goodsInfo) .UpdateColumns(x => new { x.SQ_Total, x.StockQuantity, x.PriceTotal, x.LastUpdateUserId, x.LastUpdateTime, }) .Where(x => x.Id == info.GoodsId) .ExecuteCommandAsync(); if (goodsUpd > 0) { _sqlSugar.CommitTran(); _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } _sqlSugar.RollbackTran(); _jv.Msg = $"操作失败!"; return _jv; } /// /// 获取物品审核部门 /// /// userId /// 审核部门枚举 /// /// 指定审核类型(入库/出库) /// 1:入库审核 /// 2:出库审核 /// /// public static (bool, GoodsAuditDepEnum) GoodsAuditDep(int userId, GoodsAuditDepEnum auditDepEnum, int auditType = 1) { if (userId < 1) return (false, GoodsAuditDepEnum.Hr); var auditList = GoodsStorageConfirmAuditDep(1); if (auditType == 1) { if (auditList.Any(x => x.AuditDep == auditDepEnum && x.AuditorIds.Contains(userId))) { return (true, auditDepEnum); } } return (false, GoodsAuditDepEnum.Hr); } /// /// 物品审核部门列表 /// /// /// 指定审核类型(入库/出库) /// 1:入库审核 /// 2:出库审核 /// /// public static List GoodsStorageConfirmAuditDep(int auditType = 1) { var auditList = new List(); var hrAuditorIds = new GoodsAuditDepView() { AuditDep = GoodsAuditDepEnum.Hr, AuditorIds = new int[] { 309, // 赖红燕 343, // 陈湘 //374, // 罗颖 208, // 雷怡 } }; var finAuditorIds = new GoodsAuditDepView() { AuditDep = GoodsAuditDepEnum.Financial, AuditorIds = new int[] { 187, // 曾艳 281, // 伏虹瑾 208, // 雷怡 } }; if (auditType == 1)//入库 { hrAuditorIds.AuditorIds = new int[] { //343, // 陈湘 374, // 罗颖 208, // 雷怡 }; auditList.Add(hrAuditorIds); auditList.Add(finAuditorIds); } else if (auditType == 2) //出库 { auditList.Add(hrAuditorIds); auditList.Add(finAuditorIds); } return auditList; } /// /// 物品入库 Del /// /// /// public async Task GoodsStorageDel(int id, int userId) { var storageInfo = await _sqlSugar .Queryable() .Where(x => x.Id == id) .FirstAsync(); if (storageInfo == null) return _jv; var auditStatus = storageInfo.ConfirmStatus; if (auditStatus == GoodsConfirmEnum.Confirmed || auditStatus == GoodsConfirmEnum.PartConfirmed) { _sqlSugar.RollbackTran(); _jv.Msg = $"该条入库信息已确认或部分确认审核,不可删除!如若删除请取消已确认或部分确认审核状态!"; return _jv; } decimal delAgoQuantity = storageInfo.Quantity, delAgoTotalPrice = storageInfo.TotalPrice; var goodsId = storageInfo.GoodsId; _sqlSugar.BeginTran(); var storageDel = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsStorage { DeleteUserId = userId, DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), IsDel = 1 }) .Where(x => x.Id == id) .ExecuteCommandAsync(); if (storageDel < 1) { _sqlSugar.RollbackTran(); _jv.Msg = $"操作失败!"; return _jv; } var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == goodsId); goodsInfo.SQ_Total -= delAgoQuantity; goodsInfo.StockQuantity -= delAgoQuantity; goodsInfo.PriceTotal -= delAgoTotalPrice; goodsInfo.LastUpdateUserId = userId; goodsInfo.LastUpdateTime = DateTime.Now; var goodsEdit = await _sqlSugar.Updateable(goodsInfo) .UpdateColumns(x => new { x.SQ_Total, x.StockQuantity, x.PriceTotal, x.LastUpdateUserId, x.LastUpdateTime, }) .Where(x => x.Id == goodsId) .ExecuteCommandAsync(); if (goodsEdit > 0) { _sqlSugar.CommitTran(); _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } _sqlSugar.RollbackTran(); _jv.Msg = $"操作失败!"; return _jv; } /// /// 物品入库 /// excelDownload /// /// /// public async Task GoodsStorageExcelDownload() { var fileName = $"物资入库{Guid.NewGuid()}.xlsx"; var excelTempPath = $"{_excelPath}Template/物资入库Temp.xlsx"; if (!File.Exists(excelTempPath)) { _jv.Code = StatusCodes.Status204NoContent; _jv.Msg = $"该模板文件不存在!"; return _jv; } _url = $"{_url}Office/Excel/GoodsFiles/"; _excelPath = $"{_excelPath}GoodsFiles"; if (!Directory.Exists(_excelPath)) { Directory.CreateDirectory(_excelPath); } //入库记录 var storageData = await _sqlSugar.Queryable() .LeftJoin((gs, su) => gs.StorageUserId == su.Id) .Where((gs, su) => gs.IsDel == 0) .Select((gs, su) => new { gs.GoodsId, gs.Quantity, su.CnName, gs.StorageTime }) .ToListAsync(); //出库记录 var receiveData = await _sqlSugar.Queryable() .LeftJoin((gr, su) => gr.CreateUserId == su.Id) .Where((gr, su) => gr.IsDel == 0) .Select((gr, su) => new { gr.GoodsId, gr.Quantity, su.CnName, gr.CreateTime, gr.Reason }) .ToListAsync(); var data = await _sqlSugar.Queryable() .Where(gi => gi.IsDel == 0) .Select(gi => new GoodsStorageExcelDownloadView { Id = gi.Id, Name = gi.Name, SQ_Total = gi.SQ_Total, OQ_Total = gi.OQ_Total, StockQuantity = gi.StockQuantity, Unit = gi.Unit }) .ToListAsync(); foreach (var item in data) { var storageData1 = storageData.Where(x => x.GoodsId == item.Id).ToList(); if (storageData1.Any()) { item.SQ_Total1 = storageData1.Sum(x => x.Quantity); item.SQ_Total -= item.SQ_Total1; item.StorageLabel = string.Join("\r\n", storageData1.Select(x => "数量:【" + x.Quantity.ToString("#0.00") + "】 入库人:【" + x.CnName + "】 入库时间:【" + x.StorageTime + "】").ToList()); } var receiveData1 = receiveData.Where(x => x.GoodsId == item.Id).ToList(); if (receiveData1.Any()) { item.ReceiveLabel = string.Join("\r\n", receiveData1.Select(x => "数量:【" + x.Quantity.ToString("#0.00") + "】 申请人:【" + x.CnName + "】 申请时间:【" + x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") + "】 原因:【" + x.Reason + "】").ToList()); } } //载入模板 WorkbookDesigner designer = new() { Workbook = new Workbook(excelTempPath) }; designer.SetDataSource("Export", data); designer.Process(); #region 渲染Cell批注 var sheet = designer.Workbook.Worksheets[0]; for (int i = 0; i < data.Count; i++) { string storageComment = $"C{i + 2}", receiveComment = $"D{i + 2}", storageCommentText = data[i].StorageLabel, receiveCommentText = data[i].ReceiveLabel; if (!string.IsNullOrEmpty(storageCommentText)) { int storageIndex = sheet.Comments.Add(storageComment); Aspose.Cells.Comment comment = sheet.Comments[storageIndex]; comment.Note = storageCommentText; comment.Width = 500; comment.Height = 200; //comment.Font.Color = Color.Red; } if (!string.IsNullOrEmpty(receiveCommentText)) { int receiveIndex = sheet.Comments.Add(receiveComment); Aspose.Cells.Comment comment = sheet.Comments[receiveIndex]; comment.Note = receiveCommentText; comment.Width = 800; comment.Height = 200; //comment.Font.Color = Color.Red; } } #endregion string serverPath = $"{_url}{fileName}"; designer.Workbook.Save($"{_excelPath}/{fileName}"); _jv.Code = StatusCodes.Status200OK; _jv.Data = new { url = serverPath }; _jv.Msg = $"操作成功"; return _jv; } /// /// 物品领用列表 /// /// /// public async Task GoodsReceiveList(GoodsReceiveListDTO dto) { //参数处理 int[] typeLabel = Array.Empty(), userLabel = Array.Empty(), auditLabel = Array.Empty(), groupLabel = Array.Empty(); string[] userNameLabel = Array.Empty(); int currUserId = dto.CurrUserId; if (!string.IsNullOrEmpty(dto.TypeLabel)) { typeLabel = dto.TypeLabel .Split(',') .Select(x => { if (int.TryParse(x, out var id)) return id; return id; }) .ToArray(); } if (!string.IsNullOrEmpty(dto.UserLabel)) { userLabel = dto.UserLabel .Split(',') .Select(x => { if (int.TryParse(x, out var id)) return id; return id; }) .ToArray(); if (userLabel.Any()) { userNameLabel = await _sqlSugar.Queryable().Where(x => userLabel.Contains(x.Id)).Select(x => x.CnName).ToArrayAsync(); } } if (!string.IsNullOrEmpty(dto.AuditLabel)) { auditLabel = dto.AuditLabel .Split(',') .Select(x => { if (int.TryParse(x, out var id)) return id; return id; }) .ToArray(); if (auditLabel.Any(x => x == -1)) { auditLabel = auditLabel.Where(x => x != -1).ToArray(); } } if (!string.IsNullOrEmpty(dto.GroupLabel)) { groupLabel = dto.GroupLabel .Split(',') .Select(x => { if (int.TryParse(x, out var id)) return id; return id; }) .ToArray(); } //全部团组 bool isAllGroups = false; if (groupLabel.Contains(-3)) isAllGroups = true; //物品ID和物品名称只能传一个 if (dto.GoodsId > 0) dto.GoodsName = string.Empty; if (!string.IsNullOrEmpty(dto.GoodsName)) dto.GoodsId = 0; if (currUserId == 343) //陈湘OAId登录 只显示贵重物品审核信息 { if (_goodsTypeIds.Any()) { var newArray = typeLabel.ToList(); newArray.AddRange(_goodsTypeIds); typeLabel = newArray.ToArray(); } } var beginBool = DateTime.TryParse(!string.IsNullOrEmpty(dto.BeginDt) ? $"{dto.BeginDt} 00:00:00" : string.Empty, out var begin); var endBool = DateTime.TryParse(!string.IsNullOrEmpty(dto.EndDt) ? $"{dto.EndDt} 00:00:00" : string.Empty, out var end); //新旧领用数据整合 var oldDatas = _sqlSugar.Queryable() .InnerJoin((gr, gi) => gr.GoodsId == gi.Id) .LeftJoin((gr, gi, sd) => gi.Type == sd.Id) .LeftJoin((gr, gi, sd, u1) => gr.AuditUserId == u1.Id) .LeftJoin((gr, gi, sd, u1, u2) => gr.CreateUserId == u2.Id) .LeftJoin((gr, gi, sd, u1, u2, di) => gr.GroupId == di.Id) .Where((gr, gi, sd, u1, u2, di) => gr.IsDel == 0 && gr.GoodsId > 0) .Select((gr, gi, sd, u1, u2, di) => new GoodsReceiveListMobileView { Id = gr.Id, GroupId = gr.GroupId, GroupName = di.TeamName, GoodsId = gr.GoodsId, GoodsName = gi.Name, GoodsTypeId = gi.Type, GoodsType = sd.Name, Quantity = gr.Quantity, Unit = gi.Unit, Reason = gr.Reason, Remark = gr.Remark, AuditStatus = gr.AuditStatus, StatusDesc = gr.StatusDesc, AuditUserId = gr.AuditUserId, AuditUserName = u1.CnName, AuditTime = gr.AuditTime, CreateUserName = u2.CnName, CreateTime = gr.CreateTime }); var newDatas = _sqlSugar.Queryable() .LeftJoin((gr, grd) => gr.Id == grd.GoodsReceiveId) .LeftJoin((gr, grd, gi) => grd.GoodsId == gi.Id) .LeftJoin((gr, grd, gi, sd) => gi.Type == sd.Id) .LeftJoin((gr, grd, gi, sd, u1) => gr.AuditUserId == u1.Id) .LeftJoin((gr, grd, gi, sd, u1, u2) => gr.CreateUserId == u2.Id) .LeftJoin((gr, grd, gi, sd, u1, u2, di) => gr.GroupId == di.Id) .Where((gr, grd, gi, sd, u1, u2, di) => gr.IsDel == 0 && grd.IsDel == 0 && gr.GoodsId < 1) .Select((gr, grd, gi, sd, u1, u2, di) => new GoodsReceiveListMobileView { Id = gr.Id, GroupId = gr.GroupId, GroupName = di.TeamName, GoodsId = gr.GoodsId, GoodsName = gi.Name, GoodsTypeId = gi.Type, GoodsType = sd.Name, Quantity = grd.Quantity, Unit = gi.Unit, Reason = gr.Reason, Remark = gr.Remark, AuditStatus = gr.AuditStatus, StatusDesc = gr.StatusDesc, AuditUserId = gr.AuditUserId, AuditUserName = u1.CnName, AuditTime = gr.AuditTime, CreateUserName = u2.CnName, CreateTime = gr.CreateTime }); var isIdSelect = false; var isNameSelect = false; if (dto.GoodsId > 0) { isIdSelect = true; dto.GoodsName = string.Empty; } if (!string.IsNullOrEmpty(dto.GoodsName)) { isIdSelect = false; isNameSelect = true; } RefAsync total = 0; var data = _sqlSugar.UnionAll(oldDatas, newDatas) .WhereIF(isIdSelect && !isNameSelect, x => x.GoodsId == dto.GoodsId) .WhereIF(!isIdSelect && isNameSelect, x => x.GoodsName.Contains(dto.GoodsName)) .WhereIF(auditLabel.Length > 0, x => auditLabel.Contains((int)x.AuditStatus)) .WhereIF(typeLabel.Length > 0, x => typeLabel.Contains(x.GoodsTypeId)) .WhereIF(userNameLabel.Length > 0, x => userNameLabel.Contains(x.CreateUserName)) .WhereIF(!isAllGroups && groupLabel.Length > 0, x => groupLabel.Contains(x.GroupId)) .WhereIF(isAllGroups, x => x.GroupId > 0) .WhereIF(beginBool && endBool, x => x.CreateTime >= begin && x.CreateTime <= end) .OrderByDescending(x => x.CreateTime); //excel导出 if (dto.IsExcelDownload) { var fileName = $"物资领用{Guid.NewGuid()}.xlsx"; var excelTempPath = $"{_excelPath}Template/物资领用Temp.xlsx"; if (!File.Exists(excelTempPath)) { _jv.Code = StatusCodes.Status204NoContent; _jv.Msg = $"该模板文件不存在!"; return _jv; } _url = $"{_url}Office/Excel/GoodsFiles/"; _excelPath = $"{_excelPath}GoodsFiles"; if (!Directory.Exists(_excelPath)) { Directory.CreateDirectory(_excelPath); } //载入模板 WorkbookDesigner designer = new() { Workbook = new Workbook(excelTempPath) }; var tableData = await data.ToListAsync(); foreach (var item in tableData) { var oldGroupName = item.GroupName; item.GroupName = item.GroupId switch { 0 => "其他物资(公司内部物资)", -1 => "拜访客户所使用的物资", -2 => "库存调整", _ => oldGroupName }; //审核相关处理 if (string.IsNullOrEmpty(item.AuditUserName)) { var oldAuditDatas = await _sqlSugar.Queryable() .LeftJoin((x, u) => x.AuditUserId == u.Id) .Where((x, u) => x.IsDel == 0 && x.Type == 2 && x.DataId == item.Id) .Select((x, u) => new { x.AuditTime, u.CnName }) .ToListAsync(); if (oldAuditDatas.Any()) { item.AuditUserName = string.Join("、", oldAuditDatas.Select(x => x.CnName).ToArray()); if (!string.IsNullOrEmpty(item.AuditUserName)) { item.AuditTime = oldAuditDatas.Last().AuditTime; } else item.AuditTime = DateTime.Now; } else { var newAuditDatas = await _sqlSugar.Queryable() .InnerJoin((x, y) => x.FlowId == y.Id) .Where((x, y) => x.IsDel == 0 && y.BusinessType == 1 && y.BusinessId == item.Id) .Select((x, y) => new { x.AuditTime, x.AuditorName }) .ToListAsync(); if (newAuditDatas.Any()) { item.AuditUserName = string.Join("、", newAuditDatas.Select(x => x.AuditorName).Distinct().ToArray()); if (!string.IsNullOrEmpty(item.AuditUserName)) { item.AuditTime = newAuditDatas.Last().AuditTime; } else item.AuditTime = DateTime.Now; } } } } designer.SetDataSource("Export", tableData); designer.Process(); string serverPath = $"{_url}{fileName}"; designer.Workbook.Save($"{_excelPath}/{fileName}"); _jv.Code = StatusCodes.Status200OK; _jv.Data = new { url = serverPath }; _jv.Msg = $"操作成功"; return _jv; } //返回分页数据 var view = await data.ToPageListAsync(dto.PageIndex, dto.PageSize, total); foreach (var item in view) { //团组名称处理 var oldGroupName = item.GroupName; item.GroupName = item.GroupId switch { 0 => "其他物资(公司内部物资)", -1 => "拜访客户所使用的物资", -2 => "库存调整", _ => oldGroupName }; //审核相关处理 if (string.IsNullOrEmpty(item.AuditUserName)) { var oldAuditDatas = await _sqlSugar.Queryable() .LeftJoin((x, u) => x.AuditUserId == u.Id) .Where((x, u) => x.IsDel == 0 && x.Type == 2 && x.DataId == item.Id) .Select((x, u) => new { x.AuditTime, u.CnName }) .ToListAsync(); if (oldAuditDatas.Any()) { item.AuditUserName = string.Join("、", oldAuditDatas.Select(x => x.CnName).ToArray()); if (!string.IsNullOrEmpty(item.AuditUserName)) { item.AuditTime = oldAuditDatas.Last().AuditTime; } else item.AuditTime = DateTime.Now; } else { var newAuditDatas = await _sqlSugar.Queryable() .InnerJoin((x, y) => x.FlowId == y.Id) .Where((x, y) => x.IsDel == 0 && y.BusinessType == 1 && y.BusinessId == item.Id) .Select((x, y) => new { x.AuditTime, x.AuditorName }) .ToListAsync(); if (newAuditDatas.Any()) { item.AuditUserName = string.Join("、", newAuditDatas.Select(x => x.AuditorName).Distinct().ToArray()); if (!string.IsNullOrEmpty(item.AuditUserName)) { item.AuditTime = newAuditDatas.Last().AuditTime; } else item.AuditTime = DateTime.Now; } } } //权限前台验证 var auditPers = new List { new() { AuditPer = true, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr_Reception.GetDescription() } }; if (_goodsTypeIds.Contains(item.GoodsTypeId)) { auditPers.Add(new() { AuditPer = true, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr.GetDescription() }); } item.AuditPers = auditPers.ToArray(); } if (dto.PortType == 2 || dto.PortType == 3) { _jv.Data = view; } else if (dto.PortType == 1) { var view1 = _mapper.Map>(view); _jv.Data = view1; } _jv.Code = StatusCodes.Status200OK; _jv.Count = total; _jv.Msg = $"操作成功"; return _jv; } /// /// 物品领用详情 /// /// /// /// public async Task GoodsReceiveInfo(int portType, int id) { var data = await _sqlSugar.Queryable() .LeftJoin((gr, gi) => gr.GoodsId == gi.Id) .LeftJoin((gr, gi, u1) => gr.AuditUserId == u1.Id) .LeftJoin((gr, gi, u1, u2) => gr.CreateUserId == u2.Id) .LeftJoin((gr, gi, u1, u2, di) => gr.GroupId == di.Id) .Where((gr, gi, u1, u2, di) => gr.IsDel == 0) .WhereIF(id > 0, (gr, gi, u1, u2, di) => gr.Id == id) .Select((gr, gi, u1, u2, di) => new GoodsReceiveInfoMobileView { Id = gr.Id, GroupId = gr.GroupId, GroupName = di.TeamName, GoodsId = gr.GoodsId, GoodsName = gi.Name, Quantity = gr.Quantity, Reason = gr.Reason, Remark = gr.Remark, GoodsStorageInfo = gr.GoodsStorageInfo, AuditStatus = gr.AuditStatus, AuditUserId = gr.AuditUserId, AuditUserName = u1.CnName, AuditTime = gr.AuditTime, CreateUserName = u2.CnName, CreateTime = gr.CreateTime }) .FirstAsync(); if (!string.IsNullOrEmpty(data.GoodsStorageInfo)) { var subData = new List(); try { var subData1 = JsonConvert.DeserializeObject>(data.GoodsStorageInfo); if (subData1.Count > 0) { string goodsStorageInfoStr = string.Empty; var storageIds = subData1.Select(x => x.StorageId).ToList(); var storages = await _sqlSugar.Queryable().Where(x => x.IsDel == 0 && storageIds.Contains(x.Id)).ToListAsync(); foreach (var item in subData1) { var storageInfo = storages.Find(x => x.Id == item.StorageId); if (storageInfo != null) { subData.Add(new { item.StorageId, storageInfo.BatchNo, RecsiveQuantity = item.Quantity }); goodsStorageInfoStr += $"物品名称:{data.GoodsName} 批次号:{storageInfo.BatchNo} 领用数量:{item.Quantity} \r\n"; } } data.QuantityInfos = subData; data.GoodsStorageInfoStr = goodsStorageInfoStr; } } catch (Exception e) { Console.WriteLine(e); } } _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"操作成功"; if (portType == 2 || portType == 3) //移动端 { _jv.Data = data; } else if (portType == 1) //pc端 { _jv.Data = _mapper.Map(data); } return _jv; } /// /// 物品领用 OP(Add Or Edit) /// /// /// /// public async Task GoodsReceiveOp(GoodsReceiveOpDto dto, int currUserId) { var info = _mapper.Map(dto); info.CreateUserId = currUserId; var auditEnums = new List() { GoodsAuditEnum.Approved, // 1 GoodsAuditEnum.UnApproved, // 2 GoodsAuditEnum.OutConfirmed,// 5 GoodsAuditEnum.OutRejected // 6 }; _sqlSugar.BeginTran(); //物品现有库存 var goodsInfo = _sqlSugar.Queryable().First(x => x.Id == info.GoodsId); var stockQuantity = goodsInfo?.StockQuantity ?? 0.00M; //待审核 该物品数量 var waitAuditQuantity = await _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.GoodsId == dto.GoodsId && !auditEnums.Contains(x.AuditStatus) ).SumAsync(x => x.Quantity); //验证默认审核 多条 or 单条 //出库确认默认审核状态 var isAuditPer = GoodsAuditType(goodsInfo?.Type ?? 0); //验证默认审核 多条审核时添加 var goodsAuditInfo1 = new Pm_GoodsAudit(2, GoodsAuditDepEnum.Hr_Reception, info.Id, GoodsConfirmEnum.WaitConfirm, currUserId); var goodsAuditInfo2 = new Pm_GoodsAudit(2, GoodsAuditDepEnum.Hr, info.Id, GoodsConfirmEnum.WaitConfirm, currUserId); var goodsAuditInfos = new List() { goodsAuditInfo1 }; //状态描述 StringBuilder stringBuilder = new(); stringBuilder.Append($"领用确认:状态:待确认 审核人:- 审核时间:-;
"); if (isAuditPer) { goodsAuditInfos.Add(goodsAuditInfo2); stringBuilder.Append($"人事部:状态:待确认 审核人:- 审核时间:-;
"); } info.StatusDesc = stringBuilder.ToString(); if (info.Id > 0) //修改 { //审核验证 var selectInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == info.Id); if (auditEnums.Contains(selectInfo.AuditStatus)) { _sqlSugar.RollbackTran(); _jv.Msg = $"该条数据已执行操作({selectInfo.AuditStatus.GetEnumDescription()}),不可更改!"; return _jv; } //物品数量验证 var editAfterQuantity = waitAuditQuantity - selectInfo.Quantity + info.Quantity; if (editAfterQuantity > stockQuantity) { _sqlSugar.RollbackTran(); _jv.Msg = $"该物品现有库存不足,不可更改!请联系采购人员购买!"; return _jv; } var edit = await _sqlSugar.Updateable(info) .UpdateColumns(x => new { x.GroupId, x.Quantity, x.Reason, x.Remark, x.StatusDesc, }) .Where(x => x.Id == info.Id) .ExecuteCommandAsync(); if (edit > 0) { var auditInfos = await _sqlSugar.Queryable().Where(x => x.DataId == info.Id).ToListAsync(); if (!auditInfos.Any()) await _sqlSugar.Insertable(goodsAuditInfos).ExecuteCommandAsync(); _sqlSugar.CommitTran(); _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } } else if (info.Id < 1) //添加 { //物品数量验证 decimal addAgoQuantity = waitAuditQuantity + info.Quantity; if (addAgoQuantity > stockQuantity) { _sqlSugar.RollbackTran(); _jv.Msg = $"该物品现有库存不足,不可更改!请联系采购人员购买!"; return _jv; } var add = await _sqlSugar.Insertable(info).ExecuteReturnIdentityAsync(); if (add > 0) { goodsAuditInfos.ForEach(x => x.DataId = add); await _sqlSugar.Insertable(goodsAuditInfos).ExecuteCommandAsync(); _sqlSugar.CommitTran(); _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } } _sqlSugar.RollbackTran(); return _jv; } /// /// 物品领用 Audit /// /// /// /// /// public async Task GoodsReceiveAudit(int[] idArray, int userId, GoodsAuditEnum auditEnum) { if (idArray.Length < 1) return _jv; if (!Enum.IsDefined(typeof(GoodsAuditEnum), (int)auditEnum)) { _jv.Msg = $"出库确认状态超出可用范围!"; return _jv; } int receiveId = idArray[0]; var currUserName = _sqlSugar.Queryable().First(x => x.Id == userId)?.CnName ?? "-"; _sqlSugar.BeginTran(); var receiveInfo = await _sqlSugar.Queryable().FirstAsync(x => x.IsDel == 0 && receiveId == x.Id); if (receiveInfo == null) { _sqlSugar.RollbackTran(); _jv.Msg = $"当前领用信息不存在!"; return _jv; } var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == receiveInfo.GoodsId); int goodTypeId = goodsInfo?.Type ?? 0; //审核前状态 var preChangeStatus = receiveInfo.AuditStatus; //状态验证 //if (preChangeStatus == auditEnum) //{ // _sqlSugar.RollbackTran(); // _jv.Msg = $"该条数据状态已设置,不可重复设置!"; // return _jv; //} var isAuditPer = GoodsAuditType(goodTypeId); if (isAuditPer) //多人审核 { var auditDep = GoodsAuditDepEnum.Hr_Reception; var auditInfo = await _sqlSugar.Queryable() .FirstAsync(x => x.Type == 2 && x.DataId == receiveInfo.Id && x.Dep == GoodsAuditDepEnum.Hr_Reception); if (auditInfo != null && auditInfo.AuditStatus == GoodsConfirmEnum.Confirmed) { auditDep = GoodsAuditDepEnum.Hr; //多人审核的时候验证审核权限 var auditList = GoodsStorageConfirmAuditDep(2); var auditDepInfo = auditList.Find(x => x.AuditorIds.Contains(userId)); if (auditDepInfo == null) { _jv.Msg = string.Format("未分配出库确认权限!"); _sqlSugar.RollbackTran(); return _jv; } } // 确认中 确认 拒绝 _jv = await GoodsReceiveOutConfirmingMultiple(receiveInfo, userId, auditDep, auditEnum); //switch (auditEnum) //{ // case GoodsAuditEnum.Pending: //领用待确认(取消确认、取消拒绝) // _jv = await GoodsReceivePending(preChangeStatus, receiveId, userId, currUserName, auditEnum); // break; // case GoodsAuditEnum.Approved: //领用确认 // _jv = await GoodsReceiveApproved(preChangeStatus, receiveId, userId, currUserName, auditEnum); // break; // case GoodsAuditEnum.UnApproved: //领用拒绝 // _jv = await GoodsReceiveUnApproved(preChangeStatus, receiveId, userId, currUserName, auditEnum); // break; // case GoodsAuditEnum.OutPending: //出库待确认(取消出库确认、取消出库拒绝) // _jv = await GoodsReceiveOutPending(preChangeStatus, receiveInfo, userId, auditDep, auditEnum); // break; // case GoodsAuditEnum.OutConfirmed: //出库确认 // _jv = await GoodsReceiveOutConfirming(receiveInfo, userId, auditDep, auditEnum); // break; // case GoodsAuditEnum.OutRejected: //出库拒绝 // _jv = await GoodsReceiveOutConfirming(receiveInfo, userId, auditDep, auditEnum); // break; //} } else //单人审核 { //领用确认 --> 已确认 / 领用拒绝 --> 已拒绝 _jv = await GoodsReceiveOutConfirmingSingle(receiveInfo, userId, currUserName, auditEnum); } if (_jv.Code == StatusCodes.Status200OK) { _sqlSugar.CommitTran(); _jv.Msg = $"操作成功!"; _jv.Data = auditEnum; return _jv; } _sqlSugar.RollbackTran(); return _jv; } #region 多人审核状态变更 /// /// 物品领用状态 - 领用待确认(取消确认、取消拒绝) /// /// 更改前状态 /// /// /// /// /// public async Task GoodsReceivePending(GoodsAuditEnum preChangeStatus, int receiveId, int userId, string userName, GoodsAuditEnum auditEnum) { _jv.Code = StatusCodes.Status400BadRequest; //领用待确认 操作范围 var audirEnumPers = new List() { GoodsAuditEnum.Approved, GoodsAuditEnum.UnApproved }; if (!audirEnumPers.Contains(preChangeStatus)) { _jv.Msg = $"{GoodsAuditEnum.Approved.GetEnumDescription()}、{GoodsAuditEnum.UnApproved.GetEnumDescription()},状态下可取消操作!"; return _jv; } var currUserOpDt = DateTime.Now; var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss"); var statusDesc = string.Format(@"领用确认:状态:{0} 审核人:{1} 审核时间:{2};
人事部确认:状态:待确认 审核人:- 审核时间:-;
财务部确认:状态:待确认 审核人:- 审核时间:-;", auditEnum.GetEnumDescription(), userName, currUserOpTime); auditEnum = GoodsAuditEnum.Pending; var changeStatus = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, AuditUserId = userId, AuditTime = currUserOpDt, StatusDesc = statusDesc }) .Where(x => x.Id == receiveId) .ExecuteCommandAsync(); if (changeStatus > 0) { _jv.Code = StatusCodes.Status200OK; } return _jv; } /// /// 物品领用状态 - 领用确认 /// /// 更改前状态 /// /// /// /// /// public async Task GoodsReceiveApproved(GoodsAuditEnum preChangeStatus, int receiveId, int userId, string userName, GoodsAuditEnum auditEnum) { _jv.Code = StatusCodes.Status400BadRequest; if (preChangeStatus != GoodsAuditEnum.Pending) { _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()},状态下可取消操作!"; return _jv; } var currUserOpDt = DateTime.Now; var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss"); var statusDesc = string.Format(@"领用确认:状态:{0} 审核人:{1} 审核时间:{2};
人事部确认:状态:待确认 审核人:- 审核时间:-;
财务部确认:状态:待确认 审核人:- 审核时间:-;", auditEnum.GetEnumDescription(), userName, currUserOpTime); auditEnum = GoodsAuditEnum.OutPending; var changeStatus = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, AuditUserId = userId, AuditTime = currUserOpDt, StatusDesc = statusDesc }) .Where(x => x.Id == receiveId) .ExecuteCommandAsync(); if (changeStatus > 0) { _jv.Code = StatusCodes.Status200OK; } return _jv; } /// /// 物品领用状态 - 领用拒绝 /// /// 更改前状态 /// /// /// /// /// public async Task GoodsReceiveUnApproved(GoodsAuditEnum preChangeStatus, int receiveId, int userId, string userName, GoodsAuditEnum auditEnum) { _jv.Code = StatusCodes.Status400BadRequest; if (preChangeStatus != GoodsAuditEnum.Pending) { _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()},状态下可取消操作!"; return _jv; } auditEnum = GoodsAuditEnum.UnApproved; var currUserOpDt = DateTime.Now; var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss"); var statusDesc = string.Format(@"领用确认:状态:{0} 审核人:{1} 审核时间:{2};
人事部确认:状态:待确认 审核人:- 审核时间:-;
财务部认:状态:待确认 审核人:- 审核时间:-;
", auditEnum.GetEnumDescription(), userName, currUserOpTime); var changeStatus = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, AuditUserId = userId, AuditTime = currUserOpDt, StatusDesc = statusDesc }) .Where(x => x.Id == receiveId) .ExecuteCommandAsync(); if (changeStatus > 0) { _jv.Code = StatusCodes.Status200OK; } return _jv; } /// /// 物品领用状态 - 出库待确认(出库确认、出库拒绝) /// /// 更改前状态 /// /// /// /// /// public async Task GoodsReceiveOutPending(GoodsAuditEnum preChangeStatus, Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum, GoodsAuditEnum auditEnum) { _jv.Code = StatusCodes.Status400BadRequest; //出库待确认 操作范围 var audirEnumPers = new List() { GoodsAuditEnum.OutConfirmed, GoodsAuditEnum.OutRejected }; if (!audirEnumPers.Contains(preChangeStatus)) { _jv.Msg = $"{GoodsAuditEnum.OutConfirmed.GetEnumDescription()}、{GoodsAuditEnum.OutRejected.GetEnumDescription()},状态下可取消操作!"; return _jv; } var currUserOpDt = DateTime.Now; var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss"); var auditInfos = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2) .ToListAsync(); auditEnum = GoodsAuditEnum.OutPending; var auditStatus = GoodsConfirmEnum.WaitConfirm; var auditInfo = auditInfos.Find(x => x.Dep == depEnum); if (auditInfo == null) { auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId); var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync(); if (addStatus < 1) { _jv.Msg = $"出库确认取消操作失败!"; return _jv; } auditInfos.Add(auditInfo); } else { //移除旧数据 auditInfos.Remove(auditInfo); auditInfo.AuditStatus = auditStatus; auditInfo.AuditUserId = userId; auditInfo.AuditTime = currUserOpDt; var updStatus = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsAudit() { AuditStatus = auditStatus, AuditUserId = userId, AuditTime = currUserOpDt }) .Where(x => x.Id == auditInfo.Id) .ExecuteCommandAsync(); if (updStatus < 1) { _jv.Msg = $"出库确认操作失败!"; return _jv; } //添加更新后的数据 auditInfos.Add(auditInfo); } //处理状态描述 StringBuilder statusDesc = new(); var receiveUserName = _sqlSugar.Queryable().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-"; string receiveStatusDesc = string.Format("{0}:状态:{1} 审核人:{2} 审核时间:{3};
", "领用确认", GoodsAuditEnum.Approved.GetEnumDescription(), receiveUserName, receiveInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss")); statusDesc.Append(receiveStatusDesc); foreach (var auditInf in auditInfos) { string userName = _sqlSugar.Queryable().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-"; string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-"; string auditInfStatusDesc = string.Format("{0}:状态:{1} 审核人:{2} 审核时间:{3};
", auditInf.Dep.GetEnumDescription(), auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime); statusDesc.Append(auditInfStatusDesc); } //批次库存信息 string goodsStorageInfo = receiveInfo.GoodsStorageInfo; //出库确认取消是单独处理 if (preChangeStatus == GoodsAuditEnum.OutConfirming) { if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1) { auditEnum = GoodsAuditEnum.OutConfirming; } //2.1 更改库存 var goodsInfo = await _sqlSugar.Queryable().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync(); goodsInfo.StockQuantity -= receiveInfo.Quantity; goodsInfo.OQ_Total += receiveInfo.Quantity; goodsInfo.LastUpdateTime = DateTime.Now; goodsInfo.LastUpdateUserId = userId; var editGoods = await _sqlSugar .Updateable(goodsInfo) .UpdateColumns(x => new { x.StockQuantity, x.OQ_Total, x.LastUpdateUserId, x.LastUpdateTime, }) .Where(x => x.Id == receiveInfo.GoodsId) .ExecuteCommandAsync(); if (editGoods < 1) { _jv.Msg = $"库存更新失败!"; return _jv; } //2.2 入库批次关联领用人 更改批次库存 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == receiveInfo.GoodsId && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); var receiveQuantity = 0.00M; //领用总数量 foreach (var storage in goodsStorages) { if (receiveInfo.Quantity == receiveQuantity) break; var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity; if (thisBatchSurplusQuantity <= 0.00M) continue; var thisBatchReceiveQuantity = 0.00M; //此批次领用数量 const decimal unit = 0.50M; while (receiveQuantity < receiveInfo.Quantity) { if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break; thisBatchReceiveQuantity += unit; receiveQuantity += unit; } goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView { StorageId = storage.Id, Quantity = thisBatchReceiveQuantity }); storage.ReceiveQuantity += thisBatchReceiveQuantity; var storageUpd = storage; //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity; batchStorageInfos.Add(storageUpd); } //2.2.1 更改批次库存 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable(batchStorageInfos) .UpdateColumns(x => x.ReceiveQuantity) .WhereColumns(x => x.Id) .ExecuteCommandAsync(); if (edit1 < 1) { _jv.Msg = $"批次库存更新失败!"; return _jv; } } //2.2.2 添加入库批次关联领用人 if (goodsReceiveInfos.Count > 0) { goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos); } } var statusDesc1 = statusDesc.ToString(); var changeStatus = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, StatusDesc = statusDesc1, GoodsStorageInfo = goodsStorageInfo }) .Where(x => x.Id == receiveInfo.Id) .ExecuteCommandAsync(); if (changeStatus > 0) { _jv.Code = StatusCodes.Status200OK; } return _jv; } /// /// 物品领用状态 - 出库确认中、出库确认完成、出库确认拒绝 /// /// /// /// /// /// public async Task GoodsReceiveOutConfirming(Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum, GoodsAuditEnum auditEnum) { _jv.Code = StatusCodes.Status400BadRequest; //更改前状态 var preChangeStatus = receiveInfo.AuditStatus; if (preChangeStatus < GoodsAuditEnum.OutPending) { _jv.Msg = $"领用确认执行成功!才可执行出库确认或出库拒绝操作!"; return _jv; } var currUserOpDt = DateTime.Now; var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss"); var auditInfos = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2) .ToListAsync(); var auditStatus = GoodsConfirmEnum.WaitConfirm; if (auditEnum == GoodsAuditEnum.OutRejected) auditStatus = GoodsConfirmEnum.UnApproved; else if (auditEnum == GoodsAuditEnum.OutConfirmed) auditStatus = GoodsConfirmEnum.Confirmed; var auditInfo = auditInfos.Find(x => x.Dep == depEnum); if (auditInfo == null) { auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId); var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync(); if (addStatus < 1) { _jv.Msg = $"出库确认操作失败!"; return _jv; } auditInfos.Add(auditInfo); } else { //移除旧数据 auditInfos.Remove(auditInfo); auditInfo.AuditStatus = auditStatus; auditInfo.AuditUserId = userId; auditInfo.AuditTime = currUserOpDt; var updStatus = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsAudit() { AuditStatus = auditStatus, AuditUserId = userId, AuditTime = currUserOpDt }) .Where(x => x.Id == auditInfo.Id) .ExecuteCommandAsync(); if (updStatus < 1) { _jv.Msg = $"出库确认操作失败!"; return _jv; } //添加更新后的数据 auditInfos.Add(auditInfo); } //处理状态描述 StringBuilder statusDesc = new(); var receiveUserName = _sqlSugar.Queryable().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-"; string receiveStatusDesc = string.Format("{0}:状态:{1} 审核人:{2} 审核时间:{3};
", "领用确认", GoodsAuditEnum.Approved.GetEnumDescription(), receiveUserName, receiveInfo.AuditTime.ToString("yyyy-MM-dd HH:mm:ss")); statusDesc.Append(receiveStatusDesc); foreach (var auditInf in auditInfos) { string userName = _sqlSugar.Queryable().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-"; string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-"; string auditInfStatusDesc = string.Format("{0}:状态:{1} 审核人:{2} 审核时间:{3};
", auditInf.Dep.GetEnumDescription(), auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime); statusDesc.Append(auditInfStatusDesc); } if (preChangeStatus == auditEnum) { _jv.Msg = $"此操作已执行,不可重复操作!"; return _jv; } //批次库存信息 string goodsStorageInfo = receiveInfo.GoodsStorageInfo; //更改领用状态及库存 if (auditInfos.Any(x => x.AuditStatus == GoodsConfirmEnum.UnApproved)) { //出库确认拒绝 auditEnum = GoodsAuditEnum.OutRejected; } else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 2) { //1.出库确认完成 auditEnum = GoodsAuditEnum.OutConfirmed; //2.更改前的状态为出库确认中 且 更改后的状态为出库确认完成 执行库存减操作 if (preChangeStatus == GoodsAuditEnum.OutConfirming || preChangeStatus == GoodsAuditEnum.OutRejected) { //2.1 更改库存 var goodsInfo = await _sqlSugar.Queryable().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync(); goodsInfo.StockQuantity -= receiveInfo.Quantity; goodsInfo.OQ_Total += receiveInfo.Quantity; goodsInfo.LastUpdateTime = DateTime.Now; goodsInfo.LastUpdateUserId = userId; var editGoods = await _sqlSugar .Updateable(goodsInfo) .UpdateColumns(x => new { x.StockQuantity, x.OQ_Total, x.LastUpdateUserId, x.LastUpdateTime, }) .Where(x => x.Id == receiveInfo.GoodsId) .ExecuteCommandAsync(); if (editGoods < 1) { _jv.Msg = $"库存更新失败!"; return _jv; } //2.2 入库批次关联领用人 更改批次库存 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == receiveInfo.GoodsId && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); var receiveQuantity = 0.00M; //领用总数量 foreach (var storage in goodsStorages) { if (receiveInfo.Quantity == receiveQuantity) break; var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity; if (thisBatchSurplusQuantity <= 0.00M) continue; var thisBatchReceiveQuantity = 0.00M; //此批次领用数量 const decimal unit = 0.50M; while (receiveQuantity < receiveInfo.Quantity) { if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break; thisBatchReceiveQuantity += unit; receiveQuantity += unit; } goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView { StorageId = storage.Id, Quantity = thisBatchReceiveQuantity }); storage.ReceiveQuantity += thisBatchReceiveQuantity; var storageUpd = storage; //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity; batchStorageInfos.Add(storageUpd); } //2.2.1 更改批次库存 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable(batchStorageInfos) .UpdateColumns(x => x.ReceiveQuantity) .WhereColumns(x => x.Id) .ExecuteCommandAsync(); if (edit1 < 1) { _jv.Msg = $"批次库存更新失败!"; return _jv; } } //2.2.2 添加入库批次关联领用人 if (goodsReceiveInfos.Count > 0) { goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos); } } } else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1) { //出库确认中 auditEnum = GoodsAuditEnum.OutConfirming; if (preChangeStatus == GoodsAuditEnum.OutConfirmed) { var goodsStorageInfo1 = receiveInfo.GoodsStorageInfo; if (!string.IsNullOrEmpty(goodsStorageInfo)) { var goodsStorageInfos = JsonConvert.DeserializeObject>(goodsStorageInfo); if (goodsStorageInfos.Any()) { foreach (var item in goodsStorageInfos) { var newStorageInfo = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == item.StorageId) .FirstAsync(); if (newStorageInfo == null) continue; var newEdit = await _sqlSugar.Updateable(newStorageInfo) .ReSetValue(x => x.ReceiveQuantity -= item.Quantity) .ExecuteCommandAsync(); if (newEdit < 1) { _jv.Msg = $"批次领用库存更新失败!"; return _jv; } } } } } } else { auditEnum = GoodsAuditEnum.OutPending; } var statusDesc1 = statusDesc.ToString(); var changeStatus = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, StatusDesc = statusDesc1, GoodsStorageInfo = goodsStorageInfo, }) .Where(x => x.Id == receiveInfo.Id) .ExecuteCommandAsync(); if (changeStatus > 0) { _jv.Code = StatusCodes.Status200OK; } return _jv; } /// /// /// /// /// /// /// /// public async Task GoodsReceiveOutConfirmingMultiple(Pm_GoodsReceive receiveInfo, int userId, GoodsAuditDepEnum depEnum, GoodsAuditEnum auditEnum) { _jv.Code = StatusCodes.Status400BadRequest; //更改前状态 receiveInfo.CreateUserId = userId; var preChangeStatus = receiveInfo.AuditStatus; var currUserOpDt = DateTime.Now; var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss"); var receiveUserName = _sqlSugar.Queryable().First(x => x.Id == receiveInfo.AuditUserId)?.CnName ?? "-"; var auditInfos = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.DataId == receiveInfo.Id && x.Type == 2) .ToListAsync(); var auditStatus = GoodsConfirmEnum.WaitConfirm; if (auditEnum == GoodsAuditEnum.UnApproved) auditStatus = GoodsConfirmEnum.UnApproved; else if (auditEnum == GoodsAuditEnum.Approved) auditStatus = GoodsConfirmEnum.Confirmed; var auditInfo = auditInfos.Find(x => x.Dep == depEnum); if (auditInfo == null) { auditInfo = new Pm_GoodsAudit(2, depEnum, receiveInfo.Id, auditStatus, userId) { AuditUserId = userId }; var addStatus = await _sqlSugar.Insertable(auditInfo).ExecuteCommandAsync(); if (addStatus < 1) { _jv.Msg = $"出库确认操作失败!"; return _jv; } auditInfos.Add(auditInfo); } else { //移除旧数据 auditInfos.Remove(auditInfo); auditInfo.AuditStatus = auditStatus; auditInfo.AuditUserId = userId; auditInfo.AuditTime = currUserOpDt; var updStatus = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsAudit() { AuditStatus = auditStatus, AuditUserId = userId, AuditTime = currUserOpDt }) .Where(x => x.Id == auditInfo.Id) .ExecuteCommandAsync(); if (updStatus < 1) { _jv.Msg = $"出库确认操作失败!"; return _jv; } //添加更新后的数据 auditInfos.Add(auditInfo); } auditInfos = auditInfos.OrderBy(x => x.Dep).ToList(); //处理状态描述 StringBuilder statusDesc = new(); foreach (var auditInf in auditInfos) { string auditType = auditInf.Dep == GoodsAuditDepEnum.Hr ? "人事部" : "领用确认"; string userName = _sqlSugar.Queryable().First(x => x.Id == auditInf.AuditUserId)?.CnName ?? "-"; string userOpTime = !userName.Equals("-") ? auditInf.AuditTime.ToString("yyyy-MM-dd HH:mm:ss") : "-"; string auditInfStatusDesc = string.Format("{0}:状态:{1} 审核人:{2} 审核时间:{3};
", auditType, auditInf.AuditStatus.GetEnumDescription(), userName, currUserOpTime); statusDesc.Append(auditInfStatusDesc); } if (preChangeStatus == auditEnum) { _jv.Msg = $"此操作已执行,不可重复操作!"; return _jv; } //批次库存信息 string goodsStorageInfo = receiveInfo.GoodsStorageInfo; //更改领用状态及库存 if (auditInfos.Any(x => x.AuditStatus == GoodsConfirmEnum.UnApproved)) { //出库确认拒绝 auditEnum = GoodsAuditEnum.OutRejected; if (preChangeStatus == GoodsAuditEnum.OutConfirmed) { //回滚库存 _jv = await GoodsInventoryRollback(receiveInfo); if (_jv.Code != StatusCodes.Status200OK) return _jv; } } else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 2) { //1.出库确认完成 auditEnum = GoodsAuditEnum.OutConfirmed; //2.更改前的状态为出库确认中 且 更改后的状态为出库确认完成 执行库存减操作 if (preChangeStatus == GoodsAuditEnum.OutConfirming || preChangeStatus == GoodsAuditEnum.OutRejected) { //2.1 更改库存 var goodsInfo = await _sqlSugar.Queryable().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync(); goodsInfo.StockQuantity -= receiveInfo.Quantity; goodsInfo.OQ_Total += receiveInfo.Quantity; goodsInfo.LastUpdateTime = DateTime.Now; goodsInfo.LastUpdateUserId = userId; var editGoods = await _sqlSugar .Updateable(goodsInfo) .UpdateColumns(x => new { x.StockQuantity, x.OQ_Total, x.LastUpdateUserId, x.LastUpdateTime, }) .Where(x => x.Id == receiveInfo.GoodsId) .ExecuteCommandAsync(); if (editGoods < 1) { _jv.Msg = $"库存更新失败!"; return _jv; } //2.2 入库批次关联领用人 更改批次库存 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == receiveInfo.GoodsId && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); var receiveQuantity = 0.00M; //领用总数量 foreach (var storage in goodsStorages) { if (receiveInfo.Quantity == receiveQuantity) break; var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity; if (thisBatchSurplusQuantity <= 0.00M) continue; var thisBatchReceiveQuantity = 0.00M; //此批次领用数量 const decimal unit = 0.50M; while (receiveQuantity < receiveInfo.Quantity) { if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break; thisBatchReceiveQuantity += unit; receiveQuantity += unit; } goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView { StorageId = storage.Id, Quantity = thisBatchReceiveQuantity }); storage.ReceiveQuantity += thisBatchReceiveQuantity; var storageUpd = storage; //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity; batchStorageInfos.Add(storageUpd); } //2.2.1 更改批次库存 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable(batchStorageInfos) .UpdateColumns(x => x.ReceiveQuantity) .WhereColumns(x => x.Id) .ExecuteCommandAsync(); if (edit1 < 1) { _jv.Msg = $"批次库存更新失败!"; return _jv; } } //2.2.2 添加入库批次关联领用人 if (goodsReceiveInfos.Count > 0) { goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos); } } } else if (auditInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() == 1) { //出库确认中 auditEnum = GoodsAuditEnum.OutConfirming; if (preChangeStatus == GoodsAuditEnum.OutConfirmed) { //回滚库存 _jv = await GoodsInventoryRollback(receiveInfo); if (_jv.Code != StatusCodes.Status200OK) return _jv; } } else auditEnum = GoodsAuditEnum.OutPending; var statusDesc1 = statusDesc.ToString(); var changeStatus = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, StatusDesc = statusDesc1, GoodsStorageInfo = goodsStorageInfo, }) .Where(x => x.Id == receiveInfo.Id) .ExecuteCommandAsync(); if (changeStatus > 0) { _jv.Code = StatusCodes.Status200OK; } return _jv; } /// /// 物品库存回滚 /// /// /// public async Task GoodsInventoryRollback(Pm_GoodsReceive receiveInfo) { var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == receiveInfo.GoodsId); //回滚库存 var changeGoods = await _sqlSugar .Updateable(goodsInfo) .ReSetValue(it => { it.StockQuantity += receiveInfo.Quantity; it.OQ_Total -= receiveInfo.Quantity; it.LastUpdateTime = DateTime.Now; it.LastUpdateUserId = receiveInfo.CreateUserId; }) .ExecuteCommandAsync(); if (changeGoods < 1) { _jv.Msg = $"库存回滚失败!"; return _jv; } //批次领用记录 _jv.Code = StatusCodes.Status200OK; var goodsStorageInfo = receiveInfo.GoodsStorageInfo; if (string.IsNullOrEmpty(goodsStorageInfo)) return _jv; var goodsStorageInfos = JsonConvert.DeserializeObject>(goodsStorageInfo); if (!goodsStorageInfos.Any()) return _jv; foreach (var item in goodsStorageInfos) { var newStorageInfo = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == item.StorageId) .FirstAsync(); if (newStorageInfo == null) continue; var newEdit = await _sqlSugar.Updateable(newStorageInfo) .ReSetValue(x => x.ReceiveQuantity -= item.Quantity) .ExecuteCommandAsync(); if (newEdit < 1) { _jv.Code = StatusCodes.Status400BadRequest; _jv.Msg = $"批次领用库存更新失败!"; return _jv; } } _jv.Code = StatusCodes.Status200OK; return _jv; } #endregion #region 单人审核状态变更 /// /// 物品领用状态 - 出库确认完成、出库确认拒绝 /// /// /// /// /// /// public async Task GoodsReceiveOutConfirmingSingle(Pm_GoodsReceive receiveInfo, int userId, string currUserName, GoodsAuditEnum auditEnum) { _jv.Code = StatusCodes.Status400BadRequest; //状态操作范围验证 var auditEnums = new List() { GoodsAuditEnum.Pending, GoodsAuditEnum.Approved, GoodsAuditEnum.UnApproved, }; if (!auditEnums.Contains(auditEnum)) { _jv.Msg = $"{GoodsAuditEnum.Pending.GetEnumDescription()}、{GoodsAuditEnum.OutConfirmed.GetEnumDescription()}、{GoodsAuditEnum.OutRejected.GetEnumDescription()},状态下可操作!"; return _jv; } var currUserOpDt = DateTime.Now; var currUserOpTime = currUserOpDt.ToString("yyyy-MM-dd HH:mm:ss"); //更改前状态 var preChangeStatus = receiveInfo.AuditStatus; //前台状态验证 var auditInfo = await _sqlSugar.Queryable().FirstAsync(x => x.IsDel == 0 && x.Type == 2 && x.DataId == receiveInfo.Id); if (auditInfo == null) { var addInfo = new Pm_GoodsAudit(2, GoodsAuditDepEnum.Hr_Reception, receiveInfo.Id, GoodsConfirmEnum.WaitConfirm, userId); auditInfo = await _sqlSugar.Insertable(addInfo).ExecuteReturnEntityAsync(); if (auditInfo == null) { _jv.Msg = $"确认操作失败!"; return _jv; } } if (auditEnum == GoodsAuditEnum.Approved) { auditInfo.AuditStatus = GoodsConfirmEnum.Confirmed; auditEnum = GoodsAuditEnum.OutConfirmed; } else if (auditEnum == GoodsAuditEnum.UnApproved) { auditInfo.AuditStatus = GoodsConfirmEnum.UnApproved; auditEnum = GoodsAuditEnum.OutRejected; } if (preChangeStatus == auditEnum) { _jv.Msg = $"此操作已执行,不可重复操作!"; return _jv; } //更新子表审核状态 var updStatus = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsAudit() { AuditStatus = auditInfo.AuditStatus, AuditUserId = userId, AuditTime = currUserOpDt }) .Where(x => x.Id == auditInfo.Id) .ExecuteCommandAsync(); if (updStatus < 1) { _jv.Msg = $"确认操作失败!"; return _jv; } //处理状态描述 StringBuilder statusDesc = new(); statusDesc.Append(string.Format("领用确认:状态:{0} 审核人:{1} 审核时间:{2};", auditInfo.AuditStatus.GetEnumDescription(), currUserName, currUserOpTime)); //批次库存信息 string goodsStorageInfo = receiveInfo.GoodsStorageInfo; if (auditEnum == GoodsAuditEnum.OutConfirmed) //出库确认 { //1 更改库存 var goodsInfo = await _sqlSugar.Queryable().Where(x => x.Id == receiveInfo.GoodsId).FirstAsync(); goodsInfo.StockQuantity -= receiveInfo.Quantity; goodsInfo.OQ_Total += receiveInfo.Quantity; goodsInfo.LastUpdateTime = DateTime.Now; goodsInfo.LastUpdateUserId = userId; var editGoods = await _sqlSugar.Updateable(goodsInfo) .UpdateColumns(x => new { x.StockQuantity, x.OQ_Total, x.LastUpdateUserId, x.LastUpdateTime, }) .Where(x => x.Id == receiveInfo.GoodsId) .ExecuteCommandAsync(); if (editGoods < 1) { _jv.Msg = $"库存更新失败!"; return _jv; } //2 入库批次关联领用人 更改批次库存 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == receiveInfo.GoodsId && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); var receiveQuantity = 0.00M; //领用总数量 foreach (var storage in goodsStorages) { if (receiveInfo.Quantity == receiveQuantity) break; var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity; if (thisBatchSurplusQuantity <= 0.00M) continue; var thisBatchReceiveQuantity = 0.00M; //此批次领用数量 const decimal unit = 0.50M; while (receiveQuantity < receiveInfo.Quantity) { if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break; thisBatchReceiveQuantity += unit; receiveQuantity += unit; } goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView { StorageId = storage.Id, Quantity = thisBatchReceiveQuantity }); storage.ReceiveQuantity += thisBatchReceiveQuantity; var storageUpd = storage; //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity; batchStorageInfos.Add(storageUpd); } //3 更改批次库存 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable(batchStorageInfos) .UpdateColumns(x => x.ReceiveQuantity) .WhereColumns(x => x.Id) .ExecuteCommandAsync(); if (edit1 < 1) { _jv.Msg = $"批次库存更新失败!"; return _jv; } } //4 添加入库批次关联领用人 if (goodsReceiveInfos.Count > 0) { goodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos); } } else if (auditEnum == GoodsAuditEnum.OutRejected) //出库拒绝 { //拒绝之前的状态为已完成 回滚库存 if (preChangeStatus == GoodsAuditEnum.OutConfirmed) { //回滚库存 var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == receiveInfo.GoodsId); var changeGoods = await _sqlSugar .Updateable(goodsInfo) .ReSetValue(it => { it.StockQuantity += receiveInfo.Quantity; it.OQ_Total -= receiveInfo.Quantity; it.LastUpdateTime = DateTime.Now; it.LastUpdateUserId = userId; }) .ExecuteCommandAsync(); if (changeGoods < 1) { _jv.Msg = $"库存回滚失败!"; return _jv; } //批次号库存 信息更新 var goodsStorageInfo1 = receiveInfo.GoodsStorageInfo; if (!string.IsNullOrEmpty(goodsStorageInfo)) { var goodsStorageInfos = JsonConvert.DeserializeObject>(goodsStorageInfo); if (goodsStorageInfos.Any()) { foreach (var item in goodsStorageInfos) { var newStorageInfo = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == item.StorageId) .FirstAsync(); if (newStorageInfo == null) continue; var newEdit = await _sqlSugar.Updateable(newStorageInfo) .ReSetValue(x => x.ReceiveQuantity -= item.Quantity) .ExecuteCommandAsync(); if (newEdit < 1) { _jv.Msg = $"批次领用库存更新失败!"; return _jv; } } } } } } var statusDesc1 = statusDesc.ToString(); var changeStatus = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, StatusDesc = statusDesc1, GoodsStorageInfo = goodsStorageInfo, }) .Where(x => x.Id == receiveInfo.Id) .ExecuteCommandAsync(); if (changeStatus > 0) _jv.Code = StatusCodes.Status200OK; return _jv; } #endregion /// /// 物品领用 Del /// /// /// /// public async Task GoodsReceiveDel(int id, int currUserId) { var receiveInfo = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.Id == id) .FirstAsync(); if (receiveInfo.AuditStatus >= GoodsAuditEnum.Approved) { _jv.Msg = $"该条数据已进入审批流程,不可删除!"; return _jv; } var edit = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { IsDel = 1, DeleteUserId = currUserId, DeleteTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), }) .Where(x => x.Id == id) .ExecuteCommandAsync(); if (edit > 0) { _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } return _jv; } #region New 物品领用、审核 /// /// 物品领用审核列表 /// /// /// public async Task GoodsReceiveAuditList(GoodsReceiveAuditListDTO dto) { var currUserId = dto.CurrUserId; var auditStatus = dto.AuditStatus; var goodsName = dto.GoodsName; var sql = string.Format(@"SELECT ROW_NUMBER() OVER (ORDER BY CreateTime DESC) AS RowNumber, * FROM ( Select gr.Id, gr.GroupId, CASE WHEN gr.GroupId = 0 THEN '其他物资(公司内部物资)' WHEN gr.GroupId = -1 THEN '拜访客户所使用的物资' WHEN gr.GroupId = -2 THEN '库存调整' ELSE di.TeamName END [GroupName], gr.GoodsId, CASE WHEN gr.GoodsId = 0 THEN gr.GoodsName ELSE gi.Name END [GoodsName], gi.Type [GoodsTypeId], sd.Name [GoodsType], CASE WHEN gi.Type = 0 OR gi.Type IS NULL THEN CASE WHEN af.TemplateId = 3 THEN 1 ELSE 0 END WHEN gi.Type = 1423 THEN 1 ELSE 0 END [IsValuable], gr.Quantity, gi.Unit, gr.Reason, gr.Remark, gr.AuditStatus, gr.StatusDesc, gr.AuditUserId, u1.CnName [AuditUserName], gr.AuditTime, u2.CnName [CreateUserName], gr.CreateTime FROM OA2023DB.dbo.Pm_GoodsReceive gr LEFT JOIN Pm_GoodsInfo gi ON gr.GoodsId = gi.Id LEFT JOIN Grp_DelegationInfo di ON gr.GroupId = di.Id LEFT JOIN Sys_Users u1 ON gr.AuditUserId = u1.Id LEFT JOIN Sys_Users u2 ON gr.CreateUserId = u2.Id LEFT JOIN Sys_AuditFlow af ON gr.Id = af.BusinessId LEFT JOIN Sys_SetData sd ON gi.Type = sd.Id WHERE gr.IsDel = 0 ) Temp "); var isValueable = false; if (currUserId == 343) //陈湘OAId登录 只显示贵重物品审核信息 { isValueable = true; } RefAsync total = 0; var view = await _sqlSugar.SqlQueryable(sql) .WhereIF(isValueable, x => x.IsValuable == true) .WhereIF(!string.IsNullOrEmpty(goodsName), x => x.GoodsName.Contains(goodsName)) .ToPageListAsync(dto.PageIndex, dto.PageSize, total); //普通物品领用审核模板 var normAuditTemps = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(2); //普通物品 var normAuditUsers = new List(); normAuditTemps?.TempNodes.ForEach(x => { var auditDep = GoodsAuditDepEnum.Hr_Reception; if (x.NodeName.Contains("人事部主管/经理审核")) auditDep = GoodsAuditDepEnum.Hr; else if (x.NodeName.Contains("前台审核")) auditDep = GoodsAuditDepEnum.Hr; x.NodeUsers.ForEach(y => { var userFlang = false; if (y.UserId == currUserId) userFlang = true; var info = new GoodsStorageAuditPerView() { ButtonText = x.NodeName, AuditDep = auditDep, AuditPer = userFlang }; normAuditUsers.Add(info); }); }); //贵重物品领用审核模板 var valuableAuditTemps = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(3); //贵重物品 var valuableAuditUsers = new List(); valuableAuditTemps?.TempNodes.ForEach(x => { var auditDep = GoodsAuditDepEnum.Hr_Reception; if (x.NodeName.Contains("人事部主管/经理审核")) auditDep = GoodsAuditDepEnum.Hr; else if (x.NodeName.Contains("前台审核")) auditDep = GoodsAuditDepEnum.Hr; x.NodeUsers.ForEach(y => { var userFlang = false; if (y.UserId == currUserId) userFlang = true; var info = new GoodsStorageAuditPerView() { ButtonText = x.NodeName, AuditDep = auditDep, AuditPer = userFlang }; valuableAuditUsers.Add(info); }); }); foreach (var item in view) { var details = $"暂无物品信息数据"; //设置领用详情 if (item.GoodsTypeId < 1) { var detailsData = await _sqlSugar.Queryable() .LeftJoin((grd, gi) => grd.GoodsId == gi.Id) .LeftJoin((grd, gi, sd) => gi.Type == sd.Id) .Where((grd, gi, sd) => grd.IsDel == 0 && grd.GoodsReceiveId == item.Id) .Select((grd, gi, sd) => new { gi.Name, TypeName = sd.Name, grd.Quantity, grd.Remark }) .ToListAsync(); if (detailsData.Any()) { //设置领用数量 多个物品 计算领用合计 item.Quantity = detailsData.Sum(x => x.Quantity); var text = new StringBuilder(); text.Append($"归属团组:{item.GroupName}

"); detailsData.ForEach(x => { var str = $"物品名称:{x.Name} 物品类型:{x.TypeName} 领用数量:{x.Quantity} 备注:{x.Remark}
"; text.Append(str); }); details = text.ToString(); } } else details = $"归属团组/类型:{item.GroupName}

物品名称:{item.GoodsName} 物品类型:{item.GoodsType} 领用数量:{item.Quantity} 备注:{item.Remark}
"; item.GoodsDetails = details; //设置领用状态描述 var auditRecords = await _sqlSugar.Queryable() .InnerJoin((ar, af) => ar.FlowId == af.Id) .Where((ar, af) => ar.IsDel == 0 && af.BusinessId == item.Id && af.BusinessType == 1) .Select((ar, af) => new { ar.NodeId, ar.NodeName, ar.AuditResult, ar.AuditorName, ar.AuditTime }) //.OrderBy((ar, af) => ar.AuditTime) .ToListAsync(); if (auditRecords.Any()) { var text = new StringBuilder(); auditRecords.ForEach(x => { var statusText = x.AuditResult switch { 0 => "待审核", 1 => "已审核", 2 => "已拒绝", 3 => "无需处理", _ => "未知" }; var str = $"{x.NodeName}:状态:{statusText} 审核人:{x.AuditorName} 审核时间:{x.AuditTime:yyyy-MM-dd HH:mm:ss}
"; text.Append(str); }); item.StatusDesc = text.ToString(); } //多情况下审核、操作权限验证 if (item.GoodsTypeId == 0) { int tempId = 2; if (item.IsValuable) tempId = 3; item.IsAuditPer = await _approvalProcessRep.VerifyAuditAuthAsync(tempId, 1, item.Id, currUserId); } else { if (item.AuditStatus == GoodsAuditEnum.Pending) { item.IsAuditPer = normAuditTemps?.TempNodes.FirstOrDefault()?.NodeUsers.Any(x => x.UserId == currUserId) ?? false; } else if (item.AuditStatus == GoodsAuditEnum.OutConfirming) { item.IsAuditPer = valuableAuditTemps?.TempNodes.FirstOrDefault(x => x.NodeOrder == 1)?.NodeUsers.Any(x => x.UserId == currUserId) ?? false; } } //前端权限验证 if (item.IsValuable) { item.AuditPers = valuableAuditUsers.ToArray(); } else item.AuditPers = normAuditUsers.ToArray(); } if (dto.PortType == 2 || dto.PortType == 3) { _jv.Data = view; } else if (dto.PortType == 1) { var view1 = _mapper.Map>(view); _jv.Data = view1; } _jv.Code = StatusCodes.Status200OK; _jv.Count = total; _jv.Msg = $"操作成功"; return _jv; } /// /// 物品领用 可批量 OP(Add Or Edit) /// /// /// /// public async Task GoodsReceiveBatchOpAsync(GoodsReceiveBatchOpDto dto) { var goodsReceiveId = dto.Id; var currUserId = dto.CurrUserId; //请求参数处理 var receiveInfo = new Pm_GoodsReceive() { Id = goodsReceiveId, GroupId = dto.GroupId, Reason = dto.Reason, Remark = dto.Remark, AuditStatus = GoodsAuditEnum.Pending, CreateUserId = currUserId, }; var receiveDetails = _mapper.Map(dto.ReceiveDetails); //receiveDetails.ForEach(x => { x.CreateUserId = dto.CurrUserId; }); _sqlSugar.BeginTran(); //审核状态验证 false:其他物品 true:贵重物品 var isBatchVail = false; //物品库存验证 int goodsIndex = 1; var goodsNames = new List(); foreach (var item in receiveDetails) { item.CreateUserId = currUserId; int goodsId = item.GoodsId; //物品验证 var goodsInfo = _sqlSugar.Queryable().First(x => x.IsDel == 0 && x.Id == goodsId); if (goodsInfo == null) { _jv.Msg = $"第{goodsIndex}项物品不存在!"; _sqlSugar.RollbackTran(); return _jv; } goodsNames.Add(goodsInfo.Name); //物品库存验证 var stockQuantity = goodsInfo.StockQuantity; var awaitAuditQuantity = await GoodsAwaitQuantityAsync(goodsId); stockQuantity -= awaitAuditQuantity; if (item.Quantity > stockQuantity) { _jv.Msg = $"“{goodsInfo.Name}”物品库存不足!剩余库存:{stockQuantity} {goodsInfo.Unit}(待审数量:{awaitAuditQuantity});"; _sqlSugar.RollbackTran(); return _jv; } //物品类型验证 if (_goodsTypeIds.Contains(goodsInfo.Type)) isBatchVail = true; //入库批次关联领用人 更改批次库存 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == receiveInfo.GoodsId && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); var receiveQuantity = 0.00M; //领用总数量 foreach (var storage in goodsStorages) { if (receiveInfo.Quantity == receiveQuantity) break; var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity; if (thisBatchSurplusQuantity <= 0.00M) continue; var thisBatchReceiveQuantity = 0.00M; //此批次领用数量 const decimal unit = 0.50M; while (receiveQuantity < receiveInfo.Quantity) { if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break; thisBatchReceiveQuantity += unit; receiveQuantity += unit; } goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView { StorageId = storage.Id, Quantity = thisBatchReceiveQuantity }); storage.ReceiveQuantity += thisBatchReceiveQuantity; var storageUpd = storage; //storageUpd.ReceiveQuantity += thisBatchReceiveQuantity; batchStorageInfos.Add(storageUpd); } goodsIndex++; } if (goodsNames.Any()) { receiveInfo.GoodsName = string.Join("、", goodsNames); } //验证领用 添加OR编辑 var goodsReceiveInfo = await _sqlSugar.Queryable().FirstAsync(x => x.IsDel == 0 && x.Id == goodsReceiveId); if (goodsReceiveInfo == null) //添加 { goodsReceiveId = await _sqlSugar.Insertable(receiveInfo).ExecuteReturnIdentityAsync(); if (goodsReceiveId < 1) { _jv.Msg = $"领用添加失败!"; _sqlSugar.RollbackTran(); return _jv; } receiveDetails.ForEach(x => { x.GoodsReceiveId = goodsReceiveId; }); var receiveDetailsStatus = await _sqlSugar.Insertable(receiveDetails).ExecuteCommandAsync(); if (receiveDetailsStatus < 1) { _jv.Msg = $"领用明细添加失败!"; _sqlSugar.RollbackTran(); return _jv; } } else //修改 { //更改前状态验证 if (goodsReceiveInfo.AuditStatus != GoodsAuditEnum.Pending) { _jv.Msg = $"领用状态在“领用待确认”,即可修改!"; _sqlSugar.RollbackTran(); return _jv; } var receiveStatus = await _sqlSugar.Updateable(receiveInfo).ExecuteCommandAsync(); if (receiveStatus < 1) { _jv.Msg = $"领用更新失败!"; _sqlSugar.RollbackTran(); return _jv; } //更新子表数据 if (receiveDetails.Any()) { receiveDetails.ForEach(x => { x.GoodsReceiveId = receiveInfo.Id; }); var db_receiveDetails = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.GoodsReceiveId == goodsReceiveId) .ToListAsync(); var toDelete = db_receiveDetails.Where(p => !receiveDetails.Any(np => np.Id == p.Id)).ToList(); if (toDelete.Any()) { var delStatus = _sqlSugar.Deleteable(toDelete).ExecuteCommand(); if (delStatus < 1) { _jv.Msg = $"领用明细旧数据删除失败!"; _sqlSugar.RollbackTran(); return _jv; } } var addOrUpdStatus = await _sqlSugar.Storageable(receiveDetails.ToList()).ExecuteCommandAsync(); if (addOrUpdStatus < 1) { _jv.Msg = $"领用明细更新失败!"; _sqlSugar.RollbackTran(); return _jv; } } } #region 审批流程验证、创建 //审核验证 物品含有贵重物品 使用贵重物品审批流程 var auditTempInfo = new ApprovalProcessView(); if (isBatchVail) //贵重物品审核模板 { auditTempInfo = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(3); } else //其他物品审核模板 { auditTempInfo = await _approvalProcessRep.GetTemplateByBusinessTypeAsync(2); } if (auditTempInfo == null) { _jv.Msg = $"未配置审核模板!"; _sqlSugar.RollbackTran(); return _jv; } if (auditTempInfo == null && !auditTempInfo.TempNodes.Any()) { _jv.Msg = $"审核模板未配置节点!"; _sqlSugar.RollbackTran(); return _jv; } //创建审核流程 var firstNode = auditTempInfo.TempNodes.OrderBy(x => x.NodeOrder).First(); var flow = await _approvalProcessRep.GetFlowByBusinessAsync(goodsReceiveId, 1); int flowId; if (flow == null) { flow = new Sys_AuditFlow() { BusinessId = goodsReceiveId, BusinessType = 1, TemplateId = auditTempInfo.Id, CurrentNodeId = firstNode.Id, Status = 1, }; flowId = await _sqlSugar.Insertable(flow).ExecuteReturnIdentityAsync(); if (flowId < 1) { _jv.Msg = $"审核流程添加失败!"; _sqlSugar.RollbackTran(); return _jv; } } else flowId = flow.Id; #endregion //获取第一个节点的审核人员 var nodeUsers = firstNode.NodeUsers; //删除旧的审核记录 var delRecords = await _sqlSugar.Deleteable() .Where(x => x.FlowId == flowId && x.NodeId == firstNode.Id && x.NodeName == firstNode.NodeName) .ExecuteCommandHasChangeAsync(); //创建审核记录 var records = nodeUsers.Select(user => new Sys_AuditRecord { FlowId = flowId, NodeId = firstNode.Id, NodeName = firstNode.NodeName, AuditorId = user.UserId, AuditorName = user.UserName, AuditResult = 0, // 审核中 AuditTime = DateTime.Now }).ToList(); var recordStatus = await _sqlSugar.Insertable(records).ExecuteCommandAsync(); if (recordStatus < 1) { _jv.Msg = $"审核记录创建失败!"; _sqlSugar.RollbackTran(); return _jv; } _sqlSugar.CommitTran(); _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"操作成功!"; return _jv; } /// /// 物品领用 批量 List /// /// /// /// public async Task GoodsReceiveBatchListAsync(GoodsReceiveBatchListDto dto) { int currUserId = dto.CurrUserId; string goodsName = dto.GoodsName; var showAllPeopleIds = new List() { 374, // 罗颖 233, // 刘华举 208, // 雷怡 343, // 陈湘 }; var isShowAllPeople = showAllPeopleIds.Any(x => x == currUserId); RefAsync total = 0; var receiveList = await _sqlSugar.Queryable() .LeftJoin((x, y) => x.CreateUserId == y.Id) .Where((x, y) => x.IsDel == 0 && x.GoodsId == 0) .WhereIF(!string.IsNullOrEmpty(goodsName), (x, y) => x.GoodsName.Contains(goodsName)) .WhereIF(!isShowAllPeople, (x, y) => x.CreateUserId == currUserId) .OrderByDescending((x, y) => x.CreateTime) .Select((x, y) => new GoodsReceiveBatchListView() { Id = x.Id, GoodsName = x.GoodsName, AccumQty = SqlFunc.Subqueryable().Where(z => z.IsDel == 0 && z.GoodsReceiveId == x.Id).Sum(z => z.Quantity), Reason = x.Reason, Remark = x.Remark, Status = x.AuditStatus, Applicant = y.CnName, ApplyTime = x.CreateTime, }) .ToPageListAsync(dto.PageIndex, dto.PageSize, total); foreach (var item in receiveList) { var detailsText = new StringBuilder(); if (item.AccumQty > 0) { var goodsInfos = await _sqlSugar.Queryable() .InnerJoin((x, y) => x.GoodsId == y.Id) .LeftJoin((x, y, z) => y.Type == z.Id) .Where((x, y, z) => x.IsDel == 0 && x.GoodsReceiveId == item.Id) .Select((x, y, z) => new { goodsId = x.GoodsId, goodsName = y.Name, goodsType = z.Name, quantity = x.Quantity, remark = x.Remark, }) .ToListAsync(); if (goodsInfos.Any()) { int index = 1; goodsInfos.ForEach(x => { detailsText.Append($"{index}.{x.goodsName}({x.goodsType}) 数量:{x.quantity:#0.00} 备注:{x.remark ?? "-"}
"); index++; }); } } else detailsText.Append($"暂无数据!"); item.GoodsDetails = detailsText.ToString(); } _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"操作成功!"; _jv.Data = receiveList; _jv.Count = total; return _jv; } /// /// 物品领用 批量 详情 /// /// /// /// public async Task GoodsReceiveBatchInfoAsync(int id) { var receiveInfo = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == id) .FirstAsync(); if (receiveInfo == null) { _jv.Msg = "暂无数据!"; return _jv; } var info = new GoodsReceiveBatchView { Id = receiveInfo.Id, GroupId = receiveInfo.GroupId, Reason = receiveInfo.Reason, Remark = receiveInfo.Remark, }; info.ReceiveDetails = await _sqlSugar .Queryable() .LeftJoin((x, y) => x.GoodsId == y.Id) .Where((x, y) => x.IsDel == 0 && x.GoodsReceiveId == receiveInfo.Id) .Select((x, y) => new GoodsReceiveDetailsView() { Id = x.Id, GoodsId = x.GoodsId, GoodsName = y.Name, Quantity = x.Quantity, Remark = x.Remark, }) .ToArrayAsync(); _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"操作成功!"; _jv.Data = info; return _jv; } /// /// 物品领用 审核 通过 /// /// /// /// public async Task GoodsReceiveApproveAsync(int id, int currUserId) { var appId = id; //验证审核流程 var flow = await _approvalProcessRep.GetFlowByBusinessAsync(appId, 1); if (flow == null) { _jv.Msg = $"审核流程不存在"; return _jv; } if (flow.Status != 1) { _jv.Msg = $"当前流程不在审核中"; return _jv; } //获取当前节点 var currNode = (await _approvalProcessRep.GetTemplateNodesAsync(flow.TemplateId)).FirstOrDefault(x => x.Id == flow.CurrentNodeId); if (currNode == null) { _jv.Msg = $"当前审核节点不存在"; return _jv; } //检查用户是否有权审核 var canAudit = (await _approvalProcessRep.GetTemplateNodeUsersAsync(currNode.Id)) .Any(x => x.UserId == currUserId); if (!canAudit) { _jv.Msg = $"您无权审核此领用"; return _jv; } //检查是否已审核过 var existingRecord = await _sqlSugar.Queryable() .Where(x => x.FlowId == flow.Id && x.NodeId == currNode.Id && x.AuditorId == currUserId) .FirstAsync(); if (existingRecord != null && existingRecord.AuditResult == 1) { _jv.Msg = $"您已审核过此领用"; return _jv; } // 创建或更新审核记录 var currUserName = _sqlSugar.Queryable().First(x => x.Id == currUserId)?.CnName ?? "-"; var record = existingRecord ?? new Sys_AuditRecord { FlowId = flow.Id, NodeId = currNode.Id, NodeName = currNode.NodeName, AuditorId = currUserId, AuditorName = currUserName, AuditResult = 1, // 通过 AuditTime = DateTime.Now, AuditOpinion = "", }; _sqlSugar.BeginTran(); if (existingRecord == null) await _sqlSugar.Insertable(record).ExecuteCommandAsync(); else { record.AuditResult = 1; // 通过 record.AuditTime = DateTime.Now; await _sqlSugar.Updateable(record).ExecuteCommandAsync(); } //检查节点是否完成 var nodeRecords = await _sqlSugar.Queryable() .Where(x => x.FlowId == flow.Id && x.NodeId == currNode.Id) .ToListAsync(); bool isNodeComplete = false; if (currNode.ApproveType == 2) // 或签模式 { //或签逻辑:任意一人通过即通过 if (nodeRecords.Any(x => x.AuditResult == 1)) { isNodeComplete = true; // 标记其他未审核的记录为"无需处理" var unprocessed = nodeRecords .Where(x => x.AuditResult == 0 && x.AuditorId != currUserId) .ToList(); foreach (var r in unprocessed) { r.AuditResult = 3; // 无需处理 r.AuditTime = DateTime.Now; r.AuditOpinion = "其他审核人已处理"; } if (unprocessed.Any()) { await _sqlSugar.Updateable(unprocessed).ExecuteCommandAsync(); } } } else // 会签模式 { // 会签逻辑:全部通过才通过 isNodeComplete = nodeRecords.All(x => x.AuditResult == 1); } if (isNodeComplete) { // 查找下一个节点 var nextNode = (await _approvalProcessRep.GetTemplateNodesAsync(flow.TemplateId)) .Where(x => x.NodeOrder > currNode.NodeOrder) .OrderBy(x => x.NodeOrder) .FirstOrDefault(); if (nextNode == null) { // 所有节点完成,审核通过 flow.Status = 2; // 已完成 flow.CurrentNodeId = 0; // 更新业务状态为审核通过 var auditStatus = await UpdateStatusAsync(appId, GoodsAuditEnum.OutConfirmed); if (!auditStatus) { _jv.Msg = $"审核失败!"; _sqlSugar.RollbackTran(); return _jv; } // 扣除库存 var deductStatus = await DeductStockAsync(appId); if (!deductStatus) { _jv.Msg = $"库存扣除失败!"; _sqlSugar.RollbackTran(); return _jv; } } else { // 进入下一个节点 flow.CurrentNodeId = nextNode.Id; // 更新业务状态为审核中 var auditStatus = await UpdateStatusAsync(appId, GoodsAuditEnum.OutConfirming); if (!auditStatus) { _jv.Msg = $"审核状态更新失败!"; _sqlSugar.RollbackTran(); return _jv; } // 为下一个节点创建审核记录 var nextNodeUsers = await _approvalProcessRep.GetTemplateNodeUsersAsync(nextNode.Id); var records = nextNodeUsers.Select(user => new Sys_AuditRecord { FlowId = flow.Id, NodeId = nextNode.Id, NodeName = nextNode.NodeName, AuditorId = user.UserId, AuditorName = user.UserName, AuditResult = 0, AuditTime = DateTime.Now }).ToList(); var recordStatus = await _sqlSugar.Insertable(records).ExecuteCommandAsync(); if (recordStatus < 1) { _jv.Msg = $"下一节点审批记录创建失败!"; _sqlSugar.RollbackTran(); return _jv; } } var flowStatus = await _sqlSugar.Updateable(flow).ExecuteCommandAsync(); if (flowStatus < 1) { _jv.Msg = $"审批流程更新失败!"; _sqlSugar.RollbackTran(); return _jv; } } _sqlSugar.CommitTran(); _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"操作成功!"; return _jv; } /// /// 物品领用 审核 拒绝 /// /// /// /// public async Task GoodsReceiveRejectAsync(int id, int currUserId) { var appId = id; //验证领用单 var receviveInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == appId); if (receviveInfo == null) { _jv.Msg = $"当前领用信息不存在"; return _jv; } //验证审核流程 var flow = await _approvalProcessRep.GetFlowByBusinessAsync(appId, 1); if (flow == null) { _jv.Msg = $"审核流程不存在"; return _jv; } //if (flow.Status != 1) //{ // _jv.Msg = $"当前流程不在审核中"; // return _jv; //} //获取当前节点 var currNode = (await _approvalProcessRep.GetTemplateNodesAsync(flow.TemplateId)).FirstOrDefault(x => x.Id == flow.CurrentNodeId); if (currNode == null) { _jv.Msg = $"当前审核节点不存在"; return _jv; } //检查用户是否有权审核 var canAudit = (await _approvalProcessRep.GetTemplateNodeUsersAsync(currNode.Id)) .Any(x => x.UserId == currUserId); if (!canAudit) { _jv.Msg = $"您无权审核此申请"; return _jv; } //检查是否已审核过 var existingRecord = await _sqlSugar.Queryable() .Where(x => x.FlowId == flow.Id && x.NodeId == currNode.Id && x.AuditorId == currUserId) .FirstAsync(); if (existingRecord != null && existingRecord.AuditResult == 2) { _jv.Msg = $"您已审核过此申请"; return _jv; } //验证是否已经审核通过 bool isApproved = receviveInfo.AuditStatus == GoodsAuditEnum.OutConfirmed; _sqlSugar.BeginTran(); if (isApproved) //审核通过拒绝 { //回滚库存 var rollbackStatus = await RollbackStockAsync(appId); if (!rollbackStatus) { _jv.Msg = $"物品库存回滚失败!"; _sqlSugar.RollbackTran(); return _jv; } } //更新流程状态为已拒绝 flow.Status = 3; // 已拒绝 flow.CurrentNodeId = currNode.Id; var flowStatus = await _sqlSugar.Updateable(flow).ExecuteCommandAsync(); if (flowStatus < 1) { _jv.Msg = $"流程状态更新失败!"; _sqlSugar.RollbackTran(); return _jv; } // 更新领用状态为已拒绝 var receviveStatus = await UpdateStatusAsync(appId, GoodsAuditEnum.OutRejected); // 已拒绝 if (!receviveStatus) { _jv.Msg = $"领用物品状态更新失败!"; _sqlSugar.RollbackTran(); return _jv; } // 创建拒绝记录 var currUserName = _sqlSugar.Queryable().First(x => x.Id == currUserId)?.CnName ?? "-"; var record = new Sys_AuditRecord { FlowId = flow.Id, NodeId = flow.CurrentNodeId, NodeName = $"{currNode.NodeName}-撤销", AuditorId = currUserId, AuditorName = currUserName, AuditResult = 2, // 拒绝 AuditTime = DateTime.Now, AuditOpinion = $"用户操作撤销", }; var recordStatus = await _sqlSugar.Insertable(record).ExecuteCommandAsync(); if (recordStatus < 1) { _jv.Msg = $"领用物品拒绝记录创建失败!"; _sqlSugar.RollbackTran(); return _jv; } _sqlSugar.CommitTran(); _jv.Code = StatusCodes.Status200OK; _jv.Msg = $"操作成功!"; return _jv; } /// /// 物品待审核数量 /// /// /// public async Task GoodsAwaitQuantityAsync(int goodsId) { decimal quantity = 0.00M; //单条领用 待审核、确认中 物品数量 var waitAuditQuantity = await _sqlSugar.Queryable().Where(x => x.IsDel == 0 && x.GoodsId == goodsId && (x.AuditStatus == GoodsAuditEnum.Pending || x.AuditStatus == GoodsAuditEnum.OutConfirming) ).SumAsync(x => x.Quantity); //批量领用 待审核、确认中 物品数量 var waitAuditBatchQuantity = await _sqlSugar.Queryable() .InnerJoin((gr, grd) => gr.Id == grd.GoodsReceiveId) .Where((gr, grd) => gr.IsDel == 0 && (gr.AuditStatus == GoodsAuditEnum.Pending || gr.AuditStatus == GoodsAuditEnum.OutConfirming) && grd.GoodsId == goodsId ) .Select((gr, grd) => new { grd.GoodsReceiveId, gr.AuditStatus, grd.Quantity }) .SumAsync(gr => gr.Quantity); quantity = waitAuditQuantity + waitAuditBatchQuantity; return quantity; } /// /// 更改领用状态 /// /// /// /// public async Task UpdateStatusAsync(int id, GoodsAuditEnum status) { return await _sqlSugar.Updateable() .SetColumns(x => x.AuditStatus == status) .Where(x => x.Id == id) .ExecuteCommandHasChangeAsync(); } /// /// 领用状态完成扣除库存 /// /// /// /// public async Task DeductStockAsync(int id) { var receiveInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == id); if (receiveInfo == null) return false; var receiveDetails = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.GoodsReceiveId == id) .ToListAsync(); if (!receiveDetails.Any()) return false; var goodsInfos = new List(); foreach (var item in receiveDetails) { var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == item.GoodsId); if (goodsInfo == null) return false; //1、物品库存扣除 goodsInfo.StockQuantity -= item.Quantity; goodsInfo.OQ_Total += item.Quantity; //2、入库批次关联领用人 更改批次库存 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == item.GoodsId && x.ConfirmStatus == GoodsConfirmEnum.Confirmed && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); var receiveQuantity = 0.00M; //领用总数量 foreach (var storage in goodsStorages) { if (item.Quantity == receiveQuantity) break; var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity; if (thisBatchSurplusQuantity <= 0.00M) continue; var thisBatchReceiveQuantity = 0.00M; //此批次领用数量 const decimal unit = 0.50M; while (receiveQuantity < storage.Quantity) { if (thisBatchSurplusQuantity == thisBatchReceiveQuantity || receiveQuantity == item.Quantity) break; thisBatchReceiveQuantity += unit; receiveQuantity += unit; } goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView { StorageId = storage.Id, Quantity = thisBatchReceiveQuantity }); storage.ReceiveQuantity += thisBatchReceiveQuantity; batchStorageInfos.Add(storage); } //3 更改批次库存 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable(batchStorageInfos) .UpdateColumns(x => x.ReceiveQuantity) .WhereColumns(x => x.Id) .ExecuteCommandAsync(); if (edit1 < 1) return false; } //4 添加入库批次关联领用人 if (goodsReceiveInfos.Count > 0) { item.GoodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos); } goodsInfos.Add(goodsInfo); } //库存更改 var editGoods = await _sqlSugar.Updateable(goodsInfos) .UpdateColumns(x => new { x.StockQuantity, x.OQ_Total, }) .Where(x => x.Id == x.Id) .ExecuteCommandAsync(); if (editGoods < 1) return false; //领用明细更改 var editDetails = await _sqlSugar.Updateable(receiveDetails) .UpdateColumns(x => new { x.GoodsStorageInfo, }) .Where(x => x.GoodsReceiveId == x.GoodsReceiveId) .ExecuteCommandAsync(); if (editDetails < 1) return false; return true; } /// /// 领用状态拒绝回滚所有物资的库存 /// /// /// /// public async Task RollbackStockAsync(int id) { var receiveInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == id); if (receiveInfo == null) return false; var receiveDetails = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.GoodsReceiveId == id) .ToListAsync(); if (!receiveDetails.Any()) return false; var goodsInfos = new List(); foreach (var item in receiveDetails) { var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == item.GoodsId); if (goodsInfo == null) return false; //1、物品表库存回滚 var receiveQuantity = item.Quantity; goodsInfo.StockQuantity += receiveQuantity; goodsInfo.OQ_Total -= receiveQuantity; //2、入库批次关联领用人 更改批次库存 回滚 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == receiveInfo.GoodsId && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); foreach (var storage in goodsStorages) { if (receiveInfo.Quantity == receiveQuantity) break; var thisBatchSurplusQuantity = storage.Quantity - storage.ReceiveQuantity; if (thisBatchSurplusQuantity <= 0.00M) continue; var thisBatchReceiveQuantity = 0.00M; //此批次领用数量 const decimal unit = 0.50M; while (receiveQuantity < receiveInfo.Quantity) { if (thisBatchSurplusQuantity == thisBatchReceiveQuantity) break; thisBatchReceiveQuantity -= unit; receiveQuantity -= unit; } goodsReceiveInfos.Add(new GoodsReceiveLinkStorageView { StorageId = storage.Id, Quantity = thisBatchReceiveQuantity }); storage.ReceiveQuantity -= thisBatchReceiveQuantity; batchStorageInfos.Add(storage); } //3 批次库存 回滚 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable(batchStorageInfos) .UpdateColumns(x => x.ReceiveQuantity) .WhereColumns(x => x.Id) .ExecuteCommandAsync(); if (edit1 < 1) return false; } item.GoodsStorageInfo = null; goodsInfos.Add(goodsInfo); } //库存 回滚 var editGoods = await _sqlSugar.Updateable(goodsInfos) .UpdateColumns(x => new { x.StockQuantity, x.OQ_Total, }) .Where(x => x.Id == x.Id) .ExecuteCommandAsync(); if (editGoods < 1) return false; //领用明细 回滚 var editDetails = await _sqlSugar.Updateable(receiveDetails) .UpdateColumns(x => new { x.GoodsStorageInfo, }) .Where(x => x.GoodsReceiveId == x.GoodsReceiveId) .ExecuteCommandAsync(); if (editDetails < 1) return false; return true; } #endregion } }