24 changed files with 550 additions and 31 deletions
@ -0,0 +1,17 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- |
|||
https://go.microsoft.com/fwlink/?LinkID=208121. |
|||
--> |
|||
<Project> |
|||
<PropertyGroup> |
|||
<DeleteExistingFiles>false</DeleteExistingFiles> |
|||
<ExcludeApp_Data>false</ExcludeApp_Data> |
|||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish> |
|||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> |
|||
<LastUsedPlatform>Any CPU</LastUsedPlatform> |
|||
<PublishProvider>FileSystem</PublishProvider> |
|||
<PublishUrl>bin\Release\net6.0\publish\</PublishUrl> |
|||
<WebPublishMethod>FileSystem</WebPublishMethod> |
|||
<_TargetId>Folder</_TargetId> |
|||
</PropertyGroup> |
|||
</Project> |
@ -0,0 +1,17 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- |
|||
https://go.microsoft.com/fwlink/?LinkID=208121. |
|||
--> |
|||
<Project> |
|||
<PropertyGroup> |
|||
<DeleteExistingFiles>false</DeleteExistingFiles> |
|||
<ExcludeApp_Data>false</ExcludeApp_Data> |
|||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish> |
|||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> |
|||
<LastUsedPlatform>Any CPU</LastUsedPlatform> |
|||
<PublishProvider>FileSystem</PublishProvider> |
|||
<PublishUrl>bin\Release\net6.0\publish\</PublishUrl> |
|||
<WebPublishMethod>FileSystem</WebPublishMethod> |
|||
<_TargetId>Folder</_TargetId> |
|||
</PropertyGroup> |
|||
</Project> |
@ -0,0 +1,26 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class MesNoteDTO : SfsStoreDTOBase<MesNoteDetailDTO>, IHasNumber |
|||
{ |
|||
|
|||
/// <summary>
|
|||
/// 任务ID
|
|||
/// </summary>
|
|||
[Display(Name = "任务ID")] |
|||
public string JobNumber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 报废类型
|
|||
/// </summary>
|
|||
[Display(Name = "报废类型")] |
|||
public string Type { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 报废请求单号
|
|||
/// </summary>
|
|||
[Display(Name = "报废请求单号")] |
|||
public string ScrapRequestNumber { get; set; } |
|||
|
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class MesNoteDetailDTO : SfsStoreDetailWithFromToDTOBase |
|||
{ |
|||
/// <summary>
|
|||
/// 原因代码
|
|||
/// </summary>
|
|||
[Display(Name = "原因代码")] |
|||
public string ReasonCode { get; set; } |
|||
|
|||
} |
@ -0,0 +1,17 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
using System.Threading; |
|||
|
|||
public interface IMesNoteAppService : ISfsStoreMasterReadOnlyAppServiceBase<MesNoteDTO, SfsStoreRequestInputBase, MesNoteDetailDTO, SfsStoreRequestInputBase> |
|||
{ |
|||
Task<MesNoteDTO> CreateAsync(MesNoteEditInput input); |
|||
|
|||
Task<PagedResultDto<MesNoteDTO>> GetListByTypeAsync( |
|||
SfsStoreRequestInputBase requestInput, |
|||
string type, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default); |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class MesNoteDetailInput : SfsStoreDetailWithFromToInputBase |
|||
{ |
|||
/// <summary>
|
|||
/// 原因代码
|
|||
/// </summary>
|
|||
[Display(Name = "原因代码")] |
|||
public string ReasonCode { get; set; } |
|||
|
|||
} |
@ -0,0 +1,41 @@ |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Win_in.Sfs.Shared.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class MesNoteEditInput : SfsStoreCreateOrUpdateInputBase |
|||
{ |
|||
#region Create
|
|||
/// <summary>
|
|||
/// 任务ID
|
|||
/// </summary>
|
|||
[Display(Name = "任务ID")] |
|||
public string JobNumber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 报废记录号
|
|||
/// </summary>
|
|||
[Display(Name = "报废记录号")] |
|||
[StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] |
|||
public string Number { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 报废请求单号
|
|||
/// </summary>
|
|||
[Display(Name = "报废请求单号")] |
|||
public string ScrapRequestNumber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 报废类型
|
|||
/// </summary>
|
|||
[Display(Name = "报废类型")] |
|||
public string Type { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 明细列表
|
|||
/// </summary>
|
|||
[Display(Name = "明细列表")] |
|||
public List<MesNoteDetailInput> Details { get; set; } |
|||
#endregion
|
|||
} |
@ -0,0 +1,20 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class MesNoteImportInput : SfsStoreImportInputBase |
|||
{ |
|||
|
|||
/// <summary>
|
|||
/// 任务ID
|
|||
/// </summary>
|
|||
[Display(Name = "任务ID")] |
|||
public string JobNumber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 报废请求单号
|
|||
/// </summary>
|
|||
[Display(Name = "报废请求单号")] |
|||
public string ScrapRequestNumber { get; set; } |
|||
|
|||
} |
@ -0,0 +1,30 @@ |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public static class MesNotePermissions |
|||
{ |
|||
|
|||
public const string Default = StorePermissions.GroupName + "." + nameof(MesNote); |
|||
public const string Create = Default + "." + StorePermissions.CreateStr; |
|||
public const string Update = Default + "." + StorePermissions.UpdateStr; |
|||
public const string Delete = Default + "." + StorePermissions.DeleteStr; |
|||
|
|||
//完工收货报废记录
|
|||
public const string ProductScrapNote = StorePermissions.GroupName + "." + nameof(ProductScrapNote); |
|||
//线边报废记录
|
|||
public const string WipScrapNote = StorePermissions.GroupName + "." + nameof(WipScrapNote); |
|||
|
|||
public static void AddMesNotePermission(this PermissionGroupDefinition permissionGroup) |
|||
{ |
|||
var scrapNotePermission = permissionGroup.AddPermission(Default, StorePermissionDefinitionProvider.L(nameof(MesNote))); |
|||
scrapNotePermission.AddChild(Create, StorePermissionDefinitionProvider.L(StorePermissions.CreateStr)); |
|||
scrapNotePermission.AddChild(Update, StorePermissionDefinitionProvider.L(StorePermissions.UpdateStr)); |
|||
scrapNotePermission.AddChild(Delete, StorePermissionDefinitionProvider.L(StorePermissions.DeleteStr)); |
|||
|
|||
permissionGroup.AddPermission(ProductScrapNote, StorePermissionDefinitionProvider.L(nameof(ProductScrapNote))); |
|||
permissionGroup.AddPermission(WipScrapNote, StorePermissionDefinitionProvider.L(nameof(WipScrapNote))); |
|||
|
|||
} |
|||
} |
@ -0,0 +1,134 @@ |
|||
using System; |
|||
using System.Linq.Expressions; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using DocumentFormat.OpenXml.Bibliography; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.EventBus; |
|||
using Win_in.Sfs.Basedata.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; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application; |
|||
|
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using IdentityModel; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.ObjectMapping; |
|||
using Win_in.Sfs.Shared.Domain; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
using Win_in.Sfs.Shared.Event; |
|||
using Win_in.Sfs.Wms.Inventory.Application.Contracts; |
|||
|
|||
[Authorize] |
|||
[Route($"{StoreConsts.RootPath}mes-note")] |
|||
public class MesNoteAppService : |
|||
SfsStoreWithDetailsAppServiceBase<MesNote, MesNoteDTO, SfsStoreRequestInputBase, MesNoteEditInput, |
|||
MesNoteDetail, MesNoteDetailDTO, SfsStoreRequestInputBase, MesNoteImportInput>, |
|||
IMesNoteAppService |
|||
{ |
|||
private readonly ILocationAppService _locationAppService; |
|||
private readonly IItemBasicAppService _itemBasicAppService; |
|||
private readonly IBalanceAppService _balanceAppService; |
|||
public MesNoteAppService( |
|||
IMesNoteRepository repository, ILocationAppService locationAppService, IItemBasicAppService itemBasicAppService,IBalanceAppService balanceAppService) : base(repository) |
|||
{ |
|||
_locationAppService = locationAppService; |
|||
_itemBasicAppService = itemBasicAppService; |
|||
_balanceAppService = balanceAppService; |
|||
} |
|||
|
|||
[HttpPost("")] |
|||
public override async Task<MesNoteDTO> CreateAsync(MesNoteEditInput input) |
|||
{ |
|||
var entity = ObjectMapper.Map<MesNoteEditInput, MesNote>(input); |
|||
|
|||
var number = string.IsNullOrEmpty(entity.Number) ? await GenerateNumberAsync(nameof(MesNote), entity.ActiveDate).ConfigureAwait(false) : entity.Number; |
|||
entity.SetIdAndNumberWithDetails(GuidGenerator, number); |
|||
|
|||
foreach (var detail in entity.Details) |
|||
{ |
|||
var fromLocation=await _locationAppService.GetByCodeAsync(detail.FromLocationCode).ConfigureAwait(false); |
|||
var toLocation =await _locationAppService.GetByCodeAsync(detail.ToLocationCode).ConfigureAwait(false); |
|||
var itemBasicDto =await _itemBasicAppService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false); |
|||
|
|||
detail.SetIdAndNumber(GuidGenerator, entity.Id, entity.Number); |
|||
detail.FromLocationArea = fromLocation.AreaCode; |
|||
detail.FromLocationErpCode = fromLocation.ErpLocationCode; |
|||
detail.FromLocationGroup = fromLocation.LocationGroupCode; |
|||
detail.FromWarehouseCode = fromLocation.WarehouseCode; |
|||
detail.ToLocationArea = toLocation.AreaCode; |
|||
detail.ToLocationErpCode = toLocation.ErpLocationCode; |
|||
detail.ToLocationGroup = toLocation.LocationGroupCode; |
|||
detail.ToWarehouseCode = toLocation.WarehouseCode; |
|||
detail.ToStatus = detail.FromStatus; |
|||
detail.Uom = itemBasicDto.BasicUom; |
|||
detail.StdPackQty = itemBasicDto.StdPackQty; |
|||
|
|||
#region 添加校验
|
|||
|
|||
RecommendBalanceRequestInput rInput = new RecommendBalanceRequestInput(); |
|||
rInput.ItemCode = detail.ItemCode; |
|||
rInput.Locations = new List<string>() { detail.FromLocationCode }; |
|||
rInput.Qty = detail.Qty; |
|||
rInput.Statuses = new List<EnumInventoryStatus> { EnumInventoryStatus.OK }; |
|||
var balanceLst = await _balanceAppService.GetRecommendBalancesByLocationsAsync(rInput).ConfigureAwait(false); |
|||
|
|||
var first = balanceLst.FirstOrDefault(); |
|||
if (first != null) |
|||
{ |
|||
if (detail.Qty > first.Qty) |
|||
{ } |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} |
|||
else |
|||
{ |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
#endregion
|
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
entity = await _repository.InsertAsync(entity).ConfigureAwait(false); |
|||
await LocalEventBus.PublishAsync(new SfsCreatedEntityEventData<MesNote>(entity), false).ConfigureAwait(false); |
|||
|
|||
var dto = ObjectMapper.Map<MesNote, MesNoteDTO>(entity); |
|||
return dto; |
|||
} |
|||
|
|||
[HttpPost("by-type/{type}")] |
|||
public virtual async Task<PagedResultDto<MesNoteDTO>> GetListByTypeAsync( |
|||
SfsStoreRequestInputBase requestInput, |
|||
string type, |
|||
bool includeDetails = false, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
Expression<Func<MesNote, bool>> expression = p => p.Type == type; |
|||
if (requestInput.Condition.Filters?.Count > 0) |
|||
{ |
|||
expression = expression.And(requestInput.Condition.Filters.ToLambda<MesNote>()); |
|||
} |
|||
|
|||
return await GetPagedListAsync(expression, requestInput.SkipCount, requestInput.MaxResultCount, |
|||
requestInput.Sorting, includeDetails, cancellationToken).ConfigureAwait(false); |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
using AutoMapper; |
|||
using Volo.Abp.AutoMapper; |
|||
using Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
using Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application; |
|||
|
|||
public partial class StoreApplicationAutoMapperProfile : Profile |
|||
{ |
|||
private void MesNoteAutoMapperProfile() |
|||
{ |
|||
CreateMap<MesNote, MesNoteDTO>() |
|||
.ReverseMap(); |
|||
|
|||
CreateMap<MesNoteDetail, MesNoteDetailDTO>(); |
|||
|
|||
CreateMap<MesNoteDetailInput, MesNoteDetail>() |
|||
.IgnoreAuditedObjectProperties() |
|||
.Ignore(x => x.MasterID) |
|||
.Ignore(x => x.TenantId) |
|||
.Ignore(x => x.Number) |
|||
.Ignore(x => x.Id); |
|||
|
|||
CreateMap<MesNoteEditInput, MesNote>() |
|||
.IgnoreAuditedObjectProperties() |
|||
.Ignore(x => x.TenantId) |
|||
.Ignore(x => x.Number) |
|||
.Ignore(x => x.Id); |
|||
; |
|||
CreateMap<MesNoteDetailInput, MesNoteDetail>() |
|||
.IgnoreAuditedObjectProperties() |
|||
.Ignore(x => x.MasterID) |
|||
.Ignore(x => x.TenantId) |
|||
.Ignore(x => x.Number) |
|||
.Ignore(x => x.Id); |
|||
; |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
namespace Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
public interface IMesNoteManager : ISfsStoreManager<MesNote, MesNoteDetail> |
|||
{ |
|||
} |
@ -0,0 +1,6 @@ |
|||
namespace Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
public interface IMesNoteRepository : ISfsStoreRepositoryBase<MesNote> |
|||
{ |
|||
|
|||
} |
@ -0,0 +1,34 @@ |
|||
using System.Collections.Generic; |
|||
using Win_in.Sfs.Shared.Domain.Entities; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
/// <summary>
|
|||
/// 报废记录
|
|||
/// </summary>
|
|||
public class MesNote : SfsStoreAggregateRootBase<MesNoteDetail>, IHasJobNumber |
|||
{ |
|||
/// <summary>
|
|||
/// 任务ID
|
|||
/// </summary>
|
|||
[IgnoreUpdate] |
|||
public string JobNumber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 报废请求单号
|
|||
/// </summary>
|
|||
[IgnoreUpdate] |
|||
public string ScrapRequestNumber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Mes类型
|
|||
/// </summary>
|
|||
[IgnoreUpdate] |
|||
public string Type { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 明细列表
|
|||
/// </summary>
|
|||
[IgnoreUpdate] |
|||
public override List<MesNoteDetail> Details { get; set; } = new List<MesNoteDetail>(); |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
public class MesNoteDetail : SfsStoreDetailWithFromToEntityBase |
|||
{ |
|||
/// <summary>
|
|||
/// 原因代码
|
|||
/// </summary>
|
|||
[Display(Name = "原因代码")] |
|||
public string ReasonCode { get; set; } |
|||
|
|||
} |
@ -0,0 +1,14 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
public class MesNoteManager : SfsStoreManagerBase<MesNote, MesNoteDetail>, IMesNoteManager |
|||
{ |
|||
|
|||
public MesNoteManager( |
|||
IMesNoteRepository repository |
|||
) : base(repository) |
|||
{ |
|||
|
|||
} |
|||
} |
@ -0,0 +1,65 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore.Modeling; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
using Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.EntityFrameworkCore; |
|||
|
|||
public static class MesNoteDbContextModelCreatingExtensions |
|||
{ |
|||
public static void ConfigureMesNote(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options) |
|||
{ |
|||
builder.Entity<MesNote>(b => |
|||
{ |
|||
//Configure table & schema name
|
|||
b.ToTable(options.TablePrefix + nameof(MesNote), options.Schema); |
|||
//Configure ABP properties
|
|||
b.ConfigureByConvention(); |
|||
//Configure Sfs base properties
|
|||
b.ConfigureSfsStoreBase(); |
|||
|
|||
//Properties
|
|||
b.Property(q => q.Type).HasMaxLength(SfsPropertyConst.CodeLength); |
|||
b.Property(q => q.ScrapRequestNumber).HasMaxLength(SfsPropertyConst.CodeLength); |
|||
//Relations
|
|||
b.HasMany(q => q.Details).WithOne().HasForeignKey(d => d.MasterID).IsRequired(); |
|||
|
|||
//Indexes
|
|||
b.HasIndex(q => new { q.Number }).IsUnique(); |
|||
}); |
|||
|
|||
builder.Entity<MesNoteDetail>(b => |
|||
{ |
|||
//Configure table & schema name
|
|||
b.ToTable(options.TablePrefix + nameof(MesNoteDetail), options.Schema); |
|||
//Configure ABP properties
|
|||
b.ConfigureByConvention(); |
|||
//Configure Sfs base properties
|
|||
b.ConfigureSfsStoreBase(); |
|||
//Configure Sfs store detail properties
|
|||
b.ConfigureSfsStoreDetailBase(); |
|||
|
|||
//Properties
|
|||
b.Property(q => q.ReasonCode).HasMaxLength(SfsPropertyConst.CodeLength); |
|||
b.Property(q => q.FromStatus).HasMaxLength(SfsPropertyConst.NameLength).HasConversion<string>(); |
|||
b.Property(q => q.ToStatus).HasMaxLength(SfsPropertyConst.NameLength).HasConversion<string>(); |
|||
b.Property(q => q.FromPackingCode).HasMaxLength(SfsPropertyConst.CodeLength); |
|||
b.Property(q => q.FromLocationCode).HasMaxLength(SfsPropertyConst.CodeLength); |
|||
|
|||
//Relations
|
|||
|
|||
//Indexes
|
|||
b.HasIndex( |
|||
q => new |
|||
{ |
|||
q.Number, |
|||
q.ItemCode, |
|||
q.FromPackingCode, |
|||
q.FromLocationCode, |
|||
q.ToLocationCode, |
|||
q.FromLot, |
|||
q.FromStatus |
|||
}).IsUnique(); |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.EntityFrameworkCore; |
|||
|
|||
public class MesNoteEfCoreRepository : SfsStoreEfCoreRepositoryBase<StoreDbContext, MesNote>, IMesNoteRepository |
|||
{ |
|||
public MesNoteEfCoreRepository(IDbContextProvider<StoreDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
} |
Loading…
Reference in new issue