diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDTO.cs index c0a16a64c..12e3f745f 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDTO.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDTO.cs @@ -3,7 +3,21 @@ using Win_in.Sfs.Shared.Domain; namespace Win_in.Sfs.Wms.Store.Application.Contracts; -public class ProductRecycleJobDTO -{ +[Display(Name = "客户退拆任务")] +public class ProductRecycleJobDTO : SfsJobDTOBase +{ + /// + /// 车间 + /// + [Display(Name = "车间")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Workshop { get; set; } + + /// + /// 班次 + /// + [Display(Name = "班次")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Shift { get; set; } } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDetailDTO.cs index 7edbbb44b..32f7be931 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDetailDTO.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/DTOs/ProductRecycleJobDetailDTO.cs @@ -1,9 +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 +public class ProductRecycleJobDetailDTO : SfsJobRecommendToDetailDTOBase { + /// + /// Bom版本 + /// + public string BomVersion { get; set; } + + /// + /// 库位代码 + /// + public string LocationCode { get; set; } + + /// + /// 库区 + /// + public string LocationArea { get; set; } + + /// + /// 库位组 + /// + public string LocationGroup { get; set; } + + /// + /// ERP库位代码 + /// + public string LocationErpCode { get; set; } + + /// + /// 原料库位代码 + /// + public string RawLocationCode { get; set; } + + /// + /// 原料库区 + /// + public string RawLocationArea { get; set; } + + /// + /// 原料库位组 + /// + public string RawLocationGroup { get; set; } + + /// + /// 原料ERP库位 + /// + public string RawLocationErpCode { get; set; } + + /// + /// 原料仓库 + /// + public string RawWarehouseCode { get; set; } + + /// + /// 计量单位 + /// + [Display(Name = "计量单位")] + [MaxLength(SfsPropertyConst.CodeLength)] + public string Uom { get; set; } + + /// + /// 数量 + /// + [Display(Name = "数量")] + [Column(TypeName = "decimal(18,6)")] + public decimal Qty { get; set; } + + /// + /// 扩展属性 + /// + public ExtraPropertyDictionary ExtraProperties { get; } = new ExtraPropertyDictionary(); + + /// + /// 库存状态 + /// + public EnumInventoryStatus Status { get; set; } + + /// + /// 仓库代码 + /// + public string WarehouseCode { get; set; } } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/IProductRecycleJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/IProductRecycleJobAppService.cs index c5f53458a..c68fa097a 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/IProductRecycleJobAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/IProductRecycleJobAppService.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; namespace Win_in.Sfs.Wms.Store.Application.Contracts; public interface IProductRecycleJobAppService - : ISfsJobAppServiceBase + : ISfsJobAppServiceBase { diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobCheckInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobCheckInput.cs new file mode 100644 index 000000000..4dc7816e5 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobCheckInput.cs @@ -0,0 +1,6 @@ +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ProductRecycleJobCheckInput : SfsJobCheckInputBase +{ + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobDetailInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobDetailInput.cs new file mode 100644 index 000000000..696e2b713 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobDetailInput.cs @@ -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 +{ + /// + /// Bom版本 + /// + public string BomVersion { get; set; } + + /// + /// 库位代码 + /// + public string LocationCode { get; set; } + + /// + /// 库区 + /// + public string LocationArea { get; set; } + + /// + /// 库位组 + /// + public string LocationGroup { get; set; } + + /// + /// ERP库位代码 + /// + public string LocationErpCode { get; set; } + + /// + /// 原料库位代码 + /// + public string RawLocationCode { get; set; } + + /// + /// 原料库区 + /// + public string RawLocationArea { get; set; } + + /// + /// 原料库位组 + /// + public string RawLocationGroup { get; set; } + + /// + /// 原料ERP库位 + /// + public string RawLocationErpCode { get; set; } + + /// + /// 原料仓库 + /// + public string RawWarehouseCode { get; set; } + + /// + /// 计量单位 + /// + [Display(Name = "计量单位")] + [MaxLength(SfsPropertyConst.CodeLength)] + public string Uom { get; set; } + + /// + /// 数量 + /// + [Display(Name = "数量")] + [Column(TypeName = "decimal(18,6)")] + public decimal Qty { get; set; } + + /// + /// 扩展属性 + /// + public ExtraPropertyDictionary ExtraProperties { get; } = new ExtraPropertyDictionary(); + + /// + /// 库存状态 + /// + public EnumInventoryStatus Status { get; set; } + + /// + /// 仓库代码 + /// + public string WarehouseCode { get; set; } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobDetailSaveInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobDetailSaveInput.cs new file mode 100644 index 000000000..fa5580803 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobDetailSaveInput.cs @@ -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; + +/// +/// 客户退拆 保存模型 +/// +public class ProductRecycleJobDetailSaveInput +{ + /// + /// Id + /// + [Display(Name = "Id")] + public Guid Id { get; set; } + /// + /// 详情ID + /// + [Display(Name = "详情ID")] + public Guid DetailId { get; set; } + + /// + /// 不合格原因 + /// + [Display(Name = "不合格原因")] + public string FailedReason { get; set; } + + /// + /// 质量缺陷 + /// + [Display(Name = "质量缺陷")] + public string MassDefect { get; set; } + + + /// + /// 图片字节流 + /// + [Display(Name = "图片字节流")] + public List FilesList { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobEditInput.cs new file mode 100644 index 000000000..3fc12e68e --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ProductRecycleJobs/Inputs/ProductRecycleJobEditInput.cs @@ -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 +{ + #region Create + + /// + /// 上游任务编号 + /// + [Display(Name = "上游任务编号")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string UpStreamJobNumber { get; set; } + + /// + /// 任务类型 + /// + [Display(Name = "任务类型")] + [Required(ErrorMessage = "{0}是必填项")] + public EnumJobType JobType { get; set; } + + /// + /// 是否自动完成 + /// + [Display(Name = "是否自动完成")] + [Required(ErrorMessage = "{0}是必填项")] + public bool IsAutoComplete { get; set; } + + /// + /// 过期时间 + /// + [Display(Name = "过期时间")] + [Required(ErrorMessage = "{0}是必填项")] + public DateTime ExpiredTime { get; set; } + + /// + /// 任务明细 + /// + [Display(Name = "任务明细")] + [Required(ErrorMessage = "{0}是必填项")] + public List Details { get; set; } + #endregion +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Win_in.Sfs.Wms.Store.Application.Contracts.csproj b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Win_in.Sfs.Wms.Store.Application.Contracts.csproj index 819319a8f..a14d0abb2 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Win_in.Sfs.Wms.Store.Application.Contracts.csproj +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Win_in.Sfs.Wms.Store.Application.Contracts.csproj @@ -42,7 +42,6 @@ - diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ProductRecycleJobs/ProductRecycleJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ProductRecycleJobs/ProductRecycleJobAppService.cs new file mode 100644 index 000000000..a7842a0b5 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ProductRecycleJobs/ProductRecycleJobAppService.cs @@ -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 + , IProductRecycleJobAppService +{ + private readonly IProductRecycleJobManager _productRecycleJobManager; + + public ProductRecycleJobAppService( + IProductRecycleJobRepository repository, IProductRecycleJobManager productRecycleJobManager) + : base(repository, productRecycleJobManager) + { + _productRecycleJobManager = productRecycleJobManager; + } + + + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ProductRecycleJobs/ProductRecycleJobAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ProductRecycleJobs/ProductRecycleJobAutoMapperProfile.cs new file mode 100644 index 000000000..87069a2b4 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ProductRecycleJobs/ProductRecycleJobAutoMapperProfile.cs @@ -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() + .ReverseMap(); + + CreateMap() + ; + + CreateMap(); + + CreateMap() + .IgnoreAuditedObjectProperties() + .Ignore(x => x.MasterID) + .Ignore(x => x.TenantId) + .Ignore(x => x.Number) + .Ignore(x => x.Id); + + CreateMap() + ; + + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ProductRecycleJobs/ProductRecycleJobDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ProductRecycleJobs/ProductRecycleJobDbContextModelCreatingExtensions.cs new file mode 100644 index 000000000..84ac2f4e3 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ProductRecycleJobs/ProductRecycleJobDbContextModelCreatingExtensions.cs @@ -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(b => + { + //Configure table & schema name + b.ToTable(StoreDbProperties.JobDbTablePrefix + nameof(ProductReceiveJob), options.Schema); + //Configure ABP properties + b.ConfigureByConvention(); + //Configure Sfs base properties + b.ConfigureSfsBase(); + //Configure Job base properties + b.ConfigureJob(); + //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(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(); + }); + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ProductRecycleJobs/ProductRecycleJobEfCoreRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ProductRecycleJobs/ProductRecycleJobEfCoreRepository.cs new file mode 100644 index 000000000..7e7a9b688 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ProductRecycleJobs/ProductRecycleJobEfCoreRepository.cs @@ -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, IProductRecycleJobRepository +{ + public ProductRecycleJobEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/ProductionRecycleJobEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/ProductionRecycleJobEventHandler.cs new file mode 100644 index 000000000..8e6c7fc5b --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/ProductionRecycleJobEventHandler.cs @@ -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> +, ILocalEventHandler> +{ + private readonly IProductRecycleNoteAppService _productRecycleNoteAppService; + + public ProductionRecycleJobEventHandler( + IProductRecycleNoteAppService productRecycleNoteAppService + ) + { + _productRecycleNoteAppService = productRecycleNoteAppService; + } + + [UnitOfWork] + public virtual async Task HandleEventAsync(SfsCreatedEntityEventData 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 eventData) + { + var entity = eventData.Entity; + + var productRecycleNote = BuildProductionReturnNote(entity); + await _productRecycleNoteAppService.CreateAsync(productRecycleNote).ConfigureAwait(false); + + } + + private ProductRecycleNoteEditInput BuildProductionReturnNote(ProductRecycleJob entity) + { + var input = ObjectMapper.Map(entity); + + + input.Details = new List(); + + foreach (var detail in entity.Details.Where(detail => detail.HandledQty != 0)) + { + var inputDetail = ObjectMapper.Map(detail); + + input.Details.Add(inputDetail); + } + + return input; + } +}