diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/DTOs/ThirdLocationJobDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/DTOs/ThirdLocationJobDTO.cs new file mode 100644 index 000000000..a3f522c74 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/DTOs/ThirdLocationJobDTO.cs @@ -0,0 +1,46 @@ +using System.ComponentModel.DataAnnotations; +using Win_in.Sfs.Shared.Domain; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +/// +/// 三方库库移任务 +/// +[Display(Name = "三方库库移任务")] +public class ThirdLocationJobDTO : SfsJobDTOBase +{ + /// + /// 叫料请求类型 + /// + [Display(Name = "叫料请求类型")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string RequestType { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ProdLine { get; set; } + + /// + /// 要货申请单号 + /// + [Display(Name = "要货申请单号")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string RequestNumber { get; set; } + + /// + /// 车间 + /// + [Display(Name = "车间")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Workshop { get; set; } + + /// + /// 使用在途库 + /// + [Display(Name = "使用在途库")] + public bool UseOnTheWayLocation { get; set; } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/DTOs/ThirdLocationJobDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/DTOs/ThirdLocationJobDetailDTO.cs new file mode 100644 index 000000000..509727793 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/DTOs/ThirdLocationJobDetailDTO.cs @@ -0,0 +1,112 @@ +using System; +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 ThirdLocationJobDetailDTO : SfsJobRecommendFromDetailDTOBase, IHasToLocation +{ + + /// + /// 请求库位 + /// + [Display(Name = "请求库位")] + public string RequestLocationCode { get; set; } + + /// + /// 到库位 + /// + [Display(Name = "到库位")] + public string ToLocationCode { get; set; } + + /// + /// 到库区 + /// + [Display(Name = "到库区")] + public string ToLocationArea { get; set; } + + /// + /// 到库位组 + /// + [Display(Name = "到库位组")] + public string ToLocationGroup { get; set; } + + /// + /// 到ERP库位 + /// + [Display(Name = "到ERP库位")] + public string ToLocationErpCode { get; set; } + + /// + /// 到仓库 + /// + [Display(Name = "到仓库")] + public string ToWarehouseCode { get; set; } + + /// + /// 在途库库位 + /// + [Display(Name = "在途库库位")] + public string OnTheWayLocationCode { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + [Display(Name = "工作中心")] + public string WorkStation { get; set; } + + /// + /// 过期时间 + /// + [Display(Name = "过期时间")] + public DateTime ExpiredTime { get; set; } + + /// + /// 工序 + /// + [Display(Name = "工序")] + public string Operation { get; set; } + + /// + /// 配送方式 + /// + [Display(Name = "配送方式")] + public EnumDistributionType DistributionType { get; set; } + + /// + /// 取整方式 + /// + [Display(Name = "取整方式")] + public EnumTruncType TruncType { get; set; } + + /// + /// 取整后数量 + /// + [Display(Name = "取整后数量")] + public decimal RoundedQty { get; set; } + + /// + /// 计划拆分规则 + /// + [Display(Name = "计划拆分规则")] + public EnumPlannedSplitRule PlannedSplitRule { get; set; } + + /// + /// 计划开始时间 + /// + [Display(Name = "计划开始时间")] + public DateTime PlanBeginTime { get; set; } + + /// + /// 每次配送数量 + /// + [Display(Name = "每次配送数量")] + public decimal DeliveryQty { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/IThirdLocationJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/IThirdLocationJobAppService.cs new file mode 100644 index 000000000..8bb1eef89 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/IThirdLocationJobAppService.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public interface IThirdLocationJobAppService + : ISfsJobAppServiceBase +{ + Task> CheckJobExistByItemCodeAndLocationCode(string itemCode, string locationCode); + + Task CancelByMaterialRequestAsync(string thirdLocationNumber); + + Task> GetListByTypeAsync(SfsJobRequestInputBase requestInput, string requestType, + bool includeDetails = false, CancellationToken cancellationToken = default); + + Task> GetByRequestNumberAsync(string requestNumber); + + /// + /// 保存拆箱时涉及的明细修改 + /// + /// + Task SaveDetail_SplitPackingAsync(SplitPacking_UpdateJobDetailInput input); + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobCheckInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobCheckInput.cs new file mode 100644 index 000000000..3ababbe79 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobCheckInput.cs @@ -0,0 +1,6 @@ +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationJobCheckInput : SfsJobCheckInputBase +{ + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobDetailInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobDetailInput.cs new file mode 100644 index 000000000..c41ae9bff --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobDetailInput.cs @@ -0,0 +1,134 @@ +using System; +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 ThirdLocationJobDetailInput : SfsJobRecommendFromDetailInputBase, IHasToLocation +{ + + /// + /// 请求库位 + /// + [Display(Name = "请求库位")] + [Required(ErrorMessage = "{0}是必填项")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string RequestLocationCode { get; set; } + + /// + /// 到库位 + /// + [Display(Name = "到库位")] + [Required(ErrorMessage = "{0}是必填项")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ToLocationCode { get; set; } + + /// + /// 到库区 + /// + [Display(Name = "到库区")] + public string ToLocationArea { get; set; } + + /// + /// 到库位组 + /// + [Display(Name = "到库位组")] + public string ToLocationGroup { get; set; } + + /// + /// 到ERP库位 + /// + [Display(Name = "到ERP库位")] + [Required(ErrorMessage = "{0}是必填项")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ToLocationErpCode { get; set; } + + /// + /// 到仓库 + /// + [Display(Name = "到仓库")] + [Required(ErrorMessage = "{0}是必填项")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ToWarehouseCode { get; set; } + + /// + /// 在途库库位 + /// + [Display(Name = "在途库库位")] + public string OnTheWayLocationCode { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + [Display(Name = "工作中心")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string WorkStation { get; set; } + + /// + /// 过期时间 + /// + [Display(Name = "过期时间")] + [Required(ErrorMessage = "{0}是必填项")] + public DateTime ExpiredTime { get; set; } + + /// + /// 工序 + /// + [Display(Name = "工序")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Operation { get; set; } + + /// + /// 配送方式 + /// + [Display(Name = "配送方式")] + public EnumDistributionType DistributionType { get; set; } + + /// + /// 取整方式 + /// + [Display(Name = "取整方式")] + public EnumTruncType TruncType { get; set; } + + /// + /// 取整后数量 + /// + [Display(Name = "取整后数量")] + public decimal RoundedQty { get; set; } + + /// + /// 计划拆分规则 + /// + [Display(Name = "计划拆分规则")] + public EnumPlannedSplitRule PlannedSplitRule { get; set; } + + /// + /// 计划开始时间 + /// + [Display(Name = "计划开始时间")] + public DateTime PlanBeginTime { get; set; } + + /// + /// 每次配送数量 + /// + [Display(Name = "每次配送数量")] + public decimal DeliveryQty { get; set; } + + /// + /// 位置码 + /// + public string PositionCode { get; set; } + + /// + /// 推荐类型 + /// + public EnumRecommendType RecommendType { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobEditInput.cs new file mode 100644 index 000000000..18a65ca49 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/Inputs/ThirdLocationJobEditInput.cs @@ -0,0 +1,82 @@ +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 ThirdLocationJobEditInput : SfsJobCreateUpdateInputBase, ISfsJobCreateInput +{ + #region Create + /// + /// 上游任务编号 + /// + [Display(Name = "上游任务编号")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string UpStreamJobNumber { get; set; } + + /// + /// 要货单号 + /// + [Display(Name = "要货单号")] + [Required(ErrorMessage = "{0}是必填项")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string RequestNumber { get; set; } + + /// + /// 叫料请求类型 + /// + [Display(Name = "叫料请求类型")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string RequestType { 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; } = new(); + + /// + /// 车间 + /// + [Display(Name = "车间")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Workshop { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ProdLine { get; set; } + + /// + /// 使用在途库 + /// + [Display(Name = "使用在途库")] + public bool UseOnTheWayLocation { get; set; } + #endregion +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/ThirdLocationJobPermissions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/ThirdLocationJobPermissions.cs new file mode 100644 index 000000000..be4151800 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/ThirdLocationJobs/ThirdLocationJobPermissions.cs @@ -0,0 +1,27 @@ +using Volo.Abp.Authorization.Permissions; +using Win_in.Sfs.Wms.Store.Domain; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public static class ThirdLocationJobPermissions +{ + + public const string Default = StorePermissions.GroupName + "." + nameof(ThirdLocationJob); + public const string Create = Default + "." + StorePermissions.CreateStr; + public const string Update = Default + "." + StorePermissions.UpdateStr; + public const string Delete = Default + "." + StorePermissions.DeleteStr; + + //自动发料任务 + public const string AutoThirdLocationJob = StorePermissions.GroupName + "." + nameof(AutoThirdLocationJob); + + public static void AddThirdLocationJobPermission(this PermissionGroupDefinition permissionGroup) + { + var thirdLocationJobPermission = permissionGroup.AddPermission(Default, StorePermissionDefinitionProvider.L(nameof(ThirdLocationJob))); + thirdLocationJobPermission.AddChild(Create, StorePermissionDefinitionProvider.L(StorePermissions.CreateStr)); + thirdLocationJobPermission.AddChild(Update, StorePermissionDefinitionProvider.L(StorePermissions.UpdateStr)); + thirdLocationJobPermission.AddChild(Delete, StorePermissionDefinitionProvider.L(StorePermissions.DeleteStr)); + + permissionGroup.AddPermission(AutoThirdLocationJob, StorePermissionDefinitionProvider.L(nameof(AutoThirdLocationJob))); + + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/DTOs/ThirdLocationNoteDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/DTOs/ThirdLocationNoteDTO.cs new file mode 100644 index 000000000..ea67e0660 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/DTOs/ThirdLocationNoteDTO.cs @@ -0,0 +1,54 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Win_in.Sfs.Shared.Domain; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationNoteDTO : SfsStoreDTOBase, IHasJobNumber, IHasRequestNumber +{ + + /// + /// 任务ID + /// + [Display(Name = "任务ID")] + public string JobNumber { get; set; } + + /// + /// 车间 + /// + [Display(Name = "车间")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Workshop { get; set; } + + /// + /// 请求代码 + /// + [Display(Name = "请求代码")] + public string RequestNumber { get; set; } + + /// + /// 叫料请求类型 + /// + [Display(Name = "叫料请求类型")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string RequestType { get; set; } + + /// + /// 使用在途库 + /// + [Display(Name = "使用在途库")] + public bool UseOnTheWayLocation { get; set; } + + /// + /// 已确认 + /// + [Display(Name = "已确认")] + public bool Confirmed { get; set; } + + /// + /// 确认时间 + /// + [Display(Name = "确认时间")] + public DateTime? ConfirmTime { get; set; } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/DTOs/ThirdLocationNoteDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/DTOs/ThirdLocationNoteDetailDTO.cs new file mode 100644 index 000000000..5b0413a05 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/DTOs/ThirdLocationNoteDetailDTO.cs @@ -0,0 +1,42 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Win_in.Sfs.Shared.Domain; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationNoteDetailDTO : SfsStoreRecommendFromDetailWithFromToDTOBase +{ + + /// + /// 发料时间 + /// + [Display(Name = "发料时间")] + public DateTime IssueTime { get; set; } + + /// + /// 过期时间 + /// + [Display(Name = "过期时间")] + public DateTime ExpiredTime { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + [Display(Name = "工作中心")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string WorkStation { get; set; } + + /// + /// 在途库库位 + /// + [Display(Name = "在途库库位")] + public string OnTheWayLocationCode { get; set; } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/IThirdLocationNoteAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/IThirdLocationNoteAppService.cs new file mode 100644 index 000000000..3befdb64d --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/IThirdLocationNoteAppService.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public interface IThirdLocationNoteAppService : ISfsStoreMasterReadOnlyAppServiceBase +{ + Task CreateAsync(ThirdLocationNoteEditInput input); + + Task ConfirmAsync(Guid id); + + Task ConfirmAsync(string number); + + Task> GetListByTypeAsync(SfsStoreRequestInputBase requestInput, + string requestType, bool includeDetails = false, CancellationToken cancellationToken = default); + + Task> GetListUnConfirmedByTypeAsync(string requestType); +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteDetailInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteDetailInput.cs new file mode 100644 index 000000000..46aad25fa --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteDetailInput.cs @@ -0,0 +1,53 @@ +using System; +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 ThirdLocationNoteDetailInput : SfsStoreRecommendFromDetailWithFromToInputBase +{ + + /// + /// 发料时间 + /// + [Display(Name = "发料时间")] + public DateTime IssueTime { get; set; } + + /// + /// 过期时间 + /// + [Display(Name = "过期时间")] + public DateTime ExpiredTime { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + [Display(Name = "工作中心")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string WorkStation { get; set; } + + /// + /// 在途库库位 + /// + [Display(Name = "在途库库位")] + public string OnTheWayLocationCode { get; set; } + + /// + /// 位置码 + /// + public string PositionCode { get; set; } + + /// + /// 推荐类型 + /// + public EnumRecommendType RecommendType { get; set; } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteEditInput.cs new file mode 100644 index 000000000..371588dab --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteEditInput.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Win_in.Sfs.Shared.Domain; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationNoteEditInput : SfsStoreCreateOrUpdateInputBase +{ + #region Base + /// + /// 已确认 + /// + [Display(Name = "已确认")] + public bool Confirmed { get; set; } + #endregion + + #region Create + /// + /// 发料记录号 + /// + [Display(Name = "发料记录号")] + public string Number { get; set; } + + /// + /// 任务ID + /// + [Display(Name = "任务ID")] + [Required(ErrorMessage = "{0}是必填项")] + public string JobNumber { get; set; } + + /// + /// 车间 + /// + [Display(Name = "车间")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Workshop { get; set; } + + /// + /// 明细列表 + /// + [Display(Name = "明细列表")] + public List Details { get; set; } + + /// + /// 请求号码 + /// + [Display(Name = "请求号码")] + public string RequestNumber { get; set; } + + /// + /// 叫料请求类型 + /// + [Display(Name = "叫料请求类型")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string RequestType { get; set; } + + /// + /// 使用在途库 + /// + [Display(Name = "使用在途库")] + public bool UseOnTheWayLocation { get; set; } + #endregion +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteImportInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteImportInput.cs new file mode 100644 index 000000000..f267c18ea --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/Inputs/ThirdLocationNoteImportInput.cs @@ -0,0 +1,33 @@ +using System.ComponentModel.DataAnnotations; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationNoteImportInput : SfsStoreImportInputBase, IHasJobNumber, IHasRequestNumber +{ + /// + /// 任务ID + /// + [Display(Name = "任务ID")] + public string JobNumber { get; set; } + + /// + /// 车间 + /// + [Display(Name = "车间")] + public string Workshop { get; set; } + + public string RequestNumber { get; set; } + + /// + /// 叫料请求类型 + /// + [Display(Name = "叫料请求类型")] + public string RequestType { get; set; } + + /// + /// 使用在途库 + /// + [Display(Name = "使用在途库")] + [Required(ErrorMessage = "{0}是必填项")] + public bool UseOnTheWayLocation { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/ThirdLocationNotePermissions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/ThirdLocationNotePermissions.cs new file mode 100644 index 000000000..79e634b2c --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/ThirdLocationNotes/ThirdLocationNotePermissions.cs @@ -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 ThirdLocationNotePermissions +{ + + public const string Default = StorePermissions.GroupName + "." + nameof(ThirdLocationNote); + public const string Create = Default + "." + StorePermissions.CreateStr; + public const string Update = Default + "." + StorePermissions.UpdateStr; + public const string Delete = Default + "." + StorePermissions.DeleteStr; + + //自动发料记录 + public const string AutoThirdLocationNote = StorePermissions.GroupName + "." + nameof(AutoThirdLocationNote); + + //直接发料 + public const string DirectThirdLocationNote = StorePermissions.GroupName + "." + nameof(DirectThirdLocationNote); + + public static void AddThirdLocationNotePermission(this PermissionGroupDefinition permissionGroup) + { + var thirdLocationNotePermission = permissionGroup.AddPermission(Default, StorePermissionDefinitionProvider.L(nameof(ThirdLocationNote))); + thirdLocationNotePermission.AddChild(Create, StorePermissionDefinitionProvider.L(StorePermissions.CreateStr)); + thirdLocationNotePermission.AddChild(Update, StorePermissionDefinitionProvider.L(StorePermissions.UpdateStr)); + thirdLocationNotePermission.AddChild(Delete, StorePermissionDefinitionProvider.L(StorePermissions.DeleteStr)); + + permissionGroup.AddPermission(AutoThirdLocationNote, StorePermissionDefinitionProvider.L(nameof(AutoThirdLocationNote))); + permissionGroup.AddPermission(DirectThirdLocationNote, StorePermissionDefinitionProvider.L(nameof(DirectThirdLocationNote))); + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Permissions/StorePermissionDefinitionProvider.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Permissions/StorePermissionDefinitionProvider.cs index 9c8dad174..f58153b14 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Permissions/StorePermissionDefinitionProvider.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Permissions/StorePermissionDefinitionProvider.cs @@ -28,10 +28,12 @@ public class StorePermissionDefinitionProvider : PermissionDefinitionProvider storeGroup.AddMaterialRequestPermission(); storeGroup.AddInjectionRequestPermission(); storeGroup.AddAssembleRequestPermission(); + storeGroup.AddThirdLocationRequestPermission(); storeGroup.AddContainerRequestPermission(); storeGroup.AddIssueNotePermission(); storeGroup.AddInjectionNotePermission(); storeGroup.AddAssembleNotePermission(); + storeGroup.AddThirdLocationNotePermission(); storeGroup.AddContainerNotePermission(); storeGroup.AddUnplannedReceiptNotePermission(); storeGroup.AddUnplannedIssueNotePermission(); @@ -98,6 +100,7 @@ public class StorePermissionDefinitionProvider : PermissionDefinitionProvider storeGroup.AddIssueJobPermission(); storeGroup.AddInjectionJobPermission(); storeGroup.AddAssembleJobPermission(); + storeGroup.AddThirdLocationJobPermission(); storeGroup.AddContainerJobPermission(); storeGroup.AddDeliverJobPermission(); storeGroup.AddPurchaseReturnJobPermission(); diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/DTOs/ThirdLocationRequestDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/DTOs/ThirdLocationRequestDTO.cs new file mode 100644 index 000000000..b5b062fae --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/DTOs/ThirdLocationRequestDTO.cs @@ -0,0 +1,40 @@ +using System.ComponentModel.DataAnnotations; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationRequestDTO : SfsStoreRequestDTOBase, IHasNumber +{ + /// + /// 叫料类型 + /// + [Display(Name = "叫料类型")] + public string Type { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + public string ProdLine { get; set; } + + /// + /// 是否使用在途库 + /// + [Display(Name = "是否使用在途库")] + public bool IsUseOnTheWayLocation { get; set; } + + /// + /// 可用来源库位Json集合 + /// + public string FromLocationCodeJsonList { get; set; } + + /// + /// 叫料库位 + /// + public string ToLocationCode { get; set; } + + /// + /// 目标ERP储位 + /// + [Display(Name = "目标ERP储位")] + public string ToLocationErpCode { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/DTOs/ThirdLocationRequestDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/DTOs/ThirdLocationRequestDetailDTO.cs new file mode 100644 index 000000000..bd0610ac6 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/DTOs/ThirdLocationRequestDetailDTO.cs @@ -0,0 +1,50 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Win_in.Sfs.Shared.Domain; +using Win_in.Sfs.Shared.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationRequestDetailDTO : SfsStoreDetailWithQtyDTOBase +{ + /// + /// 已发数量 + /// + [Display(Name = "已发数量")] + public decimal IssuedQty { get; set; } + + /// + /// 已收数量 + /// + [Display(Name = "已收数量")] + public decimal ReceivedQty { get; set; } + + /// + /// 明细状态 + /// + [Display(Name = "明细状态")] + public EnumStatus Status { get; set; } + + /// + /// 请求未发 + /// + [Display(Name = "请求未发")] + [NotMapped] + public decimal ToBeIssuedQty => Qty - IssuedQty; + + /// + /// 已发未收 + /// + [Display(Name = "已发未收")] + [NotMapped] + public decimal ToBeReceivedQty => IssuedQty - ReceivedQty; + + /// + /// 请求未收 + /// + [Display(Name = "请求未收")] + [NotMapped] + public decimal NotFinishQty => Qty - ReceivedQty; + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/IThirdLocationRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/IThirdLocationRequestAppService.cs new file mode 100644 index 000000000..e1f47cb2d --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/IThirdLocationRequestAppService.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public interface IThirdLocationRequestAppService + : ISfsStoreRequestMasterAppServiceBase + +{ + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestDetailInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestDetailInput.cs new file mode 100644 index 000000000..913c639c2 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestDetailInput.cs @@ -0,0 +1,85 @@ +using System; +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 ThirdLocationRequestDetailInput : SfsStoreDetailWithQtyInputBase +{ + /// + /// 目标库位 + /// + [Display(Name = "目标库位")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ToLocationCode { get; set; } + + /// + /// 来源库区 + /// + [Display(Name = "来源库区")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string FromLocationArea { get; set; } + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + [Display(Name = "工作中心")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string WorkStation { get; set; } + + /// + /// 过期时间 + /// + [Display(Name = "过期时间")] + public DateTime ExpiredTime { get; set; } + + /// + /// 状态 + /// + [Display(Name = "状态")] + public EnumRequestStatus RequestStatus { get; set; } = EnumRequestStatus.New; + + /// + /// ERP储位 + /// + [Display(Name = "ERP储位")] + public string ToLocationErpCode { get; set; } + + /// + /// 已发数量 + /// + [Display(Name = "已发数量")] + public decimal IssuedQty { get; set; } + + /// + /// 已收数量 + /// + [Display(Name = "已收数量")] + public decimal ReceivedQty { get; set; } + + /// + /// 明细状态 + /// + [Display(Name = "明细状态")] + public EnumStatus Status { get; set; } + + /// + /// 位置码 + /// + public string PositionCode { get; set; } + + /// + /// 推荐类型 + /// + public EnumRecommendType RecommendType { get; set; } + + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestEditInput.cs new file mode 100644 index 000000000..cbe39ea9c --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestEditInput.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Win_in.Sfs.Shared.Domain; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public class ThirdLocationRequestEditInput : SfsStoreRequestCreateOrUpdateInputBase +{ + #region Base + + /// + /// 生产线 + /// + [Display(Name = "生产线")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string ProdLine { get; set; } + + /// + /// 使用在途库 + /// + [Display(Name = "使用在途库")] + public bool UseOnTheWayLocation { get; set; } + #endregion + + #region Create + /// + /// 要货单号 + /// + [Display(Name = "要货单号")] + [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")] + public string Number { get; set; } + + /// + /// 叫料类型 + /// + [Display(Name = "叫料类型")] + public string Type { get; set; } + + + /// + /// 明细列表 + /// + [Display(Name = "明细列表")] + public List Details { get; set; } = new List(); + #endregion +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestImportInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestImportInput.cs new file mode 100644 index 000000000..e4d261306 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/Inputs/ThirdLocationRequestImportInput.cs @@ -0,0 +1,53 @@ +using System.ComponentModel.DataAnnotations; +using Win_in.Sfs.Shared.Application.Contracts; +using Win_in.Sfs.Shared.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +[Display(Name = "三方库叫料申请")] +public class ThirdLocationRequestImportInput : SfsStoreImportInputBase +{ + /// + /// 叫料类型 + /// + [Display(Name = "叫料类型")] + [Required(ErrorMessage = "{0}是必填项")] + [ImporterHeader(Name = "叫料类型")] + [ExporterHeader(DisplayName = "叫料类型")] + [ValueMapping("人工拉动", EnumMaterialRequestType.Issue_Manual)] + public string Type { get; set; } + + /// + /// 物品代码 + /// + [Display(Name = "物品代码")] + [Required] + public string ItemCode { get; set; } + + /// + /// 目标库位 + /// + [Display(Name = "目标库位")] + [Required] + public string ToLocationCode { get; set; } + + /// + /// 来源库区 + /// + [Display(Name = "调出库区")] + [Required] + public string FromLocationArea { get; set; } + + /// + /// 数量 + /// + [Display(Name = "数量")] + [Required(ErrorMessage = "{0}是必填项")] + public decimal Qty { get; set; } + + /// + /// 备注 + /// + [Display(Name = "备注")] + public string Remark { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/ThirdLocationRequestPermissions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/ThirdLocationRequestPermissions.cs new file mode 100644 index 000000000..f1ed68079 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/ThirdLocationRequests/ThirdLocationRequestPermissions.cs @@ -0,0 +1,27 @@ +using Volo.Abp.Authorization.Permissions; +using Win_in.Sfs.Wms.Store.Domain; + +namespace Win_in.Sfs.Wms.Store.Application.Contracts; + +public static class ThirdLocationRequestPermissions +{ + + public const string Default = StorePermissions.GroupName + "." + nameof(ThirdLocationRequest); + public const string Create = Default + "." + StorePermissions.CreateStr; + public const string Update = Default + "." + StorePermissions.UpdateStr; + public const string Delete = Default + "." + StorePermissions.DeleteStr; + + //自动叫料申请 + public const string AutoThirdLocationRequest = StorePermissions.GroupName + "." + nameof(AutoThirdLocationRequest); + + public static void AddThirdLocationRequestPermission(this PermissionGroupDefinition permissionGroup) + { + var thirdLocationRequestPermission = permissionGroup.AddPermission(Default, StorePermissionDefinitionProvider.L(nameof(ThirdLocationRequest))); + thirdLocationRequestPermission.AddChild(Create, StorePermissionDefinitionProvider.L(StorePermissions.CreateStr)); + thirdLocationRequestPermission.AddChild(Update, StorePermissionDefinitionProvider.L(StorePermissions.UpdateStr)); + thirdLocationRequestPermission.AddChild(Delete, StorePermissionDefinitionProvider.L(StorePermissions.DeleteStr)); + + permissionGroup.AddPermission(AutoThirdLocationRequest, StorePermissionDefinitionProvider.L(nameof(AutoThirdLocationRequest))); + + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ThirdLocationJobs/ThirdLocationJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ThirdLocationJobs/ThirdLocationJobAppService.cs new file mode 100644 index 000000000..6a631835f --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ThirdLocationJobs/ThirdLocationJobAppService.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.ObjectMapping; +using Win_in.Sfs.Basedata.Domain.Shared; +using Win_in.Sfs.Shared.Domain; +using Win_in.Sfs.Shared.Domain.Shared; +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}third-location-job")] +public class ThirdLocationJobAppService + : SfsJobAppServiceBase, + IThirdLocationJobAppService +{ + private readonly IThirdLocationJobManager _thirdLocationJobManager; + + public ThirdLocationJobAppService( + IThirdLocationJobRepository repository, IThirdLocationJobManager thirdLocationJobManager + ) : base(repository, thirdLocationJobManager) + { + _thirdLocationJobManager = thirdLocationJobManager; + } + + /// + /// 根据物品和库位 检查是否存在发料任务 + /// + /// + /// + /// + /// + [Authorize] + [HttpGet("check-job-exist")] + public virtual async Task> CheckJobExistByItemCodeAndLocationCode(string itemCode, + string locationCode) + { + var entities = await _repository.GetListAsync(c => + c.Details.Any(p => + (p.ItemCode == itemCode && p.RecommendFromLocationCode == locationCode) || + (p.ItemCode == itemCode && p.ToLocationCode == locationCode)) + && (c.JobStatus == EnumJobStatus.Open || c.JobStatus == EnumJobStatus.Doing), true).ConfigureAwait(false); + var dtos = ObjectMapper.Map, List>(entities); + return dtos; + } + + [HttpPost("cancel-by-request/{assembleNumber}")] + public virtual async Task CancelByMaterialRequestAsync(string assembleNumber) + { + var entities = await _repository.GetListAsync(p => p.RequestNumber == assembleNumber).ConfigureAwait(false); + foreach (var entity in entities) + { + await _thirdLocationJobManager.CancelAsync(entity).ConfigureAwait(false); + } + } + + [HttpPost("invalid")] + public override async Task CancelAsync(Guid id) + { + var thirdLocationJob = await _repository.GetAsync(id).ConfigureAwait(false); + if (thirdLocationJob == null) + { + throw new UserFriendlyException($"未找到ID为 {id} 的任务"); + } + + await _thirdLocationJobManager.CancelAsync(thirdLocationJob).ConfigureAwait(false); + + } + + /// + /// 根据叫料请求类型获取发料任务 + /// + /// + /// + /// 叫料请求类型: + /// 人工拉动:Issue_Manual; + /// 线边拉动:Issue_WIP; + /// + /// + /// + /// + [HttpPost("by-type/{requestType}")] + public virtual async Task> GetListByTypeAsync(SfsJobRequestInputBase requestInput, + string requestType, bool includeDetails = false, CancellationToken cancellationToken = default) + { + Expression> expression = p => p.RequestType == requestType; + if (requestInput.Condition.Filters?.Count > 0) + { + expression = expression.And(requestInput.Condition.Filters.ToLambda()); + } + + return await GetPagedListAsync(expression, requestInput.SkipCount, requestInput.MaxResultCount, + requestInput.Sorting, includeDetails, cancellationToken).ConfigureAwait(false); + + } + + [HttpPost("by-request-number/{requestNumber}")] + public virtual async Task> GetByRequestNumberAsync(string requestNumber) + { + var entitys = await _repository.GetListAsync(p => p.RequestNumber == requestNumber).ConfigureAwait(false); + return ObjectMapper.Map, List>(entitys); + } + + /// + /// 保存拆箱时涉及的明细修改 + /// + /// + [HttpPost("save-detail-split-packing")] + public virtual async Task SaveDetail_SplitPackingAsync(SplitPacking_UpdateJobDetailInput input) + { + var job = await _repository.FindAsync(p => p.Number == input.Number).ConfigureAwait(false); + ThirdLocationJobDetail detail = job.Details.FirstOrDefault(p => p.RecommendPackingCode == input.FromPackingCode ); /*&& p.HandledQty == input.FromQty*/ + if (detail == null) + { + //throw new UserFriendlyException($"根据HandledPackingCode={input.FromPackingCode}取ThirdLocationJobDetail表为空!"); + throw new UserFriendlyException($"根据RecommendPackingCode={input.FromPackingCode}取ThirdLocationJobDetail表为空!"); + } + //插入目标箱 + var newDetail = CommonHelper.CloneObj(detail); + newDetail.SetId(GuidGenerator.Create()); + newDetail.RecommendPackingCode = input.ToPackingCode; + newDetail.RecommendQty = input.ToQty; + newDetail.HandledPackingCode = detail.HandledPackingCode.HasValue() ? input.ToPackingCode : null; //源实际实际箱码有值,则新记录实际箱码有值 + newDetail.HandledQty = detail.HandledQty > 0 ? input.ToQty : 0; + //newDetail.CreationTime = CommonHelper.CurTime; + job.Details.Add(newDetail); + //修改源箱 + detail.RecommendQty = input.FromQty - input.ToQty; + detail.HandledQty = detail.HandledQty > 0 ? input.FromQty - input.ToQty : 0; + var entity = await _repository.UpdateAsync(job).ConfigureAwait(false); + var ret = ObjectMapper.Map(entity); + return ret; + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ThirdLocationJobs/ThirdLocationJobAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ThirdLocationJobs/ThirdLocationJobAutoMapperProfile.cs new file mode 100644 index 000000000..d35e38e61 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/ThirdLocationJobs/ThirdLocationJobAutoMapperProfile.cs @@ -0,0 +1,29 @@ +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 ThirdLocationJobAutoMapperProfile() + { + CreateMap() + .ReverseMap(); + + CreateMap() + ; + + CreateMap() + ; + + CreateMap() + .IgnoreAuditedObjectProperties() + .Ignore(x => x.MasterID) + .Ignore(x => x.TenantId) + .Ignore(x => x.Number) + .Ignore(x => x.Id); + + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ThirdLocationNotes/ThirdLocationNoteAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ThirdLocationNotes/ThirdLocationNoteAppService.cs new file mode 100644 index 000000000..57fe10118 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ThirdLocationNotes/ThirdLocationNoteAppService.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Domain.Entities; +using Win_in.Sfs.Shared.Domain; +using Win_in.Sfs.Shared.Event; +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}third-location-note")] +public class ThirdLocationNoteAppService : + SfsStoreWithDetailsAppServiceBase, + IThirdLocationNoteAppService +{ + private readonly IThirdLocationNoteManager _thirdLocationNoteManager; + + public ThirdLocationNoteAppService( + IThirdLocationNoteRepository repository, + IThirdLocationNoteManager thirdLocationNoteManager + ) : base(repository) + { + _thirdLocationNoteManager = thirdLocationNoteManager; + } + + [HttpPost("")] + //[Authorize(ThirdLocationNotePermissions.Create)] + public override async Task CreateAsync(ThirdLocationNoteEditInput input) + { + var entity = ObjectMapper.Map(input); + await _thirdLocationNoteManager.CreateAsync(entity).ConfigureAwait(false); + var dto = ObjectMapper.Map(entity); + return dto; + } + + /// + /// 确认对应的记录单 + /// + /// + /// + [HttpPost("confirm/{id}")] + public virtual async Task ConfirmAsync(Guid id) + { + var thirdLocationNote= await _repository.GetAsync(id).ConfigureAwait(false); + thirdLocationNote.Confirmed = true; + thirdLocationNote=await _repository.UpdateAsync(thirdLocationNote).ConfigureAwait(false); + await LocalEventBus.PublishAsync(new SfsConfirmedEntityEventData(thirdLocationNote), false).ConfigureAwait(false); + return ObjectMapper.Map(thirdLocationNote); + } + + [HttpPost("confirm-by-number/{number}")] + public virtual async Task ConfirmAsync(string number) + { + var entity = await _repository.FindAsync(p => p.Number == number).ConfigureAwait(false); + Check.NotNull(entity, nameof(ThirdLocationNote)); + var result = await _thirdLocationNoteManager.ConfirmAsync(entity.Id).ConfigureAwait(false); + var dto = ObjectMapper.Map(result); + return dto; + } + /// + /// 根据叫料请求类型获取发料记录 + /// + /// + /// + /// 叫料请求类型: + /// 人工拉动:Issue_Manual; + /// 线边拉动:Issue_WIP; + /// + /// + /// + /// + [HttpPost("by-type/{requestType}")] + public virtual async Task> GetListByTypeAsync(SfsStoreRequestInputBase requestInput, + string requestType, bool includeDetails = false, CancellationToken cancellationToken = default) + { + Expression> expression = p => p.RequestType == requestType; + if (requestInput.Condition.Filters?.Count > 0) + { + expression = expression.And(requestInput.Condition.Filters.ToLambda()); + } + + return await GetPagedListAsync(expression, requestInput.SkipCount, requestInput.MaxResultCount, + requestInput.Sorting, includeDetails, cancellationToken).ConfigureAwait(false); + } + + [HttpGet("list/un-confirmed/{requestType}")] + public virtual async Task> GetListUnConfirmedByTypeAsync(string requestType) + { + var entities = await _repository.GetListAsync(c => !c.Confirmed && c.RequestType == requestType) + .ConfigureAwait(false); + + var dtos = ObjectMapper.Map, List>(entities); + + return dtos; + } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ThirdLocationNotes/ThirdLocationNoteAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ThirdLocationNotes/ThirdLocationNoteAutoMapperProfile.cs new file mode 100644 index 000000000..ec4f83f69 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ThirdLocationNotes/ThirdLocationNoteAutoMapperProfile.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 ThirdLocationNoteAutoMapperProfile() + { + CreateMap() + .ReverseMap(); + + CreateMap(); + + CreateMap() + .IgnoreAuditedObjectProperties() + .Ignore(x => x.MasterID) + .Ignore(x => x.TenantId) + .Ignore(x => x.Number) + .Ignore(x => x.Id); + + CreateMap() + .IgnoreAuditedObjectProperties() + .Ignore(x => x.TenantId) + .Ignore(x => x.Number) + .Ignore(x => x.Id); + ; + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs new file mode 100644 index 000000000..14dee5cf7 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAppService.cs @@ -0,0 +1,302 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using DocumentFormat.OpenXml.Office.PowerPoint.Y2021.M06.Main; +using IdentityModel; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +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.Contracts; +using Win_in.Sfs.Shared.Domain; +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; +using Win_in.Sfs.Wms.Store.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Application; + +/// +/// 三方库库移 +/// +[Authorize] +[Route($"{StoreConsts.RootPath}third-location-request")] +public class ThirdLocationRequestAppService : SfsStoreRequestAppServiceBase, + IThirdLocationRequestAppService +{ + private readonly IThirdLocationRequestManager _thirdLocationRequestManager; + private readonly IItemStoreRelationAppService _itemStoreRelationApp; + private readonly IAreaAppService _areaApp; + private readonly ILocationAppService _locationAppService; + private readonly IItemBasicAppService _itemBasicAppService; + private readonly IProductionLineAppService _productionLineAppService; + private readonly IInjectionJobAppService _issueJobAppService; + public ThirdLocationRequestAppService( + IThirdLocationRequestRepository repository, + IThirdLocationRequestManager thirdLocationRequestManager, + IPreparationPlanManager preparationPlanManager, + IItemStoreRelationAppService itemStoreRelationApp, + IAreaAppService areaApp, + ILocationAppService locationAppService, + IItemBasicAppService itemBasicAppService, + IProductionLineAppService productionLineAppService, + IInjectionJobAppService issueJobAppService) + : base(repository, thirdLocationRequestManager) + { + _thirdLocationRequestManager = thirdLocationRequestManager; + _itemStoreRelationApp = itemStoreRelationApp; + _areaApp = areaApp; + _locationAppService = locationAppService; + _itemBasicAppService = itemBasicAppService; + _productionLineAppService = productionLineAppService; + _issueJobAppService = issueJobAppService; + } + + + #region 东阳V2 + + public override async Task HandleAsync(Guid id) + { + var entity = await _repository.GetAsync(id).ConfigureAwait(false); + await LocalEventBus.PublishAsync(new SfsHandledEntityEventData(entity), false).ConfigureAwait(false); + return ObjectMapper.Map(entity); + } + + [HttpPost("")] + //[Authorize(ThirdLocationRequestPermissions.Create)] + public override async Task CreateAsync(ThirdLocationRequestEditInput input) + { + foreach (var item in input.Details) + { + if (item.Qty <= 0) + { + throw new UserFriendlyException($"{item.ItemCode} 物料的需求量必须大于0"); + } + } + + foreach (var detailInput in input.Details) //赋值生产线 + { + var toLocationDto = await _locationAppService.GetByCodeAsync(detailInput.ToLocationCode).ConfigureAwait(false); + CheckLocation(toLocationDto, detailInput.ToLocationCode); + var itemBasicDto = await _itemBasicAppService.GetByCodeAsync(detailInput.ItemCode).ConfigureAwait(false); + CheckItemBasic(itemBasicDto, detailInput.ItemCode); + + detailInput.ProdLine = detailInput.ToLocationCode; + detailInput.ToLocationErpCode = toLocationDto.ErpLocationCode; + } + + input.AutoSubmit = true; + input.AutoAgree = true; + input.AutoHandle = true; + input.AutoCompleteJob = false; + input.DirectCreateNote = false; + + var entity = ObjectMapper.Map(input); + + var result = await _thirdLocationRequestManager.CreateAsync(entity).ConfigureAwait(false); + + var dto = ObjectMapper.Map(result); + + return dto; + } + + //[Authorize(ThirdLocationRequestPermissions.Create)] + [HttpPost("create-and-handle")] + public async Task CreateAndHandleAsync(ThirdLocationRequestEditInput input) + { + var thirdLocationRequestDto = await CreateAsync(input).ConfigureAwait(false); + + await HandleAsync(thirdLocationRequestDto.Id).ConfigureAwait(false); + + return thirdLocationRequestDto; + } + + #endregion + + /// + /// 根据类型 获取叫料申请 + /// + /// + /// + [HttpGet("list/by-type/{type}")] + public virtual async Task> GetListByTypeAsync(string type) + { + var entities = await _repository.GetListAsync(c => c.Type == type).ConfigureAwait(false); + + var dtos = ObjectMapper.Map, List>(entities); + + return dtos; + } + + #region 导入 + + /// + /// 用来重写 导入数据时可以加工数据 + /// + /// + /// + protected override async Task> ImportProcessingEntityAsync( + Dictionary dictionary) + { + var addList = dictionary.Where(p => p.Value == EntityState.Added).Select(p => p.Key); + + foreach (var thirdLocationRequest in addList) + { + thirdLocationRequest.Worker = CurrentUser.GetUserName(); + thirdLocationRequest.CreatorId = CurrentUser.Id; + if (thirdLocationRequest.Type == EnumTransSubType.Issue_Manual.GetDisplayName()) + { + thirdLocationRequest.Type = EnumTransSubType.Issue_Manual.ToString(); + } + + foreach (var detail in thirdLocationRequest.Details) + { + var locationDto = await _locationAppService.GetByCodeAsync(detail.ToLocationCode).ConfigureAwait(false); + CheckLocation(locationDto, detail.ToLocationCode); + + var itemBasicDto = await _itemBasicAppService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false); + 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; + } + } + + return dictionary; + } + + /// + /// 导入验证 + /// + /// + /// + /// + protected override async Task ValidateImportModelAsync(ThirdLocationRequestImportInput model, + List validationRresult) + { + _ = new Dictionary(); + _ = await CheckItemBasicAsync(model, validationRresult).ConfigureAwait(false); + _ = await CheckLocationAsync(model, validationRresult).ConfigureAwait(false); + await CheckAreaAsync(model, validationRresult).ConfigureAwait(false); + await CheckStoreRelationAsync(model, validationRresult).ConfigureAwait(false); + } + + #region 校验 + + protected override async Task ValidateImportEntities(Dictionary dict) + { + foreach (var entity in dict.Keys) + { + var tranType = await TransactionTypeAclService + .GetByTransTypeAsync(EnumTransType.Issue, EnumTransSubType.None).ConfigureAwait(false); + + Check.NotNull(tranType, "事务类型", "事务类型不存在"); + + entity.AutoCompleteJob = tranType.AutoCompleteJob; + entity.AutoSubmit = tranType.AutoSubmitRequest; + entity.AutoAgree = tranType.AutoAgreeRequest; + entity.AutoHandle = tranType.AutoHandleRequest; + entity.DirectCreateNote = tranType.DirectCreateNote; + } + + return await base.ValidateImportEntities(dict).ConfigureAwait(false); + } + + protected async Task CheckItemBasicAsync(ThirdLocationRequestImportInput importInput, + List validationRresult) + { + var item = await _itemBasicAppService.GetByCodeAsync(importInput.ItemCode).ConfigureAwait(false); + if (item == null) + { + validationRresult.Add(new ValidationResult($"物品代码{importInput.ItemCode}不存在", new[] { "物品代码" })); + } + else if (item.StdPackQty == 0) + { + validationRresult.Add( + new ValidationResult($"物品代码{importInput.ItemCode}的物品信息中标准包装等于0或不存在", new[] { "标准包装" })); + } + + return item; + } + + protected async Task CheckLocationAsync(ThirdLocationRequestImportInput importInput, + List validationRresult) + { + var location = await _locationAppService.GetByCodeAsync(importInput.ToLocationCode).ConfigureAwait(false); + if (location == null) + { + validationRresult.Add(new ValidationResult($"目标库位{importInput.ToLocationCode}不存在", new[] { "目标库位" })); + } + + return location; + } + + protected async Task CheckAreaAsync(ThirdLocationRequestImportInput importInput, + List validationRresult) + { + var area = await _areaApp.GetByCodeAsync(importInput.FromLocationArea).ConfigureAwait(false); + if (area == null) + { + validationRresult.Add(new ValidationResult($"调出库区{importInput.FromLocationArea}不存在", new[] { "调出库区" })); + } + } + + protected async Task CheckStoreRelationAsync(ThirdLocationRequestImportInput importInput, + List validationRresult) + { + var itemStoreRelation = await _itemStoreRelationApp + .GetFirstAsync(importInput.ItemCode, importInput.ToLocationCode).ConfigureAwait(false); + if (itemStoreRelation == null) + { + validationRresult.Add(new ValidationResult( + $"物品代码{importInput.ItemCode}与目标库位{importInput.ToLocationCode}不存在对应关", new[] { "物品库位对应关系" })); + } + } + + #endregion + + #endregion + + #region 校验 + + private void CheckItemBasic(ItemBasicDTO ItemBasicDto, string itemCode) + { + if (ItemBasicDto == null) + { + throw new UserFriendlyException($"物品代码为【{itemCode}】不存在"); + } + } + + private void CheckLocation(LocationDTO LocationDto, string LocationCode) + { + if (LocationDto == null) + { + throw new UserFriendlyException($"库位代码为【{LocationCode}】不存在"); + } + + if (LocationDto.Type != EnumLocationType.WIP) + { + throw new UserFriendlyException($"库位代码【{LocationCode}】不是【{EnumLocationType.WIP.GetDisplayName()}】类型"); + } + } + + + #endregion +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAutoMapperProfile.cs new file mode 100644 index 000000000..856be3ddf --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ThirdLocationRequests/ThirdLocationRequestAutoMapperProfile.cs @@ -0,0 +1,72 @@ +using AutoMapper; +using Volo.Abp.AutoMapper; +using Win_in.Sfs.Shared.Domain.Shared; +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 ThirdLocationRequestAutoMapperProfile() + { + CreateMap() + .ReverseMap(); + + CreateMap() + .ReverseMap(); + + CreateMap() + .IgnoreAuditedObjectProperties() + .Ignore(x => x.ToLocationArea) + .Ignore(x => x.ToLocationGroup) + .Ignore(x => x.ToWarehouseCode) + .Ignore(x => x.MasterID) + .Ignore(x => x.TenantId) + .Ignore(x => x.Number) + .Ignore(x => x.Id); + + CreateMap() + .IgnoreAuditedObjectProperties() + .ForMember(x => x.Type, y => y.MapFrom(t => t.Type.ToString())) + .Ignore(x => x.ProdLine) + .Ignore(x => x.UseOnTheWayLocation) + .Ignore(x => x.Details) + .Ignore(x => x.Remark) + .Ignore(x => x.TenantId) + .Ignore(x => x.Number) + .Ignore(x => x.RequestStatus) + .Ignore(x => x.ConcurrencyStamp) + .Ignore(x => x.ExtraProperties) + .Ignore(x => x.ActiveDate) + .Ignore(x => x.Remark); + + CreateMap() + .IgnoreAuditedObjectProperties() + .ForMember(x => x.Status, y => y.MapFrom(t => EnumStatus.Open)) + .Ignore(x => x.ToLocationErpCode) + .Ignore(x => x.ToWarehouseCode) + .Ignore(x => x.ToLocationArea) + .Ignore(x => x.ToLocationGroup) + .Ignore(x => x.ItemName).Ignore(x => x.ItemDesc1).Ignore(x => x.ItemDesc2) + .Ignore(x => x.ProdLine) + .Ignore(x => x.WorkStation) + .Ignore(x => x.ExpiredTime) + .Ignore(x => x.IssuedQty) + .Ignore(x => x.ReceivedQty) + .Ignore(x => x.ToBeIssuedQty) + .Ignore(x => x.ToBeReceivedQty) + .Ignore(x => x.NotFinishQty) + .Ignore(x => x.StdPackQty) + .Ignore(x => x.Uom) + .Ignore(x => x.TenantId) + .Ignore(x => x.MasterID) + .Ignore(x => x.Number) + .Ignore(x => x.Id) + .Ignore(x => x.Remark); + CreateMap() + .IgnoreAuditedObjectProperties() + .Ignore(x => x.RequestStatus) + .Ignore(x => x.ConcurrencyStamp).Ignore(x => x.Id); + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/StoreApplicationAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/StoreApplicationAutoMapperProfile.cs index 8c64426d3..b59aa82f6 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/StoreApplicationAutoMapperProfile.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/StoreApplicationAutoMapperProfile.cs @@ -16,6 +16,7 @@ public partial class StoreApplicationAutoMapperProfile : Profile MaterialRequestAutoMapperProfile(); InjectionRequestAutoMapperProfile(); AssembleRequestAutoMapperProfile(); + ThirdLocationRequestAutoMapperProfile(); ProductionReturnRequestAutoMapperProfile(); ProductReceiptRequestAutoMapperProfile(); UnplannedIssueRequestAutoMapperProfile(); @@ -68,6 +69,7 @@ public partial class StoreApplicationAutoMapperProfile : Profile IssueNoteAutoMapperProfile(); InjectionNoteAutoMapperProfile(); AssembleNoteAutoMapperProfile(); + ThirdLocationNoteAutoMapperProfile(); ContainerNoteAutoMapperProfile(); ItemTransformNoteAutoMapperProfile(); JisDeliverNoteAutoMapperProfile(); @@ -103,6 +105,7 @@ public partial class StoreApplicationAutoMapperProfile : Profile IssueJobAutoMapperProfile(); InjectionJobAutoMapperProfile(); AssembleJobAutoMapperProfile(); + ThirdLocationJobAutoMapperProfile(); ContainerJobAutoMapperProfile(); JisDeliverJobAutoMapperProfile(); ProductReceiveJobAutoMapperProfile(); diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/IThirdLocationJobManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/IThirdLocationJobManager.cs new file mode 100644 index 000000000..6efac9ee7 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/IThirdLocationJobManager.cs @@ -0,0 +1,10 @@ +using System; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public interface IThirdLocationJobManager : IJobManager +{ + Task GetAsync(Expression> expression); +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/IThirdLocationJobRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/IThirdLocationJobRepository.cs new file mode 100644 index 000000000..5d1aecf6b --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/IThirdLocationJobRepository.cs @@ -0,0 +1,6 @@ +namespace Win_in.Sfs.Wms.Store.Domain; + +public interface IThirdLocationJobRepository : ISfsJobRepositoryBase +{ + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJob.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJob.cs new file mode 100644 index 000000000..705b787d2 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJob.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Win_in.Sfs.Shared.Domain.Entities; + +namespace Win_in.Sfs.Wms.Store.Domain; + +/// +/// 三方库库移任务 +/// +[Display(Name = "三方库库移任务")] +public class ThirdLocationJob : SfsJobAggregateRootBase +{ + /// + /// 叫料请求类型 + /// + [IgnoreUpdate] + public string RequestType { get; set; } + + /// + /// 生产线 + /// + [IgnoreUpdate] + public string ProdLine { get; set; } + + /// + /// 请求单号 + /// + [IgnoreUpdate] + public string RequestNumber { get; set; } + + /// + /// 车间 + /// + [IgnoreUpdate] + public string Workshop { get; set; } + + /// + /// 使用在途库 + /// + [Display(Name = "使用在途库")] + [IgnoreUpdate] + public bool UseOnTheWayLocation { get; set; } + + /// + /// 任务明细 + /// + [IgnoreUpdate] + public override List Details { get; set; } = new List(); + + /// + /// 设置任务明细的实际库位和实际数量 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public virtual async Task BuildDetail(Guid id, string handledLocationCode, string handledLocationErpCode, + string handledWarehouseCode, decimal handledQty, string handledSupplierBatch, DateTime handledArriveDate, DateTime handledProduceDate, DateTime handledExpireDate, + string handledContainerCode, string handledLot, string handledPackingCode) + { + var detail = GetDetail(id); + detail.HandledFromLocationCode = handledLocationCode; + detail.HandledFromLocationErpCode = handledLocationErpCode; + detail.HandledFromWarehouseCode = handledWarehouseCode; + detail.HandledQty = handledQty; + detail.HandledSupplierBatch = handledSupplierBatch; + detail.HandledArriveDate = handledArriveDate; + detail.HandledProduceDate = handledProduceDate; + detail.HandledExpireDate = handledExpireDate; + detail.HandledContainerCode = handledContainerCode; + detail.HandledLot = handledLot; + detail.HandledPackingCode = handledPackingCode; + await Task.CompletedTask.ConfigureAwait(false); + } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJobDetail.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJobDetail.cs new file mode 100644 index 000000000..91ffb30db --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJobDetail.cs @@ -0,0 +1,108 @@ +using System; +using Win_in.Sfs.Shared.Domain; +using Win_in.Sfs.Shared.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public class ThirdLocationJobDetail : SfsJobRecommendFromDetailEntityBase, IHasToLocation +{ + /// + /// 请求库位 + /// + public string RequestLocationCode { get; set; } + + /// + /// 到库位 + /// + public string ToLocationCode { get; set; } + + /// + /// 到库区 + /// + public string ToLocationArea { get; set; } + + /// + /// 到库位组 + /// + public string ToLocationGroup { get; set; } + + /// + /// 到ERP库位 + /// + public string ToLocationErpCode { get; set; } + + /// + /// 到仓库 + /// + public string ToWarehouseCode { get; set; } + + /// + /// 在途库库位 + /// + public string OnTheWayLocationCode { get; set; } + + /// + /// 生产线 + /// + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + public string WorkStation { get; set; } + + /// + /// 过期时间 + /// + public DateTime ExpiredTime { get; set; } + + /// + /// 工序 + /// + public string Operation { get; set; } + + /// + /// 配送方式 + /// + public EnumDistributionType DistributionType { get; set; } + + /// + /// 取整方式 + /// + public EnumTruncType TruncType { get; set; } + + /// + /// 取整后数量 + /// + public decimal RoundedQty { get; set; } + + /// + /// 计划拆分规则 + /// + public EnumPlannedSplitRule PlannedSplitRule { get; set; } + + /// + /// 计划开始时间 + /// + public DateTime PlanBeginTime { get; set; } + + /// + /// 每次配送数量 + /// + public decimal DeliveryQty { get; set; } + + /// + /// 位置码 + /// + public string PositionCode { get; set; } + + /// + /// 推荐类型 + /// + public EnumRecommendType RecommendType { get; set; } + + public void SetId(Guid id) + { + this.Id = id; + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJobManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJobManager.cs new file mode 100644 index 000000000..f9b8dc84a --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/ThirdLocationJobs/ThirdLocationJobManager.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Volo.Abp.Users; +using Volo.Abp.Validation; +using Win_in.Sfs.Shared.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public class ThirdLocationJobManager : SfsJobManagerBase, IThirdLocationJobManager +{ + + public ThirdLocationJobManager( + IThirdLocationJobRepository repository + ) : base(repository) + { + } + + /// + /// 执行任务 发料任务 + /// + /// + /// + /// + /// + public override async Task CompleteAsync(ThirdLocationJob input, ICurrentUser user) + { + var entity = await Repository.FindAsync(input.Id).ConfigureAwait(false); + + foreach (var detail in input.Details) + { + //发料子任务 赋值实际转移 + await entity.BuildDetail(detail.Id, + detail.HandledFromLocationCode, + detail.HandledFromLocationErpCode, + detail.HandledFromWarehouseCode, + detail.HandledQty, + detail.HandledSupplierBatch, + detail.HandledArriveDate, + detail.HandledProduceDate, + detail.HandledExpireDate, + detail.HandledContainerCode, + detail.HandledLot, + detail.HandledPackingCode).ConfigureAwait(false); + } + + return await base.CompleteAsync(entity, user).ConfigureAwait(false); + } + + public override void CheckDetails(ThirdLocationJob entity, AbpValidationResult result) + { + var details = entity.Details; + foreach (var detail in details) + { + if (detail.HandledFromLocationCode == null) + { + result.Errors.Add(new ValidationResult($"{detail.HandledFromLocationCode} 不能为空")); + } + + } + } + + public override async Task> 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> 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 GetAsync(Expression> expression) + { + return await Repository.FindAsync(expression).ConfigureAwait(false); + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/IThirdLocationNoteManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/IThirdLocationNoteManager.cs new file mode 100644 index 000000000..745ce7a8c --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/IThirdLocationNoteManager.cs @@ -0,0 +1,10 @@ +using System; +using System.Threading.Tasks; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public interface IThirdLocationNoteManager : ISfsStoreManager +{ + Task ConfirmAsync(Guid id); + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/IThirdLocationNoteRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/IThirdLocationNoteRepository.cs new file mode 100644 index 000000000..d034e4139 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/IThirdLocationNoteRepository.cs @@ -0,0 +1,6 @@ +namespace Win_in.Sfs.Wms.Store.Domain; + +public interface IThirdLocationNoteRepository : ISfsStoreRepositoryBase +{ + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNote.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNote.cs new file mode 100644 index 000000000..6f7d0dedf --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNote.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Volo.Abp; +using Win_in.Sfs.Shared.Domain.Entities; + +namespace Win_in.Sfs.Wms.Store.Domain; + +/// +/// 三方库库移记录 +/// +public class ThirdLocationNote : SfsStoreAggregateRootBase, IHasJobNumber, IHasRequestNumber +{ + /// + /// 任务ID + /// + [IgnoreUpdate] + public string JobNumber { get; set; } + + /// + /// 车间 + /// + [IgnoreUpdate] + public string Workshop { get; set; } + + /// + /// 明细列表 + /// + [IgnoreUpdate] + public override List Details { get; set; } = new List(); + + [IgnoreUpdate] + public string RequestNumber { get; set; } + + /// + /// 叫料请求类型 + /// + [IgnoreUpdate] + public string RequestType { get; set; } + + /// + /// 使用在途库 + /// + [IgnoreUpdate] + public bool UseOnTheWayLocation { get; set; } + + /// + /// 确认时间 + /// + [Display(Name = "确认时间")] + [IgnoreUpdate] + public DateTime? ConfirmTime { get; set; } + + /// + /// 已确认 + /// + [Display(Name = "已确认")] + public bool Confirmed { get; set; } + + public void Confirm(DateTime confirmTime) + { + + CheckStatus(Confirmed); + Confirmed = true; + ConfirmTime = confirmTime; + } + + private static void CheckStatus(bool confirmed) + { + if (confirmed) + { + throw new UserFriendlyException($"当前状态为 【已确认】 ,无法再次确认!"); + } + + } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNoteDetail.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNoteDetail.cs new file mode 100644 index 000000000..c9b6a230e --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNoteDetail.cs @@ -0,0 +1,43 @@ +using System; +using Win_in.Sfs.Shared.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public class ThirdLocationNoteDetail : SfsStoreRecommendFromDetailWithFromToEntityBase +{ + + /// + /// 发料时间 + /// + public DateTime IssueTime { get; set; } + + /// + /// 过期时间 + /// + public DateTime ExpiredTime { get; set; } + + /// + /// 生产线 + /// + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + public string WorkStation { get; set; } + + /// + /// 在途库库位 + /// + public string OnTheWayLocationCode { get; set; } + + /// + /// 位置码 + /// + public string PositionCode { get; set; } + + /// + /// 推荐类型 + /// + public EnumRecommendType RecommendType { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNoteManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNoteManager.cs new file mode 100644 index 000000000..d71b82c3e --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/ThirdLocationNotes/ThirdLocationNoteManager.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Volo.Abp; +using Volo.Abp.Uow; +using Win_in.Sfs.Shared.Event; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public class ThirdLocationNoteManager : SfsStoreManagerBase, IThirdLocationNoteManager +{ + + public ThirdLocationNoteManager( + IThirdLocationNoteRepository repository + ) : base(repository) + { + } + + [UnitOfWork] + public virtual async Task ConfirmAsync(Guid id) + { + var entity = await Repository.FindAsync(id).ConfigureAwait(false); + Check.NotNull(entity, EntityClassName); + entity.Confirm(Clock.Now); + await PublishConfirmedAsync(entity).ConfigureAwait(false); + return await Repository.UpdateAsync(entity).ConfigureAwait(false); + } + private async Task PublishConfirmedAsync(ThirdLocationNote entity) + { + try + { + await LocalEventBus.PublishAsync(new SfsConfirmedEntityEventData(entity), false).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.LogDebug($"{nameof(ThirdLocationNote)} Confirmed Event:{ex.Message}", null); + Console.WriteLine(ex.Source); + throw; + } + } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/IThirdLocationRequestManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/IThirdLocationRequestManager.cs new file mode 100644 index 000000000..d17413a2a --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/IThirdLocationRequestManager.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; + +namespace Win_in.Sfs.Wms.Store.Domain; + +using Win_in.Sfs.Shared.Domain; + +public interface IThirdLocationRequestManager : ISfsStoreRequestManager, + IBulkImportService +{ + + Task UpdateDetailsAsync(ThirdLocationRequest entity); + + Task CompleteAsync(string number); + + Task CreateBynNumberAsync(ThirdLocationRequest entity); +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/IThirdLocationRequestRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/IThirdLocationRequestRepository.cs new file mode 100644 index 000000000..9e9d4502e --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/IThirdLocationRequestRepository.cs @@ -0,0 +1,9 @@ +using Win_in.Sfs.Shared.Domain; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public interface IThirdLocationRequestRepository : ISfsStoreRepositoryBase, + ISfsBulkRepositoryBase +{ + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequest.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequest.cs new file mode 100644 index 000000000..8a2162664 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequest.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Win_in.Sfs.Shared.Domain.Entities; + +namespace Win_in.Sfs.Wms.Store.Domain; + +/// +/// 三方库移库申请 +/// +public class ThirdLocationRequest : SfsStoreRequestAggregateRootBase +{ + /// + /// 叫料类型 + /// + [Display(Name = "叫料类型")] + [IgnoreUpdate] + public string Type { get; set; } + + /// + /// 生产线 + /// + [IgnoreUpdate] + public string ProdLine { get; set; } + + /// + /// 使用在途库 + /// + public bool UseOnTheWayLocation { get; set; } + + /// + /// 明细列表 + /// + [IgnoreUpdate] + public override List Details { get; set; } = new List(); +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequestDetail.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequestDetail.cs new file mode 100644 index 000000000..e2f3f79ec --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequestDetail.cs @@ -0,0 +1,105 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Win_in.Sfs.Shared.Domain; +using Win_in.Sfs.Shared.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Domain; + +/// +/// 三方库申请明细 +/// +public class ThirdLocationRequestDetail : SfsStoreDetailWithQtyEntityBase, IHasToLocation +{ + /// + /// 到库位 + /// + public string ToLocationCode { get; set; } + + /// + /// 到库区 + /// + public string ToLocationArea { get; set; } + + /// + /// 到库位组 + /// + public string ToLocationGroup { get; set; } + + /// + /// 到ERP库位 + /// + public string ToLocationErpCode { get; set; } + + /// + /// 到仓库 + /// + public string ToWarehouseCode { get; set; } + + /// + /// 来源库区 + /// + public string FromLocationArea { get; set; } + + // /// + // /// 在途库库位 + // /// + // public string OnTheWayLocationCode { get; set; } + + /// + /// 生产线 + /// + public string ProdLine { get; set; } + + /// + /// 工作中心 + /// + public string WorkStation { get; set; } + + /// + /// 过期时间 + /// + public DateTime ExpiredTime { get; set; } + + /// + /// 已发数量 + /// + public decimal IssuedQty { get; set; } + + /// + /// 已收数量 + /// + public decimal ReceivedQty { get; set; } + + /// + /// 明细状态 + /// + public EnumStatus Status { get; set; } + + /// + /// 请求未发 还未发送的数量 + /// + [NotMapped] + public decimal ToBeIssuedQty => Qty - IssuedQty; + + /// + /// 已发未收 + /// + [NotMapped] + public decimal ToBeReceivedQty => IssuedQty - ReceivedQty; + + /// + /// 请求未收 + /// + [NotMapped] + public decimal NotFinishQty => Qty - ReceivedQty; + + /// + /// 位置码 + /// + public string PositionCode { get; set; } + + /// + /// 推荐类型 + /// + public EnumRecommendType RecommendType { get; set; } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequestManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequestManager.cs new file mode 100644 index 000000000..c9d45a6dc --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/ThirdLocationRequests/ThirdLocationRequestManager.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using DocumentFormat.OpenXml.Math; +using Win_in.Sfs.Shared.Domain.Shared; +using Win_in.Sfs.Shared.Event; +using static Win_in.Sfs.Wms.Store.Domain.Shared.StoreSettings; + +namespace Win_in.Sfs.Wms.Store.Domain; + +public class ThirdLocationRequestManager + : SfsStoreRequestManagerBase + , IThirdLocationRequestManager +{ + private readonly IThirdLocationRequestRepository _repository; + private readonly IIssueJobRepository _issueJobRepository; + + public ThirdLocationRequestManager( + IThirdLocationRequestRepository repository + , IIssueJobRepository issueJobRepository + ) : base(repository) + { + _repository = repository; + _issueJobRepository = issueJobRepository; + } + + + #region 东阳V2 + + #endregion + + + /// + /// 创建 + /// + /// + /// + public virtual async Task CreateBynNumberAsync(ThirdLocationRequest entity) + { + var number = string.IsNullOrEmpty(entity.Number) ? await GenerateNumberAsync(nameof(ThirdLocationRequest), entity.ActiveDate).ConfigureAwait(false) : entity.Number; + entity.SetIdAndNumberWithDetails(GuidGenerator, number); + entity.Submit(); + entity.Agree(); + entity.RequestStatus = EnumRequestStatus.Partial; + await LocalEventBus.PublishAsync(new SfsHandledEntityEventData(entity), false) + .ConfigureAwait(false); + await _repository.InsertAsync(entity).ConfigureAwait(false); + return entity; + } + + public virtual async Task UpdateDetailsAsync(ThirdLocationRequest newEntity) + { + var oldEntity = await Repository.FindAsync(newEntity.Id, true).ConfigureAwait(false); + if(oldEntity!=null) + { + foreach (var newDetail in newEntity.Details) + { + oldEntity.ReplaceDetail(newDetail.Id, newDetail); + } + + foreach (var detail in oldEntity.Details) + { + SetMaterialRequestDetailStatus(detail); + } + + await SetMaterialRequestStatusAsync(oldEntity).ConfigureAwait(false); + + await Repository.UpdateAsync(oldEntity).ConfigureAwait(false); + } + + } + + private void SetMaterialRequestDetailStatus(ThirdLocationRequestDetail detail) + { + if (detail.ReceivedQty >= detail.Qty)//执行的时候 实际收料 多余 要料数 + { + detail.Status = EnumStatus.Close; + } + else + { + detail.Status = EnumStatus.Open; + } + } + + private async Task SetMaterialRequestStatusAsync(ThirdLocationRequest materialRequest) + { + if (materialRequest.Details.All(p => p.Status == EnumStatus.Close)) + { + materialRequest.RequestStatus = EnumRequestStatus.Completed; + } + else + { + var issueJobs = await _issueJobRepository.GetListAsync(t => t.MaterialRequestNumber == materialRequest.Number).ConfigureAwait(false); + if (issueJobs.Count > 0) + { + if (issueJobs.All(t => t.JobStatus is EnumJobStatus.Done or EnumJobStatus.Closed or EnumJobStatus.Cancelled)) + { + if (materialRequest.Details.All(p => p.ReceivedQty >= p.Qty)) + { + materialRequest.RequestStatus = EnumRequestStatus.Completed; + } + else + { + materialRequest.RequestStatus = EnumRequestStatus.Partial; + } + } + else + { + materialRequest.RequestStatus = EnumRequestStatus.Partial; + } + } + else + { + materialRequest.RequestStatus = EnumRequestStatus.Partial; + } + } + } + + public virtual async Task CompleteAsync(string number) + { + var entity = await GetByNumberAsync(number).ConfigureAwait(false); + if (entity != null && !entity.Details.Any(p => p.ToBeIssuedQty > 0)) + { + await CompleteAsync(entity).ConfigureAwait(false); + } + } + + + #region 导入 + + /// + /// 执行导入 + /// + public virtual async Task ImportDataAsync(List mergeEntities, List deleteEntities = null) + { + if (deleteEntities != null && deleteEntities.Count > 0) + { + await _repository.BulkDeleteAsync(deleteEntities).ConfigureAwait(false); + } + + await CreateManyAsync(mergeEntities).ConfigureAwait(false); + } + + #endregion + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/IStoreDbContext.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/IStoreDbContext.cs index 9f178d167..ab42ce15c 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/IStoreDbContext.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/IStoreDbContext.cs @@ -23,6 +23,7 @@ public interface IStoreDbContext : IEfCoreDbContext public DbSet MaterialRequests { get; } public DbSet InjectionRequests { get; } public DbSet AssembleRequests { get; } + public DbSet ThirdLocationRequests { get; } public DbSet ContainerRequests { get; } public DbSet DeliverRequests { get; } public DbSet InspectRequests { get; } @@ -79,6 +80,7 @@ public interface IStoreDbContext : IEfCoreDbContext public DbSet IssueNotes { get; } public DbSet InjectionNotes { get; } public DbSet AssembleNotes { get; } + public DbSet ThirdLocationNotes { get; } public DbSet ContainerNotes { get; } public DbSet UnplannedReceiptNotes { get; } public DbSet UnplannedIssueNotes { get; } @@ -106,6 +108,7 @@ public interface IStoreDbContext : IEfCoreDbContext public DbSet IssueJobs { get; } public DbSet InjectionJobs { get; } public DbSet AssembleJobs { get; } + public DbSet ThirdLocationJobs { get; } public DbSet ContainerJobs { get; } public DbSet DeliverJobs { get; } public DbSet JisDeliverJobs { get; } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ThirdLocationJobs/ThirdLocationJobDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ThirdLocationJobs/ThirdLocationJobDbContextModelCreatingExtensions.cs new file mode 100644 index 000000000..492ecff82 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ThirdLocationJobs/ThirdLocationJobDbContextModelCreatingExtensions.cs @@ -0,0 +1,69 @@ +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 ThirdLocationJobDbContextModelCreatingExtensions +{ + public static void ConfigureThirdLocationJob(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options) + { + builder.Entity(b => + { + //Configure table & schema name + b.ToTable(StoreDbProperties.JobDbTablePrefix + nameof(ThirdLocationJob), options.Schema); + //Configure ABP properties + b.ConfigureByConvention(); + //Configure Sfs base properties + b.ConfigureSfsBase(); + //Configure Job base properties + b.ConfigureJob(); + //Properties + b.Property(q => q.RequestType).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.RequestNumber).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.Workshop).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ProdLine).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(ThirdLocationJobDetail), options.Schema); + //Configure ABP properties + b.ConfigureByConvention(); + //Configure Sfs base properties + b.ConfigureSfsBase(); + //Configure Job base properties + b.ConfigureJobRecommendFromDetail(); + //Properties + b.Property(q => q.ExpiredTime).IsRequired(); + b.Property(q => q.ToLocationCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToLocationErpCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToWarehouseCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToLocationArea).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToLocationGroup).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.RequestLocationCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ProdLine).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.WorkStation).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.Operation).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.DistributionType).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + b.Property(q => q.TruncType).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + b.Property(q => q.PlannedSplitRule).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + b.Property(q => q.OnTheWayLocationCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.PositionCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.RecommendType).HasMaxLength(SfsPropertyConst.CodeLength).HasConversion(); + + //Relations + //None + + //Indexes + //b.HasIndex(q => new { q.PackingCode }).IsUnique(); + }); + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ThirdLocationJobs/ThirdLocationJobEfCoreRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ThirdLocationJobs/ThirdLocationJobEfCoreRepository.cs new file mode 100644 index 000000000..20d2fb313 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/ThirdLocationJobs/ThirdLocationJobEfCoreRepository.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 ThirdLocationJobEfCoreRepository : SfsJobEfCoreRepositoryBase, IThirdLocationJobRepository +{ + public ThirdLocationJobEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/ThirdLocationNotes/ThirdLocationNoteDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/ThirdLocationNotes/ThirdLocationNoteDbContextModelCreatingExtensions.cs new file mode 100644 index 000000000..5cfee77f2 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/ThirdLocationNotes/ThirdLocationNoteDbContextModelCreatingExtensions.cs @@ -0,0 +1,63 @@ +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 ThirdLocationNoteDbContextModelCreatingExtensions +{ + public static void ConfigureThirdLocationNote(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options) + { + builder.Entity(b => + { + //Configure table & schema name + b.ToTable(options.TablePrefix + nameof(ThirdLocationNote), options.Schema); + //Configure ABP properties + b.ConfigureByConvention(); + //Configure Sfs base properties + b.ConfigureSfsStoreBase(); + + //Properties + b.Property(q => q.RequestNumber).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.RequestType).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.Workshop).HasMaxLength(SfsPropertyConst.NameLength); + b.Property(q => q.Remark).HasMaxLength(SfsPropertyConst.RemarkLength); + + //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(options.TablePrefix + nameof(ThirdLocationNoteDetail), 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.IssueTime).IsRequired(); + b.Property(q => q.ExpiredTime).IsRequired(); + b.Property(q => q.ProdLine).HasMaxLength(SfsPropertyConst.NameLength); + b.Property(q => q.WorkStation).HasMaxLength(SfsPropertyConst.NameLength); + b.Property(q => q.OnTheWayLocationCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.FromStatus).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + b.Property(q => q.ToStatus).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + b.Property(q => q.PositionCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.RecommendType).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + + //Relations + + //Indexes + b.HasIndex(q => new { q.Number, q.FromPackingCode, q.FromLocationCode, q.ToLocationCode }).IsUnique(); + b.HasIndex(q => new { q.FromPackingCode }); + }); + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/ThirdLocationNotes/ThirdLocationNoteEfCoreRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/ThirdLocationNotes/ThirdLocationNoteEfCoreRepository.cs new file mode 100644 index 000000000..5dc7b0783 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/ThirdLocationNotes/ThirdLocationNoteEfCoreRepository.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 ThirdLocationNoteEfCoreRepository : SfsStoreEfCoreRepositoryBase, IThirdLocationNoteRepository +{ + public ThirdLocationNoteEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/ThirdLocationRequests/ThirdLocationRequestDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/ThirdLocationRequests/ThirdLocationRequestDbContextModelCreatingExtensions.cs new file mode 100644 index 000000000..8884bf84b --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/ThirdLocationRequests/ThirdLocationRequestDbContextModelCreatingExtensions.cs @@ -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 ThirdLocationRequestDbContextModelCreatingExtensions +{ + public static void ConfigureThirdLocationRequest(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options) + { + builder.Entity(b => + { + //Configure table & schema name + b.ToTable(options.TablePrefix + nameof(ThirdLocationRequest), 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.ProdLine).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.RequestStatus).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + + //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(options.TablePrefix + nameof(ThirdLocationRequestDetail), 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.ToLocationCode).IsRequired().HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToLocationErpCode).IsRequired().HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToWarehouseCode).IsRequired().HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToLocationArea).IsRequired().HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ToLocationGroup).IsRequired().HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.ExpiredTime).IsRequired(); + b.Property(q => q.ProdLine).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.WorkStation).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.IssuedQty).HasPrecision(18, 6); + b.Property(q => q.ReceivedQty).HasPrecision(18, 6); + b.Property(q => q.Status).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + b.Property(q => q.PositionCode).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.RecommendType).HasMaxLength(SfsPropertyConst.NameLength).HasConversion(); + + //Relations + + //Indexes + b.HasIndex(q => new { q.Number, q.ItemCode, q.ToLocationCode }).IsUnique(); + b.HasIndex(q => new { q.ItemCode }); + }); + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/ThirdLocationRequests/ThirdLocationRequestEfCoreRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/ThirdLocationRequests/ThirdLocationRequestEfCoreRepository.cs new file mode 100644 index 000000000..ab76a9fbc --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/ThirdLocationRequests/ThirdLocationRequestEfCoreRepository.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 ThirdLocationRequestEfCoreRepository : SfsStoreEfCoreRepositoryBase, IThirdLocationRequestRepository +{ + public ThirdLocationRequestEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContext.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContext.cs index 714637c10..c2caf997b 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContext.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContext.cs @@ -23,6 +23,7 @@ public class StoreDbContext : AbpDbContext, IStoreDbContext public DbSet MaterialRequests { get; set; } public DbSet InjectionRequests { get; set; } public DbSet AssembleRequests { get; set; } + public DbSet ThirdLocationRequests { get; set; } public DbSet ContainerRequests { get; set; } public DbSet DeliverRequests { get; set; } public DbSet InspectRequests { get; set; } @@ -79,6 +80,7 @@ public class StoreDbContext : AbpDbContext, IStoreDbContext public DbSet IssueNotes { get; set; } public DbSet InjectionNotes { get; set; } public DbSet AssembleNotes { get; set; } + public DbSet ThirdLocationNotes { get; set; } public DbSet ContainerNotes { get; set; } public DbSet UnplannedReceiptNotes { get; set; } public DbSet UnplannedIssueNotes { get; set; } @@ -106,6 +108,7 @@ public class StoreDbContext : AbpDbContext, IStoreDbContext public DbSet IssueJobs { get; set; } public DbSet InjectionJobs { get; set; } public DbSet AssembleJobs { get; set; } + public DbSet ThirdLocationJobs { get; set; } public DbSet ContainerJobs { get; set; } public DbSet DeliverJobs { get; set; } public DbSet JisDeliverJobs { get; set; } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContextModelCreatingExtensions.cs index cd0750295..112722839 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContextModelCreatingExtensions.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreDbContextModelCreatingExtensions.cs @@ -49,6 +49,7 @@ public static class StoreDbContextModelCreatingExtensions builder.ConfigureMaterialRequest(options); builder.ConfigureInjectionRequest(options); builder.ConfigureAssembleRequest(options); + builder.ConfigureThirdLocationRequest(options); builder.ConfigureDeliverRequest(options); builder.ConfigureContainerRequest(options); builder.ConfigureInspectRequest(options); @@ -86,6 +87,7 @@ public static class StoreDbContextModelCreatingExtensions builder.ConfigureIssueNote(options); builder.ConfigureInjectionNote(options); builder.ConfigureAssembleNote(options); + builder.ConfigureThirdLocationNote(options); builder.ConfigureContainerNote(options); builder.ConfigureUnplannedReceiptNote(options); builder.ConfigureUnplannedIssueNote(options); @@ -113,6 +115,7 @@ public static class StoreDbContextModelCreatingExtensions builder.ConfigureIssueJob(options); builder.ConfigureInjectionJob(options); builder.ConfigureAssembleJob(options); + builder.ConfigureThirdLocationJob(options); builder.ConfigureContainerJob(options); builder.ConfigureDeliverJob(options); builder.ConfigureJisDeliverJob(options); diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreEntityFrameworkCoreModule.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreEntityFrameworkCoreModule.cs index 997949441..9dadc3a40 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreEntityFrameworkCoreModule.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/StoreEntityFrameworkCoreModule.cs @@ -60,6 +60,7 @@ public class StoreEntityFrameworkCoreModule : AbpModule context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); + context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); @@ -102,6 +103,7 @@ public class StoreEntityFrameworkCoreModule : AbpModule context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); + context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); @@ -131,6 +133,7 @@ public class StoreEntityFrameworkCoreModule : AbpModule context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); + context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); context.Services.AddTransient(); @@ -198,6 +201,8 @@ public class StoreEntityFrameworkCoreModule : AbpModule orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); + options.Entity(orderOptions => + orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => @@ -253,6 +258,8 @@ public class StoreEntityFrameworkCoreModule : AbpModule orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); + options.Entity(orderOptions => + orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => @@ -328,6 +335,8 @@ public class StoreEntityFrameworkCoreModule : AbpModule orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); + options.Entity(orderOptions => + orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details)); options.Entity(orderOptions => diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Jobs/ThirdLocationJobAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Jobs/ThirdLocationJobAutoMapperProfile.cs new file mode 100644 index 000000000..d9c309ed5 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Jobs/ThirdLocationJobAutoMapperProfile.cs @@ -0,0 +1,92 @@ +using System; +using AutoMapper; +using Volo.Abp.AutoMapper; +using Win_in.Sfs.Shared.Application; +using Win_in.Sfs.Wms.Inventory.Application.Contracts; +using Win_in.Sfs.Wms.Store.Application.Contracts; +using Win_in.Sfs.Wms.Store.Domain; + +namespace Win_in.Sfs.Wms.Store.Event; + +public partial class StoreEventAutoMapperProfile : Profile +{ + private void ThirdLocationJobAutoMapperProfile() + { + + CreateMap() + .ForMember(x => x.JobNumber, y => y.MapFrom(d => d.Number)) + .ForMember(x => x.RequestNumber, y => y.MapFrom(d => d.RequestNumber)) + .ForMember(x => x.ActiveDate, y => y.MapFrom(d => DateTime.Now)) + .ForMember(x => x.Worker, y => y.MapFrom(d => d.CompleteUserName)) + .Ignore(x => x.Confirmed) + .Ignore(x => x.Number) + .Ignore(x => x.ConfirmTime); + + CreateMap() + .ForMember(x => x.FromPackingCode, y => y.MapFrom(d => d.HandledPackingCode)) + .ForMember(x => x.ToPackingCode, y => y.MapFrom(d => d.HandledPackingCode)) + .ForMember(x => x.SupplierBatch, y => y.MapFrom(d => d.HandledSupplierBatch)) + .ForMember(x => x.ArriveDate, y => y.MapFrom(d => d.HandledArriveDate)) + .ForMember(x => x.ProduceDate, y => y.MapFrom(d => d.HandledProduceDate)) + .ForMember(x => x.ExpireDate, y => y.MapFrom(d => d.HandledExpireDate)) + .ForMember(x => x.FromLot, y => y.MapFrom(d => d.HandledLot)) + .ForMember(x => x.ToLot, y => y.MapFrom(d => d.HandledLot)) + .ForMember(x => x.ToContainerCode, y => y.MapFrom(d => d.HandledContainerCode)) + .ForMember(x => x.FromContainerCode, y => y.MapFrom(d => d.HandledContainerCode)) + .ForMember(x => x.FromStatus, y => y.MapFrom(d => d.Status)) + .ForMember(x => x.ToStatus, y => y.MapFrom(d => d.Status)) + .ForMember(x => x.Qty, y => y.MapFrom(d => d.HandledQty)) + .ForMember(x => x.IssueTime, y => y.MapFrom(d => DateTime.Now)) + .ForMember(x => x.FromLocationCode, y => y.MapFrom(d => d.HandledFromLocationCode)) + .ForMember(x => x.FromLocationArea, y => y.MapFrom(d => d.HandledFromLocationArea)) + .ForMember(x => x.FromLocationGroup, y => y.MapFrom(d => d.HandledFromLocationGroup)) + .ForMember(x => x.FromLocationErpCode, y => y.MapFrom(d => d.HandledFromLocationErpCode)) + .ForMember(x => x.FromWarehouseCode, y => y.MapFrom(d => d.HandledFromWarehouseCode)) + .ForMember(x => x.ToLocationCode, y => y.MapFrom(d => d.ToLocationCode)) + .Ignore(x => x.ToLocationArea) + .Ignore(x => x.ToLocationGroup) + .Ignore(x => x.ToLocationErpCode) + ; + + CreateMap() + .MapExpectInOutFrom() + .Ignore(x => x.Worker) + .Ignore(x => x.SerialNumber) + .Ignore(x => x.ExtraProperties) + ; + + CreateMap() + .MapExpectInOutFrom() + .Ignore(x => x.Worker) + .Ignore(x => x.SerialNumber) + .Ignore(x => x.ExtraProperties); + + CreateMap() + .ForMember(x => x.RequestNumber, y => y.MapFrom(d => d.RequestNumber)) + .Ignore(x => x.Confirmed) + .Ignore(x => x.JobNumber) + .Ignore(x => x.ActiveDate) + ; + CreateMap() + .ForMember(x => x.Qty, y => y.MapFrom(d => d.HandledQty)) + .ForMember(x => x.IssueTime, y => y.MapFrom(d => DateTime.Now)) + .ForMember(x => x.FromPackingCode, y => y.MapFrom(d => d.HandledPackingCode)) + .ForMember(x => x.ToPackingCode, y => y.MapFrom(d => d.HandledPackingCode)) + .ForMember(x => x.FromContainerCode, y => y.MapFrom(d => d.HandledContainerCode)) + .ForMember(x => x.ToContainerCode, y => y.MapFrom(d => d.HandledContainerCode)) + .ForMember(x => x.FromLot, y => y.MapFrom(d => d.HandledLot)) + .ForMember(x => x.ToLot, y => y.MapFrom(d => d.HandledLot)) + .ForMember(x => x.SupplierBatch, y => y.MapFrom(d => d.HandledSupplierBatch)) + .ForMember(x => x.ArriveDate, y => y.MapFrom(d => d.HandledArriveDate)) + .ForMember(x => x.ProduceDate, y => y.MapFrom(d => d.HandledProduceDate)) + .ForMember(x => x.ExpireDate, y => y.MapFrom(d => d.ExpiredTime)) + .ForMember(x => x.FromLocationCode, y => y.MapFrom(d => d.HandledFromLocationCode)) + .ForMember(x => x.FromLocationArea, y => y.MapFrom(d => d.HandledFromLocationArea)) + .ForMember(x => x.FromLocationGroup, y => y.MapFrom(d => d.HandledFromLocationGroup)) + .ForMember(x => x.FromLocationErpCode, y => y.MapFrom(d => d.HandledFromLocationErpCode)) + .ForMember(x => x.FromWarehouseCode, y => y.MapFrom(d => d.HandledFromWarehouseCode)) + .ForMember(x => x.FromStatus, y => y.MapFrom(d => d.Status)) + .ForMember(x => x.ToStatus, y => y.MapFrom(d => d.Status)) + ; + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Notes/ThirdLocationNoteAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Notes/ThirdLocationNoteAutoMapperProfile.cs new file mode 100644 index 000000000..b9f8cdb54 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Notes/ThirdLocationNoteAutoMapperProfile.cs @@ -0,0 +1,22 @@ +using AutoMapper; +using Volo.Abp.AutoMapper; +using Win_in.Sfs.Wms.Inventory.Application.Contracts; +using Win_in.Sfs.Wms.Store.Domain; + +namespace Win_in.Sfs.Wms.Store.Event; + +public partial class StoreEventAutoMapperProfile : Profile +{ + private void ThirdLocationNoteAutoMapperProfile() + { + CreateMap() + .Ignore(x => x.DocNumber) + .Ignore(x => x.JobNumber) + .Ignore(x => x.Worker) + .Ignore(x => x.TransType) + .Ignore(x => x.ExtraProperties) + .Ignore(x => x.TransSubType) + ; + } + +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/ThirdLocationRequestAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/ThirdLocationRequestAutoMapperProfile.cs new file mode 100644 index 000000000..46358c324 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/ThirdLocationRequestAutoMapperProfile.cs @@ -0,0 +1,135 @@ +using AutoMapper; +using Volo.Abp.AutoMapper; +using Win_in.Sfs.Shared.Application; +using Win_in.Sfs.Wms.Inventory.Application.Contracts; +using Win_in.Sfs.Wms.Store.Application.Contracts; +using Win_in.Sfs.Wms.Store.Domain; + +namespace Win_in.Sfs.Wms.Store.Event; + +public partial class StoreEventAutoMapperProfile : Profile +{ + private void ThirdLocationRequestAutoMapperProfile() + { + CreateMap() + .ForMember(x => x.RequestNumber, y => y.MapFrom(d => d.Number)) + .ForMember(x => x.RequestType, y => y.MapFrom(d => d.Type)) + .Ignore(x => x.WarehouseCode) + .Ignore(x => x.Workshop) + .Ignore(x => x.UpStreamJobNumber) + .Ignore(x => x.JobType) + .Ignore(x => x.IsAutoComplete) + .Ignore(x => x.ExpiredTime) + .Ignore(x => x.JobDescription) + .Ignore(x => x.JobStatus) + .Ignore(x => x.WorkGroupCode) + .Ignore(x => x.Priority) + .Ignore(x => x.PriorityIncrement) + .Ignore(x => x.AcceptUserId) + .Ignore(x => x.AcceptTime) + .Ignore(x => x.AcceptUserName) + .Ignore(x => x.CompleteUserId) + .Ignore(x => x.CompleteUserName) + .Ignore(x => x.CompleteTime) + .Ignore(x => x.Details) + ; + + CreateMap() + .ForMember(x => x.RequestLocationCode, y => y.MapFrom(d => d.ToLocationCode)) + .Ignore(x => x.RecommendFromLocationArea) + .Ignore(x => x.RecommendFromLocationGroup) + .Ignore(x => x.HandledFromLocationArea) + .Ignore(x => x.HandledFromLocationGroup) + .Ignore(x => x.RecommendFromWarehouseCode) + .Ignore(x => x.HandledFromWarehouseCode) + .Ignore(x => x.OnTheWayLocationCode) + .Ignore(x => x.DistributionType) + .Ignore(x => x.RoundedQty) + .Ignore(x => x.Operation) + .Ignore(x => x.ExpiredTime) + .Ignore(x => x.TruncType) + .Ignore(x => x.PlanBeginTime) + .Ignore(x => x.PlannedSplitRule) + .Ignore(x => x.DeliveryQty) + .Ignore(x => x.Status) + .Ignore(x => x.RecommendContainerCode) + .Ignore(x => x.StdPackQty) + .Ignore(x => x.RecommendPackingCode) + .Ignore(x => x.HandledContainerCode) + .Ignore(x => x.HandledPackingCode) + .Ignore(x => x.RecommendSupplierBatch) + .Ignore(x => x.RecommendProduceDate) + .Ignore(x => x.RecommendArriveDate) + .Ignore(x => x.RecommendExpireDate) + .Ignore(x => x.HandledFromLocationCode) + .Ignore(x => x.HandledFromLocationErpCode) + .Ignore(x => x.HandledUom) + .Ignore(x => x.RecommendFromLocationErpCode) + .Ignore(x => x.HandledExpireDate) + .Ignore(x => x.HandledLot) + .Ignore(x => x.HandledArriveDate) + .Ignore(x => x.HandledProduceDate) + .Ignore(x => x.HandledQty) + .Ignore(x => x.RecommendQty) + .Ignore(x => x.Uom) + .Ignore(x => x.HandledSupplierBatch) + .Ignore(x => x.RecommendFromLocationCode) + .Ignore(x => x.RecommendLot) + .IgnoreIHasRecommendAndHandledFrom(); + + CreateMap() + .ForMember(x => x.RecommendArriveDate, y => y.MapFrom(d => d.ArriveDate)) + .ForMember(x => x.RecommendContainerCode, y => y.MapFrom(d => d.ContainerCode)) + .ForMember(x => x.RecommendExpireDate, y => y.MapFrom(d => d.ExpireDate)) + .ForMember(x => x.RecommendFromLocationCode, y => y.MapFrom(d => d.LocationCode)) + .ForMember(x => x.RecommendFromLocationErpCode, y => y.MapFrom(d => d.LocationErpCode)) + .ForMember(x => x.RecommendFromWarehouseCode, y => y.MapFrom(d => d.WarehouseCode)) + .ForMember(x => x.RecommendFromLocationArea, y => y.MapFrom(d => d.LocationArea)) + .ForMember(x => x.RecommendFromLocationGroup, y => y.MapFrom(d => d.LocationGroup)) + .ForMember(x => x.RecommendLot, y => y.MapFrom(d => d.Lot)) + .ForMember(x => x.RecommendPackingCode, y => y.MapFrom(d => d.PackingCode)) + .ForMember(x => x.RecommendProduceDate, y => y.MapFrom(d => d.ProduceDate)) + .ForMember(x => x.RecommendQty, y => y.MapFrom(d => d.Qty)) + .ForMember(x => x.RecommendSupplierBatch, y => y.MapFrom(d => d.SupplierBatch)) + .ForMember(x => x.Uom, y => y.MapFrom(d => d.Uom)).Ignore(x => x.HandledArriveDate) + .Ignore(x => x.HandledFromLocationArea) + .Ignore(x => x.HandledFromLocationGroup) + .Ignore(x => x.ToLocationErpCode) + .Ignore(x => x.ToWarehouseCode) + .Ignore(x => x.ToLocationArea) + .Ignore(x => x.ToLocationGroup) + .Ignore(x => x.HandledFromWarehouseCode) + .Ignore(x => x.RequestLocationCode) + .Ignore(x => x.ToLocationCode) + .Ignore(x => x.ProdLine) + .Ignore(x => x.WorkStation) + .Ignore(x => x.HandledContainerCode) + .Ignore(x => x.HandledExpireDate) + .Ignore(x => x.HandledFromLocationCode) + .Ignore(x => x.HandledFromLocationErpCode) + .Ignore(x => x.HandledLot) + .Ignore(x => x.HandledPackingCode) + .Ignore(x => x.HandledProduceDate) + .Ignore(x => x.HandledQty) + .Ignore(x => x.HandledSupplierBatch) + .Ignore(x => x.HandledUom) + .Ignore(x => x.Remark) + .Ignore(x => x.OnTheWayLocationCode) + .Ignore(x => x.DistributionType) + .Ignore(x => x.RoundedQty) + .Ignore(x => x.Operation) + .Ignore(x => x.ExpiredTime) + .Ignore(x => x.TruncType) + .Ignore(x => x.PlanBeginTime) + .Ignore(x => x.PlannedSplitRule) + .Ignore(x => x.DeliveryQty) + .Ignore(x => x.RequestLocationCode) + .Ignore(x => x.ToLocationCode) + .Ignore(x => x.ProdLine) + .Ignore(x => x.WorkStation) + .Ignore(x => x.PositionCode) + .Ignore(x => x.RecommendType) + .IgnoreIHasRecommendAndHandledFrom(); + + } +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/ThirdLocationJobEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/ThirdLocationJobEventHandler.cs new file mode 100644 index 000000000..68ff4ee5c --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/ThirdLocationJobEventHandler.cs @@ -0,0 +1,130 @@ +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.Basedata.Application.Contracts; +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; +using Win_in.Sfs.Wms.Store.Domain.Shared; + +namespace Win_in.Sfs.Wms.Store.Event.BusinessJob; + +public class ThirdLocationJobEventHandler : + StoreEventHandlerBase + , ILocalEventHandler> +{ + private const EnumTransType TransType = EnumTransType.Issue; + + private readonly IThirdLocationNoteAppService _thirdLocationNoteAppService; + private readonly ILocationAppService _locationAppService; + + public ThirdLocationJobEventHandler(IThirdLocationNoteAppService thirdLocationNoteAppService, ILocationAppService locationAppService) + { + _thirdLocationNoteAppService = thirdLocationNoteAppService; + _locationAppService = locationAppService; + } + + /// + /// 执行后 + /// + /// + /// + [UnitOfWork] + public virtual async Task HandleEventAsync(SfsCompletedEntityEventData eventData) + { + var entity = eventData.Entity; + var thirdLocationNote = await BuildThirdLocationNoteAsync(entity).ConfigureAwait(false); + await _thirdLocationNoteAppService.CreateAsync(thirdLocationNote).ConfigureAwait(false); + } + + #region 私有 + + /// + /// 创建补料记录实体 + /// + /// + /// + private async Task BuildThirdLocationNoteAsync(ThirdLocationJob entity) + { + var thirdLocationNoteCreateInput = ObjectMapper.Map(entity); + thirdLocationNoteCreateInput.JobNumber = entity.Number; + var locationCodes = thirdLocationNoteCreateInput.Details.Select(p => p.ToLocationCode).Distinct().ToList(); + var locations = await _locationAppService.GetByCodesAsync(locationCodes).ConfigureAwait(false); + + thirdLocationNoteCreateInput.Details.RemoveAll(p => p.Qty == 0); + + foreach (var detail in thirdLocationNoteCreateInput.Details) + { + var location = locations.First(p => p.Code == detail.ToLocationCode); + await RemovePackingCodeAndContainerCodeAndLotAsync(detail, location.Type).ConfigureAwait(false); //去箱 去托 去批 + + detail.ToLocationArea = location.AreaCode; + detail.ToLocationGroup = location.LocationGroupCode; + detail.ToLocationErpCode = location.ErpLocationCode; + detail.ToWarehouseCode = location.WarehouseCode; + } + + return thirdLocationNoteCreateInput; + } + + /// + /// 去除箱码 托码 批次 + /// + private async Task RemovePackingCodeAndContainerCodeAndLotAsync(ThirdLocationNoteDetailInput thirdLocationNoteDetail, + EnumLocationType locationType) + { + switch (locationType) + { + case EnumLocationType.WIP: + { + //用开关控制 发料到线边后去除箱码和托码 ??? + if (await SettingManager.IsTrueAsync(StoreSettings.Issue.ToWip.IsRemovePackingCode) + .ConfigureAwait(false)) + { + thirdLocationNoteDetail.ToPackingCode = ""; + } + + if (await SettingManager.IsTrueAsync(StoreSettings.Issue.ToWip.IsRemoveContainerCode) + .ConfigureAwait(false)) + { + thirdLocationNoteDetail.ToContainerCode = ""; + } + + if (await SettingManager.IsTrueAsync(StoreSettings.Issue.ToWip.IsRemoveLot).ConfigureAwait(false)) + { + thirdLocationNoteDetail.ToLot = ""; + } + + break; + } + case EnumLocationType.SEMI: + { + //用开关控制 发料到后去除箱码和托码 ??? + if (await SettingManager.IsTrueAsync(StoreSettings.Issue.ToSemi.IsRemovePackingCode) + .ConfigureAwait(false)) + { + thirdLocationNoteDetail.ToPackingCode = ""; + } + + if (await SettingManager.IsTrueAsync(StoreSettings.Issue.ToSemi.IsRemoveContainerCode) + .ConfigureAwait(false)) + { + thirdLocationNoteDetail.ToContainerCode = ""; + } + + if (await SettingManager.IsTrueAsync(StoreSettings.Issue.ToSemi.IsRemoveLot).ConfigureAwait(false)) + { + thirdLocationNoteDetail.ToLot = ""; + } + + break; + } + } + } + + #endregion +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/ThirdLocationRequestEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/ThirdLocationRequestEventHandler.cs new file mode 100644 index 000000000..46bc67846 --- /dev/null +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/ThirdLocationRequestEventHandler.cs @@ -0,0 +1,283 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FluentValidation.Validators; +using Volo.Abp; +using Volo.Abp.EventBus; +using Volo.Abp.SettingManagement; +using Win_in.Sfs.Basedata.Application.Contracts; +using Win_in.Sfs.Shared.Domain.Shared; +using Win_in.Sfs.Shared.Event; +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; + +namespace Win_in.Sfs.Wms.Store.Event.BusinessRequest; + +public class ThirdLocationRequestEventHandler + : StoreEventHandlerBase + , ILocalEventHandler> + , ILocalEventHandler> + , ILocalEventHandler> + , ILocalEventHandler> + , ILocalEventHandler>> +{ + private readonly IThirdLocationJobAppService _thirdLocationJobAppService; + private readonly IProductionLineAppService _productionLineAppService; + private readonly IThirdLocationRequestManager _assembleRequestManager; + private readonly ILocationAppService _locationAppService; + private readonly IBalanceAppService _balanceAppService; + + public ThirdLocationRequestEventHandler( + IThirdLocationJobAppService thirdLocationJobAppService + , IProductionLineAppService productionLineAppService + , IThirdLocationRequestManager assembleRequestManager + , ILocationAppService locationAppService + , IBalanceAppService balanceAppService) + { + _thirdLocationJobAppService = thirdLocationJobAppService; + _productionLineAppService = productionLineAppService; + _assembleRequestManager = assembleRequestManager; + _locationAppService = locationAppService; + _balanceAppService = balanceAppService; + } + + /// + /// 创建后 + /// + /// Event data + public virtual async Task HandleEventAsync(SfsCreatedEntityEventData eventData) + { + var entity = eventData.Entity; + + //if (entity.AutoSubmit) + //{ + // await _assembleRequestManager.SubmitAsync(entity).ConfigureAwait(false); + //} + } + + /// + /// 批量创建后 + /// + /// Event data + public virtual async Task HandleEventAsync(SfsCreatedEntityEventData> eventData) + { + var entitys = eventData.Entity; + foreach (var entity in entitys) + { + if (entity.AutoSubmit) + { + await _assembleRequestManager.SubmitAsync(entity).ConfigureAwait(false); + } + + } + } + + /// + /// 执行后 + /// + /// + /// + public virtual async Task HandleEventAsync(SfsHandledEntityEventData eventData) + { + var entity = eventData.Entity; + var thirdLocationJobs = await BuildThirdLocationJobAsync(entity).ConfigureAwait(false); + if (thirdLocationJobs.Any()) + { + await _thirdLocationJobAppService.CreateManyAsync(thirdLocationJobs).ConfigureAwait(false); + } + } + + /// + /// 驳回后 + /// + /// + /// + public virtual async Task HandleEventAsync(SfsAbortedEntityEventData eventData) + { + + } + + /// + /// 完成后 + /// + /// + /// + public virtual async Task HandleEventAsync(SfsCompletedEntityEventData eventData) + { + _ = eventData.Entity; + // await _thirdLocationJobAppService.CompleteByThirdLocationRequestAsync(entity.Number); + + await Task.CompletedTask.ConfigureAwait(false); + } + + #region 私有 + + private async Task> BuildThirdLocationJobAsync + (ThirdLocationRequest assembleRequest) + { + var jobs = new List(); + + var transactionType = await TransactionTypeAclService.GetByTransTypeAsync(EnumTransType.Issue, EnumTransSubType.None).ConfigureAwait(false);//库存事务 + + var toLocationCodes = assembleRequest.Details.Select(p => p.ToLocationCode).Distinct().ToList();//所有发送库位的集合 + var toLocations = await _locationAppService.GetByCodesAsync(toLocationCodes).ConfigureAwait(false);//所有库位的集合 + + var assembleRequestDetails = assembleRequest.Details.Where(p => p.ToBeIssuedQty > 0);//所有还没发送物品的集合 + foreach (var assembleRequestDetail in assembleRequestDetails)//如果有还有剩余未叫料的数量 则创建新的任务 + { + var toLocation = toLocations.FirstOrDefault(p => p.Code == assembleRequestDetail.ToLocationCode);//判断目标库位是否存在 + Check.NotNull(toLocation, "库位代码", $"库位 {assembleRequestDetail.ToLocationCode} 不存在"); + + //创建详情 + var jobDetails = await BuildThirdLocationJobDetailInputsAsync(assembleRequest, assembleRequestDetail, transactionType, toLocation.LocationGroupCode).ConfigureAwait(false); + if (!jobDetails.Any()) + { + continue; + } + + var fromLocationCode = jobDetails[0].RecommendFromLocationCode; + var fromLocation = await _locationAppService.GetByCodeAsync(fromLocationCode).ConfigureAwait(false); + var job = jobs.FirstOrDefault(p => p.WorkGroupCode == fromLocation?.WorkGroupCode); + if (job == null || job.Details.Any(p => p.ToLocationCode != assembleRequestDetail.ToLocationCode)) + { + job = BuildThirdLocationJobCreateInput(assembleRequest, fromLocation); + jobs.Add(job); + } + job.Details.AddRange(jobDetails); + if (assembleRequestDetail.ToBeIssuedQty < 0) + { + assembleRequestDetail.Status = EnumStatus.Close; + } + } + + jobs = jobs.Where(p => p.Details.Any()).ToList(); + + var openRequestDetails = + assembleRequest.Details.Where(p => p.Status != EnumStatus.Close).ToList(); + + if (!openRequestDetails.Any()) + { + return jobs; + } + + + var enableMultipleCreateThirdLocationJob = await SettingManager.IsTrueAsync(StoreSettings.MaterialRequest.EnableMultipleCreateIssueJob).ConfigureAwait(false); + if (enableMultipleCreateThirdLocationJob) + { + + //assembleRequest.Partial(); + } + else + { + var sb = new StringBuilder(); + foreach (var openRequestDetail in openRequestDetails) + { + sb.AppendLine($"{openRequestDetail.ItemCode}请求数量 {openRequestDetail.Qty},可用库存数量 {openRequestDetail.IssuedQty}"); + } + throw new UserFriendlyException($"{sb} 可用库存数量不足, 无法生成发料任务"); + } + return jobs; + } + + private ThirdLocationJobEditInput BuildThirdLocationJobCreateInput(ThirdLocationRequest assembleRequest, LocationDTO fromLocation) + { + ThirdLocationJobEditInput job; + job = ObjectMapper.Map(assembleRequest); + job.JobType = EnumJobType.IssueJob; + job.JobStatus = EnumJobStatus.Open; + job.WorkGroupCode = fromLocation.WorkGroupCode; + job.WarehouseCode = fromLocation.WarehouseCode; + job.ProdLine = fromLocation.LocationGroupCode; + job.Worker = assembleRequest.Worker; + if (string.IsNullOrEmpty(job.Worker)) + { + job.Worker = "admin"; + } + job.RequestNumber = assembleRequest.Number; + return job; + } + + private async Task> BuildThirdLocationJobDetailInputsAsync(ThirdLocationRequest assembleRequest, + ThirdLocationRequestDetail assembleRequestDetail, TransactionTypeDTO transactionType, string toLocationGroupCode) + { + var jobDetails = new List(); + var input = new RecommendBalanceRequestInput() + { + ItemCode = assembleRequestDetail.ItemCode, + Qty = assembleRequestDetail.ToBeIssuedQty, + LocationTypes = transactionType.OutLocationTypes, + LocationAreas = new List { assembleRequestDetail.FromLocationArea }, + Statuses = transactionType.OutInventoryStatuses, + }; + //获取推荐库存 + var recommendList = await _balanceAppService.GetRecommendBalancesAsync(input).ConfigureAwait(false); + //没有推荐库存时 跳过此明细 不生成任务 + if (recommendList.Count != 0) + { + foreach (var recommend in recommendList) + { + //拿走需求量 + var detail = await BuildThirdLocationJobDetailAsync(assembleRequestDetail, recommend, toLocationGroupCode).ConfigureAwait(false); + if (assembleRequest.UseOnTheWayLocation) + { + //获取在途库 + var locationDto = await _locationAppService.GetFirstByTypeAsync(EnumLocationType.TRANSPORT).ConfigureAwait(false); + + detail.OnTheWayLocationCode = locationDto.Code; + } + + jobDetails.Add(detail); + assembleRequestDetail.IssuedQty += recommend.Qty; + + //await _assembleRequestManager.UpdateDetailsAsync(assembleRequest).ConfigureAwait(false); + + } + } + return jobDetails; + } + + private async Task BuildThirdLocationJobDetailAsync(ThirdLocationRequestDetail assembleRequestDetail, BalanceDTO balance, string toLocationGroupCode) + { + + //ProductionLineDTO prodLine = await _productionLineAppService.GetByLocationGroupCodeAsync(toLocationGroupCode).ConfigureAwait(false); + + var detail = ObjectMapper.Map(balance); + detail.RequestLocationCode = assembleRequestDetail.ToLocationCode; + detail.WorkStation = assembleRequestDetail.WorkStation; + detail.ExpiredTime = assembleRequestDetail.ExpiredTime; + detail.PositionCode = assembleRequestDetail.PositionCode; + detail.RecommendType = assembleRequestDetail.RecommendType; + + detail.RecommendPackingCode = balance.PackingCode; + detail.RecommendContainerCode = balance.ContainerCode; + detail.RecommendSupplierBatch = balance.SupplierBatch; + detail.RecommendProduceDate = balance.ProduceDate; + detail.RecommendExpireDate = balance.ExpireDate; + detail.RecommendLot = balance.Lot; + detail.RecommendProduceDate = balance.ProduceDate; + detail.RecommendArriveDate = balance.ArriveDate; + detail.RecommendFromLocationArea = balance.LocationArea; + detail.RecommendFromLocationCode = balance.LocationCode; + detail.RecommendFromLocationErpCode = balance.LocationErpCode; + detail.RecommendFromLocationGroup = balance.LocationGroup; + detail.RecommendFromWarehouseCode = balance.WarehouseCode; + detail.RecommendQty = balance.Qty; + detail.Uom = balance.Uom; + + detail.ToLocationCode = assembleRequestDetail.ToLocationCode; + detail.ToLocationErpCode = assembleRequestDetail.ToLocationErpCode; + detail.ToLocationArea = assembleRequestDetail.ToLocationArea; + detail.ToWarehouseCode = assembleRequestDetail.ToWarehouseCode; + + //detail.ProdLine = prodLine == null ? toLocationGroupCode : prodLine.Code; + detail.ProdLine = toLocationGroupCode; + await Task.CompletedTask.ConfigureAwait(false); + return detail; + + } + + #endregion +} diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/StoreEventAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/StoreEventAutoMapperProfile.cs index 3f57465d5..026aa2b9d 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/StoreEventAutoMapperProfile.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/StoreEventAutoMapperProfile.cs @@ -37,6 +37,7 @@ public partial class StoreEventAutoMapperProfile : Profile IssueJobAutoMapperProfile(); InjectionJobAutoMapperProfile(); AssembleJobAutoMapperProfile(); + ThirdLocationJobAutoMapperProfile(); JisDeliverJobAutoMapperProfile(); ProductionReturnJobAutoMapperProfile(); ProductReceiveJobAutoMapperProfile(); @@ -70,12 +71,14 @@ public partial class StoreEventAutoMapperProfile : Profile IssueNoteAutoMapperProfile(); InjectionNoteAutoMapperProfile(); AssembleNoteAutoMapperProfile(); + ThirdLocationNoteAutoMapperProfile(); ItemTransformNoteAutoMapperProfile(); JisDeliverNoteAutoMapperProfile(); JisProductReceiptNoteAutoMapperProfile(); MaterialRequestAutoMapperProfile(); InjectionRequestAutoMapperProfile(); AssembleRequestAutoMapperProfile(); + ThirdLocationRequestAutoMapperProfile(); ProductionReturnRequestAutoMapperProfile(); ProductionReturnNoteAutoMapperProfile(); ProductReceiptNoteAutoMapperProfile();