diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/ExpectOuts/IExpectOutAppService.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/ExpectOuts/IExpectOutAppService.cs index 31ae65e93..f0e17a5b7 100644 --- a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/ExpectOuts/IExpectOutAppService.cs +++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application.Contracts/ExpectOuts/IExpectOutAppService.cs @@ -24,23 +24,25 @@ public interface IExpectOutAppService EnumInventoryStatus enumInventoryStatus, string lot); - Task RemoveListByItemCodeAndStatusAndPackingCodeAsync( - string itemCode, - string locationCode, - string packingCode, - EnumInventoryStatus enumInventoryStatus, - string lot); - /// - /// 保存拆箱时涉及的明细修改 + /// 保存拆箱时涉及的明细修改 /// /// Task> SaveDetail_SplitPackingAsync(SplitPacking_UpdateDetailInput input); /// - /// 根据任务号、箱码、数量、库位取预计出列表 + /// 根据任务号、箱码、数量、库位取预计出列表 /// /// Task> GetListByJobNumberAsync(SplitPacking_UpdateDetailInput input); + + Task RemoveByNumberAndInventoryAsync( + string jobNumber, + string itemCode, + string locationCode, + string packingCode, + EnumInventoryStatus enumInventoryStatus, + string lot, + decimal qty); } diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/ExpectOuts/ExpectOutAppService.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/ExpectOuts/ExpectOutAppService.cs index fb64edbd3..252ff34cd 100644 --- a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/ExpectOuts/ExpectOutAppService.cs +++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/ExpectOuts/ExpectOutAppService.cs @@ -43,6 +43,39 @@ public class ExpectOutAppService await _expectOutManager.RemoveAsync(jobNumber).ConfigureAwait(false); } + [HttpPost("remove/job-number-and-inventory-balance")] + public virtual async Task RemoveByNumberAndInventoryAsync( + string jobNumber, + string itemCode, + string locationCode, + string packingCode, + EnumInventoryStatus enumInventoryStatus, + string lot, + decimal qty) + { + var expectOut= await _repository.FindAsync(p => + p.ItemCode == itemCode && + p.Status == enumInventoryStatus && + p.PackingCode == packingCode && + p.Lot == lot&& + p.JobNumber==jobNumber + ).ConfigureAwait(false); + + if (expectOut != null) + { + expectOut.Qty -= qty; + } + + if (expectOut.Qty == 0) + { + await _repository.DeleteAsync(expectOut).ConfigureAwait(false); + } + else + { + await _repository.UpdateAsync(expectOut).ConfigureAwait(false); + } + } + [HttpPost("remove/{id}")] public virtual async Task RemoveAsync(Guid id) { diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs index 318b19bd7..549de9dac 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -11,4 +12,10 @@ public interface IKittingIssueJobAppService Task CancelByMaterialRequestAsync(string requestNumber); Task> GetByRequestNumberAsync(string requestNumber); + + /// + /// 执行任务明细 + /// + /// + Task ExecuteDetailAsync(Guid masterId,Guid detailId, KittingIssueJobDetailDTO issueJobDetailDto); } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/IssueRequest/KittingIssueRequests/IKittingIssueRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/IssueRequest/KittingIssueRequests/IKittingIssueRequestAppService.cs index 4dded00d6..f7d630cc0 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/IssueRequest/KittingIssueRequests/IKittingIssueRequestAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/IssueRequest/KittingIssueRequests/IKittingIssueRequestAppService.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -10,4 +11,5 @@ public interface IKittingIssueRequestAppService { Task CreateAndHandleAsync(KittingIssueRequestEditInput input); + Task UpdateStatusCompletedAsync(string number); } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs index 3e83c02d6..848f90ada 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs @@ -1,22 +1,14 @@ using System; using System.Collections.Generic; -using System.Data; using System.Linq; -using System.Linq.Expressions; -using System.Threading; using System.Threading.Tasks; -using Castle.Components.DictionaryAdapter; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using SQLitePCL; using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.ObjectMapping; using Win_in.Sfs.Basedata.Application.Contracts; -using Win_in.Sfs.Basedata.Domain.Shared; -using Win_in.Sfs.Shared.Domain; using Win_in.Sfs.Shared.Domain.Shared; using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; +using Win_in.Sfs.Wms.Inventory.Application.Contracts; using Win_in.Sfs.Wms.Store.Application.Contracts; using Win_in.Sfs.Wms.Store.Domain; using Win_in.Sfs.Wms.Store.Domain.Shared; @@ -35,15 +27,22 @@ public class KittingIssueJobAppService private readonly ILocationAppService _locationAppService; private readonly ITransferLibJobAppService _transferLibJobAppService; private readonly IKittingIssueNoteAppService _kittingIssueNoteAppService; + private readonly IExpectOutAppService _expectOutAppService; + + protected IKittingIssueRequestAppService KittingIssueRequestAppService => + LazyServiceProvider.LazyGetRequiredService(); public KittingIssueJobAppService( IKittingIssueJobRepository repository, IKittingIssueJobManager kittingIssueJobManager, - ILocationAppService locationAppService, ITransferLibJobAppService transferLibJobAppService, IKittingIssueNoteAppService kittingIssueNoteAppService) : base(repository, kittingIssueJobManager) + ILocationAppService locationAppService, ITransferLibJobAppService transferLibJobAppService, + IKittingIssueNoteAppService kittingIssueNoteAppService, IExpectOutAppService expectOutAppService) : base( + repository, kittingIssueJobManager) { _kittingIssueJobManager = kittingIssueJobManager; _locationAppService = locationAppService; _transferLibJobAppService = transferLibJobAppService; _kittingIssueNoteAppService = kittingIssueNoteAppService; + _expectOutAppService = expectOutAppService; } [HttpPost("add-many")] @@ -100,7 +99,7 @@ public class KittingIssueJobAppService } /// - /// 库移回调 + /// 库移回调 /// /// /// @@ -145,40 +144,36 @@ public class KittingIssueJobAppService jobDetail.TransferLibToWarehouseCode = transferLibNoteDetail.HandledToWarehouseCode; await _repository.UpdateAsync(job).ConfigureAwait(false); - - return; } /// - /// 执行任务明细 + /// 执行任务明细 /// /// [HttpPost("ExecuteDetail/{masterId}")] - public async Task ExecuteDetailAsync(Guid masterId,Guid detailId, KittingIssueJobDetailDTO issueJobDetailDto) + public async Task ExecuteDetailAsync(Guid masterId, Guid detailId, KittingIssueJobDetailDTO issueJobDetailDto) { - var kittingIssueJob= await _repository.GetAsync(masterId).ConfigureAwait(false); + var kittingIssueJob = await _repository.GetAsync(masterId).ConfigureAwait(false); - var kittingIssueJobDto=ObjectMapper.Map(kittingIssueJob); - kittingIssueJobDto.Details = new List() { issueJobDetailDto }; - var kittingIssueNoteEditInput=await BuildKittingIssueNoteAsync(kittingIssueJobDto).ConfigureAwait(false); + var kittingIssueJobDto = ObjectMapper.Map(kittingIssueJob); + kittingIssueJobDto.Details = new List { issueJobDetailDto }; + var kittingIssueNoteEditInput = await BuildKittingIssueNoteAsync(kittingIssueJobDto).ConfigureAwait(false); await _kittingIssueNoteAppService.CreateAsync(kittingIssueNoteEditInput).ConfigureAwait(false); kittingIssueJobDto = ObjectMapper.Map(kittingIssueJob); - if (kittingIssueJob.EnumIssueSendType == EnumIssueSendType.QtyType)//按箱叫料 因为任务只有1箱 所以可以直接完成 + if (kittingIssueJob.EnumIssueSendType == EnumIssueSendType.QtyType) //按箱叫料 因为任务只有1箱 所以可以直接完成 { - await CompleteAsync(masterId, kittingIssueJobDto).ConfigureAwait(false); + await UpdateJobStatusDoneAsync(kittingIssueJob, issueJobDetailDto).ConfigureAwait(false); } else { - var detail = kittingIssueJob.Details.First(p=>p.Id==issueJobDetailDto.Id); + var detail = kittingIssueJob.Details.First(p => p.Id == issueJobDetailDto.Id); if (issueJobDetailDto.HandledToQty >= detail.RequestQty) { - await CompleteAsync(masterId, kittingIssueJobDto).ConfigureAwait(false); + await UpdateJobStatusDoneAsync(kittingIssueJob, issueJobDetailDto).ConfigureAwait(false); } } - - await _kittingIssueNoteAppService.CreateAsync(kittingIssueNoteEditInput).ConfigureAwait(false); } #region 私有 @@ -190,7 +185,8 @@ public class KittingIssueJobAppService /// private async Task BuildKittingIssueNoteAsync(KittingIssueJobDTO kittingIssueJobDto) { - var kittingIssueNoteCreateInput = ObjectMapper.Map(kittingIssueJobDto); + var kittingIssueNoteCreateInput = + ObjectMapper.Map(kittingIssueJobDto); kittingIssueNoteCreateInput.JobNumber = kittingIssueJobDto.Number; await Task.CompletedTask.ConfigureAwait(false); @@ -245,7 +241,7 @@ public class KittingIssueJobAppService } /// - /// 判断是不是在立体库 + /// 判断是不是在立体库 /// /// /// @@ -264,5 +260,29 @@ public class KittingIssueJobAppService } } + private async Task UpdateJobStatusDoneAsync(KittingIssueJob kittingIssueJob, + KittingIssueJobDetailDTO kittingIssueJobDetailDto) + { + if (kittingIssueJob.JobStatus is EnumJobStatus.Closed or EnumJobStatus.Cancelled or EnumJobStatus.None + or EnumJobStatus.Done) //需要考虑下 多次提交的问题 所以不判断 进行中 + { + throw new UserFriendlyException( + $"任务状态错误:编号为【{kittingIssueJob.Number}】的任务已经【{kittingIssueJob.JobStatus.GetDisplayName()}】"); + } + + kittingIssueJob.JobStatus = EnumJobStatus.Done; + + await _expectOutAppService.RemoveByNumberAndInventoryAsync(kittingIssueJob.Number, + kittingIssueJobDetailDto.ItemCode, + kittingIssueJobDetailDto.HandledToLocationCode, kittingIssueJobDetailDto.HandledToPackingCode, + kittingIssueJobDetailDto.Status, kittingIssueJobDetailDto.HandledToLot, + kittingIssueJobDetailDto.HandledToQty).ConfigureAwait(false); + + await KittingIssueRequestAppService.UpdateStatusCompletedAsync(kittingIssueJob.KittingRequestNumber) + .ConfigureAwait(false); + + await Task.CompletedTask.ConfigureAwait(false); + } + #endregion } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/IssuelRequests/KittingIssueRequests/KittingIssueRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/IssuelRequests/KittingIssueRequests/KittingIssueRequestAppService.cs index 90309de96..f508e12b5 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/IssuelRequests/KittingIssueRequests/KittingIssueRequestAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/IssuelRequests/KittingIssueRequests/KittingIssueRequestAppService.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -27,6 +29,7 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase HandleAsync(Guid id) @@ -135,8 +138,106 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBasep.Number== number).ConfigureAwait(false); + + var kittingIssueJobDtos=await _kittingIssueJobAppService.GetByRequestNumberAsync(kittingIssueRequest.Number).ConfigureAwait(false); + + if (!kittingIssueJobDtos.Any(p => + p.JobStatus == EnumJobStatus.Open || p.JobStatus == EnumJobStatus.Doing || + p.JobStatus == EnumJobStatus.Partial) ) + { + return; + } + else + { + bool flag = true; + + foreach (var detail in kittingIssueRequest.Details) + { + if (detail.Qty > detail.IssuedQty) + { + flag = false; + return; + } + } + + if (flag) + { + CheckStatus(EnumRequestStatus.Completed, kittingIssueRequest.RequestStatus); + kittingIssueRequest.RequestStatus = EnumRequestStatus.Completed; + await _repository.UpdateAsync(kittingIssueRequest).ConfigureAwait(false); + } + } + + kittingIssueRequest.RequestStatus = EnumRequestStatus.Completed; + } + #region 校验 + private void CheckStatus(EnumRequestStatus targetStatus, EnumRequestStatus nowStatus) + { + var validSourceStatuses = new List(); + switch (targetStatus) + { + case EnumRequestStatus.None: + break; + case EnumRequestStatus.New: + break; + case EnumRequestStatus.Reviewing: + validSourceStatuses = new List { EnumRequestStatus.New }; + break; + case EnumRequestStatus.Refused: + validSourceStatuses = new List { EnumRequestStatus.Reviewing }; + break; + case EnumRequestStatus.Agreed: + validSourceStatuses = new List { EnumRequestStatus.Reviewing }; + break; + case EnumRequestStatus.Handling: + validSourceStatuses = new List + { + EnumRequestStatus.Agreed, EnumRequestStatus.Partial, + }; + break; + case EnumRequestStatus.Completed: + validSourceStatuses = new List + { + EnumRequestStatus.Handling, EnumRequestStatus.Partial, + }; + break; + case EnumRequestStatus.Cancelled: + validSourceStatuses = new List + { + EnumRequestStatus.New, EnumRequestStatus.Reviewing, EnumRequestStatus.Agreed, + }; + break; + case EnumRequestStatus.Abort: + validSourceStatuses = new List + { + EnumRequestStatus.Handling, EnumRequestStatus.Partial, + }; + break; + case EnumRequestStatus.Partial: + { + validSourceStatuses = new List + { + EnumRequestStatus.Handling, EnumRequestStatus.Partial, + }; + break; + } + default: + throw new ArgumentOutOfRangeException(nameof(targetStatus), targetStatus, null); + } + + if (!validSourceStatuses.Contains(nowStatus)) + { + throw new UserFriendlyException( + $"当前状态为 {nowStatus.GetDisplayName()} ,无法变更为 {targetStatus.GetDisplayName()}"); + } + } + private void CheckItemBasic(ItemBasicDTO itemBasicDto, string itemCode) { if (itemBasicDto == null) diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/KittingIssueRequestAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/KittingIssueRequestAutoMapperProfile.cs index f0f104c95..5333732f1 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/KittingIssueRequestAutoMapperProfile.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/KittingIssueRequestAutoMapperProfile.cs @@ -30,6 +30,7 @@ public partial class StoreEventAutoMapperProfile : Profile .Ignore(x => x.CompleteUserName) .Ignore(x => x.CompleteTime) .Ignore(x => x.Details) + .Ignore(x=>x.EnumIssueSendType) ; } }