|
@ -1,25 +1,12 @@ |
|
|
using System; |
|
|
using System; |
|
|
using System.Collections.Generic; |
|
|
using System.Collections.Generic; |
|
|
using System.ComponentModel.DataAnnotations; |
|
|
|
|
|
using System.Linq; |
|
|
using System.Linq; |
|
|
using System.Linq.Expressions; |
|
|
|
|
|
using System.Threading; |
|
|
|
|
|
using System.Threading.Tasks; |
|
|
using System.Threading.Tasks; |
|
|
using DocumentFormat.OpenXml.Office.PowerPoint.Y2021.M06.Main; |
|
|
|
|
|
using IdentityModel; |
|
|
|
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
using Microsoft.EntityFrameworkCore; |
|
|
|
|
|
using Volo.Abp; |
|
|
using Volo.Abp; |
|
|
using Volo.Abp.Application.Dtos; |
|
|
|
|
|
using Volo.Abp.Domain.Entities; |
|
|
|
|
|
using Volo.Abp.Domain.Repositories; |
|
|
|
|
|
using Volo.Abp.ObjectMapping; |
|
|
|
|
|
using Win_in.Sfs.Basedata.Application; |
|
|
|
|
|
using Win_in.Sfs.Basedata.Application.Contracts; |
|
|
using Win_in.Sfs.Basedata.Application.Contracts; |
|
|
using Win_in.Sfs.Shared.Domain; |
|
|
|
|
|
using Win_in.Sfs.Shared.Domain.Shared; |
|
|
using Win_in.Sfs.Shared.Domain.Shared; |
|
|
using Win_in.Sfs.Shared.Event; |
|
|
|
|
|
using Win_in.Sfs.Wms.Store.Application.Contracts; |
|
|
using Win_in.Sfs.Wms.Store.Application.Contracts; |
|
|
using Win_in.Sfs.Wms.Store.Domain; |
|
|
using Win_in.Sfs.Wms.Store.Domain; |
|
|
using Win_in.Sfs.Wms.Store.Domain.Shared; |
|
|
using Win_in.Sfs.Wms.Store.Domain.Shared; |
|
@ -42,6 +29,7 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
private readonly ILocationAppService _locationAppService; |
|
|
private readonly ILocationAppService _locationAppService; |
|
|
private readonly IItemBasicAppService _itemBasicAppService; |
|
|
private readonly IItemBasicAppService _itemBasicAppService; |
|
|
private readonly IProductionLineAppService _productionLineAppService; |
|
|
private readonly IProductionLineAppService _productionLineAppService; |
|
|
|
|
|
private readonly IKittingIssueJobAppService _kittingIssueJobAppService; |
|
|
|
|
|
|
|
|
private readonly ITransactionTypeAppService _transactionTypeAppService; |
|
|
private readonly ITransactionTypeAppService _transactionTypeAppService; |
|
|
|
|
|
|
|
@ -54,8 +42,7 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
ILocationAppService locationAppService, |
|
|
ILocationAppService locationAppService, |
|
|
IItemBasicAppService itemBasicAppService, |
|
|
IItemBasicAppService itemBasicAppService, |
|
|
IProductionLineAppService productionLineAppService, |
|
|
IProductionLineAppService productionLineAppService, |
|
|
ITransactionTypeAppService transactionTypeAppService |
|
|
ITransactionTypeAppService transactionTypeAppService, IKittingIssueJobAppService kittingIssueJobAppService) |
|
|
) |
|
|
|
|
|
: base(repository, kittingIssueRequestManager) |
|
|
: base(repository, kittingIssueRequestManager) |
|
|
{ |
|
|
{ |
|
|
_kittingIssueRequestManager = kittingIssueRequestManager; |
|
|
_kittingIssueRequestManager = kittingIssueRequestManager; |
|
@ -66,15 +53,12 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
_productionLineAppService = productionLineAppService; |
|
|
_productionLineAppService = productionLineAppService; |
|
|
|
|
|
|
|
|
_transactionTypeAppService = transactionTypeAppService; |
|
|
_transactionTypeAppService = transactionTypeAppService; |
|
|
|
|
|
_kittingIssueJobAppService = kittingIssueJobAppService; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 东阳V2
|
|
|
|
|
|
|
|
|
|
|
|
public override async Task<KittingIssueRequestDTO> HandleAsync(Guid id) |
|
|
public override async Task<KittingIssueRequestDTO> HandleAsync(Guid id) |
|
|
{ |
|
|
{ |
|
|
await Task.CompletedTask.ConfigureAwait(false); |
|
|
return await base.HandleAsync(id).ConfigureAwait(false); |
|
|
return null; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpPost("")] |
|
|
[HttpPost("")] |
|
@ -88,18 +72,21 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
foreach (var detailInput in input.Details) //赋值生产线
|
|
|
foreach (var detailInput in input.Details) |
|
|
{ |
|
|
{ |
|
|
var toLocationDto = |
|
|
var toLocationDto = |
|
|
await _locationAppService.GetByCodeAsync(detailInput.ToLocationCode).ConfigureAwait(false); |
|
|
await _locationAppService.GetByCodeAsync(detailInput.ToLocationCode).ConfigureAwait(false); |
|
|
CheckLocation(toLocationDto, detailInput.ToLocationCode); |
|
|
CheckLocation(toLocationDto, detailInput.ToLocationCode); |
|
|
var itemBasicDto = await _itemBasicAppService.GetByCodeAsync(detailInput.ItemCode).ConfigureAwait(false); |
|
|
var itemBasicDto = await _itemBasicAppService.GetByCodeAsync(detailInput.ItemCode).ConfigureAwait(false); |
|
|
CheckItemBasic(itemBasicDto, detailInput.ItemCode); |
|
|
CheckItemBasic(itemBasicDto, detailInput.ItemCode); |
|
|
|
|
|
var productionLineDto= await _productionLineAppService.GetByLocationCodeAsync(detailInput.ToLocationCode).ConfigureAwait(false); |
|
|
|
|
|
CheckProductionLine(productionLineDto,detailInput.ProdLine); |
|
|
|
|
|
|
|
|
|
|
|
detailInput.ProdLine = productionLineDto.Code; |
|
|
|
|
|
|
|
|
detailInput.ToLocationArea = toLocationDto.AreaCode; |
|
|
detailInput.ToLocationArea = toLocationDto.AreaCode; |
|
|
detailInput.ToLocationGroup = toLocationDto.LocationGroupCode; |
|
|
detailInput.ToLocationGroup = toLocationDto.LocationGroupCode; |
|
|
detailInput.ToWarehouseCode= toLocationDto.WarehouseCode; |
|
|
detailInput.ToWarehouseCode = toLocationDto.WarehouseCode; |
|
|
detailInput.ProdLine = detailInput.ToLocationCode; |
|
|
|
|
|
detailInput.ToLocationErpCode = toLocationDto.ErpLocationCode; |
|
|
detailInput.ToLocationErpCode = toLocationDto.ErpLocationCode; |
|
|
|
|
|
|
|
|
detailInput.ItemDesc1 = itemBasicDto.Desc1; |
|
|
detailInput.ItemDesc1 = itemBasicDto.Desc1; |
|
@ -111,6 +98,7 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
|
|
|
|
|
|
//因为是刚创建的 所以发料数一定是0
|
|
|
//因为是刚创建的 所以发料数一定是0
|
|
|
detailInput.IssuedQty = 0; |
|
|
detailInput.IssuedQty = 0; |
|
|
|
|
|
detailInput.RecommendType = EnumRecommendType.KITTING; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
await SetRequestAutoPropertiesAsync(input).ConfigureAwait(false); |
|
|
await SetRequestAutoPropertiesAsync(input).ConfigureAwait(false); |
|
@ -130,7 +118,8 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
/// <returns></returns>
|
|
|
/// <returns></returns>
|
|
|
private async Task SetRequestAutoPropertiesAsync(KittingIssueRequestEditInput entity) |
|
|
private async Task SetRequestAutoPropertiesAsync(KittingIssueRequestEditInput entity) |
|
|
{ |
|
|
{ |
|
|
var tranType = await _transactionTypeAppService.GetByTransTypeAsync(EnumTransType.Issue, EnumTransSubType.None).ConfigureAwait(false); |
|
|
var tranType = await _transactionTypeAppService.GetByTransTypeAsync(EnumTransType.Issue, EnumTransSubType.None) |
|
|
|
|
|
.ConfigureAwait(false); |
|
|
Check.NotNull(tranType, "事务类型", "事务类型不存在"); |
|
|
Check.NotNull(tranType, "事务类型", "事务类型不存在"); |
|
|
entity.AutoSubmit = tranType.AutoSubmitRequest; |
|
|
entity.AutoSubmit = tranType.AutoSubmitRequest; |
|
|
entity.AutoAgree = tranType.AutoAgreeRequest; |
|
|
entity.AutoAgree = tranType.AutoAgreeRequest; |
|
@ -144,115 +133,108 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
{ |
|
|
{ |
|
|
var kittingIssueRequestDto = await CreateAsync(input).ConfigureAwait(false); |
|
|
var kittingIssueRequestDto = await CreateAsync(input).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
await HandleAsync(kittingIssueRequestDto.Id).ConfigureAwait(false); |
|
|
//await HandleAsync(kittingIssueRequestDto.Id).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
return kittingIssueRequestDto; |
|
|
return kittingIssueRequestDto; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#endregion
|
|
|
[HttpPost("UpdateStatusCompleted")] |
|
|
|
|
|
public async Task UpdateStatusCompletedAsync(string number) |
|
|
#region 导入
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用来重写 导入数据时可以加工数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dictionary"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
protected override async Task<Dictionary<KittingIssueRequest, EntityState>> ImportProcessingEntityAsync( |
|
|
|
|
|
Dictionary<KittingIssueRequest, EntityState> dictionary) |
|
|
|
|
|
{ |
|
|
{ |
|
|
var addList = dictionary.Where(p => p.Value == EntityState.Added).Select(p => p.Key); |
|
|
var kittingIssueRequest=await _repository.FindAsync(p=>p.Number== number).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
foreach (var kittingIssueRequest in addList) |
|
|
var kittingIssueJobDtos=await _kittingIssueJobAppService.GetByRequestNumberAsync(kittingIssueRequest.Number).ConfigureAwait(false); |
|
|
{ |
|
|
|
|
|
kittingIssueRequest.Worker = CurrentUser.GetUserName(); |
|
|
if (!kittingIssueJobDtos.Any(p => |
|
|
kittingIssueRequest.CreatorId = CurrentUser.Id; |
|
|
p.JobStatus == EnumJobStatus.Open || p.JobStatus == EnumJobStatus.Doing || |
|
|
if (kittingIssueRequest.Type == EnumTransSubType.Issue_Manual.GetDisplayName()) |
|
|
p.JobStatus == EnumJobStatus.Partial) ) |
|
|
{ |
|
|
{ |
|
|
kittingIssueRequest.Type = EnumTransSubType.Issue_Manual.ToString(); |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
bool flag = true; |
|
|
|
|
|
|
|
|
foreach (var detail in kittingIssueRequest.Details) |
|
|
foreach (var detail in kittingIssueRequest.Details) |
|
|
{ |
|
|
{ |
|
|
var locationDto = await _locationAppService.GetByCodeAsync(detail.ToLocationCode).ConfigureAwait(false); |
|
|
if (detail.Qty > detail.IssuedQty) |
|
|
CheckLocation(locationDto, detail.ToLocationCode); |
|
|
{ |
|
|
|
|
|
flag = false; |
|
|
var itemBasicDto = await _itemBasicAppService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false); |
|
|
return; |
|
|
CheckItemBasic(itemBasicDto, detail.ItemCode); |
|
|
|
|
|
|
|
|
|
|
|
detail.ToLocationArea = locationDto.AreaCode; |
|
|
|
|
|
detail.ToLocationErpCode = locationDto.ErpLocationCode; |
|
|
|
|
|
detail.ToLocationGroup = locationDto.LocationGroupCode; |
|
|
|
|
|
detail.ToWarehouseCode = locationDto.WarehouseCode; |
|
|
|
|
|
detail.ItemDesc1 = itemBasicDto.Desc1; |
|
|
|
|
|
detail.ItemDesc2 = itemBasicDto.Desc2; |
|
|
|
|
|
detail.ItemName = itemBasicDto.Name; |
|
|
|
|
|
detail.Uom = itemBasicDto.BasicUom; |
|
|
|
|
|
detail.StdPackQty = itemBasicDto.StdPackQty; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return dictionary; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
if (flag) |
|
|
/// 导入验证
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="model"></param>
|
|
|
|
|
|
/// <param name="validationRresult"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
protected override async Task ValidateImportModelAsync(KittingIssueRequestImportInput model, |
|
|
|
|
|
List<ValidationResult> validationRresult) |
|
|
|
|
|
{ |
|
|
{ |
|
|
_ = new Dictionary<string, string>(); |
|
|
CheckStatus(EnumRequestStatus.Completed, kittingIssueRequest.RequestStatus); |
|
|
_ = await CheckItemBasicAsync(model, validationRresult).ConfigureAwait(false); |
|
|
kittingIssueRequest.RequestStatus = EnumRequestStatus.Completed; |
|
|
_ = await CheckLocationAsync(model, validationRresult).ConfigureAwait(false); |
|
|
await _repository.UpdateAsync(kittingIssueRequest).ConfigureAwait(false); |
|
|
await CheckAreaAsync(model, validationRresult).ConfigureAwait(false); |
|
|
} |
|
|
await CheckStoreRelationAsync(model, validationRresult).ConfigureAwait(false); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#endregion
|
|
|
kittingIssueRequest.RequestStatus = EnumRequestStatus.Completed; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#region 校验
|
|
|
#region 校验
|
|
|
|
|
|
|
|
|
protected override async Task<bool> ValidateImportEntities(Dictionary<KittingIssueRequest, EntityState> dict) |
|
|
private void CheckStatus(EnumRequestStatus targetStatus, EnumRequestStatus nowStatus) |
|
|
{ |
|
|
{ |
|
|
foreach (var entity in dict.Keys) |
|
|
var validSourceStatuses = new List<EnumRequestStatus>(); |
|
|
|
|
|
switch (targetStatus) |
|
|
{ |
|
|
{ |
|
|
var tranType = await TransactionTypeAclService |
|
|
case EnumRequestStatus.None: |
|
|
.GetByTransTypeAsync(EnumTransType.Issue, EnumTransSubType.None).ConfigureAwait(false); |
|
|
break; |
|
|
|
|
|
case EnumRequestStatus.New: |
|
|
Check.NotNull(tranType, "事务类型", "事务类型不存在"); |
|
|
break; |
|
|
|
|
|
case EnumRequestStatus.Reviewing: |
|
|
entity.AutoCompleteJob = tranType.AutoCompleteJob; |
|
|
validSourceStatuses = new List<EnumRequestStatus> { EnumRequestStatus.New }; |
|
|
entity.AutoSubmit = tranType.AutoSubmitRequest; |
|
|
break; |
|
|
entity.AutoAgree = tranType.AutoAgreeRequest; |
|
|
case EnumRequestStatus.Refused: |
|
|
entity.AutoHandle = tranType.AutoHandleRequest; |
|
|
validSourceStatuses = new List<EnumRequestStatus> { EnumRequestStatus.Reviewing }; |
|
|
entity.DirectCreateNote = tranType.DirectCreateNote; |
|
|
break; |
|
|
} |
|
|
case EnumRequestStatus.Agreed: |
|
|
|
|
|
validSourceStatuses = new List<EnumRequestStatus> { EnumRequestStatus.Reviewing }; |
|
|
return await base.ValidateImportEntities(dict).ConfigureAwait(false); |
|
|
break; |
|
|
} |
|
|
case EnumRequestStatus.Handling: |
|
|
|
|
|
validSourceStatuses = new List<EnumRequestStatus> |
|
|
protected async Task CheckAreaAsync(KittingIssueRequestImportInput importInput, |
|
|
{ |
|
|
List<ValidationResult> validationRresult) |
|
|
EnumRequestStatus.Agreed, EnumRequestStatus.Partial, |
|
|
|
|
|
}; |
|
|
|
|
|
break; |
|
|
|
|
|
case EnumRequestStatus.Completed: |
|
|
|
|
|
validSourceStatuses = new List<EnumRequestStatus> |
|
|
|
|
|
{ |
|
|
|
|
|
EnumRequestStatus.Handling, EnumRequestStatus.Partial, |
|
|
|
|
|
}; |
|
|
|
|
|
break; |
|
|
|
|
|
case EnumRequestStatus.Cancelled: |
|
|
|
|
|
validSourceStatuses = new List<EnumRequestStatus> |
|
|
|
|
|
{ |
|
|
|
|
|
EnumRequestStatus.New, EnumRequestStatus.Reviewing, EnumRequestStatus.Agreed, |
|
|
|
|
|
}; |
|
|
|
|
|
break; |
|
|
|
|
|
case EnumRequestStatus.Abort: |
|
|
|
|
|
validSourceStatuses = new List<EnumRequestStatus> |
|
|
{ |
|
|
{ |
|
|
var area = await _areaApp.GetByCodeAsync(importInput.FromLocationArea).ConfigureAwait(false); |
|
|
EnumRequestStatus.Handling, EnumRequestStatus.Partial, |
|
|
if (area == null) |
|
|
}; |
|
|
|
|
|
break; |
|
|
|
|
|
case EnumRequestStatus.Partial: |
|
|
{ |
|
|
{ |
|
|
validationRresult.Add(new ValidationResult($"调出库区{importInput.FromLocationArea}不存在", new[] { "调出库区" })); |
|
|
validSourceStatuses = new List<EnumRequestStatus> |
|
|
|
|
|
{ |
|
|
|
|
|
EnumRequestStatus.Handling, EnumRequestStatus.Partial, |
|
|
|
|
|
}; |
|
|
|
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
default: |
|
|
|
|
|
throw new ArgumentOutOfRangeException(nameof(targetStatus), targetStatus, null); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected async Task CheckStoreRelationAsync(KittingIssueRequestImportInput importInput, |
|
|
if (!validSourceStatuses.Contains(nowStatus)) |
|
|
List<ValidationResult> validationRresult) |
|
|
|
|
|
{ |
|
|
|
|
|
var itemStoreRelation = await _itemStoreRelationApp |
|
|
|
|
|
.GetFirstAsync(importInput.ItemCode, importInput.ToLocationCode).ConfigureAwait(false); |
|
|
|
|
|
if (itemStoreRelation == null) |
|
|
|
|
|
{ |
|
|
{ |
|
|
validationRresult.Add(new ValidationResult( |
|
|
throw new UserFriendlyException( |
|
|
$"物品代码{importInput.ItemCode}与目标库位{importInput.ToLocationCode}不存在对应关", new[] { "物品库位对应关系" })); |
|
|
$"当前状态为 {nowStatus.GetDisplayName()} ,无法变更为 {targetStatus.GetDisplayName()}"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -271,39 +253,18 @@ public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase<Kitti |
|
|
throw new UserFriendlyException($"库位代码为【{locationCode}】不存在"); |
|
|
throw new UserFriendlyException($"库位代码为【{locationCode}】不存在"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (locationDto.Type != EnumLocationType.WIP) |
|
|
if (locationDto.Type != EnumLocationType.KittingWip) |
|
|
{ |
|
|
{ |
|
|
throw new UserFriendlyException($"库位代码【{locationCode}】不是【{EnumLocationType.WIP.GetDisplayName()}】类型"); |
|
|
throw new UserFriendlyException($"库位代码【{locationCode}】不是【{EnumLocationType.KittingWip.GetDisplayName()}】类型"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected async Task<ItemBasicDTO> CheckItemBasicAsync(KittingIssueRequestImportInput importInput, |
|
|
private void CheckProductionLine(ProductionLineDTO productionLineDto, string productionCode) |
|
|
List<ValidationResult> validationRresult) |
|
|
|
|
|
{ |
|
|
|
|
|
var item = await _itemBasicAppService.GetByCodeAsync(importInput.ItemCode).ConfigureAwait(false); |
|
|
|
|
|
if (item == null) |
|
|
|
|
|
{ |
|
|
{ |
|
|
validationRresult.Add(new ValidationResult($"物品代码{importInput.ItemCode}不存在", new[] { "物品代码" })); |
|
|
if (productionLineDto == null) |
|
|
} |
|
|
|
|
|
else if (item.StdPackQty == 0) |
|
|
|
|
|
{ |
|
|
{ |
|
|
validationRresult.Add( |
|
|
throw new UserFriendlyException($"未找到生产线【{productionCode}】"); |
|
|
new ValidationResult($"物品代码{importInput.ItemCode}的物品信息中标准包装等于0或不存在", new[] { "标准包装" })); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return item; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected async Task<LocationDTO> CheckLocationAsync(KittingIssueRequestImportInput importInput, |
|
|
|
|
|
List<ValidationResult> validationRresult) |
|
|
|
|
|
{ |
|
|
|
|
|
var location = await _locationAppService.GetByCodeAsync(importInput.ToLocationCode).ConfigureAwait(false); |
|
|
|
|
|
if (location == null) |
|
|
|
|
|
{ |
|
|
|
|
|
validationRresult.Add(new ValidationResult($"目标库位{importInput.ToLocationCode}不存在", new[] { "目标库位" })); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return location; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#endregion
|
|
|
#endregion
|
|
|