432 lines
20 KiB
C#
432 lines
20 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 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<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.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<ChangeBoxRecord> list = new List<ChangeBoxRecord>();
|
|
var subIds = dto.Select(s => s.SubStockId).ToList();
|
|
var subStocks = await _basbicsRepositories.GetSubUcStockAsync(subIds, 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);
|
|
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;//原乡仓位需要去拉一下库存获取
|
|
if (subStock != null)
|
|
{
|
|
entity.DestSubStockId = dt.SubStockId;
|
|
entity.DestBoxOrgCode = subStock.ErpOrgCode;
|
|
entity.DestStockCode = subStock.StockCode;
|
|
}
|
|
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()
|
|
{
|
|
MaterialId = d.MaterialId,
|
|
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();
|
|
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.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);
|
|
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();
|
|
}
|
|
/// <summary>
|
|
/// 出入库回退改箱
|
|
/// </summary>
|
|
/// <param name="backRecord"></param>
|
|
/// <param name="loginInfo"></param>
|
|
/// <param name="isTransaction"></param>
|
|
/// <returns></returns>
|
|
public async Task<Result> ChangeBox_BackRecord(BackRecord backRecord, LoginInDto loginInfo, bool isTransaction = true)
|
|
{
|
|
if (backRecord.Method == InventoryInOutMethod.Box) return Result.ReSuccess();
|
|
List<SaveChangeBoxRecordRequest> dtoList = new List<SaveChangeBoxRecordRequest>();
|
|
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();
|
|
}
|
|
/// <summary>
|
|
/// 非采购入库
|
|
/// </summary>
|
|
/// <param name="inStock"></param>
|
|
/// <param name="loginInfo"></param>
|
|
/// <param name="isTransaction"></param>
|
|
/// <returns></returns>
|
|
public async Task<Result> ChangeBox_InStock(InStock inStock, LoginInDto loginInfo, bool isTransaction = true)
|
|
{
|
|
List<SaveChangeBoxRecordRequest> dtoList = new List<SaveChangeBoxRecordRequest>();
|
|
//目标箱
|
|
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);
|
|
}
|
|
}
|
|
}
|