using Aspose.Cells; using Aspose.Cells.Drawing; using Aspose.Words.Drawing; using AutoMapper; using EyeSoft.IO; using EyeSoft.Reflection; using Newtonsoft.Json; using NPOI.OpenXmlFormats.Vml; using NPOI.SS.UserModel; using NPOI.Util; 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.Domain.ViewModels.SmallFun; using OASystem.Infrastructure.Tools; using System.Collections.Specialized; using System.Drawing; using System.IO; using System.Security.Policy; namespace OASystem.Infrastructure.Repositories.PersonnelModule { /// /// 物品进销存 /// 仓储 /// public class GoodsRepository : BaseRepository { private readonly IMapper _mapper; private JsonView _jv; private string _url; private string _excelPath; public GoodsRepository(SqlSugarClient sqlSugar, IMapper mapper) : 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); } } /// /// 基础数据 /// /// 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 = "库存调整" }); 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 = "已拒绝" }, }; _jv.Code = StatusCodes.Status200OK; _jv.Data = new { goodsTypeData = typeData, stockStatus = stockStatus, 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); } } } 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.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; } /// /// 物品入库列表(带审核) /// /// /// public async Task GoodsStorageList(GoodsStorageListDto dto,int userId) { string reqAuditLabel = dto.AuditLabel; var auditLabel = Array.Empty(); 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(); } } 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)) .Select((gs, gi, u, u1) => new GoodsStorageListView() { Id = gs.Id, GoodsId = gs.GoodsId, 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, }) .OrderByDescending(gs => gs.CreateTime) .ToPageListAsync(dto.PageIndex, dto.PageSize, total); 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; } } foreach (var item in data) { item.AuditPers = new GoodsStorageAuditPerView[] { new (){ AuditPer = hrAuditPer, AuditDep = GoodsAuditDepEnum.Hr, ButtonText = GoodsAuditDepEnum.Hr.GetEnumDescription()}, new (){ AuditPer = finAuditPer, AuditDep = GoodsAuditDepEnum.Financial, ButtonText = GoodsAuditDepEnum.Financial.GetEnumDescription()} }; } _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() .Where(x => x.Id == dto.Id) .FirstAsync(); 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; } } 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()) { 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(); goodsAuditList.Add(new Pm_GoodsAudit(auditType, GoodsAuditDepEnum.Hr, dataId, GoodsConfirmEnum.WaitConfirm, currUserId)); goodsAuditList.Add(new Pm_GoodsAudit(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 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 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 (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() >= 2) { confirmStatus = GoodsConfirmEnum.Confirmed; }else if (preInfos.Where(x => x.AuditStatus == GoodsConfirmEnum.Confirmed).Count() >= 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; } //入库状态描述 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.AppendLine(string.Format("{0}:状态:{1}\t审核人:{2}\t审核时间:{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; var goodsInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == info.GoodsId); 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 (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 List GoodsStorageConfirmAuditDep(int auditType=1) { var auditList = new List(); var hrAuditorIds = new GoodsAuditDepView() { AuditDep = GoodsAuditDepEnum.Hr, AuditorIds = new int[] { 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 = goodsInfo.SQ_Total - delAgoQuantity; goodsInfo.StockQuantity = goodsInfo.StockQuantity - delAgoQuantity; goodsInfo.PriceTotal = 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 WorkbookDesigner(); designer.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(); 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 (!string.IsNullOrEmpty(dto.AuditLabel)) { auditLabel = dto.AuditLabel .Split(',') .Select(x => { if (int.TryParse(x, out var id)) return id; return id; }) .ToArray(); } if (!string.IsNullOrEmpty(dto.GroupLabel)) { groupLabel = dto.GroupLabel .Split(',') .Select(x => { if (int.TryParse(x, out var id)) return id; return id; }) .ToArray(); } //物品ID和物品名称只能传一个 if (dto.GoodsId > 0) dto.GoodsName = string.Empty; if (!string.IsNullOrEmpty(dto.GoodsName)) dto.GoodsId = 0; 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); RefAsync total = 0; var data = _sqlSugar.Queryable() .LeftJoin((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) .WhereIF(dto.GoodsId > 0, (gr, gi, sd, u1, u2, di) => gr.GoodsId == dto.GoodsId) .WhereIF(!string.IsNullOrEmpty(dto.GoodsName), (gr, gi, sd, u1, u2, di) => gi.Name.Contains(dto.GoodsName)) .WhereIF(auditLabel.Length > 0, (gr, gi, sd, u1, u2, di) => auditLabel.Contains((int)gr.AuditStatus)) .WhereIF(typeLabel.Length > 0, (gr, gi, sd, u1, u2, di) => typeLabel.Contains(gi.Type)) .WhereIF(userLabel.Length > 0, (gr, gi, sd, u1, u2, di) => userLabel.Contains(gr.CreateUserId)) .WhereIF(groupLabel.Length > 0, (gr, gi, sd, u1, u2, di) => groupLabel.Contains(gr.GroupId)) .WhereIF(beginBool && endBool, (gr, gi, sd, u1, u2, di) => gr.CreateTime >= begin && gr.CreateTime <= end) .Select((gr, gi, sd, u1, u2, di) => new GoodsReceiveListMobileView { Id = gr.Id, GroupId = gr.GroupId, GroupName = di.TeamName, GoodsId = gr.GoodsId, GoodsName = gi.Name, GoodsType = sd.Name, Quantity = gr.Quantity, Unit = gi.Unit, Reason = gr.Reason, Remark = gr.Remark, AuditStatus = gr.AuditStatus, //AuditStatusText = gr.AuditStatus.GetEnumDescription(), AuditUserId = gr.AuditUserId, AuditUserName = u1.CnName, AuditTime = gr.AuditTime, CreateUserName = u2.CnName, CreateTime = gr.CreateTime }) .OrderByDescending(gr => gr.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 WorkbookDesigner(); designer.Workbook = new Workbook(excelTempPath); var tableData = await data.ToListAsync(); 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); if (dto.PortType == 2 || dto.PortType == 3) { _jv.Data = view; } else if (dto.PortType == 1) { _jv.Data = _mapper.Map>(view); } _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 { StorageId = item.StorageId, BatchNo = 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; _sqlSugar.BeginTran(); //物品现有库存 var stockQuantity = _sqlSugar .Queryable() .First(x => x.Id == info.GoodsId) ?.StockQuantity; //待审核 该物品数量 var waitAuditQuantity = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == dto.GoodsId && x.AuditStatus == GoodsAuditEnum.Pending ) .SumAsync(x => x.Quantity); if (info.Id > 0) //修改 { //审核验证 var selectInfo = await _sqlSugar.Queryable().FirstAsync(x => x.Id == info.Id); if (selectInfo.AuditStatus == GoodsAuditEnum.Approved) { _sqlSugar.RollbackTran(); _jv.Msg = $"该条数据已通过审核,不可更改!"; 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, }) .Where(x => x.Id == info.Id) .ExecuteCommandAsync(); if (edit > 0) { _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).ExecuteCommandAsync(); if (add > 0) { _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; //TODO: 审核权限验证 _sqlSugar.BeginTran(); var receiveInfos = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && idArray.Contains(x.Id)) .ToListAsync(); var status = true; foreach (var id in idArray) { //1.更改审核状态 var currInfo = receiveInfos.Find(x => x.Id == id); if (currInfo == null) continue; var edit = await _sqlSugar .Updateable() .SetColumns(x => new Pm_GoodsReceive() { AuditStatus = auditEnum, AuditUserId = userId, AuditTime = DateTime.Now, }) .Where(x => x.Id == id) .ExecuteCommandAsync(); if (edit < 1) status = false; //if (auditEnum != GoodsAuditEnum.Approved) continue; //2.更改库存 var goodsInfo = await _sqlSugar.Queryable().Where(x => x.Id == currInfo.GoodsId).FirstAsync(); if (auditEnum == GoodsAuditEnum.Pending) { goodsInfo.StockQuantity += currInfo.Quantity; goodsInfo.OQ_Total -= currInfo.Quantity; } else if (auditEnum == GoodsAuditEnum.Approved) { goodsInfo.StockQuantity -= currInfo.Quantity; goodsInfo.OQ_Total += currInfo.Quantity; }else if(auditEnum == GoodsAuditEnum.UnApproved) continue; 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 == currInfo.GoodsId) .ExecuteCommandAsync(); if (editGoods < 1) status = false; //3.入库批次关联领用人 更改批次库存 var goodsStorages = await _sqlSugar .Queryable() .Where(x => x.IsDel == 0 && x.GoodsId == currInfo.GoodsId && (x.Quantity - x.ReceiveQuantity) > 0 ) .OrderBy(x => x.CreateTime) .ToListAsync(); var goodsReceiveInfos = new List(); var batchStorageInfos = new List(); var receiveQuantity = 0.00M; //领用总数量 if (auditEnum == GoodsAuditEnum.Approved) { foreach (var storage in goodsStorages) { if (currInfo.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 < currInfo.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.1 更改批次库存 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable(batchStorageInfos) .UpdateColumns(x => x.ReceiveQuantity) .WhereColumns(x => x.Id) .ExecuteCommandAsync(); if (edit1 < 1) status = false; } //3.2 添加入库批次关联领用人 if (goodsReceiveInfos.Count > 0) { var edit1 = await _sqlSugar.Updateable() .SetColumns(x => new Pm_GoodsReceive() { GoodsStorageInfo = JsonConvert.SerializeObject(goodsReceiveInfos) }) .Where(x => x.Id == id) .ExecuteCommandAsync(); if (edit1 < 1) status = false; } } else if (auditEnum == GoodsAuditEnum.Pending) { var goodsStorageInfo = currInfo.GoodsStorageInfo; if (!string.IsNullOrEmpty(goodsStorageInfo)) { var goodsStorageInfos = JsonConvert.DeserializeObject>(goodsStorageInfo); if (goodsStorageInfos.Count > 0) { foreach (var item in goodsStorageInfos) { var newStorageInfo = await _sqlSugar.Queryable() .Where(x => x.IsDel == 0 && x.Id == item.StorageId) .FirstAsync(); if (newStorageInfo != null) { var newEdit = await _sqlSugar.Updateable(newStorageInfo) .ReSetValue(x => x.ReceiveQuantity = x.ReceiveQuantity - item.Quantity) .ExecuteCommandAsync(); if (newEdit < 1) status = false; } } } } } } if (status) { _sqlSugar.CommitTran(); _jv.Msg = $"操作成功!"; _jv.Code = StatusCodes.Status200OK; return _jv; } _sqlSugar.RollbackTran(); return _jv; } /// /// 物品领用 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; } } }