using AutoMapper; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WMS.Web.Core.Dto; using WMS.Web.Core.Dto.ChangeBoxRecord; using WMS.Web.Core.Dto.Inventory; using WMS.Web.Core.Dto.Login; using WMS.Web.Core.Dto.MoveBoxRecord; using WMS.Web.Core.Help; using WMS.Web.Core.Internal.Results; using WMS.Web.Domain.Entitys; using WMS.Web.Domain.Infrastructure; using WMS.Web.Domain.IService; using WMS.Web.Domain.IService.Public; using WMS.Web.Domain.Values; namespace WMS.Web.Domain.Services { ///改箱 移箱服务 public class ChangeMoveBoxService : IChangeMoveBoxService { private readonly IMapper _mapper; private readonly ILoginService _loginService; private readonly IChangeBoxRecordRepositories _changeBoxRecordRepositories; public readonly IBasicsRepositories _basbicsRepositories; private readonly IMoveBoxRecordRepositories _moveBoxRecordRepositories; private readonly IBoxRepositories _boxRepositories; private readonly ISerialNumberService _serialNumberService; private readonly IBoxInventoryService _boxInventoryService; private readonly IBoxInventoryRepositories _boxInventoryRepositories; private readonly ILogger _logger; private readonly ISerialNumbersRepositories _serialNumbersRepositories; private readonly IBoxService _boxService; public ChangeMoveBoxService(IMapper mapper, ILoginService loginService, IChangeBoxRecordRepositories changeBoxRecordRepositories, IBasicsRepositories basbicsRepositories, IMoveBoxRecordRepositories moveBoxRecordRepositories, IBoxRepositories boxRepositories, ISerialNumberService serialNumberService, IBoxInventoryService boxInventoryService, IBoxInventoryRepositories boxInventoryRepositories, ILogger logger, ISerialNumbersRepositories serialNumbersRepositories, IBoxService boxService) { _mapper = mapper; _loginService = loginService; _changeBoxRecordRepositories = changeBoxRecordRepositories; _basbicsRepositories = basbicsRepositories; _moveBoxRecordRepositories = moveBoxRecordRepositories; _boxRepositories = boxRepositories; _serialNumberService = serialNumberService; _boxInventoryService = boxInventoryService; _boxInventoryRepositories = boxInventoryRepositories; _logger = logger; _serialNumbersRepositories = serialNumbersRepositories; _boxService = boxService; } /// /// 改箱保存 /// /// /// /// public async Task ChangeBoxSave(List dto, LoginInDto loginInfo, bool isTransaction = false, bool IsInventory = true, bool IsPDA = false) { _logger.LogInformation($"改箱:{JsonConvert.SerializeObject(dto)} 操作人:{loginInfo.UserInfo.StaffId}"); bool isAddBox = false; if (IsPDA) { //处理目标箱不在系统的情况,需要先增加箱信息 var d = dto.First(); if (d.DestBoxId == 0) { var dBox = await _boxRepositories.GetByNo(d.DestBoxBillNo); if (dBox == null) { var res = await CreateBox(d); if (!res.IsSuccess) return res; dBox = await _boxRepositories.GetByNo(d.DestBoxBillNo); dto.First().DestBoxId = dBox.Id; isAddBox = true; } } } //1.有原箱时 需要判断 物料对应的序列号是否存在 var srcIds = dto.Select(s => s.SrcBoxId).Distinct().ToList(); var destIds = dto.Select(s => s.DestBoxId).Distinct().ToList(); var boxs = await _boxInventoryRepositories.GetList(srcIds); var serialNumbers = dto.SelectMany(s => s.Details).SelectMany(s => s.SerialNumbers).ToList(); var serialNumberList = await _serialNumbersRepositories.GetEntityList(serialNumbers); foreach (var d in dto) { if (d.SrcBoxId == 0) { //没有原箱的情况下需要验证序列号是否有箱子绑定 var s = d.Details.SelectMany(s => s.SerialNumbers).ToList(); var sCount = serialNumberList.Where(w => s.Contains(w.SerialNumber) && w.BoxId != 0).Count(); if (sCount > 0) return Result.ReFailure(ResultCodes.SerialNumbersBoxError); } else { //有原箱的情况下验证序列号和原箱是否一致 var s = d.Details.SelectMany(s => s.SerialNumbers).ToList(); var boxCount = serialNumberList.Where(w => s.Contains(w.SerialNumber)).GroupBy(s => s.BoxId).Select(s => s.Key).ToList(); if (boxCount.Count() > 1 || (boxCount.Count() == 1 && boxCount[0] != d.SrcBoxId)) return Result.ReFailure(ResultCodes.SerialNumbersSrcBoxError); } var box = boxs.FirstOrDefault(f => f.BoxId == d.SrcBoxId); //原箱在库存中的话 进行验证 if (box != null) { foreach (var bd in box.Details) { var bDe = box.Details.FirstOrDefault(f => f.MaterialId == bd.MaterialId); if (bDe == null) return Result.ReFailure(ResultCodes.BoxMateriaNoData); var ex = bd.SerialNumbers.Except(bDe.SerialNumbers).ToList(); if (ex.Count() > 0) return Result.ReFailure(ResultCodes.BoxInventorySerialNumbersNoData); } } } List boxList = new List(); //原箱有可能没有 var srcBoxs = await _boxRepositories.GetEntityList(srcIds); var destBoxs = await _boxRepositories.GetEntityList(destIds); //if (srcBox == null) return Result.ReFailure(ResultCodes.BoxNoData); if (destBoxs.Count() != destIds.Count()) return Result.ReFailure(ResultCodes.BoxNoData); foreach (var d in dto) { var l = d.Details.Select(s => (s.MaterialId, s.Qty, s.SerialNumbers)).ToList(); var srcBox = srcBoxs.FirstOrDefault(f => f.Id == d.SrcBoxId); var destBox = destBoxs.FirstOrDefault(f => f.Id == d.DestBoxId); //原箱移出 Result res; if (srcBox != null) { res = srcBox.Out(l); if (!res.IsSuccess) return res; } if (srcBox != null) boxList.Add(srcBox); //目标箱移入 if (!isAddBox) { res = destBox.In(l); if (!res.IsSuccess) return res; if (destBox != null) boxList.Add(destBox); } } List list = new List(); var subIds = dto.Select(s => s.SubStockId).ToList(); var subStocks = await _basbicsRepositories.GetSubUcStockAsync(subIds, loginInfo.UserInfo.CompanyId); var subStocks_s = await _basbicsRepositories.GetSubUcStockAsync(boxs.Select(s=>s.SubStockId).ToList(), loginInfo.UserInfo.CompanyId); foreach (var dt in dto) { var subStock = subStocks.FirstOrDefault(f => f.Id == dt.SubStockId); var boxi = boxs.FirstOrDefault(f => f.BoxId == dt.SrcBoxId); var subStock_s = subStocks_s.FirstOrDefault(f => f.Id == (boxi?.SubStockId ?? 0)); foreach (var d in dt.Details) { ChangeBoxRecord entity = new ChangeBoxRecord(); entity.Create(loginInfo.UserInfo.StaffId, d.Qty, d.MaterialId, d.SerialNumbers, dt.SrcBoxId, dt.DestBoxId); entity.SrcSubStockId = boxi?.SubStockId ?? 0;//原乡仓位需要去拉一下库存获取 entity.SrcSubStockCode = subStock_s?.Code ?? ""; if (subStock != null) { entity.DestSubStockId = dt.SubStockId; entity.DestBoxOrgCode = subStock.ErpOrgCode; entity.DestStockCode = subStock.StockCode; entity.DestSubStockCode = subStock.Code; } list.Add(entity); } } IDbContextTransaction _transaction = null; if (isTransaction) _transaction = _basbicsRepositories.GetTransaction(); Result res_Rollback = Result.ReSuccess(); bool isSuccess = true; if (res_Rollback.IsSuccess) { isSuccess = await _changeBoxRecordRepositories.AddRange(list, false); if (!isSuccess) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError); } if (res_Rollback.IsSuccess) { var res_change = await _serialNumberService.ChangeBox(list, loginInfo, false); if (!res_change.IsSuccess) res_Rollback = res_change; } if (res_Rollback.IsSuccess) { isSuccess = await _boxRepositories.EditEntityList(boxList, false); if (!isSuccess) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError); } if (res_Rollback.IsSuccess && IsInventory) { var res_Inventory = await _boxInventoryService.GenerateChangeBox(list, false); if (!res_Inventory.IsSuccess) res_Rollback = res_Inventory; } //提交事务 if (isTransaction) { isSuccess = _basbicsRepositories.CommitTransaction(res_Rollback.IsSuccess ? false : true, _transaction); if (!res_Rollback.IsSuccess) return res_Rollback; if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); } return Result.ReSuccess(); } /// /// 自动生成箱信息 /// /// /// private async Task CreateBox(SaveChangeBoxRecordRequest dto) { //增加一个空箱子 List list = new List(); OpsBoxResponse response = new OpsBoxResponse() { BoxBillNo = dto.DestBoxBillNo }; foreach (var d in dto.Details) { List s = new List(); foreach (var sd in d.SerialNumbers) { s.Add(new OpsSerialNumbersResponse() { SerialNumber = sd }); } OpsBoxDetailsResponse dr = new OpsBoxDetailsResponse() { MaterialId = d.MaterialId, Qty = d.Qty, SerialNumbers = s }; response.Details.Add(dr); } list.Add(response); return await _boxService.Sync(list); } /// /// 移箱保存 /// /// /// /// public async Task MoveBoxSave(List dto, bool IsUp, LoginInDto loginInfo) { _logger.LogInformation($"移箱:{JsonConvert.SerializeObject(dto)} 是否上架:{IsUp} 操作人:{loginInfo.UserInfo.StaffId}"); //1.下架时 需要验证箱是否在库存里 var boxIds = dto.Select(s => s.BoxId).ToList(); var boxList = await _boxInventoryRepositories.GetList(boxIds); if (!IsUp) { if (boxIds.Count() != boxList.Count()) return Result.ReFailure(ResultCodes.BoxInventoryNoDataError); } else { //上架时 箱子不能在库存里 if (boxList.Count() > 0) { var boxs = await _boxRepositories.GetEntityList(boxList.Select(s => s.BoxId).ToList()); return Result.ReFailure($"箱号{ string.Join(",", boxs.Select(s => s.BoxBillNo))} 已上架", 343433); } } List entityList = new List(); foreach (var d in dto) { var subStock = await _basbicsRepositories.GetSubUcStockAsync(d.SubStockId, loginInfo.UserInfo.CompanyId); var entity = new MoveBoxRecord(); entity.Create(IsUp == true ? MoveBoxType.Up : MoveBoxType.Down, d.BoxId, d.Qty, subStock?.ErpOrgCode, subStock?.StockCode, d.SubStockId, loginInfo.UserInfo.StaffId, subStock?.Code); entity.Details = d.Details.Select(s => new MoveBoxRecordDetails() { MaterialId = s.MaterialId, Qty = s.Qty, SerialNumbers = s.SerialNumbers }).ToList(); entityList.Add(entity); } IDbContextTransaction _transaction = _basbicsRepositories.GetTransaction(); bool isSuccess = true; Result res_Rollback = Result.ReSuccess(); if (res_Rollback.IsSuccess) { isSuccess = await _moveBoxRecordRepositories.AddRange(entityList, false); if (!isSuccess) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError); } if (res_Rollback.IsSuccess) { var res_change = await _serialNumberService.MoveBox(entityList, loginInfo, false); if (!res_change.IsSuccess) res_Rollback = res_change; } if (res_Rollback.IsSuccess) { var res_Inventory = await _boxInventoryService.GenerateMoveBox(entityList, false); if (!res_Inventory.IsSuccess) res_Rollback = res_Inventory; } //提交事务 isSuccess = _basbicsRepositories.CommitTransaction(res_Rollback.IsSuccess ? false : true, _transaction); if (!res_Rollback.IsSuccess) return res_Rollback; if (!isSuccess) return Result.ReFailure(ResultCodes.DateWriteError); return Result.ReSuccess(); } #region 删除代码 ///// ///// 出入库回退改箱 ///// ///// ///// ///// ///// //public async Task ChangeBox_BackRecord(BackRecord backRecord, LoginInDto loginInfo, bool isTransaction = true) //{ // if (backRecord.Method == InventoryInOutMethod.Box) return Result.ReSuccess(); // List dtoList = new List(); // var boxIds = backRecord.Details.Select(s => s.BoxId).Distinct().ToList(); // var boxs = await _boxRepositories.GetEntityList(boxIds); // foreach (var d in backRecord.Details) // { // var box = boxs.FirstOrDefault(f => f.Id == d.BoxId); // if (box == null) continue; // if (backRecord.Type == BackRecordType.InstockOff) // box.BackRecordDown(d.MaterialId, d.Qty); // else // box.BackRecordUp(d.MaterialId, d.Qty); // } // IDbContextTransaction _transaction = null; // if (isTransaction) // _transaction = _basbicsRepositories.GetTransaction(); // Result res_Rollback = Result.ReSuccess(); // bool isSuccess = true; // if (res_Rollback.IsSuccess) // { // isSuccess = await _boxRepositories.EditEntityList(boxs, false); // if (!isSuccess) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError); // } // //提交事务 // if (isTransaction) // { // isSuccess = _basbicsRepositories.CommitTransaction(res_Rollback.IsSuccess ? false : true, _transaction); // if (!res_Rollback.IsSuccess) return res_Rollback; // if (!isSuccess) // return Result.ReFailure(ResultCodes.DateWriteError); // } // return Result.ReSuccess(); //} ///// ///// 非采购入库 ///// ///// ///// ///// ///// //public async Task ChangeBox_InStock(InStock inStock, LoginInDto loginInfo, bool isTransaction = true) //{ // List dtoList = new List(); // //目标箱 // var destIds = inStock.Details.GroupBy(g => g.BoxId); // var serialNumbers = inStock.Details.SelectMany(s => s.SerialNumbers).ToList(); // var serialNumberList = await _serialNumbersRepositories.GetEntityList(serialNumbers); // foreach (var detail in inStock.Details) // { // if (detail.Qty == 0) continue; // var detailClone = detail.Clone(); // //处理序列号 // var sList = serialNumberList.Where(w => detailClone.SerialNumbers.Contains(w.SerialNumber)).ToList(); // foreach (var s in sList) // { // //原箱和目标箱一样不处理 // if (s.BoxId == detailClone.BoxId) // { // detailClone.Qty = detailClone.Qty - 1; // detailClone.SerialNumbers.Remove(s.SerialNumber); // continue; // } // var d = dtoList.FirstOrDefault(f => f.DestBoxId == detailClone.BoxId && f.SrcBoxId == s.BoxId); // if (d == null) // { // d = new SaveChangeBoxRecordRequest(s.BoxId, detailClone.BoxId); // d.Details.Add(new SaveChangeBoxRecordDetailsRequest(detailClone.MaterialId, 1, s.SerialNumber)); // } // else // { // var dtoDetail = d.Details.FirstOrDefault(f => f.MaterialId == detailClone.MaterialId); // if (dtoDetail == null) // d.Details.Add(new SaveChangeBoxRecordDetailsRequest(detailClone.MaterialId, 1, s.SerialNumber)); // else // { // dtoDetail.Qty += 1; // dtoDetail.SerialNumbers.Add(s.SerialNumber); // } // } // detailClone.Qty = detailClone.Qty - 1; // detailClone.SerialNumbers.Remove(s.SerialNumber); // } // //处理非序列号的数据 // if (detailClone.Qty <= 0) continue; // var dto = dtoList.FirstOrDefault(f => f.DestBoxId == detailClone.BoxId && f.SrcBoxId == 0); // if (dto == null) // { // dto = new SaveChangeBoxRecordRequest(0, detailClone.BoxId); // dto.Details.Add(new SaveChangeBoxRecordDetailsRequest(detailClone.MaterialId, detailClone.Qty, detailClone.SerialNumbers)); // } // else // { // var dtoDetail = dto.Details.FirstOrDefault(f => f.MaterialId == detailClone.MaterialId); // if (dtoDetail == null) // dto.Details.Add(new SaveChangeBoxRecordDetailsRequest(detailClone.MaterialId, detailClone.Qty, detailClone.SerialNumbers)); // else // { // dtoDetail.Qty += detailClone.Qty; // dtoDetail.SerialNumbers.AddRange(detailClone.SerialNumbers); // } // } // } // return await ChangeBoxSave(dtoList, loginInfo, isTransaction, false); //} ///// ///// 出库 ///// ///// ///// ///// //public async Task ChangeBox_OutStock(OutStock outStock, bool isTransaction = true) //{ // if (outStock.Method == InventoryInOutMethod.Box) return Result.ReSuccess(); // List dtoList = new List(); // var boxDetails = outStock.Details.SelectMany(s => s.BoxsDetails); // var boxIds = boxDetails.Select(s => s.BoxId).Distinct().ToList(); // var boxs = await _boxRepositories.GetEntityList(boxIds); // foreach (var d in outStock.Details) // { // foreach (var db in d.BoxsDetails) // { // var box = boxs.FirstOrDefault(f => f.Id == db.BoxId); // if (box == null) continue; // box.OutStock(d.MaterialId, db.Qty); // } // } // IDbContextTransaction _transaction = null; // if (isTransaction) // _transaction = _basbicsRepositories.GetTransaction(); // Result res_Rollback = Result.ReSuccess(); // bool isSuccess = true; // if (res_Rollback.IsSuccess) // { // isSuccess = await _boxRepositories.EditEntityList(boxs, false); // if (!isSuccess) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError); // } // //提交事务 // if (isTransaction) // { // isSuccess = _basbicsRepositories.CommitTransaction(res_Rollback.IsSuccess ? false : true, _transaction); // if (!res_Rollback.IsSuccess) return res_Rollback; // if (!isSuccess) // return Result.ReFailure(ResultCodes.DateWriteError); // } // return Result.ReSuccess(); //} #endregion } }