Browse Source

更新

Agv分支2024-11-19
赵新宇 4 months ago
parent
commit
06582eeb24
  1. 2
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/InjectionJobs/IInjectionIssueJobAppService.cs
  2. 2
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs
  3. 2
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/SparePartIssueJobs/ISparePartIssueJobAppService.cs
  4. 1
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/IUnplannedIssueJobAppService.cs
  5. 404
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/CoatingIssueJobs/CoatingIssueJobAppService.cs
  6. 556
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/InjectionIssueJobs/InjectionIssueJobAppService.cs
  7. 542
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs
  8. 639
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/SparePartIssueJobs/SparePartIssueJobAppService.cs
  9. 542
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/UnplannedIssueJobs/UnplannedIssueJobAppService.cs

2
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/InjectionJobs/IInjectionIssueJobAppService.cs

@ -28,7 +28,7 @@ public interface IInjectionIssueJobAppService
Task<InjectionIssueJobDTO> GetByNumber2Async(string number);
Task<InjectionIssueJobDTO> GetJobByPackingCodeAsync(string packingCode);
Task<AgvResultObject> CallBackAgvAsync(AgvRequestDto request);
}

2
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs

@ -27,6 +27,6 @@ public interface IKittingIssueJobAppService
Task<KittingIssueJobDTO> GetByNumber2Async(string number);
Task<KittingIssueJobDTO> GetJobByPackingCodeAsync(string packingCode);
Task<AgvResultObject> CallBackAgvAsync(AgvRequestDto request);
}

2
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/SparePartIssueJobs/ISparePartIssueJobAppService.cs

@ -28,6 +28,6 @@ public interface ISparePartIssueJobAppService
Task<SparePartIssueJobDTO> GetByNumber2Async(string number);
Task<SparePartIssueJobDTO> GetJobByPackingCodeAsync(string packingCode);
Task<AgvResultObject> CallBackAgvAsync(AgvRequestDto request);
}

1
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/IUnplannedIssueJobAppService.cs

@ -11,7 +11,6 @@ public interface IUnplannedIssueJobAppService
Task CreateByRecommendAsync(UnplannedIssueRequest requestDto);
Task<bool> IsAllJobOverByRequestNumberAsync(string requestNumber);
Task<ReusltObject> CallAgvAsync(UnplannedIssueJobDTO input);

404
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/CoatingIssueJobs/CoatingIssueJobAppService.cs

@ -181,7 +181,10 @@ public class CoatingIssueJobAppService
if (coatingJob.JobStatus == EnumJobStatus.Open ||
coatingJob.JobStatus == EnumJobStatus.Partial ||
coatingJob.JobStatus == EnumJobStatus.Wait ||
coatingJob.JobStatus == EnumJobStatus.Doing)
coatingJob.JobStatus == EnumJobStatus.Doing||
coatingJob.JobStatus == EnumJobStatus.WaitAgv
)
{
await _expectOutAppService.RemoveByNumberAsync(coatingJob.Number).ConfigureAwait(false);
await _transferLibRequestAppService.CancelByCallRequestNumberAsync(coatingJob.CoatingRequestNumber)
@ -196,7 +199,9 @@ public class CoatingIssueJobAppService
$"{EnumJobStatus.Open.GetDisplayName()}、" +
$"{EnumJobStatus.Partial.GetDisplayName()}、" +
$"{EnumJobStatus.Doing.GetDisplayName()}、" +
$"{EnumJobStatus.Wait.GetDisplayName()}");
$"{EnumJobStatus.Wait.GetDisplayName()}"+
$"{EnumJobStatus.WaitAgv.GetDisplayName()}"
);
}
}
@ -830,163 +835,18 @@ public class CoatingIssueJobAppService
}
#endregion
#region 私有
/// <summary>
/// 创建补料记录实体
/// </summary>
/// <param name="coatingIssueJobDto"></param>
/// <returns></returns>
private async Task<CoatingIssueNoteEditInput> BuildCoatingIssueNoteAsync(CoatingIssueJobDTO coatingIssueJobDto)
{
var coatingIssueNoteCreateInput =
ObjectMapper.Map<CoatingIssueJobDTO, CoatingIssueNoteEditInput>(coatingIssueJobDto);
coatingIssueNoteCreateInput.JobNumber = coatingIssueJobDto.Number;
await Task.CompletedTask.ConfigureAwait(false);
return coatingIssueNoteCreateInput;
}
/// <summary>
/// 判断是不是在最底层 如果不是则把状态变更为待库移 并把库移推荐的From和To赋值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task CheckMinRowAndSetStatusAsync(CoatingIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode != 1)
{
input.JobStatus = EnumJobStatus.Wait;
}
else if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode == 1)
{
jobDetailInputdetail.TransferLibFromArriveDate = jobDetailInputdetail.RecommendFromArriveDate;
jobDetailInputdetail.TransferLibFromContainerCode = jobDetailInputdetail.RecommendFromContainerCode;
jobDetailInputdetail.TransferLibFromExpireDate = jobDetailInputdetail.RecommendFromExpireDate;
jobDetailInputdetail.TransferLibFromLocationArea = jobDetailInputdetail.RecommendFromLocationArea;
jobDetailInputdetail.TransferLibFromLocationCode = jobDetailInputdetail.RecommendFromLocationCode;
jobDetailInputdetail.TransferLibFromLocationErpCode = jobDetailInputdetail.RecommendFromLocationErpCode;
jobDetailInputdetail.TransferLibFromLocationGroup = jobDetailInputdetail.RecommendFromLocationGroup;
jobDetailInputdetail.TransferLibFromLot = jobDetailInputdetail.RecommendFromLot;
jobDetailInputdetail.TransferLibFromPackingCode = jobDetailInputdetail.RecommendFromPackingCode;
jobDetailInputdetail.TransferLibFromProduceDate = jobDetailInputdetail.RecommendFromProduceDate;
jobDetailInputdetail.TransferLibFromQty = jobDetailInputdetail.RecommendFromQty;
jobDetailInputdetail.TransferLibFromSupplierBatch = jobDetailInputdetail.RecommendFromSupplierBatch;
jobDetailInputdetail.TransferLibFromWarehouseCode = jobDetailInputdetail.RecommendFromWarehouseCode;
jobDetailInputdetail.TransferLibToArriveDate = jobDetailInputdetail.RecommendToArriveDate;
jobDetailInputdetail.TransferLibToContainerCode = jobDetailInputdetail.RecommendToContainerCode;
jobDetailInputdetail.TransferLibToExpireDate = jobDetailInputdetail.RecommendToExpireDate;
jobDetailInputdetail.TransferLibToLot = jobDetailInputdetail.RecommendToLot;
jobDetailInputdetail.TransferLibToPackingCode = jobDetailInputdetail.RecommendToPackingCode;
jobDetailInputdetail.TransferLibToProduceDate = jobDetailInputdetail.RecommendToProduceDate;
jobDetailInputdetail.TransferLibToQty = jobDetailInputdetail.RecommendToQty;
jobDetailInputdetail.TransferLibToSupplierBatch = jobDetailInputdetail.RecommendToSupplierBatch;
jobDetailInputdetail.TransferLibToWarehouseCode = jobDetailInputdetail.TransferLibFromWarehouseCode;
jobDetailInputdetail.TransferLibToLocationArea = jobDetailInputdetail.TransferLibFromLocationArea;
jobDetailInputdetail.TransferLibToLocationCode = jobDetailInputdetail.TransferLibFromLocationCode;
jobDetailInputdetail.TransferLibToLocationErpCode = jobDetailInputdetail.TransferLibFromLocationErpCode;
jobDetailInputdetail.TransferLibToLocationGroup = jobDetailInputdetail.TransferLibFromLocationGroup;
}
}
/// <summary>
/// 判断是不是在立体库
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task CheckDimensionalStorehouseAsync(CoatingIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
input.JobStatus = EnumJobStatus.Wait;
}
}
/// <summary>
/// 修改当前任务状态 和 该任务的请求状态
/// </summary>
/// <param name="coatingIssueJob"></param>
/// <param name="coatingIssueJobDetailDto"></param>
/// <param name="handledToQty"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task UpdateRequestAndjobStatusDoneAsync(CoatingIssueJob coatingIssueJob,
CoatingIssueJobDetailDTO coatingIssueJobDetailDto, decimal handledToQty)
{
if (coatingIssueJob.JobStatus is EnumJobStatus.Closed or EnumJobStatus.Cancelled or EnumJobStatus.None
or EnumJobStatus.Done) //需要考虑下 多次提交的问题 所以不判断 进行中
{
throw new UserFriendlyException(
$"任务状态错误:编号为【{coatingIssueJob.Number}】的任务状态为【{coatingIssueJob.JobStatus.GetDisplayName()}】");
}
coatingIssueJob.JobStatus = EnumJobStatus.Done;
await RemoveExpectOutAsync(coatingIssueJob, coatingIssueJobDetailDto, handledToQty).ConfigureAwait(false);
//await _expectOutAppService.RemoveByNumberAsync(coatingIssueJob.Number).ConfigureAwait(false);
await CoatingIssueRequestAppService.UpdateStatusCompletedAsync(coatingIssueJob.CoatingRequestNumber)
.ConfigureAwait(false);
await Task.CompletedTask.ConfigureAwait(false);
}
/// <summary>
/// 判断实际TO的箱码是否被占用
/// </summary>
/// <param name="packingCode"></param>
/// <param name="jobNumber"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task CheckPackingCodeIsUserAsync(string packingCode, string jobNumber)
{
var list = await _expectOutAppService.GetListByPackingCodeAsync(packingCode).ConfigureAwait(false);
list = list.Where(p => p.JobNumber != jobNumber).ToList();
if (list.Any())
{
throw new UserFriendlyException($"任务号【{list.First().JobNumber}】的任务,已占用【{packingCode}】箱码的库存。");
}
}
private async Task RemoveExpectOutAsync(CoatingIssueJob coatingIssueJob,
CoatingIssueJobDetailDTO coatingIssueJobDetailDto,
decimal handledToQty)
{
await _expectOutAppService.RemoveByNumberAndInventoryAsync(coatingIssueJob.Number,
coatingIssueJobDetailDto.ItemCode,
coatingIssueJobDetailDto.HandledToLocationCode, coatingIssueJobDetailDto.HandledToPackingCode,
coatingIssueJobDetailDto.Status, coatingIssueJobDetailDto.HandledToLot,
handledToQty).ConfigureAwait(false);
}
#region Agv
/// <summary>
/// 调用AGV
/// </summary>
/// <param name="assembleIssueJobDto"></param>
/// <param name="CoatingIssueJobDto"></param>
/// <param name="fromLocationCode"></param>
/// <param name="toLocationCode"></param>
/// <returns></returns>
private async Task<bool> DoingAgvAsync(CoatingIssueJobDTO assembleIssueJobDto, string fromLocationCode, string toLocationCode)
private async Task<bool> DoingAgvAsync(CoatingIssueJobDTO CoatingIssueJobDto, string fromLocationCode, string toLocationCode)
{
var jobDetailInputdetail = assembleIssueJobDto.Details.FirstOrDefault();
var jobDetailInputdetail = CoatingIssueJobDto.Details.FirstOrDefault();
var locationDeliveryDto = await _locationDeliveryAppService.GetByFromLocationCodeAndToLocationCodeAsync(
fromLocationCode, toLocationCode).ConfigureAwait(false);
@ -994,7 +854,7 @@ public class CoatingIssueJobAppService
{
//TODO AGV
//来源永远是库位 目标永远是工位
var ret = await CallAgvAsync(assembleIssueJobDto, fromLocationCode, jobDetailInputdetail.Remark).ConfigureAwait(false);
var ret = await CallAgvAsync(CoatingIssueJobDto, fromLocationCode, jobDetailInputdetail.Remark).ConfigureAwait(false);
#if DEBUG
@ -1067,14 +927,13 @@ public class CoatingIssueJobAppService
}
/// <summary>
/// Agv 回调 接口
/// Agv 执行完发料回调接口
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("call-back-agv")]
public async Task<AgvResultObject> CallBackAgvAsync(AgvRequestDto request)
public async Task<AgvResultObject> CallBackAgvIssueAsync(AgvRequestDto request)
{
var entity = await _repository.FindAsync(p => p.Number == request.Data.First().OrderNum).ConfigureAwait(false);
var dto = ObjectMapper.Map<CoatingIssueJob, CoatingIssueJobDTO>(entity);
@ -1173,46 +1032,29 @@ public class CoatingIssueJobAppService
foreach (var detail in notes)
{
TransferNoteEditInput transfer = new TransferNoteEditInput();
var transfer = new TransferNoteEditInput();
transfer.CallJobNumber = detail.OrderNum;
transfer.Type = EnumTransSubType.Agv_Return_Coating.ToString();
transfer.Type = EnumTransSubType.Transfer_WIP.ToString();
transfer.Worker = "Agv";
transfer.UseOnTheWayLocation = false;
List<TransferNoteDetailInput> transferNoteDetailInputs = new List<TransferNoteDetailInput>();
TransferNoteDetailInput detailInput = new TransferNoteDetailInput();
var fromloc = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源起始点{detail.BeginPosition}没查到");
}
LocationDTO fromlocation = null;
if (fromloc != null)
{
fromlocation = await _locationAppService.GetByCodeAsync(fromloc.LocationCode).ConfigureAwait(false);
}
if (fromlocation == null)
{
errors.Add($"来源起始点{detail.BeginPosition}库位没查到");
}
var toloc = await _postionLocationAppService.GetByCodeAsync(detail.EndPosition)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"结束点{detail.EndPosition}没查到");
}
LocationDTO tolocation = null;
if (toloc != null)
transfer.Confirmed = true;
var detailInput = new TransferNoteDetailInput();
var fromPosition = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromPosition == null)
{
tolocation = await _locationAppService.GetByCodeAsync(toloc.LocationCode).ConfigureAwait(false);
errors.Add($"未查询到工位{detail.BeginPosition}关联的库位");
}
if (tolocation == null)
var fromLocationDto = await _locationAppService.GetByCodeAsync(fromPosition.LocationCode).ConfigureAwait(false);
var tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
if (tolocationDto != null)
{
errors.Add($"结束点{detail.EndPosition}库位没查到");
tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
}
var item = await _itemBasicAppService.GetByCodeAsync(detail.MatCode).ConfigureAwait(false);
if (item == null)
{
errors.Add($"零件号{detail.MatCode}的零件不存在!");
errors.Add($"ERP料号{detail.MatCode}不存在!");
}
else
{
@ -1230,27 +1072,26 @@ public class CoatingIssueJobAppService
Message = string.Join(",", errors.ToArray())
};
}
detailInput.ToLocationCode = tolocation.Code;
detailInput.ToLocationGroup = tolocation.LocationGroupCode;
detailInput.ToLocationArea = tolocation.AreaCode;
detailInput.ToLocationErpCode = tolocation.ErpLocationCode;
detailInput.ToWarehouseCode = tolocation.WarehouseCode;
detailInput.FromStatus = tolocation.DefaultInventoryStatus;
detailInput.ToLocationCode = tolocationDto.Code;
detailInput.ToLocationGroup = tolocationDto.LocationGroupCode;
detailInput.ToLocationArea = tolocationDto.AreaCode;
detailInput.ToLocationErpCode = tolocationDto.ErpLocationCode;
detailInput.ToWarehouseCode = tolocationDto.WarehouseCode;
detailInput.FromLocationCode = fromLocationDto.Code;
detailInput.FromLocationGroup = fromLocationDto.LocationGroupCode;
detailInput.FromLocationArea = fromLocationDto.AreaCode;
detailInput.FromLocationErpCode = fromLocationDto.ErpLocationCode;
detailInput.FromWarehouseCode = fromLocationDto.WarehouseCode;
detailInput.Qty = detail.MatQty;
detailInput.ToLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.ToLot = detail.BatchAttr07;
detailInput.ToPackingCode = detail.PakingCode;
detailInput.FromWarehouseCode = fromlocation.WarehouseCode;
detailInput.FromLocationCode = fromlocation.Code;
detailInput.FromLocationGroup = fromlocation.LocationGroupCode;
detailInput.FromLocationArea = fromlocation.AreaCode;
detailInput.FromLocationErpCode = fromlocation.ErpLocationCode;
detailInput.ToStatus = fromlocation.DefaultInventoryStatus;
detailInput.Qty = detail.MatQty;
detailInput.FromLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.FromLot = detail.BatchAttr07;
detailInput.FromPackingCode = detail.PakingCode;
detailInput.FromStatus = EnumInventoryStatus.OK;
detailInput.ToStatus = EnumInventoryStatus.OK;
detailInput.Remark = "AGV反库";
transfer.Details.Add(detailInput);
@ -1293,15 +1134,12 @@ public class CoatingIssueJobAppService
}
/// <summary>
/// 调用Agv接口实现
/// </summary>
/// <param name="job"></param>
/// <param name="beginPosition"></param>
/// <param name="endPosition"></param>
/// <returns></returns>
private async Task<AgvResultObject> SendInterFaceAsync(CoatingIssueJobDTO job, string beginPosition, string endPosition)
{
@ -1327,17 +1165,15 @@ public class CoatingIssueJobAppService
{
throw new UserFriendlyException($"任务{job.Number}没有推荐库存!");
}
var first = job.Details.FirstOrDefault();
var request = new AgvRequest();
request.MatCode = first.ItemCode;
request.MatQty = first.HandledToQty;
request.OrderNum = job.Number;
request.OrderType = EnumJobType.CoatingIssueJob.ToString();
request.BeginPosition = beginPosition;
request.EndPosition = endPosition;
var httpclient = _httpClientFactory.CreateClient();
_agvOptions.Value.Address = string.IsNullOrEmpty(_agvOptions.Value.Address)
? "http://7e42682n64.goho.co:21171/"
@ -1382,6 +1218,154 @@ public class CoatingIssueJobAppService
}
return ret;
}
#endregion
#region 私有
/// <summary>
/// 创建补料记录实体
/// </summary>
/// <param name="coatingIssueJobDto"></param>
/// <returns></returns>
private async Task<CoatingIssueNoteEditInput> BuildCoatingIssueNoteAsync(CoatingIssueJobDTO coatingIssueJobDto)
{
var coatingIssueNoteCreateInput =
ObjectMapper.Map<CoatingIssueJobDTO, CoatingIssueNoteEditInput>(coatingIssueJobDto);
coatingIssueNoteCreateInput.JobNumber = coatingIssueJobDto.Number;
await Task.CompletedTask.ConfigureAwait(false);
return coatingIssueNoteCreateInput;
}
/// <summary>
/// 判断是不是在最底层 如果不是则把状态变更为待库移 并把库移推荐的From和To赋值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task CheckMinRowAndSetStatusAsync(CoatingIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode != 1)
{
input.JobStatus = EnumJobStatus.Wait;
}
else if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode == 1)
{
jobDetailInputdetail.TransferLibFromArriveDate = jobDetailInputdetail.RecommendFromArriveDate;
jobDetailInputdetail.TransferLibFromContainerCode = jobDetailInputdetail.RecommendFromContainerCode;
jobDetailInputdetail.TransferLibFromExpireDate = jobDetailInputdetail.RecommendFromExpireDate;
jobDetailInputdetail.TransferLibFromLocationArea = jobDetailInputdetail.RecommendFromLocationArea;
jobDetailInputdetail.TransferLibFromLocationCode = jobDetailInputdetail.RecommendFromLocationCode;
jobDetailInputdetail.TransferLibFromLocationErpCode = jobDetailInputdetail.RecommendFromLocationErpCode;
jobDetailInputdetail.TransferLibFromLocationGroup = jobDetailInputdetail.RecommendFromLocationGroup;
jobDetailInputdetail.TransferLibFromLot = jobDetailInputdetail.RecommendFromLot;
jobDetailInputdetail.TransferLibFromPackingCode = jobDetailInputdetail.RecommendFromPackingCode;
jobDetailInputdetail.TransferLibFromProduceDate = jobDetailInputdetail.RecommendFromProduceDate;
jobDetailInputdetail.TransferLibFromQty = jobDetailInputdetail.RecommendFromQty;
jobDetailInputdetail.TransferLibFromSupplierBatch = jobDetailInputdetail.RecommendFromSupplierBatch;
jobDetailInputdetail.TransferLibFromWarehouseCode = jobDetailInputdetail.RecommendFromWarehouseCode;
jobDetailInputdetail.TransferLibToArriveDate = jobDetailInputdetail.RecommendToArriveDate;
jobDetailInputdetail.TransferLibToContainerCode = jobDetailInputdetail.RecommendToContainerCode;
jobDetailInputdetail.TransferLibToExpireDate = jobDetailInputdetail.RecommendToExpireDate;
jobDetailInputdetail.TransferLibToLot = jobDetailInputdetail.RecommendToLot;
jobDetailInputdetail.TransferLibToPackingCode = jobDetailInputdetail.RecommendToPackingCode;
jobDetailInputdetail.TransferLibToProduceDate = jobDetailInputdetail.RecommendToProduceDate;
jobDetailInputdetail.TransferLibToQty = jobDetailInputdetail.RecommendToQty;
jobDetailInputdetail.TransferLibToSupplierBatch = jobDetailInputdetail.RecommendToSupplierBatch;
jobDetailInputdetail.TransferLibToWarehouseCode = jobDetailInputdetail.TransferLibFromWarehouseCode;
jobDetailInputdetail.TransferLibToLocationArea = jobDetailInputdetail.TransferLibFromLocationArea;
jobDetailInputdetail.TransferLibToLocationCode = jobDetailInputdetail.TransferLibFromLocationCode;
jobDetailInputdetail.TransferLibToLocationErpCode = jobDetailInputdetail.TransferLibFromLocationErpCode;
jobDetailInputdetail.TransferLibToLocationGroup = jobDetailInputdetail.TransferLibFromLocationGroup;
}
}
/// <summary>
/// 判断是不是在立体库
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task CheckDimensionalStorehouseAsync(CoatingIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
input.JobStatus = EnumJobStatus.Wait;
}
}
/// <summary>
/// 修改当前任务状态 和 该任务的请求状态
/// </summary>
/// <param name="coatingIssueJob"></param>
/// <param name="coatingIssueJobDetailDto"></param>
/// <param name="handledToQty"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task UpdateRequestAndjobStatusDoneAsync(CoatingIssueJob coatingIssueJob,
CoatingIssueJobDetailDTO coatingIssueJobDetailDto, decimal handledToQty)
{
if (coatingIssueJob.JobStatus is EnumJobStatus.Closed or EnumJobStatus.Cancelled or EnumJobStatus.None
or EnumJobStatus.Done) //需要考虑下 多次提交的问题 所以不判断 进行中
{
throw new UserFriendlyException(
$"任务状态错误:编号为【{coatingIssueJob.Number}】的任务状态为【{coatingIssueJob.JobStatus.GetDisplayName()}】");
}
coatingIssueJob.JobStatus = EnumJobStatus.Done;
await RemoveExpectOutAsync(coatingIssueJob, coatingIssueJobDetailDto, handledToQty).ConfigureAwait(false);
//await _expectOutAppService.RemoveByNumberAsync(coatingIssueJob.Number).ConfigureAwait(false);
await CoatingIssueRequestAppService.UpdateStatusCompletedAsync(coatingIssueJob.CoatingRequestNumber)
.ConfigureAwait(false);
await Task.CompletedTask.ConfigureAwait(false);
}
/// <summary>
/// 判断实际TO的箱码是否被占用
/// </summary>
/// <param name="packingCode"></param>
/// <param name="jobNumber"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task CheckPackingCodeIsUserAsync(string packingCode, string jobNumber)
{
var list = await _expectOutAppService.GetListByPackingCodeAsync(packingCode).ConfigureAwait(false);
list = list.Where(p => p.JobNumber != jobNumber).ToList();
if (list.Any())
{
throw new UserFriendlyException($"任务号【{list.First().JobNumber}】的任务,已占用【{packingCode}】箱码的库存。");
}
}
private async Task RemoveExpectOutAsync(CoatingIssueJob coatingIssueJob,
CoatingIssueJobDetailDTO coatingIssueJobDetailDto,
decimal handledToQty)
{
await _expectOutAppService.RemoveByNumberAndInventoryAsync(coatingIssueJob.Number,
coatingIssueJobDetailDto.ItemCode,
coatingIssueJobDetailDto.HandledToLocationCode, coatingIssueJobDetailDto.HandledToPackingCode,
coatingIssueJobDetailDto.Status, coatingIssueJobDetailDto.HandledToLot,
handledToQty).ConfigureAwait(false);
}
#endregion
}

556
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/InjectionIssueJobs/InjectionIssueJobAppService.cs

@ -36,7 +36,7 @@ namespace Win_in.Sfs.Wms.Store.Application;
public class InjectionIssueJobAppService
: SfsJobAppServiceBase<InjectionIssueJob, InjectionIssueJobDetail, InjectionIssueJobDTO, SfsJobRequestInputBase,
InjectionIssueJobCheckInput, InjectionIssueJobEditInput>,
IInjectionIssueJobAppService, ITransferLibCallback, IAgvJobAccountService
IInjectionIssueJobAppService, ITransferLibCallback
{
private readonly IInjectionIssueJobManager _injectionIssueJobManager;
private readonly ILocationAppService _locationAppService;
@ -101,32 +101,66 @@ public class InjectionIssueJobAppService
foreach (var input in inputs)
{
await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
await CheckDimensionalStorehouseAsync(input).ConfigureAwait(false);
//如果是立库 就给直接承接了
var dimensionalStorehouseflag = await UpdateJobStatusWaitByDimensionalStorehouseAsync(input).ConfigureAwait(false);
if (dimensionalStorehouseflag)
{
input.IsClaims = true;
input.ClaimsUserId = string.IsNullOrEmpty(_options.Value.StereosUser)
? "LYF"
: _options.Value.StereosUser;
input.ClaimsUserName = string.IsNullOrEmpty(_options.Value.StereosPassword)
? "LYF"
: _options.Value.StereosPassword;
}
if (dimensionalStorehouseflag == false)
{
//如果是Agv
var agvFlag = await UpdateJobStatusWaitByAgvAsync(input).ConfigureAwait(false);
if (agvFlag)
{
input.IsClaims = true;
input.ClaimsUserId = string.IsNullOrEmpty(_options.Value.StereosUser)
? "AGV"
: _options.Value.StereosUser;
input.ClaimsUserName = string.IsNullOrEmpty(_options.Value.StereosPassword)
? "AGV"
: _options.Value.StereosPassword;
}
}
}
var injectionIssueJobDtos = await base.CreateManyAsync(inputs).ConfigureAwait(false);
foreach (var injectionIssueJobDto in injectionIssueJobDtos)
var assembleIssueJobDtos = await base.CreateManyAsync(inputs).ConfigureAwait(false);
foreach (var assembleIssueJobDto in assembleIssueJobDtos)
{
await DoingDimensionalStorehouseAsync(injectionIssueJobDto).ConfigureAwait(false);
var firstDetail = injectionIssueJobDto.Details.First();
await DoingAgvAsync(injectionIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(assembleIssueJobDto).ConfigureAwait(false);
var firstDetail = assembleIssueJobDto.Details.First();
await DoingAgvAsync(assembleIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
}
return injectionIssueJobDtos;
return assembleIssueJobDtos;
}
[HttpPost("")]
public override async Task<InjectionIssueJobDTO> CreateAsync(InjectionIssueJobEditInput input)
{
await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
await CheckDimensionalStorehouseAsync(input).ConfigureAwait(false);
var flagDimensionalStorehouse = await UpdateJobStatusWaitByDimensionalStorehouseAsync(input).ConfigureAwait(false);
if (flagDimensionalStorehouse == false)
{
await UpdateJobStatusWaitByAgvAsync(input).ConfigureAwait(false);
}
var injectionIssueJobDto = await base.CreateAsync(input).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(injectionIssueJobDto).ConfigureAwait(false);
var firstDetail = injectionIssueJobDto.Details.First();
await DoingAgvAsync(injectionIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
var assembleIssueJobDto = await base.CreateAsync(input).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(assembleIssueJobDto).ConfigureAwait(false);
if (flagDimensionalStorehouse == false)
{
var firstDetail = assembleIssueJobDto.Details.First();
await DoingAgvAsync(assembleIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
}
return injectionIssueJobDto;
return assembleIssueJobDto;
}
[HttpPost("invalid")]
@ -141,7 +175,11 @@ public class InjectionIssueJobAppService
if (injectionJob.JobStatus == EnumJobStatus.Open ||
injectionJob.JobStatus == EnumJobStatus.Partial ||
injectionJob.JobStatus == EnumJobStatus.Wait ||
injectionJob.JobStatus == EnumJobStatus.Doing)
injectionJob.JobStatus == EnumJobStatus.Doing||
injectionJob.JobStatus == EnumJobStatus.WaitAgv)
{
await _expectOutAppService.RemoveByNumberAsync(injectionJob.Number).ConfigureAwait(false);
await _transferLibRequestAppService.CancelByCallRequestNumberAsync(injectionJob.InjectionRequestNumber)
@ -156,7 +194,11 @@ public class InjectionIssueJobAppService
$"{EnumJobStatus.Open.GetDisplayName()}、" +
$"{EnumJobStatus.Partial.GetDisplayName()}、" +
$"{EnumJobStatus.Doing.GetDisplayName()}、" +
$"{EnumJobStatus.Wait.GetDisplayName()}");
$"{EnumJobStatus.Wait.GetDisplayName()}"+
$"{EnumJobStatus.WaitAgv.GetDisplayName()}"
);
}
}
@ -528,81 +570,6 @@ public class InjectionIssueJobAppService
return ret;
}
[HttpPost("receive-issue-job-stereo")]
public virtual async Task<ReusltObject> SyncReciveIssueJobStereoAsync(IssueRequestFromRestoDTO input)
{
#if DEBUG
var json = JsonSerializer.Serialize(input);
#endif
var errors = new List<string>();
var ret = new ReusltObject { Code = 1, OperateTime = DateTime.Now.ToString("yyyy-MM-dd"), Message = "操作成功" };
try
{
if (input.Jobs.Count > 0)
{
var jobs = input.Jobs;
var numbers = jobs.Select(p => p.JobNumber);
var query = _repository.WithDetails()
.Where(p => numbers.Contains(p.Number));
var entities = query.ToList();
var dtos = ObjectMapper.Map<List<InjectionIssueJob>, List<InjectionIssueJobDTO>>(entities);
if (input.Jobs.Count == entities.Count)
{
errors.Add("立体库提交出库任务和WMS任务不符,请核对! \n");
}
foreach (var itm in dtos)
{
var first = jobs.FirstOrDefault(p => p.JobNumber == itm.Number);
var itmDetails = itm.Details.ToList();
var details = new List<InjectionIssueJobDetailDTO>();
foreach (var detail in first.Details)
{
var entity = itmDetails.FirstOrDefault(p => p.ItemCode == detail.ItemCode);
var dto = new InjectionIssueJobDetailDTO();
dto.HandledFromLocationCode = entity.HandledFromLocationCode;
dto.HandledToLocationCode = entity.HandledToLocationCode;
dto.ItemCode = detail.ItemCode;
dto.RecommendFromQty = detail.Qty;
dto.RecommendToQty = detail.Qty;
dto.HandledFromQty = detail.Qty;
dto.HandledToQty = detail.Qty;
dto.Status = entity.Status;
details.Add(dto);
}
itm.Details = details;
await CompleteAsync(itm.Id, itm).ConfigureAwait(false);
}
}
else
{
errors.Add("立体库确认单据里无数据! \n");
}
}
catch (Exception ex)
{
ret = new ReusltObject
{
Code = 2,
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = ex.Message
};
return ret;
}
if (errors.Count > 0)
{
ret = new ReusltObject
{
Code = 2,
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray())
};
}
return ret;
}
#endregion
@ -690,30 +657,7 @@ public class InjectionIssueJobAppService
}
}
/// <summary>
/// 调用立体库
/// </summary>
/// <param name="injectionIssueJobDto"></param>
/// <returns></returns>
private async Task DoingDimensionalStorehouseAsync(InjectionIssueJobDTO injectionIssueJobDto)
{
var jobDetailInputdetail = injectionIssueJobDto.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
//TODO 立体库
var ret = await SyncIssueJobStereoAsync(new List<InjectionIssueJobDTO> { injectionIssueJobDto },
loctionDto.Code).ConfigureAwait(false);
if (ret.Code != 1)
{
throw new UserFriendlyException($"调用立体库不成功!原因:{ret.Message}");
}
}
}
/// <summary>
/// 修改当前任务状态 和 该任务的请求状态
/// </summary>
@ -773,6 +717,14 @@ public class InjectionIssueJobAppService
}
#endregion
#region Agv
/// <summary>
@ -865,12 +817,12 @@ public class InjectionIssueJobAppService
}
/// <summary>
/// Agv 回调 接口
/// Agv 执行完发料回调接口
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("call-back-agv")]
public async Task<AgvResultObject> CallBackAgvAsync(AgvRequestDto request)
public async Task<AgvResultObject> CallBackAgvIssueAsync(AgvRequestDto request)
{
var entity = await _repository.FindAsync(p => p.Number == request.Data.First().OrderNum).ConfigureAwait(false);
var dto = ObjectMapper.Map<InjectionIssueJob, InjectionIssueJobDTO>(entity);
@ -970,46 +922,29 @@ public class InjectionIssueJobAppService
foreach (var detail in notes)
{
TransferNoteEditInput transfer = new TransferNoteEditInput();
var transfer = new TransferNoteEditInput();
transfer.CallJobNumber = detail.OrderNum;
transfer.Type = EnumTransSubType.Agv_Return_Injection.ToString();
transfer.Type = EnumTransSubType.Transfer_WIP.ToString();
transfer.Worker = "Agv";
transfer.UseOnTheWayLocation = false;
List<TransferNoteDetailInput> transferNoteDetailInputs = new List<TransferNoteDetailInput>();
TransferNoteDetailInput detailInput = new TransferNoteDetailInput();
var fromloc = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源起始点{detail.BeginPosition}没查到");
}
LocationDTO fromlocation = null;
if (fromloc != null)
{
fromlocation = await _locationAppService.GetByCodeAsync(fromloc.LocationCode).ConfigureAwait(false);
}
if (fromlocation == null)
{
errors.Add($"来源起始点{detail.BeginPosition}库位没查到");
}
var toloc = await _postionLocationAppService.GetByCodeAsync(detail.EndPosition)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"结束点{detail.EndPosition}没查到");
}
LocationDTO tolocation = null;
if (toloc != null)
transfer.Confirmed = true;
var detailInput = new TransferNoteDetailInput();
var fromPosition = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromPosition == null)
{
tolocation = await _locationAppService.GetByCodeAsync(toloc.LocationCode).ConfigureAwait(false);
errors.Add($"未查询到工位{detail.BeginPosition}关联的库位");
}
if (tolocation == null)
var fromLocationDto = await _locationAppService.GetByCodeAsync(fromPosition.LocationCode).ConfigureAwait(false);
var tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
if (tolocationDto != null)
{
errors.Add($"结束点{detail.EndPosition}库位没查到");
tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
}
var item = await _itemBasicAppService.GetByCodeAsync(detail.MatCode).ConfigureAwait(false);
if (item == null)
{
errors.Add($"零件号{detail.MatCode}的零件不存在!");
errors.Add($"ERP料号{detail.MatCode}不存在!");
}
else
{
@ -1027,27 +962,26 @@ public class InjectionIssueJobAppService
Message = string.Join(",", errors.ToArray())
};
}
detailInput.ToLocationCode = tolocation.Code;
detailInput.ToLocationGroup = tolocation.LocationGroupCode;
detailInput.ToLocationArea = tolocation.AreaCode;
detailInput.ToLocationErpCode = tolocation.ErpLocationCode;
detailInput.ToWarehouseCode = tolocation.WarehouseCode;
detailInput.FromStatus = tolocation.DefaultInventoryStatus;
detailInput.ToLocationCode = tolocationDto.Code;
detailInput.ToLocationGroup = tolocationDto.LocationGroupCode;
detailInput.ToLocationArea = tolocationDto.AreaCode;
detailInput.ToLocationErpCode = tolocationDto.ErpLocationCode;
detailInput.ToWarehouseCode = tolocationDto.WarehouseCode;
detailInput.FromLocationCode = fromLocationDto.Code;
detailInput.FromLocationGroup = fromLocationDto.LocationGroupCode;
detailInput.FromLocationArea = fromLocationDto.AreaCode;
detailInput.FromLocationErpCode = fromLocationDto.ErpLocationCode;
detailInput.FromWarehouseCode = fromLocationDto.WarehouseCode;
detailInput.Qty = detail.MatQty;
detailInput.ToLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.ToLot = detail.BatchAttr07;
detailInput.ToPackingCode = detail.PakingCode;
detailInput.FromWarehouseCode = fromlocation.WarehouseCode;
detailInput.FromLocationCode = fromlocation.Code;
detailInput.FromLocationGroup = fromlocation.LocationGroupCode;
detailInput.FromLocationArea = fromlocation.AreaCode;
detailInput.FromLocationErpCode = fromlocation.ErpLocationCode;
detailInput.ToStatus = fromlocation.DefaultInventoryStatus;
detailInput.Qty = detail.MatQty;
detailInput.FromLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.FromLot = detail.BatchAttr07;
detailInput.FromPackingCode = detail.PakingCode;
detailInput.FromStatus = EnumInventoryStatus.OK;
detailInput.ToStatus = EnumInventoryStatus.OK;
detailInput.Remark = "AGV反库";
transfer.Details.Add(detailInput);
@ -1177,10 +1111,304 @@ public class InjectionIssueJobAppService
#endregion
#region 立库
/// <summary>
/// 调用立体库
/// </summary>
/// <param name="InjectionIssueJobDto"></param>
/// <returns></returns>
private async Task DoingDimensionalStorehouseAsync(InjectionIssueJobDTO InjectionIssueJobDto)
{
var jobDetailInputdetail = InjectionIssueJobDto.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
//TODO 立体库
var ret = await SyncIssueJobStereoAsync(new List<InjectionIssueJobDTO> { InjectionIssueJobDto },
jobDetailInputdetail.RecommendToLocationCode, InjectionIssueJobDto.Id).ConfigureAwait(false);
if (ret.Code != 0)
{
throw new UserFriendlyException($"调用立体库不成功!原因:{ret.Message}");
}
}
}
/// <summary>
/// 判断是不是在立体库
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<bool> UpdateJobStatusWaitByDimensionalStorehouseAsync(InjectionIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
input.JobStatus = EnumJobStatus.Wait;
return true;
}
return false;
}
/// <summary>
/// 立体库同步
/// </summary>
/// <param name="input"></param>
/// <param name="pLoc"></param>
/// <returns></returns>
[HttpPost("sync-issue-job-stereo")]
public async Task<ReusltObject> SyncIssueJobStereoAsync(List<InjectionIssueJobDTO> input, string pLoc, Guid uid)
{
var ret = new ReusltObject();
ret.Code = 0;
ret.Message = "操作成功";
ret.OperateTime = DateTime.Now.ToString("yyyy-MM-dd");
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
var IssueJobToRestoDetailDTOs = new List<IssueJobToRestoDetailDTO>();
var main = new IssueJobToRestoDTO();
main.Uuid = uid;
main.OperatorName = string.IsNullOrEmpty(CurrentUser.UserName) ? "admin" : CurrentUser.UserName;
foreach (var job in input)
{
foreach (var jobitem in job.Details)
{
IssueJobToRestoDetailDTOs.Add(new IssueJobToRestoDetailDTO
{
Count = jobitem.RecommendFromQty,
ProductNo = jobitem.ItemCode,
NeedSite = pLoc,
WorkNo = job.InjectionRequestNumber,
TaskNo = job.Number
});
}
}
main.Details = IssueJobToRestoDetailDTOs;
var httpclient = _httpClientFactory.CreateClient();
#if DEBUG
var json = JsonSerializer.Serialize(main);
_options.Value.Address = "http://localhost:59094/"; //测试地址
_options.Value.Token = ""; //测试token
_options.Value.UserName = ""; //测试用户名
_options.Value.Password = ""; //测试密码
#endif
//var json = JsonSerializer.Serialize(main);
_options.Value.Address = string.IsNullOrEmpty(_options.Value.Address)
? "http://7e42682n64.goho.co:21171/"
: _options.Value.Address; //测试地址
_options.Value.Token =
string.IsNullOrEmpty(_options.Value.Token) ? string.Empty : _options.Value.Token; //测试token
_options.Value.UserName =
string.IsNullOrEmpty(_options.Value.UserName) ? "" : _options.Value.UserName; //测试用户名
_options.Value.Password =
string.IsNullOrEmpty(_options.Value.Password) ? "" : _options.Value.Password; //测试密码
_options.Value.Path = string.IsNullOrEmpty(_options.Value.Path)
? "zozocnApi/custom/receiveProductionPlan"
: _options.Value.Path; //测试密码
_logger.LogInformation(JsonSerializer.Serialize(_options));
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"标志{flag}开始调用高通WMS:传递值{JsonSerializer.Serialize(main)}");
if (!string.IsNullOrEmpty(_options.Value.Token))
{
var token = _options.Value.Token;
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
if (!string.IsNullOrEmpty(_options.Value.UserName) && !string.IsNullOrEmpty(_options.Value.Password))
{
var username = _options.Value.UserName;
var password = _options.Value.Password;
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}")));
}
var client = new IssueJobToRestoClient(_options.Value.Address, httpclient, _options.Value.Path);
ret = await client.SyncIssueJobStereoAsync(main).ConfigureAwait(false);
_logger.LogInformation($"标志{flag}调用高通WMS:返回值{JsonSerializer.Serialize(ret)}");
}
catch (Exception ex)
{
ret = new ReusltObject();
ret.Code = 1;
ret.Message = ex.Message;
ret.OperateTime = DateTime.Now.ToString("yyyy-MM-dd");
await unitOfWork.RollbackAsync().ConfigureAwait(false);
}
return ret;
}
[HttpPost("receive-issue-job-stereo")]
public virtual async Task<ReusltObject> SyncReciveIssueJobStereoAsync(IssueRequestFromRestoDTO input)
{
var json = JsonSerializer.Serialize(input);
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"{flag}接收到立体库确认单据内容:" + json);
#if DEBUG
#endif
var errors = new List<string>();
var ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Success),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
Message = "操作成功"
};
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
if (input.Jobs.Count > 0)
{
var jobs = input.Jobs;
var numbers = jobs.Select(p => p.JobNumber);
var query = _repository.WithDetails()
.Where(p => numbers.Contains(p.Number) && p.JobStatus != EnumJobStatus.Done);
var entities = query.ToList();
if (entities.Count == 0)
{
errors.Add($"任务号{string.Join(",", numbers)}不存在!");
}
var dtos = ObjectMapper.Map<List<InjectionIssueJob>, List<InjectionIssueJobDTO>>(entities);
if (input.Jobs.Count != entities.Count)
{
errors.Add("立体库提交出库任务和WMS任务不符,请核对! \n");
}
foreach (var itm in dtos)
{
var first = jobs.FirstOrDefault(p => p.JobNumber == itm.Number);
var itmDetails = itm.Details.ToList();
var details = new List<InjectionIssueJobDetailDTO>();
foreach (var detail in first.Details)
{
var fromloc = await _locationAppService.GetByCodeAsync(detail.FromLocationCode)
.ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源库位{detail.FromLocationCode}没查到");
}
var toloc = await _locationAppService.GetByCodeAsync(detail.ToLocationCode)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"目标库位{detail.ToLocationCode}没查到");
}
var entity = itmDetails.FirstOrDefault(p => p.ItemCode == detail.ItemCode);
if (entity == null)
{
errors.Add($"物料号{detail.ItemCode}不在任务明细内!");
}
var dto = new InjectionIssueJobDetailDTO();
dto.InjectFrom(entity);
/*
dto.RecommendFromQty = detail.Qty;
dto.RecommendToQty = detail.Qty;
dto.HandledFromQty = detail.Qty;
dto.HandledToQty = detail.Qty;
*/
//dto.RecommendFromQty = detail.Qty;
//dto.RecommendToQty = detail.Qty;
//dto.HandledFromQty = detail.Qty;
//dto.HandledToQty = detail.Qty;
dto.HandledToLocationCode = toloc.Code;
dto.HandledToLocationGroup = toloc.LocationGroupCode;
dto.HandledToLocationArea = toloc.AreaCode;
dto.HandledToLocationErpCode = toloc.ErpLocationCode;
dto.HandledToLot = string.Empty;
dto.HandledToWarehouseCode = toloc.WarehouseCode;
dto.HandledToQty = detail.Qty;
dto.HandledToLot = string.Empty;
dto.HandledToPackingCode = string.Empty;
dto.HandledFromWarehouseCode = fromloc.WarehouseCode;
dto.HandledFromLocationCode = fromloc.Code;
dto.HandledFromLocationGroup = fromloc.LocationGroupCode;
dto.HandledFromLocationArea = fromloc.AreaCode;
dto.HandledFromLocationErpCode = fromloc.ErpLocationCode;
dto.HandledFromQty = detail.Qty;
dto.HandledFromLot = string.Empty;
dto.HandledFromPackingCode = string.Empty;
details.Add(dto);
await ExecuteDetailExtAsync(itm.Id, entity.Id, dto).ConfigureAwait(false);
}
if (errors.Count > 0)
{
ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray()),
Data = json
};
}
itm.Worker = "LITK";
itm.Details = details;
// await CompleteAsync(itm.Id, itm).ConfigureAwait(false);
_logger.LogInformation($"{flag}接收到立体库确认单据内容:" + json + "立体库任务完成");
}
}
else
{
errors.Add("立体库确认单据里无数据! \n");
}
}
catch (Exception ex)
{
ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = ex.Message,
Data = json
};
await unitOfWork.RollbackAsync();
return ret;
}
if (errors.Count > 0)
{
ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray()),
Data = json
};
}
return ret;
}
#endregion
}

542
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs

@ -100,38 +100,69 @@ public class KittingIssueJobAppService
[HttpPost("add-many")]
public override async Task<List<KittingIssueJobDTO>> CreateManyAsync(List<KittingIssueJobEditInput> inputs)
{
foreach (var input in inputs)
{
await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
//如果是立库 就给直接承接了
var dimensionalStorehouseflag = await CheckDimensionalStorehouseAsync(input).ConfigureAwait(false);
var dimensionalStorehouseflag = await UpdateJobStatusWaitByDimensionalStorehouseAsync(input).ConfigureAwait(false);
if (dimensionalStorehouseflag)
{
input.IsClaims = true;
input.ClaimsUserId = "立库账号"; //todo
input.ClaimsUserName = "立库账号"; //todo
input.ClaimsUserId = string.IsNullOrEmpty(_options.Value.StereosUser)
? "LYF"
: _options.Value.StereosUser;
input.ClaimsUserName = string.IsNullOrEmpty(_options.Value.StereosPassword)
? "LYF"
: _options.Value.StereosPassword;
}
if (dimensionalStorehouseflag == false)
{
//如果是Agv
var agvFlag = await UpdateJobStatusWaitByAgvAsync(input).ConfigureAwait(false);
if (agvFlag)
{
input.IsClaims = true;
input.ClaimsUserId = string.IsNullOrEmpty(_options.Value.StereosUser)
? "AGV"
: _options.Value.StereosUser;
input.ClaimsUserName = string.IsNullOrEmpty(_options.Value.StereosPassword)
? "AGV"
: _options.Value.StereosPassword;
}
}
}
var kittingIssueJobDtos = await base.CreateManyAsync(inputs).ConfigureAwait(false);
foreach (var kittingIssueJobDto in kittingIssueJobDtos)
var assembleIssueJobDtos = await base.CreateManyAsync(inputs).ConfigureAwait(false);
foreach (var assembleIssueJobDto in assembleIssueJobDtos)
{
await DoingDimensionalStorehouseAsync(kittingIssueJobDto).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(assembleIssueJobDto).ConfigureAwait(false);
var firstDetail = assembleIssueJobDto.Details.First();
await DoingAgvAsync(assembleIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
}
return kittingIssueJobDtos;
return assembleIssueJobDtos;
}
[HttpPost("")]
public override async Task<KittingIssueJobDTO> CreateAsync(KittingIssueJobEditInput input)
{
await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
await CheckDimensionalStorehouseAsync(input).ConfigureAwait(false);
var flagDimensionalStorehouse = await UpdateJobStatusWaitByDimensionalStorehouseAsync(input).ConfigureAwait(false);
if (flagDimensionalStorehouse == false)
{
await UpdateJobStatusWaitByAgvAsync(input).ConfigureAwait(false);
}
var kittingIssueJobDto = await base.CreateAsync(input).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(kittingIssueJobDto).ConfigureAwait(false);
var assembleIssueJobDto = await base.CreateAsync(input).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(assembleIssueJobDto).ConfigureAwait(false);
if (flagDimensionalStorehouse == false)
{
var firstDetail = assembleIssueJobDto.Details.First();
await DoingAgvAsync(assembleIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
}
return kittingIssueJobDto;
return assembleIssueJobDto;
}
[HttpPost("invalid")]
@ -146,7 +177,11 @@ public class KittingIssueJobAppService
if (kittingJob.JobStatus == EnumJobStatus.Open ||
kittingJob.JobStatus == EnumJobStatus.Partial ||
kittingJob.JobStatus == EnumJobStatus.Wait||
kittingJob.JobStatus == EnumJobStatus.Doing)
kittingJob.JobStatus == EnumJobStatus.Doing||
kittingJob.JobStatus == EnumJobStatus.WaitAgv
)
{
await _expectOutAppService.RemoveByNumberAsync(kittingJob.Number).ConfigureAwait(false);
await _transferLibRequestAppService.CancelByCallRequestNumberAsync(kittingJob.KittingRequestNumber)
@ -161,7 +196,12 @@ public class KittingIssueJobAppService
$"{EnumJobStatus.Open.GetDisplayName()}、" +
$"{EnumJobStatus.Partial.GetDisplayName()}、" +
$"{EnumJobStatus.Doing.GetDisplayName()}、" +
$"{EnumJobStatus.Wait.GetDisplayName()}");
$"{EnumJobStatus.Wait.GetDisplayName()}"+
$"{EnumJobStatus.WaitAgv.GetDisplayName()}"
);
}
}
@ -546,79 +586,6 @@ public class KittingIssueJobAppService
return ret;
}
[HttpPost("receive-issue-job-stereo")]
public virtual async Task<ReusltObject> SyncReciveIssueJobStereoAsync(IssueRequestFromRestoDTO input)
{
#if DEBUG
var json = JsonSerializer.Serialize(input);
#endif
var errors = new List<string>();
var ret = new ReusltObject { Code = 1, OperateTime = DateTime.Now.ToString("yyyy-MM-dd"), Message = "操作成功" };
try
{
if (input.Jobs.Count > 0)
{
var jobs = input.Jobs;
var numbers = jobs.Select(p => p.JobNumber);
var query = _repository.WithDetails()
.Where(p => numbers.Contains(p.Number));
var entities = query.ToList();
var dtos = ObjectMapper.Map<List<KittingIssueJob>, List<KittingIssueJobDTO>>(entities);
if (input.Jobs.Count == entities.Count)
{
errors.Add("立体库提交出库任务和WMS任务不符,请核对! \n");
}
foreach (var itm in dtos)
{
var first = jobs.FirstOrDefault(p => p.JobNumber == itm.Number);
var itmDetails = itm.Details.ToList();
var details = new List<KittingIssueJobDetailDTO>();
foreach (var detail in first.Details)
{
var entity = itmDetails.FirstOrDefault(p => p.ItemCode == detail.ItemCode);
var dto = new KittingIssueJobDetailDTO();
dto.HandledFromLocationCode = entity.HandledFromLocationCode;
dto.HandledToLocationCode = entity.HandledToLocationCode;
dto.ItemCode = detail.ItemCode;
dto.RecommendFromQty = detail.Qty;
dto.RecommendToQty = detail.Qty;
dto.HandledFromQty = detail.Qty;
dto.HandledToQty = detail.Qty;
dto.Status = entity.Status;
details.Add(dto);
}
itm.Details = details;
await CompleteAsync(itm.Id, itm).ConfigureAwait(false);
}
}
else
{
errors.Add("立体库确认单据里无数据! \n");
}
}
catch (Exception ex)
{
ret = new ReusltObject
{
Code = 2, OperateTime = DateTime.Now.ToString("yyyy-MM-dd"), Message = ex.Message
};
return ret;
}
if (errors.Count > 0)
{
ret = new ReusltObject
{
Code = 2,
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray())
};
}
return ret;
}
#endregion
@ -711,29 +678,7 @@ public class KittingIssueJobAppService
}
}
/// <summary>
/// 调用立体库
/// </summary>
/// <param name="kittingIssueJobDto"></param>
/// <returns></returns>
private async Task DoingDimensionalStorehouseAsync(KittingIssueJobDTO kittingIssueJobDto)
{
var jobDetailInputdetail = kittingIssueJobDto.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
//TODO 立体库
var ret = await SyncIssueJobStereoAsync(new List<KittingIssueJobDTO> { kittingIssueJobDto },
loctionDto.Code).ConfigureAwait(false);
if (ret.Code != 1)
{
throw new UserFriendlyException($"调用立体库不成功!原因:{ret.Message}");
}
}
}
/// <summary>
/// 修改当前任务状态 和 该任务的请求状态
@ -798,7 +743,304 @@ public class KittingIssueJobAppService
#endregion
#region 立库
/// <summary>
/// 调用立体库
/// </summary>
/// <param name="KittingIssueJobDto"></param>
/// <returns></returns>
private async Task DoingDimensionalStorehouseAsync(KittingIssueJobDTO KittingIssueJobDto)
{
var jobDetailInputdetail = KittingIssueJobDto.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
//TODO 立体库
var ret = await SyncIssueJobStereoAsync(new List<KittingIssueJobDTO> { KittingIssueJobDto },
jobDetailInputdetail.RecommendToLocationCode, KittingIssueJobDto.Id).ConfigureAwait(false);
if (ret.Code != 0)
{
throw new UserFriendlyException($"调用立体库不成功!原因:{ret.Message}");
}
}
}
/// <summary>
/// 判断是不是在立体库
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<bool> UpdateJobStatusWaitByDimensionalStorehouseAsync(KittingIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
input.JobStatus = EnumJobStatus.Wait;
return true;
}
return false;
}
/// <summary>
/// 立体库同步
/// </summary>
/// <param name="input"></param>
/// <param name="pLoc"></param>
/// <returns></returns>
[HttpPost("sync-issue-job-stereo")]
public async Task<ReusltObject> SyncIssueJobStereoAsync(List<KittingIssueJobDTO> input, string pLoc, Guid uid)
{
var ret = new ReusltObject();
ret.Code = 0;
ret.Message = "操作成功";
ret.OperateTime = DateTime.Now.ToString("yyyy-MM-dd");
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
var IssueJobToRestoDetailDTOs = new List<IssueJobToRestoDetailDTO>();
var main = new IssueJobToRestoDTO();
main.Uuid = uid;
main.OperatorName = string.IsNullOrEmpty(CurrentUser.UserName) ? "admin" : CurrentUser.UserName;
foreach (var job in input)
{
foreach (var jobitem in job.Details)
{
IssueJobToRestoDetailDTOs.Add(new IssueJobToRestoDetailDTO
{
Count = jobitem.RecommendFromQty,
ProductNo = jobitem.ItemCode,
NeedSite = pLoc,
WorkNo = job.KittingRequestNumber,
TaskNo = job.Number
});
}
}
main.Details = IssueJobToRestoDetailDTOs;
var httpclient = _httpClientFactory.CreateClient();
#if DEBUG
var json = JsonSerializer.Serialize(main);
_options.Value.Address = "http://localhost:59094/"; //测试地址
_options.Value.Token = ""; //测试token
_options.Value.UserName = ""; //测试用户名
_options.Value.Password = ""; //测试密码
#endif
//var json = JsonSerializer.Serialize(main);
_options.Value.Address = string.IsNullOrEmpty(_options.Value.Address)
? "http://7e42682n64.goho.co:21171/"
: _options.Value.Address; //测试地址
_options.Value.Token =
string.IsNullOrEmpty(_options.Value.Token) ? string.Empty : _options.Value.Token; //测试token
_options.Value.UserName =
string.IsNullOrEmpty(_options.Value.UserName) ? "" : _options.Value.UserName; //测试用户名
_options.Value.Password =
string.IsNullOrEmpty(_options.Value.Password) ? "" : _options.Value.Password; //测试密码
_options.Value.Path = string.IsNullOrEmpty(_options.Value.Path)
? "zozocnApi/custom/receiveProductionPlan"
: _options.Value.Path; //测试密码
_logger.LogInformation(JsonSerializer.Serialize(_options));
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"标志{flag}开始调用高通WMS:传递值{JsonSerializer.Serialize(main)}");
if (!string.IsNullOrEmpty(_options.Value.Token))
{
var token = _options.Value.Token;
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
if (!string.IsNullOrEmpty(_options.Value.UserName) && !string.IsNullOrEmpty(_options.Value.Password))
{
var username = _options.Value.UserName;
var password = _options.Value.Password;
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}")));
}
var client = new IssueJobToRestoClient(_options.Value.Address, httpclient, _options.Value.Path);
ret = await client.SyncIssueJobStereoAsync(main).ConfigureAwait(false);
_logger.LogInformation($"标志{flag}调用高通WMS:返回值{JsonSerializer.Serialize(ret)}");
}
catch (Exception ex)
{
ret = new ReusltObject();
ret.Code = 1;
ret.Message = ex.Message;
ret.OperateTime = DateTime.Now.ToString("yyyy-MM-dd");
await unitOfWork.RollbackAsync().ConfigureAwait(false);
}
return ret;
}
[HttpPost("receive-issue-job-stereo")]
public virtual async Task<ReusltObject> SyncReciveIssueJobStereoAsync(IssueRequestFromRestoDTO input)
{
var json = JsonSerializer.Serialize(input);
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"{flag}接收到立体库确认单据内容:" + json);
#if DEBUG
#endif
var errors = new List<string>();
var ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Success),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
Message = "操作成功"
};
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
if (input.Jobs.Count > 0)
{
var jobs = input.Jobs;
var numbers = jobs.Select(p => p.JobNumber);
var query = _repository.WithDetails()
.Where(p => numbers.Contains(p.Number) && p.JobStatus != EnumJobStatus.Done);
var entities = query.ToList();
if (entities.Count == 0)
{
errors.Add($"任务号{string.Join(",", numbers)}不存在!");
}
var dtos = ObjectMapper.Map<List<KittingIssueJob>, List<KittingIssueJobDTO>>(entities);
if (input.Jobs.Count != entities.Count)
{
errors.Add("立体库提交出库任务和WMS任务不符,请核对! \n");
}
foreach (var itm in dtos)
{
var first = jobs.FirstOrDefault(p => p.JobNumber == itm.Number);
var itmDetails = itm.Details.ToList();
var details = new List<KittingIssueJobDetailDTO>();
foreach (var detail in first.Details)
{
var fromloc = await _locationAppService.GetByCodeAsync(detail.FromLocationCode)
.ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源库位{detail.FromLocationCode}没查到");
}
var toloc = await _locationAppService.GetByCodeAsync(detail.ToLocationCode)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"目标库位{detail.ToLocationCode}没查到");
}
var entity = itmDetails.FirstOrDefault(p => p.ItemCode == detail.ItemCode);
if (entity == null)
{
errors.Add($"物料号{detail.ItemCode}不在任务明细内!");
}
var dto = new KittingIssueJobDetailDTO();
dto.InjectFrom(entity);
/*
dto.RecommendFromQty = detail.Qty;
dto.RecommendToQty = detail.Qty;
dto.HandledFromQty = detail.Qty;
dto.HandledToQty = detail.Qty;
*/
//dto.RecommendFromQty = detail.Qty;
//dto.RecommendToQty = detail.Qty;
//dto.HandledFromQty = detail.Qty;
//dto.HandledToQty = detail.Qty;
dto.HandledToLocationCode = toloc.Code;
dto.HandledToLocationGroup = toloc.LocationGroupCode;
dto.HandledToLocationArea = toloc.AreaCode;
dto.HandledToLocationErpCode = toloc.ErpLocationCode;
dto.HandledToLot = string.Empty;
dto.HandledToWarehouseCode = toloc.WarehouseCode;
dto.HandledToQty = detail.Qty;
dto.HandledToLot = string.Empty;
dto.HandledToPackingCode = string.Empty;
dto.HandledFromWarehouseCode = fromloc.WarehouseCode;
dto.HandledFromLocationCode = fromloc.Code;
dto.HandledFromLocationGroup = fromloc.LocationGroupCode;
dto.HandledFromLocationArea = fromloc.AreaCode;
dto.HandledFromLocationErpCode = fromloc.ErpLocationCode;
dto.HandledFromQty = detail.Qty;
dto.HandledFromLot = string.Empty;
dto.HandledFromPackingCode = string.Empty;
details.Add(dto);
await ExecuteDetailExtAsync(itm.Id, entity.Id, dto).ConfigureAwait(false);
}
if (errors.Count > 0)
{
ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray()),
Data = json
};
}
itm.Worker = "LITK";
itm.Details = details;
// await CompleteAsync(itm.Id, itm).ConfigureAwait(false);
_logger.LogInformation($"{flag}接收到立体库确认单据内容:" + json + "立体库任务完成");
}
}
else
{
errors.Add("立体库确认单据里无数据! \n");
}
}
catch (Exception ex)
{
ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = ex.Message,
Data = json
};
await unitOfWork.RollbackAsync();
return ret;
}
if (errors.Count > 0)
{
ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray()),
Data = json
};
}
return ret;
}
#endregion
#region Agv
/// <summary>
@ -891,12 +1133,12 @@ public class KittingIssueJobAppService
}
/// <summary>
/// Agv 回调 接口
/// Agv 执行完发料回调接口
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("call-back-agv")]
public async Task<AgvResultObject> CallBackAgvAsync(AgvRequestDto request)
public async Task<AgvResultObject> CallBackAgvIssueAsync(AgvRequestDto request)
{
var entity = await _repository.FindAsync(p => p.Number == request.Data.First().OrderNum).ConfigureAwait(false);
var dto = ObjectMapper.Map<KittingIssueJob, KittingIssueJobDTO>(entity);
@ -996,46 +1238,29 @@ public class KittingIssueJobAppService
foreach (var detail in notes)
{
TransferNoteEditInput transfer = new TransferNoteEditInput();
var transfer = new TransferNoteEditInput();
transfer.CallJobNumber = detail.OrderNum;
transfer.Type = EnumTransSubType.Agv_Return_Kitting.ToString();
transfer.Type = EnumTransSubType.Transfer_WIP.ToString();
transfer.Worker = "Agv";
transfer.UseOnTheWayLocation = false;
List<TransferNoteDetailInput> transferNoteDetailInputs = new List<TransferNoteDetailInput>();
TransferNoteDetailInput detailInput = new TransferNoteDetailInput();
var fromloc = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源起始点{detail.BeginPosition}没查到");
}
LocationDTO fromlocation = null;
if (fromloc != null)
{
fromlocation = await _locationAppService.GetByCodeAsync(fromloc.LocationCode).ConfigureAwait(false);
}
if (fromlocation == null)
{
errors.Add($"来源起始点{detail.BeginPosition}库位没查到");
}
var toloc = await _postionLocationAppService.GetByCodeAsync(detail.EndPosition)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"结束点{detail.EndPosition}没查到");
}
LocationDTO tolocation = null;
if (toloc != null)
transfer.Confirmed = true;
var detailInput = new TransferNoteDetailInput();
var fromPosition = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromPosition == null)
{
tolocation = await _locationAppService.GetByCodeAsync(toloc.LocationCode).ConfigureAwait(false);
errors.Add($"未查询到工位{detail.BeginPosition}关联的库位");
}
if (tolocation == null)
var fromLocationDto = await _locationAppService.GetByCodeAsync(fromPosition.LocationCode).ConfigureAwait(false);
var tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
if (tolocationDto != null)
{
errors.Add($"结束点{detail.EndPosition}库位没查到");
tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
}
var item = await _itemBasicAppService.GetByCodeAsync(detail.MatCode).ConfigureAwait(false);
if (item == null)
{
errors.Add($"零件号{detail.MatCode}的零件不存在!");
errors.Add($"ERP料号{detail.MatCode}不存在!");
}
else
{
@ -1053,27 +1278,26 @@ public class KittingIssueJobAppService
Message = string.Join(",", errors.ToArray())
};
}
detailInput.ToLocationCode = tolocation.Code;
detailInput.ToLocationGroup = tolocation.LocationGroupCode;
detailInput.ToLocationArea = tolocation.AreaCode;
detailInput.ToLocationErpCode = tolocation.ErpLocationCode;
detailInput.ToWarehouseCode = tolocation.WarehouseCode;
detailInput.FromStatus = tolocation.DefaultInventoryStatus;
detailInput.ToLocationCode = tolocationDto.Code;
detailInput.ToLocationGroup = tolocationDto.LocationGroupCode;
detailInput.ToLocationArea = tolocationDto.AreaCode;
detailInput.ToLocationErpCode = tolocationDto.ErpLocationCode;
detailInput.ToWarehouseCode = tolocationDto.WarehouseCode;
detailInput.FromLocationCode = fromLocationDto.Code;
detailInput.FromLocationGroup = fromLocationDto.LocationGroupCode;
detailInput.FromLocationArea = fromLocationDto.AreaCode;
detailInput.FromLocationErpCode = fromLocationDto.ErpLocationCode;
detailInput.FromWarehouseCode = fromLocationDto.WarehouseCode;
detailInput.Qty = detail.MatQty;
detailInput.ToLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.ToLot = detail.BatchAttr07;
detailInput.ToPackingCode = detail.PakingCode;
detailInput.FromWarehouseCode = fromlocation.WarehouseCode;
detailInput.FromLocationCode = fromlocation.Code;
detailInput.FromLocationGroup = fromlocation.LocationGroupCode;
detailInput.FromLocationArea = fromlocation.AreaCode;
detailInput.FromLocationErpCode = fromlocation.ErpLocationCode;
detailInput.ToStatus = fromlocation.DefaultInventoryStatus;
detailInput.Qty = detail.MatQty;
detailInput.FromLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.FromLot = detail.BatchAttr07;
detailInput.FromPackingCode = detail.PakingCode;
detailInput.FromStatus = EnumInventoryStatus.OK;
detailInput.ToStatus = EnumInventoryStatus.OK;
detailInput.Remark = "AGV反库";
transfer.Details.Add(detailInput);

639
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/SparePartIssueJobs/SparePartIssueJobAppService.cs

@ -103,30 +103,67 @@ public class SparePartIssueJobAppService
foreach (var input in inputs)
{
await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
await CheckDimensionalStorehouseAsync(input).ConfigureAwait(false);
//如果是立库 就给直接承接了
var dimensionalStorehouseflag = await UpdateJobStatusWaitByDimensionalStorehouseAsync(input).ConfigureAwait(false);
if (dimensionalStorehouseflag)
{
input.IsClaims = true;
input.ClaimsUserId = string.IsNullOrEmpty(_options.Value.StereosUser)
? "LYF"
: _options.Value.StereosUser;
input.ClaimsUserName = string.IsNullOrEmpty(_options.Value.StereosPassword)
? "LYF"
: _options.Value.StereosPassword;
}
if (dimensionalStorehouseflag == false)
{
//如果是Agv
var agvFlag = await UpdateJobStatusWaitByAgvAsync(input).ConfigureAwait(false);
if (agvFlag)
{
input.IsClaims = true;
input.ClaimsUserId = string.IsNullOrEmpty(_options.Value.StereosUser)
? "AGV"
: _options.Value.StereosUser;
input.ClaimsUserName = string.IsNullOrEmpty(_options.Value.StereosPassword)
? "AGV"
: _options.Value.StereosPassword;
}
}
}
var sparePartIssueJobDtos = await base.CreateManyAsync(inputs).ConfigureAwait(false);
foreach (var sparePartIssueJobDto in sparePartIssueJobDtos)
var assembleIssueJobDtos = await base.CreateManyAsync(inputs).ConfigureAwait(false);
foreach (var assembleIssueJobDto in assembleIssueJobDtos)
{
await DoingDimensionalStorehouseAsync(sparePartIssueJobDto).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(assembleIssueJobDto).ConfigureAwait(false);
var firstDetail = assembleIssueJobDto.Details.First();
await DoingAgvAsync(assembleIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
}
return sparePartIssueJobDtos;
return assembleIssueJobDtos;
}
[HttpPost("")]
public override async Task<SparePartIssueJobDTO> CreateAsync(SparePartIssueJobEditInput input)
{
await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
await CheckDimensionalStorehouseAsync(input).ConfigureAwait(false);
var flagDimensionalStorehouse = await UpdateJobStatusWaitByDimensionalStorehouseAsync(input).ConfigureAwait(false);
if (flagDimensionalStorehouse == false)
{
await UpdateJobStatusWaitByAgvAsync(input).ConfigureAwait(false);
}
var sparePartIssueJobDto = await base.CreateAsync(input).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(sparePartIssueJobDto).ConfigureAwait(false);
var assembleIssueJobDto = await base.CreateAsync(input).ConfigureAwait(false);
await DoingDimensionalStorehouseAsync(assembleIssueJobDto).ConfigureAwait(false);
if (flagDimensionalStorehouse == false)
{
var firstDetail = assembleIssueJobDto.Details.First();
await DoingAgvAsync(assembleIssueJobDto, firstDetail.RecommendFromLocationCode, firstDetail.RecommendToLocationCode).ConfigureAwait(false);
}
return sparePartIssueJobDto;
return assembleIssueJobDto;
}
[HttpPost("invalid")]
public override async Task CancelAsync(Guid id)
{
@ -139,7 +176,9 @@ public class SparePartIssueJobAppService
if (sparePartJob.JobStatus == EnumJobStatus.Open ||
sparePartJob.JobStatus == EnumJobStatus.Partial ||
sparePartJob.JobStatus == EnumJobStatus.Wait||
sparePartJob.JobStatus == EnumJobStatus.Doing)
sparePartJob.JobStatus == EnumJobStatus.Doing||
sparePartJob.JobStatus == EnumJobStatus.WaitAgv)
{
await _expectOutAppService.RemoveByNumberAsync(sparePartJob.Number).ConfigureAwait(false);
await _transferLibRequestAppService.CancelByCallRequestNumberAsync(sparePartJob.SparePartRequestNumber)
@ -154,7 +193,11 @@ public class SparePartIssueJobAppService
$"{EnumJobStatus.Open.GetDisplayName()}、" +
$"{EnumJobStatus.Partial.GetDisplayName()}、" +
$"{EnumJobStatus.Doing.GetDisplayName()}、" +
$"{EnumJobStatus.Wait.GetDisplayName()}");
$"{EnumJobStatus.Wait.GetDisplayName()}"+
$"{EnumJobStatus.WaitAgv.GetDisplayName()}"
);
}
}
@ -455,8 +498,54 @@ public class SparePartIssueJobAppService
return dto;
}
#region 立库
/// <summary>
/// 调用立体库
/// </summary>
/// <param name="SparePartIssueJobDto"></param>
/// <returns></returns>
private async Task DoingDimensionalStorehouseAsync(SparePartIssueJobDTO SparePartIssueJobDto)
{
var jobDetailInputdetail = SparePartIssueJobDto.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
//TODO 立体库
var ret = await SyncIssueJobStereoAsync(new List<SparePartIssueJobDTO> { SparePartIssueJobDto },
jobDetailInputdetail.RecommendToLocationCode, SparePartIssueJobDto.Id).ConfigureAwait(false);
if (ret.Code != 0)
{
throw new UserFriendlyException($"调用立体库不成功!原因:{ret.Message}");
}
}
}
/// <summary>
/// 判断是不是在立体库
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<bool> UpdateJobStatusWaitByDimensionalStorehouseAsync(SparePartIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
input.JobStatus = EnumJobStatus.Wait;
return true;
}
return false;
}
/// <summary>
/// 立体库同步
/// </summary>
@ -464,27 +553,29 @@ public class SparePartIssueJobAppService
/// <param name="pLoc"></param>
/// <returns></returns>
[HttpPost("sync-issue-job-stereo")]
public async Task<ReusltObject> SyncIssueJobStereoAsync(List<SparePartIssueJobDTO> input, string pLoc)
public async Task<ReusltObject> SyncIssueJobStereoAsync(List<SparePartIssueJobDTO> input, string pLoc, Guid uid)
{
var ret = new ReusltObject();
ret.Code = 1;
ret.Code = 0;
ret.Message = "操作成功";
ret.OperateTime = DateTime.Now.ToString("yyyy-MM-dd");
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
var IssueJobToRestoDetailDTOs = new List<IssueJobToRestoDetailDTO>();
var main = new IssueJobToRestoDTO();
main.OperatorName = CurrentUser.UserName;
main.Uuid = uid;
main.OperatorName = string.IsNullOrEmpty(CurrentUser.UserName) ? "admin" : CurrentUser.UserName;
foreach (var job in input)
{
foreach (var jobitem in job.Details)
{
IssueJobToRestoDetailDTOs.Add(new IssueJobToRestoDetailDTO
{
Count = jobitem.HandledToQty,
Count = jobitem.RecommendFromQty,
ProductNo = jobitem.ItemCode,
NeedSite = pLoc,
WorkNo = job.Number,
WorkNo = job.SparePartRequestNumber,
TaskNo = job.Number
});
}
@ -501,6 +592,27 @@ public class SparePartIssueJobAppService
_options.Value.Password = ""; //测试密码
#endif
//var json = JsonSerializer.Serialize(main);
_options.Value.Address = string.IsNullOrEmpty(_options.Value.Address)
? "http://7e42682n64.goho.co:21171/"
: _options.Value.Address; //测试地址
_options.Value.Token =
string.IsNullOrEmpty(_options.Value.Token) ? string.Empty : _options.Value.Token; //测试token
_options.Value.UserName =
string.IsNullOrEmpty(_options.Value.UserName) ? "" : _options.Value.UserName; //测试用户名
_options.Value.Password =
string.IsNullOrEmpty(_options.Value.Password) ? "" : _options.Value.Password; //测试密码
_options.Value.Path = string.IsNullOrEmpty(_options.Value.Path)
? "zozocnApi/custom/receiveProductionPlan"
: _options.Value.Path; //测试密码
_logger.LogInformation(JsonSerializer.Serialize(_options));
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"标志{flag}开始调用高通WMS:传递值{JsonSerializer.Serialize(main)}");
if (!string.IsNullOrEmpty(_options.Value.Token))
{
var token = _options.Value.Token;
@ -517,13 +629,16 @@ public class SparePartIssueJobAppService
var client = new IssueJobToRestoClient(_options.Value.Address, httpclient, _options.Value.Path);
ret = await client.SyncIssueJobStereoAsync(main).ConfigureAwait(false);
_logger.LogInformation($"标志{flag}调用高通WMS:返回值{JsonSerializer.Serialize(ret)}");
}
catch (Exception ex)
{
ret = new ReusltObject();
ret.Code = -1;
ret.Code = 1;
ret.Message = ex.Message;
ret.OperateTime = DateTime.Now.ToString("yyyy-MM-dd");
await unitOfWork.RollbackAsync().ConfigureAwait(false);
}
return ret;
@ -532,11 +647,19 @@ public class SparePartIssueJobAppService
[HttpPost("receive-issue-job-stereo")]
public virtual async Task<ReusltObject> SyncReciveIssueJobStereoAsync(IssueRequestFromRestoDTO input)
{
#if DEBUG
var json = JsonSerializer.Serialize(input);
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"{flag}接收到立体库确认单据内容:" + json);
#if DEBUG
#endif
var errors = new List<string>();
var ret = new ReusltObject { Code = 1, OperateTime = DateTime.Now.ToString("yyyy-MM-dd"), Message = "操作成功" };
var ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Success),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
Message = "操作成功"
};
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
if (input.Jobs.Count > 0)
@ -544,36 +667,102 @@ public class SparePartIssueJobAppService
var jobs = input.Jobs;
var numbers = jobs.Select(p => p.JobNumber);
var query = _repository.WithDetails()
.Where(p => numbers.Contains(p.Number));
.Where(p => numbers.Contains(p.Number) && p.JobStatus != EnumJobStatus.Done);
var entities = query.ToList();
if (entities.Count == 0)
{
errors.Add($"任务号{string.Join(",", numbers)}不存在!");
}
var dtos = ObjectMapper.Map<List<SparePartIssueJob>, List<SparePartIssueJobDTO>>(entities);
if (input.Jobs.Count == entities.Count)
if (input.Jobs.Count != entities.Count)
{
errors.Add("立体库提交出库任务和WMS任务不符,请核对! \n");
}
foreach (var itm in dtos)
{
var first = jobs.FirstOrDefault(p => p.JobNumber == itm.Number);
var itmDetails = itm.Details.ToList();
var details = new List<SparePartIssueJobDetailDTO>();
foreach (var detail in first.Details)
{
var fromloc = await _locationAppService.GetByCodeAsync(detail.FromLocationCode)
.ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源库位{detail.FromLocationCode}没查到");
}
var toloc = await _locationAppService.GetByCodeAsync(detail.ToLocationCode)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"目标库位{detail.ToLocationCode}没查到");
}
var entity = itmDetails.FirstOrDefault(p => p.ItemCode == detail.ItemCode);
if (entity == null)
{
errors.Add($"物料号{detail.ItemCode}不在任务明细内!");
}
var dto = new SparePartIssueJobDetailDTO();
dto.HandledFromLocationCode = entity.HandledFromLocationCode;
dto.HandledToLocationCode = entity.HandledToLocationCode;
dto.ItemCode = detail.ItemCode;
dto.InjectFrom(entity);
/*
dto.RecommendFromQty = detail.Qty;
dto.RecommendToQty = detail.Qty;
dto.HandledFromQty = detail.Qty;
dto.HandledToQty = detail.Qty;
dto.Status = entity.Status;
*/
//dto.RecommendFromQty = detail.Qty;
//dto.RecommendToQty = detail.Qty;
//dto.HandledFromQty = detail.Qty;
//dto.HandledToQty = detail.Qty;
dto.HandledToLocationCode = toloc.Code;
dto.HandledToLocationGroup = toloc.LocationGroupCode;
dto.HandledToLocationArea = toloc.AreaCode;
dto.HandledToLocationErpCode = toloc.ErpLocationCode;
dto.HandledToLot = string.Empty;
dto.HandledToWarehouseCode = toloc.WarehouseCode;
dto.HandledToQty = detail.Qty;
dto.HandledToLot = string.Empty;
dto.HandledToPackingCode = string.Empty;
dto.HandledFromWarehouseCode = fromloc.WarehouseCode;
dto.HandledFromLocationCode = fromloc.Code;
dto.HandledFromLocationGroup = fromloc.LocationGroupCode;
dto.HandledFromLocationArea = fromloc.AreaCode;
dto.HandledFromLocationErpCode = fromloc.ErpLocationCode;
dto.HandledFromQty = detail.Qty;
dto.HandledFromLot = string.Empty;
dto.HandledFromPackingCode = string.Empty;
details.Add(dto);
await ExecuteDetailExtAsync(itm.Id, entity.Id, dto).ConfigureAwait(false);
}
if (errors.Count > 0)
{
ret = new ReusltObject
{
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray()),
Data = json
};
}
itm.Worker = "LITK";
itm.Details = details;
await CompleteAsync(itm.Id, itm).ConfigureAwait(false);
// await CompleteAsync(itm.Id, itm).ConfigureAwait(false);
_logger.LogInformation($"{flag}接收到立体库确认单据内容:" + json + "立体库任务完成");
}
}
else
@ -585,8 +774,12 @@ public class SparePartIssueJobAppService
{
ret = new ReusltObject
{
Code = 2, OperateTime = DateTime.Now.ToString("yyyy-MM-dd"), Message = ex.Message
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = ex.Message,
Data = json
};
await unitOfWork.RollbackAsync();
return ret;
}
@ -594,9 +787,10 @@ public class SparePartIssueJobAppService
{
ret = new ReusltObject
{
Code = 2,
Code = int.Parse(GaoTongResultStatus.Failure),
OperateTime = DateTime.Now.ToString("yyyy-MM-dd"),
Message = string.Join(",", errors.ToArray())
Message = string.Join(",", errors.ToArray()),
Data = json
};
}
@ -605,176 +799,6 @@ public class SparePartIssueJobAppService
#endregion
#region 私有
/// <summary>
/// 创建补料记录实体
/// </summary>
/// <param name="sparePartIssueJobDto"></param>
/// <returns></returns>
private async Task<SparePartIssueNoteEditInput> BuildSparePartIssueNoteAsync(SparePartIssueJobDTO sparePartIssueJobDto)
{
var sparePartIssueNoteCreateInput =
ObjectMapper.Map<SparePartIssueJobDTO, SparePartIssueNoteEditInput>(sparePartIssueJobDto);
sparePartIssueNoteCreateInput.JobNumber = sparePartIssueJobDto.Number;
await Task.CompletedTask.ConfigureAwait(false);
return sparePartIssueNoteCreateInput;
}
/// <summary>
/// 判断是不是在最底层 如果不是则把状态变更为待库移 并把库移推荐的From和To赋值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task CheckMinRowAndSetStatusAsync(SparePartIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
//if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode != 1)
//{
// input.JobStatus = EnumJobStatus.Wait;
//}
//else if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode == 1)
//{
jobDetailInputdetail.TransferLibFromArriveDate = jobDetailInputdetail.RecommendFromArriveDate;
jobDetailInputdetail.TransferLibFromContainerCode = jobDetailInputdetail.RecommendFromContainerCode;
jobDetailInputdetail.TransferLibFromExpireDate = jobDetailInputdetail.RecommendFromExpireDate;
jobDetailInputdetail.TransferLibFromLocationArea = jobDetailInputdetail.RecommendFromLocationArea;
jobDetailInputdetail.TransferLibFromLocationCode = jobDetailInputdetail.RecommendFromLocationCode;
jobDetailInputdetail.TransferLibFromLocationErpCode = jobDetailInputdetail.RecommendFromLocationErpCode;
jobDetailInputdetail.TransferLibFromLocationGroup = jobDetailInputdetail.RecommendFromLocationGroup;
jobDetailInputdetail.TransferLibFromLot = jobDetailInputdetail.RecommendFromLot;
jobDetailInputdetail.TransferLibFromPackingCode = jobDetailInputdetail.RecommendFromPackingCode;
jobDetailInputdetail.TransferLibFromProduceDate = jobDetailInputdetail.RecommendFromProduceDate;
jobDetailInputdetail.TransferLibFromQty = jobDetailInputdetail.RecommendFromQty;
jobDetailInputdetail.TransferLibFromSupplierBatch = jobDetailInputdetail.RecommendFromSupplierBatch;
jobDetailInputdetail.TransferLibFromWarehouseCode = jobDetailInputdetail.RecommendFromWarehouseCode;
jobDetailInputdetail.TransferLibToArriveDate = jobDetailInputdetail.RecommendToArriveDate;
jobDetailInputdetail.TransferLibToContainerCode = jobDetailInputdetail.RecommendToContainerCode;
jobDetailInputdetail.TransferLibToExpireDate = jobDetailInputdetail.RecommendToExpireDate;
jobDetailInputdetail.TransferLibToLot = jobDetailInputdetail.RecommendToLot;
jobDetailInputdetail.TransferLibToPackingCode = jobDetailInputdetail.RecommendToPackingCode;
jobDetailInputdetail.TransferLibToProduceDate = jobDetailInputdetail.RecommendToProduceDate;
jobDetailInputdetail.TransferLibToQty = jobDetailInputdetail.RecommendToQty;
jobDetailInputdetail.TransferLibToSupplierBatch = jobDetailInputdetail.RecommendToSupplierBatch;
jobDetailInputdetail.TransferLibToWarehouseCode = jobDetailInputdetail.TransferLibFromWarehouseCode;
jobDetailInputdetail.TransferLibToLocationArea = jobDetailInputdetail.TransferLibFromLocationArea;
jobDetailInputdetail.TransferLibToLocationCode = jobDetailInputdetail.TransferLibFromLocationCode;
jobDetailInputdetail.TransferLibToLocationErpCode = jobDetailInputdetail.TransferLibFromLocationErpCode;
jobDetailInputdetail.TransferLibToLocationGroup = jobDetailInputdetail.TransferLibFromLocationGroup;
//}
}
/// <summary>
/// 判断是不是在立体库
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task CheckDimensionalStorehouseAsync(SparePartIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
input.JobStatus = EnumJobStatus.Wait;
}
}
/// <summary>
/// 调用立体库
/// </summary>
/// <param name="sparePartIssueJobDto"></param>
/// <returns></returns>
private async Task DoingDimensionalStorehouseAsync(SparePartIssueJobDTO sparePartIssueJobDto)
{
var jobDetailInputdetail = sparePartIssueJobDto.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
if (loctionDto.Type == EnumLocationType.DimensionalStorehouse)
{
//TODO 立体库
var ret = await SyncIssueJobStereoAsync(new List<SparePartIssueJobDTO> { sparePartIssueJobDto },
loctionDto.Code).ConfigureAwait(false);
if (ret.Code != 1)
{
throw new UserFriendlyException($"调用立体库不成功!原因:{ret.Message}");
}
}
}
/// <summary>
/// 修改当前任务状态 和 该任务的请求状态
/// </summary>
/// <param name="sparePartIssueJob"></param>
/// <param name="sparePartIssueJobDetailDto"></param>
/// <param name="handledToQty"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task UpdateRequestAndjobStatusDoneAsync(SparePartIssueJob sparePartIssueJob,
SparePartIssueJobDetailDTO sparePartIssueJobDetailDto, decimal handledToQty)
{
if (sparePartIssueJob.JobStatus is EnumJobStatus.Closed or EnumJobStatus.Cancelled or EnumJobStatus.None
or EnumJobStatus.Done) //需要考虑下 多次提交的问题 所以不判断 进行中
{
throw new UserFriendlyException(
$"任务状态错误:编号为【{sparePartIssueJob.Number}】的任务状态为【{sparePartIssueJob.JobStatus.GetDisplayName()}】");
}
sparePartIssueJob.JobStatus = EnumJobStatus.Done;
await RemoveExpectOutAsync(sparePartIssueJob, sparePartIssueJobDetailDto, handledToQty).ConfigureAwait(false);
//await _expectOutAppService.RemoveByNumberAsync(sparePartIssueJob.Number).ConfigureAwait(false);
await SparePartIssueRequestAppService.UpdateStatusCompletedAsync(sparePartIssueJob.SparePartRequestNumber)
.ConfigureAwait(false);
await Task.CompletedTask.ConfigureAwait(false);
}
/// <summary>
/// 判断实际TO的箱码是否被占用
/// </summary>
/// <param name="packingCode"></param>
/// <param name="jobNumber"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task CheckPackingCodeIsUserAsync(string packingCode,string jobNumber)
{
var list = await _expectOutAppService.GetListByPackingCodeAsync(packingCode).ConfigureAwait(false);
list=list.Where(p => p.JobNumber != jobNumber).ToList();
if (list.Any())
{
throw new UserFriendlyException($"任务号【{list.First().JobNumber}】的任务,已占用【{packingCode}】箱码的库存。");
}
}
private async Task RemoveExpectOutAsync(SparePartIssueJob sparePartIssueJob,
SparePartIssueJobDetailDTO sparePartIssueJobDetailDto,
decimal handledToQty)
{
await _expectOutAppService.RemoveByNumberAndInventoryAsync(sparePartIssueJob.Number,
sparePartIssueJobDetailDto.ItemCode,
sparePartIssueJobDetailDto.HandledToLocationCode, sparePartIssueJobDetailDto.HandledToPackingCode,
sparePartIssueJobDetailDto.Status, sparePartIssueJobDetailDto.HandledToLot,
handledToQty).ConfigureAwait(false);
}
#endregion
#region Agv
/// <summary>
@ -867,12 +891,12 @@ public class SparePartIssueJobAppService
}
/// <summary>
/// Agv 回调 接口
/// Agv 执行完发料回调接口
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("call-back-agv")]
public async Task<AgvResultObject> CallBackAgvAsync(AgvRequestDto request)
public async Task<AgvResultObject> CallBackAgvIssueAsync(AgvRequestDto request)
{
var entity = await _repository.FindAsync(p => p.Number == request.Data.First().OrderNum).ConfigureAwait(false);
var dto = ObjectMapper.Map<SparePartIssueJob, SparePartIssueJobDTO>(entity);
@ -972,46 +996,29 @@ public class SparePartIssueJobAppService
foreach (var detail in notes)
{
TransferNoteEditInput transfer = new TransferNoteEditInput();
var transfer = new TransferNoteEditInput();
transfer.CallJobNumber = detail.OrderNum;
transfer.Type = EnumTransSubType.Agv_Return_SparePart.ToString();
transfer.Type = EnumTransSubType.Transfer_WIP.ToString();
transfer.Worker = "Agv";
transfer.UseOnTheWayLocation = false;
List<TransferNoteDetailInput> transferNoteDetailInputs = new List<TransferNoteDetailInput>();
TransferNoteDetailInput detailInput = new TransferNoteDetailInput();
var fromloc = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源起始点{detail.BeginPosition}没查到");
}
LocationDTO fromlocation = null;
if (fromloc != null)
{
fromlocation = await _locationAppService.GetByCodeAsync(fromloc.LocationCode).ConfigureAwait(false);
}
if (fromlocation == null)
{
errors.Add($"来源起始点{detail.BeginPosition}库位没查到");
}
var toloc = await _postionLocationAppService.GetByCodeAsync(detail.EndPosition)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"结束点{detail.EndPosition}没查到");
}
LocationDTO tolocation = null;
if (toloc != null)
transfer.Confirmed = true;
var detailInput = new TransferNoteDetailInput();
var fromPosition = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromPosition == null)
{
tolocation = await _locationAppService.GetByCodeAsync(toloc.LocationCode).ConfigureAwait(false);
errors.Add($"未查询到工位{detail.BeginPosition}关联的库位");
}
if (tolocation == null)
var fromLocationDto = await _locationAppService.GetByCodeAsync(fromPosition.LocationCode).ConfigureAwait(false);
var tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
if (tolocationDto != null)
{
errors.Add($"结束点{detail.EndPosition}库位没查到");
tolocationDto = await _locationAppService.GetByCodeAsync(detail.EndPosition).ConfigureAwait(false);
}
var item = await _itemBasicAppService.GetByCodeAsync(detail.MatCode).ConfigureAwait(false);
if (item == null)
{
errors.Add($"零件号{detail.MatCode}的零件不存在!");
errors.Add($"ERP料号{detail.MatCode}不存在!");
}
else
{
@ -1029,27 +1036,26 @@ public class SparePartIssueJobAppService
Message = string.Join(",", errors.ToArray())
};
}
detailInput.ToLocationCode = tolocation.Code;
detailInput.ToLocationGroup = tolocation.LocationGroupCode;
detailInput.ToLocationArea = tolocation.AreaCode;
detailInput.ToLocationErpCode = tolocation.ErpLocationCode;
detailInput.ToWarehouseCode = tolocation.WarehouseCode;
detailInput.FromStatus = tolocation.DefaultInventoryStatus;
detailInput.ToLocationCode = tolocationDto.Code;
detailInput.ToLocationGroup = tolocationDto.LocationGroupCode;
detailInput.ToLocationArea = tolocationDto.AreaCode;
detailInput.ToLocationErpCode = tolocationDto.ErpLocationCode;
detailInput.ToWarehouseCode = tolocationDto.WarehouseCode;
detailInput.FromLocationCode = fromLocationDto.Code;
detailInput.FromLocationGroup = fromLocationDto.LocationGroupCode;
detailInput.FromLocationArea = fromLocationDto.AreaCode;
detailInput.FromLocationErpCode = fromLocationDto.ErpLocationCode;
detailInput.FromWarehouseCode = fromLocationDto.WarehouseCode;
detailInput.Qty = detail.MatQty;
detailInput.ToLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.ToLot = detail.BatchAttr07;
detailInput.ToPackingCode = detail.PakingCode;
detailInput.FromWarehouseCode = fromlocation.WarehouseCode;
detailInput.FromLocationCode = fromlocation.Code;
detailInput.FromLocationGroup = fromlocation.LocationGroupCode;
detailInput.FromLocationArea = fromlocation.AreaCode;
detailInput.FromLocationErpCode = fromlocation.ErpLocationCode;
detailInput.ToStatus = fromlocation.DefaultInventoryStatus;
detailInput.Qty = detail.MatQty;
detailInput.FromLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.FromLot = detail.BatchAttr07;
detailInput.FromPackingCode = detail.PakingCode;
detailInput.FromStatus = EnumInventoryStatus.OK;
detailInput.ToStatus = EnumInventoryStatus.OK;
detailInput.Remark = "AGV反库";
transfer.Details.Add(detailInput);
@ -1178,4 +1184,139 @@ public class SparePartIssueJobAppService
}
#endregion
#region 私有
/// <summary>
/// 创建补料记录实体
/// </summary>
/// <param name="sparePartIssueJobDto"></param>
/// <returns></returns>
private async Task<SparePartIssueNoteEditInput> BuildSparePartIssueNoteAsync(SparePartIssueJobDTO sparePartIssueJobDto)
{
var sparePartIssueNoteCreateInput =
ObjectMapper.Map<SparePartIssueJobDTO, SparePartIssueNoteEditInput>(sparePartIssueJobDto);
sparePartIssueNoteCreateInput.JobNumber = sparePartIssueJobDto.Number;
await Task.CompletedTask.ConfigureAwait(false);
return sparePartIssueNoteCreateInput;
}
/// <summary>
/// 判断是不是在最底层 如果不是则把状态变更为待库移 并把库移推荐的From和To赋值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task CheckMinRowAndSetStatusAsync(SparePartIssueJobEditInput input)
{
var jobDetailInputdetail = input.Details.FirstOrDefault();
var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
.ConfigureAwait(false);
//if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode != 1)
//{
// input.JobStatus = EnumJobStatus.Wait;
//}
//else if (loctionDto.Type == EnumLocationType.RAW && loctionDto.RowCode == 1)
//{
jobDetailInputdetail.TransferLibFromArriveDate = jobDetailInputdetail.RecommendFromArriveDate;
jobDetailInputdetail.TransferLibFromContainerCode = jobDetailInputdetail.RecommendFromContainerCode;
jobDetailInputdetail.TransferLibFromExpireDate = jobDetailInputdetail.RecommendFromExpireDate;
jobDetailInputdetail.TransferLibFromLocationArea = jobDetailInputdetail.RecommendFromLocationArea;
jobDetailInputdetail.TransferLibFromLocationCode = jobDetailInputdetail.RecommendFromLocationCode;
jobDetailInputdetail.TransferLibFromLocationErpCode = jobDetailInputdetail.RecommendFromLocationErpCode;
jobDetailInputdetail.TransferLibFromLocationGroup = jobDetailInputdetail.RecommendFromLocationGroup;
jobDetailInputdetail.TransferLibFromLot = jobDetailInputdetail.RecommendFromLot;
jobDetailInputdetail.TransferLibFromPackingCode = jobDetailInputdetail.RecommendFromPackingCode;
jobDetailInputdetail.TransferLibFromProduceDate = jobDetailInputdetail.RecommendFromProduceDate;
jobDetailInputdetail.TransferLibFromQty = jobDetailInputdetail.RecommendFromQty;
jobDetailInputdetail.TransferLibFromSupplierBatch = jobDetailInputdetail.RecommendFromSupplierBatch;
jobDetailInputdetail.TransferLibFromWarehouseCode = jobDetailInputdetail.RecommendFromWarehouseCode;
jobDetailInputdetail.TransferLibToArriveDate = jobDetailInputdetail.RecommendToArriveDate;
jobDetailInputdetail.TransferLibToContainerCode = jobDetailInputdetail.RecommendToContainerCode;
jobDetailInputdetail.TransferLibToExpireDate = jobDetailInputdetail.RecommendToExpireDate;
jobDetailInputdetail.TransferLibToLot = jobDetailInputdetail.RecommendToLot;
jobDetailInputdetail.TransferLibToPackingCode = jobDetailInputdetail.RecommendToPackingCode;
jobDetailInputdetail.TransferLibToProduceDate = jobDetailInputdetail.RecommendToProduceDate;
jobDetailInputdetail.TransferLibToQty = jobDetailInputdetail.RecommendToQty;
jobDetailInputdetail.TransferLibToSupplierBatch = jobDetailInputdetail.RecommendToSupplierBatch;
jobDetailInputdetail.TransferLibToWarehouseCode = jobDetailInputdetail.TransferLibFromWarehouseCode;
jobDetailInputdetail.TransferLibToLocationArea = jobDetailInputdetail.TransferLibFromLocationArea;
jobDetailInputdetail.TransferLibToLocationCode = jobDetailInputdetail.TransferLibFromLocationCode;
jobDetailInputdetail.TransferLibToLocationErpCode = jobDetailInputdetail.TransferLibFromLocationErpCode;
jobDetailInputdetail.TransferLibToLocationGroup = jobDetailInputdetail.TransferLibFromLocationGroup;
//}
}
/// <summary>
/// 修改当前任务状态 和 该任务的请求状态
/// </summary>
/// <param name="sparePartIssueJob"></param>
/// <param name="sparePartIssueJobDetailDto"></param>
/// <param name="handledToQty"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task UpdateRequestAndjobStatusDoneAsync(SparePartIssueJob sparePartIssueJob,
SparePartIssueJobDetailDTO sparePartIssueJobDetailDto, decimal handledToQty)
{
if (sparePartIssueJob.JobStatus is EnumJobStatus.Closed or EnumJobStatus.Cancelled or EnumJobStatus.None
or EnumJobStatus.Done) //需要考虑下 多次提交的问题 所以不判断 进行中
{
throw new UserFriendlyException(
$"任务状态错误:编号为【{sparePartIssueJob.Number}】的任务状态为【{sparePartIssueJob.JobStatus.GetDisplayName()}】");
}
sparePartIssueJob.JobStatus = EnumJobStatus.Done;
await RemoveExpectOutAsync(sparePartIssueJob, sparePartIssueJobDetailDto, handledToQty).ConfigureAwait(false);
//await _expectOutAppService.RemoveByNumberAsync(sparePartIssueJob.Number).ConfigureAwait(false);
await SparePartIssueRequestAppService.UpdateStatusCompletedAsync(sparePartIssueJob.SparePartRequestNumber)
.ConfigureAwait(false);
await Task.CompletedTask.ConfigureAwait(false);
}
/// <summary>
/// 判断实际TO的箱码是否被占用
/// </summary>
/// <param name="packingCode"></param>
/// <param name="jobNumber"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
private async Task CheckPackingCodeIsUserAsync(string packingCode,string jobNumber)
{
var list = await _expectOutAppService.GetListByPackingCodeAsync(packingCode).ConfigureAwait(false);
list=list.Where(p => p.JobNumber != jobNumber).ToList();
if (list.Any())
{
throw new UserFriendlyException($"任务号【{list.First().JobNumber}】的任务,已占用【{packingCode}】箱码的库存。");
}
}
private async Task RemoveExpectOutAsync(SparePartIssueJob sparePartIssueJob,
SparePartIssueJobDetailDTO sparePartIssueJobDetailDto,
decimal handledToQty)
{
await _expectOutAppService.RemoveByNumberAndInventoryAsync(sparePartIssueJob.Number,
sparePartIssueJobDetailDto.ItemCode,
sparePartIssueJobDetailDto.HandledToLocationCode, sparePartIssueJobDetailDto.HandledToPackingCode,
sparePartIssueJobDetailDto.Status, sparePartIssueJobDetailDto.HandledToLot,
handledToQty).ConfigureAwait(false);
}
#endregion
}

542
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/UnplannedIssueJobs/UnplannedIssueJobAppService.cs

@ -26,6 +26,7 @@ using Win_in.Sfs.Wms.Store.Options;
using Volo.Abp.ObjectMapping;
using Win_in.Sfs.Basedata.Application;
using System.Text.Json;
using Win_in.Sfs.Shared.Event;
namespace Win_in.Sfs.Wms.Store.Application;
@ -51,6 +52,7 @@ public class UnplannedIssueJobAppService
private readonly IHttpClientFactory _httpClientFactory;
private readonly IPostionLocationAppService _postionLocationAppService;
private readonly ITransferNoteAppService _transferNoteAppService;
private readonly ILocationDeliveryAppService _locationDeliveryAppService;
public UnplannedIssueJobAppService(
@ -60,7 +62,8 @@ public class UnplannedIssueJobAppService
IUnitOfWorkManager unitOfWorkManager, ILogger<UnplannedIssueJobAppService> logger,
IItemBasicAppService itemBasicAppService, IOptions<AgvOptions> agvOptions,
IPostionLocationAppService postionLocationAppService,
ITransferNoteAppService transferNoteAppService
ITransferNoteAppService transferNoteAppService,
ILocationDeliveryAppService locationDeliveryAppService
, IHttpClientFactory httpClientFactory
) : base(repository, unplannedIssueJobManager)
@ -76,6 +79,7 @@ public class UnplannedIssueJobAppService
_httpClientFactory = httpClientFactory;
_transferNoteAppService= transferNoteAppService;
_postionLocationAppService = postionLocationAppService;
_locationDeliveryAppService = locationDeliveryAppService;
}
/// <summary>
@ -471,7 +475,129 @@ public class UnplannedIssueJobAppService
public override async Task<UnplannedIssueJobDTO> CompleteAsync(Guid id, UnplannedIssueJobDTO dto)
{
var job = await _repository.GetAsync(id).ConfigureAwait(false);
//var facQuery=job.FacDetails.GroupBy(p => new { p.ItemCode }).Select(p=>new {ItemCode= p.Key.ItemCode,Qty= p.Sum(itm=>itm.RecommendQty) });
var isHasAgvFlag = false;
//var details = ObjectMapper.Map<List<UnplannedReceiptJobDetailDTO>, List<UnplannedReceiptJobDetail>>(detailDtos);
//var job = await _repository.FindAsync(p => p.Number == jobNumber).ConfigureAwait(false);
//var isHasAgvFlag = false;
//if (job == null)
//{
// throw new UserFriendlyException($"{jobNumber}【任务】不存在");
//}
//if (job.JobStatus != EnumJobStatus.Doing)
//{
// throw new UserFriendlyException($"{jobNumber}【任务】不是【执行】状态");
//}
//if (detailDtos.Count(p => p.ItemCode != job.ItemCode) > 0)
//{
// throw new UserFriendlyException("请确认ERP料号是否正确");
//}
//if (detailDtos.Sum(p => p.HandledQty) > job.Qty)
//{
// throw new UserFriendlyException("实际数量大于申请数量");
//}
//foreach (var detail in details)
//{
// var locationDto = await _locationAppService.GetByCodeAsync(detail.HandledToLocationCode).ConfigureAwait(false);
// var itemBasicDto = await _itemBasicAppService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false);
// detail.HandledToLocationArea = locationDto.AreaCode;
// detail.HandledToLocationErpCode = locationDto.ErpLocationCode;
// detail.HandledToLocationGroup = locationDto.LocationGroupCode;
// detail.HandledToLocationCode = locationDto.Code;
// detail.Status = EnumInventoryStatus.OK;
// detail.HandledArriveDate = DateTime.Now;
// detail.HandledProduceDate = DateTime.Now;
// detail.Uom = itemBasicDto.BasicUom;
// detail.ItemName = itemBasicDto.Name;
// detail.ItemDesc1 = itemBasicDto.Desc1;
// detail.ItemDesc2 = itemBasicDto.Desc2;
// detail.StdPackQty = itemBasicDto.StdPackQty;
// #region 过期时间
// if (itemBasicDto.ValidityUnit == EnumValidityUnit.Day)
// {
// detail.HandledExpireDate = detail.HandledArriveDate.AddDays(itemBasicDto.Validity);
// }
// else if (itemBasicDto.ValidityUnit == EnumValidityUnit.WeeK)
// {
// detail.HandledExpireDate = detail.HandledArriveDate.AddDays(itemBasicDto.Validity * 7);
// }
// else if (itemBasicDto.ValidityUnit == EnumValidityUnit.Month)
// {
// detail.HandledExpireDate = detail.HandledArriveDate.AddDays(itemBasicDto.Validity * 30);
// }
// else if (itemBasicDto.ValidityUnit == EnumValidityUnit.Infinite)
// {
// detail.HandledExpireDate = DateTime.MaxValue;
// }
// #endregion
// if (locationDto.ErpLocationCode != job.FromErpLocationCode)
// {
// throw new UserFriendlyException($"库位【{locationDto.ErpLocationCode}】不在【{job.FromErpLocationCode}】储位下");
// }
// if (locationDto.Type == EnumLocationType.DimensionalStorehouse)
// {
// throw new UserFriendlyException("立库功能暂未开放");
// }
// var dto = await _locationDeliveryAppService.GetByFromLocationCodeAndToLocationCodeAsync(detail.HandledToLocationCode, detail.HandledToLocationCode).ConfigureAwait(false);
// if (dto != null)
// {
// await CallAgvAsync(job, detail).ConfigureAwait(false);
// isHasAgvFlag = true;
// }
//}
//job.Details = details;
//job.CompleteUserName = worker;
//job.JobStatus = EnumJobStatus.Done;
//job.CompleteTime = DateTime.Now;
//job.Worker = worker;
//if (isHasAgvFlag)
//{
// job.JobStatus = EnumJobStatus.WaitAgv;
//}
//job = await _repository.UpdateAsync(job).ConfigureAwait(false);
//if (!isHasAgvFlag)//没有AGV就执行
//{
// await LocalEventBus.PublishAsync(new SfsCompletedEntityEventData<UnplannedReceiptJob>(job), false)
// .ConfigureAwait(false);
// await UpdateRequestStatusAsync(job.UnplannedReceiptRequestNumber).ConfigureAwait(false);
//}
if (dto.Details.Count > 0)
@ -639,37 +765,64 @@ public class UnplannedIssueJobAppService
{
var itemBasicDto = await _itemBasicAppService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false);
detail.Uom = itemBasicDto.BasicUom;
}
foreach (var itm in handleEntity.Details)//AGV
{
var dto1 = await _locationDeliveryAppService.GetByFromLocationCodeAndToLocationCodeAsync(itm.HandledFromLocationCode, itm.HandledFromLocationCode).ConfigureAwait(false);
if (dto1 != null)
{
await CallAgvAsync(job, itm).ConfigureAwait(false);
isHasAgvFlag = true;
}
}
var handleResult =
await _unplannedIssueJobManager.CompleteAsync(handleEntity, CurrentUser).ConfigureAwait(false);
handleDto = ObjectMapper.Map<UnplannedIssueJob, UnplannedIssueJobDTO>(handleResult);
await _expectOutAppService.RemoveAsync(job.Number).ConfigureAwait(false);
if (isHasAgvFlag)//agv
{
job.JobStatus = EnumJobStatus.WaitAgv;
}
handleResult.CompleteUserName = dto.Worker;
handleResult.JobStatus = EnumJobStatus.Done;
job = await _repository.UpdateAsync(handleResult).ConfigureAwait(false);
await UpdateRequestStatusAsync(job.UnplannedIssueRequestNumber).ConfigureAwait(false);
job = await _repository.UpdateAsync(job).ConfigureAwait(false);
if (!isHasAgvFlag)
{
var handleResult =
await _unplannedIssueJobManager.CompleteAsync(handleEntity, CurrentUser).ConfigureAwait(false);
handleDto = ObjectMapper.Map<UnplannedIssueJob, UnplannedIssueJobDTO>(handleResult);
await _expectOutAppService.RemoveAsync(job.Number).ConfigureAwait(false);
handleResult.CompleteUserName = dto.Worker;
handleResult.JobStatus = EnumJobStatus.Done;
job = await _repository.UpdateAsync(handleResult).ConfigureAwait(false);
await UpdateRequestStatusAsync(job.UnplannedIssueRequestNumber).ConfigureAwait(false);
}
else
{
}
//};
return handleDto;
}
/// <summary>
/// 调用 Agv 接口
/// </summary>
/// <param name="input"></param>
/// <param name="pLoc"></param>
/// <param name="uid"></param>
/// <param name="job"></param>
/// <param name="detail"></param>
/// <returns></returns>
[HttpPost("call-agv")]
public async Task<ReusltObject> CallAgvAsync(UnplannedIssueJobDTO input)
public async Task<ReusltObject> CallAgvAsync(UnplannedIssueJob job, UnplannedIssueJobDetail detail)
{
var res = new ReusltObject();
List<string> errors = new List<string>();
List<string> successList = new List<string>();
var jobres = await SendInterFaceAsync(input).ConfigureAwait(false);
var jobres = await SendInterFaceAsync(job, detail).ConfigureAwait(false);
if (jobres.Code != "0")
{
_logger.LogInformation(jobres.Message);
@ -697,319 +850,58 @@ public class UnplannedIssueJobAppService
[HttpPost("call-back-agv")]
public async Task<AgvResultObject> CallBackAgvAsync(AgvRequestUnplannedDto request)
{
var json = JsonSerializer.Serialize(request);
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"{flag}接收到AGV确认单据内容:" + json);
#if DEBUG
#endif
var errors = new List<string>();
var first = request.Data.FirstOrDefault();
var job = await _repository.GetAsync(p => p.Number == first.OrderNum).ConfigureAwait(false);
var ret = new AgvResultObject
{
Code = "0",
Message = "OK",
ReqCode = job.UnplannedIssueRequestNumber,
};
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
if (request.Data.Count > 0)
{
var jobs = request.Data;
var numbers = jobs.Select(p => p.OrderNum);
var query = _repository.WithDetails()
.Where(p => numbers.Contains(p.Number) && p.JobStatus != EnumJobStatus.Done);
var entities = query.ToList();
if (entities.Count == 0)
{
errors.Add($"任务号{string.Join(",", numbers)}不存在!");
}
var dtos = ObjectMapper.Map<List<UnplannedIssueJob>, List<UnplannedIssueJobDTO>>(entities);
foreach (var itm in dtos)
{
var arys = jobs.Where(p => p.OrderNum == itm.Number);
var itmDetails = itm.Details.ToList();
var details = new List<UnplannedIssueJobDetailDTO>();
foreach (var detail in arys)
{
var fromloc = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源起始点{detail.BeginPosition}没查到");
}
LocationDTO fromlocation = null;
if (fromloc != null)
{
fromlocation = await _locationAppService.GetByCodeAsync(fromloc.LocationCode).ConfigureAwait(false);
}
if (fromlocation == null)
{
errors.Add($"来源起始点{detail.BeginPosition}库位没查到");
}
var toloc = await _postionLocationAppService.GetByCodeAsync(detail.EndPosition)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"结束点{detail.EndPosition}库位没查到");
}
var agvRequest = request.Data.First();
LocationDTO tolocation = null;
if (toloc != null)
{
tolocation = await _locationAppService.GetByCodeAsync(toloc.LocationCode).ConfigureAwait(false);
}
if (tolocation == null)
{
errors.Add($"结束点{detail.EndPosition}库位没查到");
}
var item = await _itemBasicAppService.GetByCodeAsync(detail.MatCode).ConfigureAwait(false);
if (item == null)
{
errors.Add($"零件号{detail.MatCode}不存在!");
}
var entity = itmDetails.FirstOrDefault(p => p.ItemCode == detail.MatCode);
if (entity == null)
{
errors.Add($"零件号{detail.MatCode}不在任务明细内!");
}
if (errors.Count > 0)
{
await unitOfWork.RollbackAsync().ConfigureAwait(false);
return ret = new AgvResultObject()
{
Code = "-1",
ReqCode = "",
Message = string.Join(",", errors.ToArray())
};
}
var dto = new UnplannedIssueJobDetailDTO();
dto.InjectFrom(entity);
dto.HandledQty = detail.MatQty;
dto.HandledPackingCode = detail.PakingCode;
dto.HandledFromWarehouseCode = fromlocation.WarehouseCode;
dto.HandledFromLocationCode = fromlocation.Code;
dto.HandledFromLocationGroup = fromlocation.LocationGroupCode;
dto.HandledFromLocationArea = fromlocation.AreaCode;
dto.HandledFromLocationErpCode = fromlocation.ErpLocationCode;
details.Add(dto);
//await ExecuteDetailExtAsync(itm.Id, entity.Id, dto).ConfigureAwait(false);
}
if (errors.Count > 0)
{
await unitOfWork.RollbackAsync().ConfigureAwait(false);
ret = new AgvResultObject()
{
Code = "-1",
ReqCode = "",
Message = string.Join(",", errors.ToArray())
};
}
itm.Worker = "AGV";
itm.Details = details;
await CompleteAsync(itm.Id, itm).ConfigureAwait(false);//是否这么调待明确
_logger.LogInformation($"{flag}接收Agv确认单据内容:" + json + "Agv任务完成");
}
}
else
{
errors.Add("Agv确认单据里无数据! \n");
}
}
catch (Exception ex)
var job = await _repository.FindAsync(p => p.Number == agvRequest.OrderNum).ConfigureAwait(false);
if (job == null)
{
ret = new AgvResultObject
{
Code = "-1",
ReqCode = job.UnplannedIssueRequestNumber,
Message = ex.Message
};
await unitOfWork.RollbackAsync().ConfigureAwait(false);
return ret;
throw new UserFriendlyException("未找到该任务");
}
if (errors.Count > 0)
if (job.JobStatus != EnumJobStatus.WaitAgv)
{
ret = new AgvResultObject
{
Code = "-1",
Message = string.Join(",", errors.ToArray()),
ReqCode = job.UnplannedIssueRequestNumber
};
throw new UserFriendlyException("该任务状态不是等待AGV中");
}
return ret;
}
/// <summary>
/// Agv 回库 接口
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("call-return-back-agv")]
public async Task<AgvResultObject> CallReturnBackAgvAsync(AgvRequestDto request)
{
var json = JsonSerializer.Serialize(request);
var flag = DateTime.Now.ToString("yyyyMMddHHmmss");
_logger.LogInformation($"{flag}接收到AGV确认单据内容:" + json);
#if DEBUG
#endif
var errors = new List<string>();
var ret = new AgvResultObject
{
Code = "0",
Message = "OK",
ReqCode = "",
};
using var unitOfWork = _unitOfWorkManager.Begin();
try
{
if (request.Data.Count > 0)
{
var notes = request.Data;
foreach (var detail in notes)
{
TransferNoteEditInput transfer = new TransferNoteEditInput();
transfer.CallJobNumber = detail.OrderNum;
transfer.Type = EnumTransSubType.Agv_Transfer_WIP.ToString();
transfer.Worker = "Agv";
transfer.UseOnTheWayLocation = false;
List<TransferNoteDetailInput> transferNoteDetailInputs = new List<TransferNoteDetailInput>();
TransferNoteDetailInput detailInput = new TransferNoteDetailInput();
var fromloc = await _postionLocationAppService.GetByCodeAsync(detail.BeginPosition).ConfigureAwait(false);
if (fromloc == null)
{
errors.Add($"来源起始点{detail.BeginPosition}没查到");
}
LocationDTO fromlocation = null;
if (fromloc != null)
{
fromlocation = await _locationAppService.GetByCodeAsync(fromloc.LocationCode).ConfigureAwait(false);
}
if (fromlocation == null)
{
errors.Add($"来源起始点{detail.BeginPosition}库位没查到");
}
var toloc = await _postionLocationAppService.GetByCodeAsync(detail.EndPosition)
.ConfigureAwait(false);
if (toloc == null)
{
errors.Add($"结束点{detail.EndPosition}没查到");
}
LocationDTO tolocation = null;
if (toloc != null)
{
tolocation = await _locationAppService.GetByCodeAsync(toloc.LocationCode).ConfigureAwait(false);
}
if (tolocation == null)
{
errors.Add($"结束点{detail.EndPosition}库位没查到");
}
var item = await _itemBasicAppService.GetByCodeAsync(detail.MatCode).ConfigureAwait(false);
if (item == null)
{
errors.Add($"零件号{detail.MatCode}的零件不存在!");
}
else
{
detailInput.ItemCode = item.Code;
detailInput.Uom = item.BasicUom;
detailInput.ItemName = item.Name;
detailInput.ItemDesc1 = !string.IsNullOrEmpty(item.Desc1) ? item.Desc1 : string.Empty;
}
if (errors.Count > 0)
{
return ret = new AgvResultObject()
{
Code = "-1",
ReqCode = "",
Message = string.Join(",", errors.ToArray())
};
}
detailInput.ToLocationCode = tolocation.Code;
detailInput.ToLocationGroup = tolocation.LocationGroupCode;
detailInput.ToLocationArea = tolocation.AreaCode;
detailInput.ToLocationErpCode = tolocation.ErpLocationCode;
detailInput.ToWarehouseCode = tolocation.WarehouseCode;
detailInput.FromStatus = tolocation.DefaultInventoryStatus;
detailInput.Qty = detail.MatQty;
detailInput.ToLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.ToPackingCode = string.Empty;
detailInput.FromWarehouseCode = fromlocation.WarehouseCode;
detailInput.FromLocationCode = fromlocation.Code;
detailInput.FromLocationGroup = fromlocation.LocationGroupCode;
detailInput.FromLocationArea = fromlocation.AreaCode;
detailInput.FromLocationErpCode = fromlocation.ErpLocationCode;
detailInput.ToStatus = fromlocation.DefaultInventoryStatus;
detailInput.Qty = detail.MatQty;
detailInput.FromLot = !string.IsNullOrEmpty(detail.BatchAttr07) ? detail.BatchAttr07 : string.Empty;
detailInput.FromPackingCode = string.Empty;
var toLocationDto = await _locationAppService.GetByCodeAsync(agvRequest.EndPosition).ConfigureAwait(false);
transfer.Details.Add(detailInput);
var detail = job.Details.First();
detail.HandledQty = agvRequest.MatQty;
detail.HandledPackingCode = agvRequest.PakingCode;
detail.HandledFromWarehouseCode = toLocationDto.WarehouseCode;
detail.HandledFromLocationCode = toLocationDto.Code;
detail.HandledFromLocationGroup = toLocationDto.LocationGroupCode;
detail.HandledFromLocationArea = toLocationDto.AreaCode;
detail.HandledFromLocationErpCode = toLocationDto.ErpLocationCode;
job = await _repository.UpdateAsync(job).ConfigureAwait(false);
await LocalEventBus.PublishAsync(new SfsCompletedEntityEventData<UnplannedIssueJob>(job), false)
.ConfigureAwait(false);
await UpdateRequestStatusAsync(job.UnplannedIssueRequestNumber).ConfigureAwait(false);//await ExecuteDetailExtAsync(itm.Id, entity.Id, dto).ConfigureAwait(false);
await _transferNoteAppService.CreateAsync(transfer).ConfigureAwait(false);
}
}
else
{
errors.Add("Agv确认单据里无数据! \n");
}
}
catch (Exception ex)
return new AgvResultObject()
{
ret = new AgvResultObject
{
Code = "-1",
ReqCode = "",
Message = ex.Message
};
await unitOfWork.RollbackAsync().ConfigureAwait(false);
Code = "",
Message = "",
ReqCode = ""
};
}
}
///// <summary>
///// Agv 回库 接口
///// </summary>
///// <param name="request"></param>
///// <returns></returns>
//[HttpPost("call-return-back-agv")]
//public async Task<AgvResultObject> CallReturnBackAgvAsync(AgvRequestDto request)
//{
if (errors.Count > 0)
{
ret = new AgvResultObject
{
Code = "-1",
Message = string.Join(",", errors.ToArray()),
ReqCode = ""
};
await unitOfWork.RollbackAsync().ConfigureAwait(false);
}
return ret;
}
//}
@ -1018,10 +910,10 @@ public class UnplannedIssueJobAppService
/// </summary>
/// <param name="job"></param>
/// <returns></returns>
private async Task<AgvResultObject> SendInterFaceAsync(UnplannedIssueJobDTO job)
private async Task<AgvResultObject> SendInterFaceAsync(UnplannedIssueJob job, UnplannedIssueJobDetail detail)
{
#if DEBUG
return new AgvResultObject();
#endif
var ret = new AgvResultObject
{
@ -1033,30 +925,21 @@ public class UnplannedIssueJobAppService
try
{
if (job.JobStatus == EnumJobStatus.Done)
{
throw new UserFriendlyException($"任务{job.Number}为已完成状态,不能发起AGV任务!");
}
if (job.Details.Count == 0)
{
throw new UserFriendlyException($"任务{job.Number}没有推荐库存!");
}
var first = job.FacDetails.FirstOrDefault();
var request = new AgvRequestUnplanned();
request.MatCode = first.ItemCode;
request.MatQty = first.RecommendQty;
request.MatCode = detail.ItemCode;
request.MatQty = detail.RecommendQty;
request.OrderNum = job.Number;
request.OrderType = job.UnplannedIssueType==EnumUnplannedIssueType.Raw?EnumJobType.UnplannedIssueJobHasPacking.ToString():EnumJobType.UnplannedIssueJobNoPacking.ToString() ;
request.PakingCode = first.RecommendPackingCode;
request.Batch = detail.HandledPackingCode;
request.ErpLocationCode = job.FromErpLocationCode;
request.BeginPosition = first.HandledFromLocationCode;
request.PakingCode = detail.HandledPackingCode;
request.EndPosition = detail.HandledFromLocationCode;
request.OrderType = request.OrderType = job.UnplannedIssueType == EnumUnplannedIssueType.Raw ? EnumJobType.UnplannedIssueJobHasPacking.ToString() : EnumJobType.UnplannedIssueJobNoPacking.ToString(); ;
var httpclient = _httpClientFactory.CreateClient();
_agvOptions.Value.Address = string.IsNullOrEmpty(_agvOptions.Value.Address)
@ -1090,6 +973,7 @@ public class UnplannedIssueJobAppService
var client = new AgvJobClient(_agvOptions.Value.Address, httpclient, _agvOptions.Value.Path);
ret = await client.PushOutTaskUnplannedAsync(request).ConfigureAwait(false);
}
catch (Exception e)
{

Loading…
Cancel
Save