Browse Source

修改 领料

dev_DY_CC
郑勃旭 6 months ago
parent
commit
982c806d65
  1. 169
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/UnplannedIssueJobs/UnplannedIssueJobAppService.cs
  2. 23
      be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/UnplannedIssueJobEventHandler.cs

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

@ -1,24 +1,16 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Castle.Components.DictionaryAdapter;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Wordprocessing;
using Irony;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Omu.ValueInjecter;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Uow;
using Win_in.Sfs.Basedata.Application.Contracts;
using Win_in.Sfs.Shared.Domain.Entities;
using Win_in.Sfs.Shared.Domain.Shared;
using Win_in.Sfs.Shared.Domain.Shared.Enums.Store;
using Win_in.Sfs.Wms.Inventory.Application.Contracts;
@ -30,24 +22,27 @@ namespace Win_in.Sfs.Wms.Store.Application;
[Authorize]
[Route($"{StoreConsts.RootPath}unplanned-issue-job")]
public class UnplannedIssueJobAppService
: SfsJobAppServiceBase<UnplannedIssueJob, UnplannedIssueJobDetail, UnplannedIssueJobDTO, SfsJobRequestInputBase, UnplannedIssueJobCheckInput, UnplannedIssueJobEditInput>,
IUnplannedIssueJobAppService
: SfsJobAppServiceBase<UnplannedIssueJob, UnplannedIssueJobDetail, UnplannedIssueJobDTO, SfsJobRequestInputBase,
UnplannedIssueJobCheckInput, UnplannedIssueJobEditInput>,
IUnplannedIssueJobAppService
{
protected IUnplannedIssueRequestAppService UnplannedReceiptRequestAppService =>
LazyServiceProvider.LazyGetRequiredService<IUnplannedIssueRequestAppService>();
LazyServiceProvider.LazyGetRequiredService<IUnplannedIssueRequestAppService>();
private readonly IUnplannedIssueJobManager _unplannedIssueJobManager;
private readonly ILocationAppService _locationAppService;
private readonly IBalanceAppService _balanceAppService;
private readonly IExpectOutAppService _expectOutAppService;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly ILogger<UnplannedIssueJobAppService> _logger;
private readonly IItemBasicAppService _itemBasicAppService;
public UnplannedIssueJobAppService(
IUnplannedIssueJobRepository repository, IUnplannedIssueJobManager unplannedIssueJobManager, ILocationAppService locationAppService,
IBalanceAppService balanceAppService, IExpectOutAppService expectOutAppService, IUnitOfWorkManager unitOfWorkManager, ILogger<UnplannedIssueJobAppService> logger
) : base(repository, unplannedIssueJobManager )
IUnplannedIssueJobRepository repository, IUnplannedIssueJobManager unplannedIssueJobManager,
ILocationAppService locationAppService,
IBalanceAppService balanceAppService, IExpectOutAppService expectOutAppService,
IUnitOfWorkManager unitOfWorkManager, ILogger<UnplannedIssueJobAppService> logger, IItemBasicAppService itemBasicAppService) : base(repository, unplannedIssueJobManager)
{
_unplannedIssueJobManager = unplannedIssueJobManager;
_locationAppService = locationAppService;
@ -55,17 +50,19 @@ public class UnplannedIssueJobAppService
_expectOutAppService = expectOutAppService;
_unitOfWorkManager = unitOfWorkManager;
_logger = logger;
_itemBasicAppService = itemBasicAppService;
}
/// <summary>
/// 根据申请单号作废任务
/// 根据申请单号作废任务
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
[HttpPost("cancel-by-number")]
public virtual async Task CancelByRequestNumberAsync(string number)
{
var entities = await _repository.GetListAsync(p => p.UnplannedIssueRequestNumber == number).ConfigureAwait(false);
var entities = await _repository.GetListAsync(p => p.UnplannedIssueRequestNumber == number)
.ConfigureAwait(false);
foreach (var entity in entities)
{
await _unplannedIssueJobManager.CancelAsync(entity).ConfigureAwait(false);
@ -78,12 +75,8 @@ public class UnplannedIssueJobAppService
}
/// <summary>
/// 根据储位推荐
/// 根据储位推荐
/// </summary>
/// <returns></returns>
[HttpPost("create-by-recommend")]
@ -100,25 +93,22 @@ public class UnplannedIssueJobAppService
job.SetIdAndNumberWithDetails(GuidGenerator, job.Number);
//await SendNotifyMessageAsync(job).ConfigureAwait(false);
}
//await PublishCreatedAsync(jobs).ConfigureAwait(false);
await Repository.InsertManyAsync(jobs).ConfigureAwait(false);
//await _unplannedIssueJobManager.AddManyAsync(jobs).ConfigureAwait(false);
//await _repository.InsertManyAsync(jobs.ToList()).ConfigureAwait(false);
var outEditInputs = await BuildExpectOutAsync(useBalancesOut).ConfigureAwait(false);
//foreach (var itm in outEditInputs)
//{
// itm.JobNumber = first.Number;
//}
await _expectOutAppService.AddManyAsync(outEditInputs).ConfigureAwait(false);
}
//public static string[] GetAllFields(Type type)
//{
// // 获取公共实例字段
@ -129,31 +119,30 @@ public class UnplannedIssueJobAppService
//}
private async Task<Tuple<List<BalanceDTO>,List<BalanceDTO>>> DeductInventory(List<BalanceDTO> inventory, decimal quantityToDeduct, EnumLocationType enumLocationType)
private async Task<Tuple<List<BalanceDTO>, List<BalanceDTO>>> DeductInventory(List<BalanceDTO> inventory,
decimal quantityToDeduct, EnumLocationType enumLocationType)
{
List<BalanceDTO> balanceDTOs = new List<BalanceDTO>();
List<BalanceDTO> unbalanceDTOs = new List<BalanceDTO>();
var balanceDTOs = new List<BalanceDTO>();
var unbalanceDTOs = new List<BalanceDTO>();
decimal totalDeducted = 0;
foreach (var item in inventory)
{
decimal availableToDeduct = Math.Min(item.Qty, quantityToDeduct - totalDeducted);
var availableToDeduct = Math.Min(item.Qty, quantityToDeduct - totalDeducted);
item.Qty -= availableToDeduct;
totalDeducted += availableToDeduct;
if (availableToDeduct > 0)
{
var locationDto = await _locationAppService.GetByCodeAsync(item.LocationCode).ConfigureAwait(false);
BalanceDTO dto = new BalanceDTO();
BalanceDTO undto = new BalanceDTO();
var dto = new BalanceDTO();
var undto = new BalanceDTO();
dto.InjectFrom(item);
dto.Qty = availableToDeduct;
balanceDTOs.Add(dto);
if (enumLocationType == EnumLocationType.RAW)
{
undto.InjectFrom(item);
unbalanceDTOs.Add(dto);
unbalanceDTOs.Add(dto);
}
else
{
@ -161,8 +150,8 @@ public class UnplannedIssueJobAppService
undto.Qty = availableToDeduct;
unbalanceDTOs.Add(dto);
}
}
// 如果已经扣减达到所需数量,退出循环
if (totalDeducted >= quantityToDeduct)
{
@ -170,7 +159,7 @@ public class UnplannedIssueJobAppService
}
}
Tuple<List<BalanceDTO>, List<BalanceDTO>> tuple = new Tuple<List<BalanceDTO>, List<BalanceDTO>>( balanceDTOs,unbalanceDTOs);
var tuple = new Tuple<List<BalanceDTO>, List<BalanceDTO>>(balanceDTOs, unbalanceDTOs);
// 返回实际扣减的库存数量
@ -178,22 +167,24 @@ public class UnplannedIssueJobAppService
}
private async Task<List<UnplannedIssueJob>> BuildUnplannedIssueJobAsync(UnplannedIssueRequest requestDto, List<BalanceDTO> useBalancesOut)
private async Task<List<UnplannedIssueJob>> BuildUnplannedIssueJobAsync(UnplannedIssueRequest requestDto,
List<BalanceDTO> useBalancesOut)
{
List<UnplannedIssueJob> jobs = new EditableList<UnplannedIssueJob>();
List<string> Errors= new List<string>();
var Errors = new List<string>();
foreach (var requestDtoDetail in requestDto.Details)//非计划领料明细
foreach (var requestDtoDetail in requestDto.Details) //非计划领料明细
{
var locationCodes = await _locationAppService.GetListByErpLocationCodes(new StringList(requestDtoDetail.LocationErpCode)).ConfigureAwait(false);//获取存放库位
var locationCodes = await _locationAppService
.GetListByErpLocationCodes(new StringList(requestDtoDetail.LocationErpCode))
.ConfigureAwait(false); //获取存放库位
if (locationCodes.Count == 0)
{
throw new UserFriendlyException("ERP库位没有对应WMS库位!");
}
var first=locationCodes.FirstOrDefault();
var first = locationCodes.FirstOrDefault();
var locationDto = await _locationAppService.GetByCodeAsync(first.Code).ConfigureAwait(false);
var input = new RecommendBalanceRequestInput();
@ -291,8 +282,9 @@ public class UnplannedIssueJobAppService
};
break;
}
var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false);//获取推荐库存
usableList = usableList.Where(p => p.Qty> 0).ToList();
var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false); //获取推荐库存
usableList = usableList.Where(p => p.Qty > 0).ToList();
usableList = usableList
.OrderBy(p => p.Lot)
.ThenBy(p => p.PutInTime)
@ -303,14 +295,14 @@ public class UnplannedIssueJobAppService
decimal qty = 0;
//实际要用库存
List<BalanceDTO> useBalances = new List<BalanceDTO>();
var returnlist=await DeductInventory(usableList, requestDtoDetail.Qty, locationDto.Type).ConfigureAwait(false);
var useBalances = new List<BalanceDTO>();
var returnlist = await DeductInventory(usableList, requestDtoDetail.Qty, locationDto.Type)
.ConfigureAwait(false);
useBalances.AddRange(returnlist.Item1);
useBalancesOut.AddRange(returnlist.Item2);
//foreach (var balanceDto in usableList)
//{
// decimal availableToDeduct = Math.Min(balanceDto.Qty, balanceDto.Qty - qty);
@ -338,15 +330,13 @@ public class UnplannedIssueJobAppService
//}
if (returnlist.Item1.Count == 0)
{
_logger.LogError($"{"" + requestDto.Number + ":" + requestDtoDetail.ItemCode + "" + requestDtoDetail.Qty.ToString()}");
// Errors.Add($"{"非生产领料"+requestDto.Number+"零件号:"+requestDtoDetail.ItemCode + "库存不够" + requestDtoDetail.Qty.ToString()}");
_logger.LogError(
$"{"" + requestDto.Number + ":" + requestDtoDetail.ItemCode + "" + requestDtoDetail.Qty}");
// Errors.Add($"{"非生产领料"+requestDto.Number+"零件号:"+requestDtoDetail.ItemCode + "库存不够" + requestDtoDetail.Qty.ToString()}");
}
if (useBalances.Count > 0)
{
foreach (var balanceDtoGroup in useBalances.GroupBy(p => p.LocationErpCode))
{
//var locationDto = await _locationAppService.GetByCodeAsync(balanceDtoGroup.Key).ConfigureAwait(false);
@ -417,7 +407,7 @@ public class UnplannedIssueJobAppService
job.WarehouseCode = balanceDtoGroup.First().WarehouseCode;
job.BuildDate = DateTime.Now;
job.Explain = requestDtoDetail.Explain;
job.CaseCode = requestDtoDetail.CaseCode;
job.ProjCapacityCode = requestDtoDetail.ProjCapacityCode;
job.OnceBusiCode = requestDtoDetail.OnceBusiCode;
@ -472,21 +462,21 @@ public class UnplannedIssueJobAppService
job.FacDetails.Add(jobfacDetail);
}
if (locationDto.Type == EnumLocationType.DimensionalStorehouse)//如果是立库的
if (locationDto.Type == EnumLocationType.DimensionalStorehouse) //如果是立库的
{
await SendDimensionalStorehouseAsync().ConfigureAwait(false);
job.JobStatus = EnumJobStatus.Wait;
}
jobs.Add(job);
foreach (var itm in returnlist.Item2)
{
itm.Remark = job.Number;
useBalancesOut.Add(itm);
}
//useBalancesOut.AddRange(returnlist.Item2);
}
}
else
@ -532,6 +522,7 @@ public class UnplannedIssueJobAppService
job.UnplannedIssueType = EnumUnplannedIssueType.Wip;
break;
}
job.ItemCode = requestDtoDetail.ItemCode;
job.ItemName = requestDtoDetail.ItemName;
job.ItemDesc1 = requestDtoDetail.ItemDesc1;
@ -556,11 +547,7 @@ public class UnplannedIssueJobAppService
job.BuildDate = DateTime.Now;
jobs.Add(job);
}
}
//if (Errors.Count > 0)
//{
@ -575,22 +562,24 @@ public class UnplannedIssueJobAppService
private async Task<List<ExpectOutEditInput>> BuildExpectOutAsync(List<BalanceDTO> balanceDtos)
{
var lst=ObjectMapper.Map<List<BalanceDTO>, List<ExpectOutEditInput>>(balanceDtos);
var lst = ObjectMapper.Map<List<BalanceDTO>, List<ExpectOutEditInput>>(balanceDtos);
foreach (var itm in lst)
{
itm.JobNumber = itm.Remark;
}
return lst;
}
/// <summary>
/// 给立体库发送
/// 给立体库发送
/// </summary>
/// <returns></returns>
private async Task SendDimensionalStorehouseAsync()
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
/// <summary>
/// 创建补料记录实体
/// </summary>
@ -617,71 +606,72 @@ public class UnplannedIssueJobAppService
issuenote.Details = new List<UnplannedIssueNoteDetailInput>();
foreach (var detail in unplannedIssueJobDto.FacDetails)
{
var entity=new UnplannedIssueNoteDetailInput();
var entity = new UnplannedIssueNoteDetailInput();
entity.InjectFrom(detail);
entity.Qty = detail.HandledQty;
issuenote.Details.Add(entity);
}
await Task.CompletedTask.ConfigureAwait(false);
return issuenote;
}
/// <summary>
/// 根据申请单号判断下面的任务是否都是完成或取消
/// 根据申请单号判断下面的任务是否都是完成或取消
/// </summary>
/// <returns></returns>
[HttpPost("is-all-job-over-by-request-number")]
public async Task<bool> IsAllJobOverByRequestNumberAsync(string requestNumber)
{
var unplannedRequestJobs = await _repository.GetListAsync(p => p.UnplannedIssueRequestNumber == requestNumber).ConfigureAwait(false);
var unplannedRequestJobs = await _repository.GetListAsync(p => p.UnplannedIssueRequestNumber == requestNumber)
.ConfigureAwait(false);
if (unplannedRequestJobs.Any(p =>
p.JobStatus == EnumJobStatus.Open || p.JobStatus == EnumJobStatus.Partial ||
p.JobStatus == EnumJobStatus.Doing || p.JobStatus == EnumJobStatus.Wait))
{
return false;
}
return true;
}
[HttpPost("handle/{id}")]
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 query=dto.Details.GroupBy(p => new { p.ItemCode }).Select(p => new { ItemCode = p.Key.ItemCode, Qty = p.Sum(itm => itm.HandledQty) });
var query = dto.Details.GroupBy(p => new { p.ItemCode })
.Select(p => new { p.Key.ItemCode, Qty = p.Sum(itm => itm.HandledQty) });
//var errorQuery = from itm in facQuery join itm1 in query on itm.ItemCode equals itm1.ItemCode where itm1.Qty > itm.Qty select itm.ItemCode ;
//var errorList = errorQuery.ToList();
var sumqty = query.FirstOrDefault().Qty;
if (job.Qty < sumqty)
{
throw new UserFriendlyException($"零件实际数量不能大于需求数量!");
throw new UserFriendlyException("零件实际数量不能大于需求数量!");
}
var handleDto = new UnplannedIssueJobDTO();
//using (var uow = _unitOfWorkManager.Begin())
//{
// 在工作单元中插入数据
if (job.JobStatus is EnumJobStatus.Closed or EnumJobStatus.Cancelled or EnumJobStatus.None or EnumJobStatus.Done)//需要考虑下 多次提交的问题 所以不判断 进行中
// 在工作单元中插入数据
if (job.JobStatus is EnumJobStatus.Closed or EnumJobStatus.Cancelled or EnumJobStatus.None
or EnumJobStatus.Done) //需要考虑下 多次提交的问题 所以不判断 进行中
{
throw new UserFriendlyException($"任务状态错误:编号为【{job.Number}】的任务已经【{job.JobStatus.GetDisplayName()}】");
}
var handleEntity = ObjectMapper.Map<UnplannedIssueJobDTO, UnplannedIssueJob>(dto);
var handleResult = await _unplannedIssueJobManager.CompleteAsync(handleEntity, CurrentUser).ConfigureAwait(false);
foreach (var detail in dto.Details)
{
var itemBasicDto=await _itemBasicAppService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false);
detail.Uom = itemBasicDto.BasicUom;
}
var handleResult =
await _unplannedIssueJobManager.CompleteAsync(handleEntity, CurrentUser).ConfigureAwait(false);
handleDto = ObjectMapper.Map<UnplannedIssueJob, UnplannedIssueJobDTO>(handleResult);
await _expectOutAppService.RemoveAsync(job.Number).ConfigureAwait(false);
@ -692,13 +682,6 @@ public class UnplannedIssueJobAppService
//};
return handleDto;
}
}

23
be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/UnplannedIssueJobEventHandler.cs

@ -6,6 +6,7 @@ using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Uow;
using Win_in.Sfs.Basedata.Application.Contracts;
using Win_in.Sfs.Shared.Domain.Shared;
using Win_in.Sfs.Shared.Event;
using Win_in.Sfs.Wms.Store.Application.Contracts;
@ -20,12 +21,13 @@ public class UnplannedIssueJobEventHandler :
, ILocalEventHandler<SfsCompletedEntityEventData<UnplannedIssueJob>>
{
private readonly IUnplannedIssueNoteAppService _noteApp;
private readonly IItemBasicAppService _itemBasicApp;
public UnplannedIssueJobEventHandler(
IUnplannedIssueNoteAppService noteApp
)
IUnplannedIssueNoteAppService noteApp, IItemBasicAppService itemBasicApp)
{
_noteApp = noteApp;
_itemBasicApp = itemBasicApp;
}
[UnitOfWork]
@ -48,8 +50,8 @@ public class UnplannedIssueJobEventHandler :
if (entity.Details.Any())
{
var note = BuildUnplannedIssueNoteCreateInput(entity);
await _noteApp.CreateAsync(note).ConfigureAwait(false);
var note = BuildUnplannedIssueNoteCreateInputAsync(entity);
await _noteApp.CreateAsync(await note.ConfigureAwait(false)).ConfigureAwait(false);
}
entity.JobStatus=EnumJobStatus.Done;
@ -72,8 +74,8 @@ public class UnplannedIssueJobEventHandler :
var entity = eventData.Entity;
if (entity.Details.Any())
{
var note = BuildUnplannedIssueNoteCreateInput(entity);
await _noteApp.CreateAsync(note).ConfigureAwait(false);
var note = BuildUnplannedIssueNoteCreateInputAsync(entity);
await _noteApp.CreateAsync(await note.ConfigureAwait(false)).ConfigureAwait(false);
}
}
@ -83,7 +85,7 @@ public class UnplannedIssueJobEventHandler :
/// <param name="entity"></param>
/// <param name="input"></param>
/// <returns></returns>
private UnplannedIssueNoteEditInput BuildUnplannedIssueNoteCreateInput(UnplannedIssueJob entity)
private async Task<UnplannedIssueNoteEditInput> BuildUnplannedIssueNoteCreateInputAsync(UnplannedIssueJob entity)
{
var createInput = ObjectMapper.Map<UnplannedIssueJob, UnplannedIssueNoteEditInput>(entity);
@ -96,7 +98,7 @@ public class UnplannedIssueJobEventHandler :
createInput.ItemDesc1 =entity.ItemDesc1;
createInput.ItemDesc2 = entity.ItemDesc2;
createInput.Qty=entity.Qty;
@ -111,6 +113,9 @@ public class UnplannedIssueJobEventHandler :
{
if (inputDetail.HandledQty > 0)
{
var itemBasicDto = await _itemBasicApp.GetByCodeAsync(inputDetail.ItemCode).ConfigureAwait(false);
var detail = ObjectMapper.Map<UnplannedIssueJobDetail, UnplannedIssueNoteDetailInput>(inputDetail);
detail.LocationCode = inputDetail.HandledFromLocationCode;
detail.LocationArea = inputDetail.HandledFromLocationArea;
@ -125,7 +130,7 @@ public class UnplannedIssueJobEventHandler :
detail.ArriveDate=inputDetail.HandledArriveDate;
detail.ProduceDate = inputDetail.HandledProduceDate;
detail.ExpireDate=inputDetail.HandledExpireDate;
detail.Uom = inputDetail.Uom;
detail.Uom = itemBasicDto.BasicUom;
detail.ExtraProperties = inputDetail.ExtraProperties;
createInput.Details.Add(detail);
}

Loading…
Cancel
Save