31 changed files with 608 additions and 47 deletions
@ -1,16 +0,0 @@ |
|||
<?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>D:\~all-publish\WMS2.0_东阳\Win_in.Sfs.Wms.Store.HttpApi.Host</PublishUrl> |
|||
<WebPublishMethod>FileSystem</WebPublishMethod> |
|||
</PropertyGroup> |
|||
</Project> |
@ -0,0 +1,23 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Win_in.Sfs.Shared.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
[Display(Name = "客户退拆任务")] |
|||
public class ProductRecycleJobDTO : SfsJobDTOBase<ProductRecycleJobDetailDTO> |
|||
{ |
|||
|
|||
/// <summary>
|
|||
/// 车间
|
|||
/// </summary>
|
|||
[Display(Name = "车间")] |
|||
[StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] |
|||
public string Workshop { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 班次
|
|||
/// </summary>
|
|||
[Display(Name = "班次")] |
|||
[StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] |
|||
public string Shift { get; set; } |
|||
} |
@ -0,0 +1,90 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.ComponentModel.DataAnnotations.Schema; |
|||
using Volo.Abp.Data; |
|||
using Win_in.Sfs.Shared.Domain; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class ProductRecycleJobDetailDTO : SfsJobRecommendToDetailDTOBase |
|||
{ |
|||
/// <summary>
|
|||
/// Bom版本
|
|||
/// </summary>
|
|||
public string BomVersion { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 库位代码
|
|||
/// </summary>
|
|||
public string LocationCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 库区
|
|||
/// </summary>
|
|||
public string LocationArea { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 库位组
|
|||
/// </summary>
|
|||
public string LocationGroup { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// ERP库位代码
|
|||
/// </summary>
|
|||
public string LocationErpCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料库位代码
|
|||
/// </summary>
|
|||
public string RawLocationCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料库区
|
|||
/// </summary>
|
|||
public string RawLocationArea { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料库位组
|
|||
/// </summary>
|
|||
public string RawLocationGroup { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料ERP库位
|
|||
/// </summary>
|
|||
public string RawLocationErpCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料仓库
|
|||
/// </summary>
|
|||
public string RawWarehouseCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 计量单位
|
|||
/// </summary>
|
|||
[Display(Name = "计量单位")] |
|||
[MaxLength(SfsPropertyConst.CodeLength)] |
|||
public string Uom { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 数量
|
|||
/// </summary>
|
|||
[Display(Name = "数量")] |
|||
[Column(TypeName = "decimal(18,6)")] |
|||
public decimal Qty { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 扩展属性
|
|||
/// </summary>
|
|||
public ExtraPropertyDictionary ExtraProperties { get; } = new ExtraPropertyDictionary(); |
|||
|
|||
/// <summary>
|
|||
/// 库存状态
|
|||
/// </summary>
|
|||
public EnumInventoryStatus Status { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 仓库代码
|
|||
/// </summary>
|
|||
public string WarehouseCode { get; set; } |
|||
|
|||
} |
@ -0,0 +1,10 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public interface IProductRecycleJobAppService |
|||
: ISfsJobAppServiceBase<ProductRecycleJobDTO, SfsJobRequestInputBase, ProductRecycleJobCheckInput, ProductRecycleJobEditInput> |
|||
|
|||
{ |
|||
|
|||
} |
@ -0,0 +1,6 @@ |
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class ProductRecycleJobCheckInput : SfsJobCheckInputBase |
|||
{ |
|||
|
|||
} |
@ -0,0 +1,90 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.ComponentModel.DataAnnotations.Schema; |
|||
using Volo.Abp.Data; |
|||
using Win_in.Sfs.Shared.Domain; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class ProductRecycleJobDetailInput : SfsJobRecommendToDetailInputBase |
|||
{ |
|||
/// <summary>
|
|||
/// Bom版本
|
|||
/// </summary>
|
|||
public string BomVersion { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 库位代码
|
|||
/// </summary>
|
|||
public string LocationCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 库区
|
|||
/// </summary>
|
|||
public string LocationArea { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 库位组
|
|||
/// </summary>
|
|||
public string LocationGroup { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// ERP库位代码
|
|||
/// </summary>
|
|||
public string LocationErpCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料库位代码
|
|||
/// </summary>
|
|||
public string RawLocationCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料库区
|
|||
/// </summary>
|
|||
public string RawLocationArea { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料库位组
|
|||
/// </summary>
|
|||
public string RawLocationGroup { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料ERP库位
|
|||
/// </summary>
|
|||
public string RawLocationErpCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 原料仓库
|
|||
/// </summary>
|
|||
public string RawWarehouseCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 计量单位
|
|||
/// </summary>
|
|||
[Display(Name = "计量单位")] |
|||
[MaxLength(SfsPropertyConst.CodeLength)] |
|||
public string Uom { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 数量
|
|||
/// </summary>
|
|||
[Display(Name = "数量")] |
|||
[Column(TypeName = "decimal(18,6)")] |
|||
public decimal Qty { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 扩展属性
|
|||
/// </summary>
|
|||
public ExtraPropertyDictionary ExtraProperties { get; } = new ExtraPropertyDictionary(); |
|||
|
|||
/// <summary>
|
|||
/// 库存状态
|
|||
/// </summary>
|
|||
public EnumInventoryStatus Status { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 仓库代码
|
|||
/// </summary>
|
|||
public string WarehouseCode { get; set; } |
|||
|
|||
} |
@ -0,0 +1,43 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Win_in.Sfs.FileStorage.Application.Contracts; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
/// <summary>
|
|||
/// 客户退拆 保存模型
|
|||
/// </summary>
|
|||
public class ProductRecycleJobDetailSaveInput |
|||
{ |
|||
/// <summary>
|
|||
/// Id
|
|||
/// </summary>
|
|||
[Display(Name = "Id")] |
|||
public Guid Id { get; set; } |
|||
/// <summary>
|
|||
/// 详情ID
|
|||
/// </summary>
|
|||
[Display(Name = "详情ID")] |
|||
public Guid DetailId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 不合格原因
|
|||
/// </summary>
|
|||
[Display(Name = "不合格原因")] |
|||
public string FailedReason { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 质量缺陷
|
|||
/// </summary>
|
|||
[Display(Name = "质量缺陷")] |
|||
public string MassDefect { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 图片字节流
|
|||
/// </summary>
|
|||
[Display(Name = "图片字节流")] |
|||
public List<FileDTO> FilesList { get; set; } |
|||
} |
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Win_in.Sfs.Shared.Domain; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Application.Contracts; |
|||
|
|||
public class ProductRecycleJobEditInput : SfsJobCreateUpdateInputBase, ISfsJobCreateInput<ProductRecycleJobDetailInput> |
|||
{ |
|||
#region Create
|
|||
|
|||
/// <summary>
|
|||
/// 上游任务编号
|
|||
/// </summary>
|
|||
[Display(Name = "上游任务编号")] |
|||
[StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] |
|||
public string UpStreamJobNumber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 任务类型
|
|||
/// </summary>
|
|||
[Display(Name = "任务类型")] |
|||
[Required(ErrorMessage = "{0}是必填项")] |
|||
public EnumJobType JobType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否自动完成
|
|||
/// </summary>
|
|||
[Display(Name = "是否自动完成")] |
|||
[Required(ErrorMessage = "{0}是必填项")] |
|||
public bool IsAutoComplete { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 过期时间
|
|||
/// </summary>
|
|||
[Display(Name = "过期时间")] |
|||
[Required(ErrorMessage = "{0}是必填项")] |
|||
public DateTime ExpiredTime { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 任务明细
|
|||
/// </summary>
|
|||
[Display(Name = "任务明细")] |
|||
[Required(ErrorMessage = "{0}是必填项")] |
|||
public List<ProductRecycleJobDetailInput> Details { get; set; } |
|||
#endregion
|
|||
} |
@ -0,0 +1,28 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
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; |
|||
|
|||
[Authorize] |
|||
[Route($"{StoreConsts.RootPath}production-recycle-job")] |
|||
|
|||
public class ProductRecycleJobAppService |
|||
: SfsJobAppServiceBase<ProductRecycleJob, ProductRecycleJobDetail, ProductRecycleJobDTO, SfsJobRequestInputBase, ProductRecycleJobCheckInput, ProductRecycleJobEditInput> |
|||
, IProductRecycleJobAppService |
|||
{ |
|||
private readonly IProductRecycleJobManager _productRecycleJobManager; |
|||
|
|||
public ProductRecycleJobAppService( |
|||
IProductRecycleJobRepository repository, IProductRecycleJobManager productRecycleJobManager) |
|||
: base(repository, productRecycleJobManager) |
|||
{ |
|||
_productRecycleJobManager = productRecycleJobManager; |
|||
} |
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,31 @@ |
|||
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 ProductRecycleJobAutoMapperProfile() |
|||
{ |
|||
CreateMap<ProductRecycleJob, ProductRecycleJobDTO>() |
|||
.ReverseMap(); |
|||
|
|||
CreateMap<ProductRecycleJobDetail, ProductRecycleJobDetailDTO>() |
|||
; |
|||
|
|||
CreateMap<ProductRecycleJobEditInput, ProductRecycleJob>(); |
|||
|
|||
CreateMap<ProductRecycleJobDetailInput, ProductRecycleJobDetail>() |
|||
.IgnoreAuditedObjectProperties() |
|||
.Ignore(x => x.MasterID) |
|||
.Ignore(x => x.TenantId) |
|||
.Ignore(x => x.Number) |
|||
.Ignore(x => x.Id); |
|||
|
|||
CreateMap<ProductRecycleJobDetailDTO, ProductRecycleJobDetail>() |
|||
; |
|||
|
|||
} |
|||
} |
@ -1,10 +1,61 @@ |
|||
using System; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Linq.Expressions; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Users; |
|||
using Volo.Abp.Validation; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Jobs.ProductRecycleJobs; |
|||
internal class ProductRecycleJobManager |
|||
namespace Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
public class ProductRecycleJobManager : SfsJobManagerBase<ProductRecycleJob, ProductRecycleJobDetail>, IProductRecycleJobManager |
|||
{ |
|||
|
|||
public ProductRecycleJobManager( |
|||
IProductRecycleJobRepository repository |
|||
) : base(repository) |
|||
{ |
|||
} |
|||
|
|||
public override void CheckDetails(ProductRecycleJob entity, AbpValidationResult result) |
|||
{ |
|||
var details = entity.Details; |
|||
foreach (var detail in details) |
|||
{ |
|||
if (detail.HandledToLocationCode == null) |
|||
{ |
|||
result.Errors.Add(new ValidationResult($"{detail.HandledToLocationCode} 不能为空")); |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
public override async Task<List<ProductRecycleJob>> GetWorkingListByPackingAsync(string packingCode) |
|||
{ |
|||
return await Repository.GetListAsync( |
|||
c => c.Details.Any(p => p.RecommendPackingCode == packingCode) |
|||
&& c.JobStatus != EnumJobStatus.Closed |
|||
&& c.JobStatus != EnumJobStatus.Cancelled |
|||
, true).ConfigureAwait(false); |
|||
|
|||
} |
|||
|
|||
public override async Task<List<ProductRecycleJob>> GetWorkingListByContainerAsync(string containerCode) |
|||
{ |
|||
return await Repository.GetListAsync( |
|||
c => c.Details.Any(p => p.RecommendContainerCode == containerCode) |
|||
&& c.JobStatus != EnumJobStatus.Closed |
|||
&& c.JobStatus != EnumJobStatus.Cancelled |
|||
, true).ConfigureAwait(false); |
|||
|
|||
} |
|||
|
|||
public async Task<ProductRecycleJob> GetAsync(Expression<Func<ProductRecycleJob, bool>> expression) |
|||
{ |
|||
return await Repository.FindAsync(expression).ConfigureAwait(false); |
|||
} |
|||
|
|||
} |
|||
|
@ -0,0 +1,52 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore.Modeling; |
|||
using Win_in.Sfs.Shared.Domain.Shared; |
|||
using Win_in.Sfs.Shared.EntityFrameworkCore; |
|||
using Win_in.Sfs.Wms.Store.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.EntityFrameworkCore; |
|||
|
|||
public static class ProductRecycleJobDbContextModelCreatingExtensions |
|||
{ |
|||
public static void ConfigureProductRecycleJob(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options) |
|||
{ |
|||
builder.Entity<ProductRecycleJob>(b => |
|||
{ |
|||
//Configure table & schema name
|
|||
b.ToTable(StoreDbProperties.JobDbTablePrefix + nameof(ProductRecycleJob), options.Schema); |
|||
//Configure ABP properties
|
|||
b.ConfigureByConvention(); |
|||
//Configure Sfs base properties
|
|||
b.ConfigureSfsBase(); |
|||
//Configure Job base properties
|
|||
b.ConfigureJob<ProductRecycleJob, ProductRecycleJobDetail>(); |
|||
//Properties
|
|||
b.Property(q => q.Workshop).IsRequired().HasMaxLength(SfsPropertyConst.CodeLength); |
|||
b.Property(q => q.Shift).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<ProductRecycleJobDetail>(b => |
|||
{ |
|||
//Configure table & schema name
|
|||
b.ToTable(StoreDbProperties.JobDbTablePrefix + nameof(ProductRecycleJobDetail), options.Schema); |
|||
//Configure ABP properties
|
|||
b.ConfigureByConvention(); |
|||
//Configure Sfs base properties
|
|||
b.ConfigureSfsBase(); |
|||
//Configure Job base properties
|
|||
b.ConfigureJobRecommendToDetail(); |
|||
//Properties
|
|||
|
|||
|
|||
//Relations
|
|||
//None
|
|||
|
|||
//Indexes
|
|||
//b.HasIndex(q => new { q.PackingCode }).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 ProductRecycleJobEfCoreRepository : SfsJobEfCoreRepositoryBase<StoreDbContext, ProductRecycleJob>, IProductRecycleJobRepository |
|||
{ |
|||
public ProductRecycleJobEfCoreRepository(IDbContextProvider<StoreDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
} |
@ -0,0 +1,75 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.EventBus; |
|||
using Volo.Abp.Uow; |
|||
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.Domain; |
|||
|
|||
namespace Win_in.Sfs.Wms.Store.Event.BusinessJob; |
|||
|
|||
|
|||
public class ProductionRecycleJobEventHandler : |
|||
StoreEventHandlerBase |
|||
, ILocalEventHandler<SfsCreatedEntityEventData<ProductRecycleJob>> |
|||
, ILocalEventHandler<SfsCompletedEntityEventData<ProductRecycleJob>> |
|||
{ |
|||
private readonly IProductRecycleNoteAppService _productRecycleNoteAppService; |
|||
|
|||
public ProductionRecycleJobEventHandler( |
|||
IProductRecycleNoteAppService productRecycleNoteAppService |
|||
) |
|||
{ |
|||
_productRecycleNoteAppService = productRecycleNoteAppService; |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public virtual async Task HandleEventAsync(SfsCreatedEntityEventData<ProductRecycleJob> eventData) |
|||
{ |
|||
var entity = eventData.Entity; |
|||
|
|||
if (entity.IsAutoComplete) |
|||
{ |
|||
entity.CompleteTime = Clock.Now; |
|||
entity.JobStatus = EnumJobStatus.Done; |
|||
|
|||
foreach (var detail in eventData.Entity.Details) |
|||
{ |
|||
detail.SetHandledFromRecommend(); |
|||
} |
|||
|
|||
var note = BuildProductionReturnNote(entity); |
|||
await _productRecycleNoteAppService.CreateAsync(note).ConfigureAwait(false); |
|||
} |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public virtual async Task HandleEventAsync(SfsCompletedEntityEventData<ProductRecycleJob> eventData) |
|||
{ |
|||
var entity = eventData.Entity; |
|||
|
|||
var productRecycleNote = BuildProductionReturnNote(entity); |
|||
await _productRecycleNoteAppService.CreateAsync(productRecycleNote).ConfigureAwait(false); |
|||
|
|||
} |
|||
|
|||
private ProductRecycleNoteEditInput BuildProductionReturnNote(ProductRecycleJob entity) |
|||
{ |
|||
var input = ObjectMapper.Map<ProductRecycleJob, ProductRecycleNoteEditInput>(entity); |
|||
|
|||
|
|||
input.Details = new List<ProductRecycleNoteDetailInput>(); |
|||
|
|||
foreach (var detail in entity.Details.Where(detail => detail.HandledQty != 0)) |
|||
{ |
|||
var inputDetail = ObjectMapper.Map<ProductRecycleJobDetail, ProductRecycleNoteDetailInput>(detail); |
|||
|
|||
input.Details.Add(inputDetail); |
|||
} |
|||
|
|||
return input; |
|||
} |
|||
} |
Loading…
Reference in new issue