Files
WMS-Api/src/WMS.Web.Domain/Services/ChangeMoveBoxService.cs
18942506660 5eb941a0ae 修复bug
2024-03-21 10:28:42 +08:00

336 lines
16 KiB
C#

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<ChangeMoveBoxService> _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<ChangeMoveBoxService> 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;
}
/// <summary>
/// 改箱保存
/// </summary>
/// <param name="dto"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
public async Task<Result> ChangeBoxSave(List<SaveChangeBoxRecordRequest> 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 destIds_boxs = await _boxInventoryRepositories.GetList(destIds);
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);
var dest_box = destIds_boxs.FirstOrDefault(f => f.BoxId == d.DestBoxId);
if (dest_box != null)
return Result.ReFailure(ResultCodes.BoxInventoryChangeBoxError);
}
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.MaterialNumber == bd.MaterialNumber);
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<Box> boxList = new List<Box>();
//原箱有可能没有
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.MaterialNumber, 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<ChangeBoxRecord> list = new List<ChangeBoxRecord>();
var subIds = dto.Select(s => s.SubStockCode).ToList();
var subStocks = await _basbicsRepositories.GetSubUcStockAsync(subIds, loginInfo.UserInfo.CompanyId);
var subStocks_s = await _basbicsRepositories.GetSubUcStockAsync(boxs.Select(s => s.SubStockCode).ToList(), loginInfo.UserInfo.CompanyId);
foreach (var dt in dto)
{
var subStock = subStocks.FirstOrDefault(f => f.Code == dt.SubStockCode);
var boxi = boxs.FirstOrDefault(f => f.BoxId == dt.SrcBoxId);
var subStock_s = subStocks_s.FirstOrDefault(f => f.Code == (boxi?.SubStockCode ?? ""));
foreach (var d in dt.Details)
{
ChangeBoxRecord entity = new ChangeBoxRecord();
entity.Create(loginInfo.UserInfo.StaffId, d.Qty, d.MaterialNumber, d.SerialNumbers, dt.SrcBoxId, dt.DestBoxId);
//entity.SrcSubStockId = boxi?.SubStockId ?? 0;//原乡仓位需要去拉一下库存获取
if (subStock_s != null)
{
entity.SrcSubStockCode = subStock_s.Code;//原乡仓位需要去拉一下库存获取
entity.SrcBoxOrgCode = subStock_s.ErpOrgCode;
entity.SrcStockCode = subStock_s.StockCode;
}
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();
}
/// <summary>
/// 自动生成箱信息
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
private async Task<Result> CreateBox(SaveChangeBoxRecordRequest dto)
{
//增加一个空箱子
List<OpsBoxResponse> list = new List<OpsBoxResponse>();
OpsBoxResponse response = new OpsBoxResponse() { BoxBillNo = dto.DestBoxBillNo };
foreach (var d in dto.Details)
{
List<OpsSerialNumbersResponse> s = new List<OpsSerialNumbersResponse>();
foreach (var sd in d.SerialNumbers)
{
s.Add(new OpsSerialNumbersResponse() { SerialNumber = sd });
}
OpsBoxDetailsResponse dr = new OpsBoxDetailsResponse()
{
MaterialNumber = d.MaterialNumber,
Qty = d.Qty,
SerialNumbers = s
};
response.Details.Add(dr);
}
list.Add(response);
return await _boxService.Sync(list);
}
/// <summary>
/// 移箱保存
/// </summary>
/// <param name="dto"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
public async Task<Result> MoveBoxSave(List<SaveMoveBoxRecordRequest> dto, bool IsUp, LoginInDto loginInfo)
{
_logger.LogInformation($"移箱:{JsonConvert.SerializeObject(dto)} 是否上架:{IsUp} 操作人:{loginInfo.UserInfo.StaffId}");
//1.下架时 需要验证箱是否在库存里
var boxIds = dto.Select(s => s.BoxId).ToList();
if (boxIds.Distinct().Count() != boxIds.Count())
return Result.ReFailure(ResultCodes.BoxOutStockTaskBoxError);
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<MoveBoxRecord> entityList = new List<MoveBoxRecord>();
foreach (var d in dto)
{
var subStock = await _basbicsRepositories.GetSubUcStockAsync(d.SubStockCode, loginInfo.UserInfo.CompanyId);
var entity = new MoveBoxRecord();
entity.Create(IsUp == true ? MoveBoxType.Up : MoveBoxType.Down, d.BoxId, d.Qty, subStock?.ErpOrgCode, subStock?.StockCode, loginInfo.UserInfo.StaffId, d.SubStockCode);
entity.Details = d.Details.Select(s => new MoveBoxRecordDetails()
{
MaterialNumber = s.MaterialNumber,
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();
}
}
}