diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/DTOs/KittingIssueJobDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/DTOs/KittingIssueJobDTO.cs
new file mode 100644
index 000000000..edfc95b19
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/DTOs/KittingIssueJobDTO.cs
@@ -0,0 +1,38 @@
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+///
+/// Kitting叫料任务
+///
+[Display(Name = "Kitting叫料任务")]
+public class KittingIssueJobDTO : 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 KittingRequestNumber { get; set; }
+
+ ///
+ /// 使用在途库
+ ///
+ [Display(Name = "使用在途库")]
+ public bool UseOnTheWayLocation { get; set; }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/DTOs/KittingIssueJobDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/DTOs/KittingIssueJobDetailDTO.cs
new file mode 100644
index 000000000..53b40608a
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/DTOs/KittingIssueJobDetailDTO.cs
@@ -0,0 +1,519 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Win_in.Sfs.Shared.Application.Contracts;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueJobDetailDTO : SfsDetailDTOBase
+{
+ #region 库存基础信息
+
+ ///
+ /// 物品代码
+ ///
+ public string ItemCode { get; set; }
+
+ ///
+ /// 物品名称
+ ///
+ public string ItemName { get; set; }
+
+ ///
+ /// 物品描述1
+ ///
+ public string ItemDesc1 { get; set; }
+
+ ///
+ /// 物品描述2
+ ///
+ public string ItemDesc2 { get; set; }
+
+ ///
+ /// 标包数量
+ ///
+ [Display(Name = "标包数量")]
+ [Column(TypeName = "decimal(18,6)")]
+ public decimal StdPackQty { get; set; }
+
+ ///
+ /// 库存状态
+ ///
+ public EnumInventoryStatus Status { get; set; }
+
+ ///
+ /// 计量单位
+ ///
+ public string Uom { get; set; }
+
+ #endregion
+
+ #region 请求信息
+
+ ///
+ /// 请求库位
+ ///
+ public string RequestLocationCode { get; set; }
+
+ ///
+ /// 到库区
+ ///
+ public string RequestLocationArea { get; set; }
+
+ ///
+ /// 到库位组
+ ///
+ public string RequestLocationGroup { get; set; }
+
+ ///
+ /// 到ERP库位
+ ///
+ public string RequestLocationErpCode { get; set; }
+
+ ///
+ /// 到仓库
+ ///
+ public string RequestWarehouseCode { get; set; }
+
+ ///
+ /// 在途库库位
+ ///
+ public string OnTheWayLocationCode { get; set; }
+
+ ///
+ /// 生产线
+ ///
+ public string ProdLine { get; set; }
+
+ ///
+ /// 位置码
+ ///
+ public string PositionCode { get; set; }
+
+ ///
+ /// 推荐的类型
+ ///
+ public EnumRecommendType RecommendType { get; set; }
+
+ ///
+ /// 需求数量
+ ///
+ public decimal RequestQty { get; set; }
+
+ #endregion
+
+ #region 推荐来源
+
+ ///
+ /// 推荐来源托标签
+ ///
+ public string RecommendFromContainerCode { get; set; }
+
+ ///
+ /// 推荐来源箱标签
+ ///
+ public string RecommendFromPackingCode { get; set; }
+
+ ///
+ /// 推荐来源批次供应商批次
+ ///
+ public string RecommendFromSupplierBatch { get; set; }
+
+ ///
+ /// 推荐来源批次到货时间
+ ///
+ public DateTime RecommendFromArriveDate { get; set; }
+
+ ///
+ /// 推荐来源批次生产时间
+ ///
+ public DateTime RecommendFromProduceDate { get; set; }
+
+ ///
+ /// 推荐来源批次过期时间
+ ///
+ public DateTime RecommendFromExpireDate { get; set; }
+
+ ///
+ /// 推荐来源批次排序
+ ///
+ public string RecommendFromLot { get; set; }
+
+ ///
+ /// 推荐来源库位
+ ///
+ public string RecommendFromLocationCode { get; set; }
+
+ ///
+ /// 推荐来源库区
+ ///
+ public string RecommendFromLocationArea { get; set; }
+
+ ///
+ /// 推荐来源库位组
+ ///
+ public string RecommendFromLocationGroup { get; set; }
+
+ ///
+ /// 推荐来源ERP库位
+ ///
+ public string RecommendFromLocationErpCode { get; set; }
+
+ ///
+ /// 推荐来源仓库
+ ///
+ public string RecommendFromWarehouseCode { get; set; }
+
+ ///
+ /// 推荐来源数量
+ ///
+ public decimal RecommendFromQty { get; set; }
+
+ #endregion
+
+ #region 推荐目标
+
+ ///
+ /// 推荐目标托标签
+ ///
+ public string RecommendToContainerCode { get; set; }
+
+ ///
+ /// 推荐目标箱标签
+ ///
+ public string RecommendToPackingCode { get; set; }
+
+ ///
+ /// 推荐目标批次供应商批次
+ ///
+ public string RecommendToSupplierBatch { get; set; }
+
+ ///
+ /// 推荐目标批次到货时间
+ ///
+ public DateTime RecommendToArriveDate { get; set; }
+
+ ///
+ /// 推荐目标批次生产时间
+ ///
+ public DateTime RecommendToProduceDate { get; set; }
+
+ ///
+ /// 推荐目标批次过期时间
+ ///
+ public DateTime RecommendToExpireDate { get; set; }
+
+ ///
+ /// 推荐目标批次排序
+ ///
+ public string RecommendToLot { get; set; }
+
+ ///
+ /// 推荐目标库位
+ ///
+ public string RecommendToLocationCode { get; set; }
+
+ ///
+ /// 推荐目标库区
+ ///
+ public string RecommendToLocationArea { get; set; }
+
+ ///
+ /// 推荐目标库位组
+ ///
+ public string RecommendToLocationGroup { get; set; }
+
+ ///
+ /// 推荐目标ERP库位
+ ///
+ public string RecommendToLocationErpCode { get; set; }
+
+ ///
+ /// 推荐目标仓库
+ ///
+ public string RecommendToWarehouseCode { get; set; }
+
+ ///
+ /// 推荐目标数量
+ ///
+ public decimal RecommendToQty { get; set; }
+
+ #endregion
+
+ #region 库移来源
+
+ ///
+ /// 库移来源托标签
+ ///
+ public string TransferLibFromContainerCode { get; set; }
+
+ ///
+ /// 库移来源箱标签
+ ///
+ public string TransferLibFromPackingCode { get; set; }
+
+ ///
+ /// 库移来源批次供应商批次
+ ///
+ public string TransferLibFromSupplierBatch { get; set; }
+
+ ///
+ /// 库移来源批次到货时间
+ ///
+ public DateTime TransferLibFromArriveDate { get; set; }
+
+ ///
+ /// 库移来源批次生产时间
+ ///
+ public DateTime TransferLibFromProduceDate { get; set; }
+
+ ///
+ /// 库移来源批次过期时间
+ ///
+ public DateTime TransferLibFromExpireDate { get; set; }
+
+ ///
+ /// 库移来源批次排序
+ ///
+ public string TransferLibFromLot { get; set; }
+
+ ///
+ /// 库移来源库位
+ ///
+ public string TransferLibFromLocationCode { get; set; }
+
+ ///
+ /// 库移来源库区
+ ///
+ public string TransferLibFromLocationArea { get; set; }
+
+ ///
+ /// 库移来源库位组
+ ///
+ public string TransferLibFromLocationGroup { get; set; }
+
+ ///
+ /// 库移来源ERP库位
+ ///
+ public string TransferLibFromLocationErpCode { get; set; }
+
+ ///
+ /// 库移来源仓库
+ ///
+ public string TransferLibFromWarehouseCode { get; set; }
+
+ ///
+ /// 库移来源数量
+ ///
+ public decimal TransferLibFromQty { get; set; }
+
+ #endregion
+
+ #region 库移目标
+
+ ///
+ /// 库移目标托标签
+ ///
+ public string TransferLibToContainerCode { get; set; }
+
+ ///
+ /// 库移目标箱标签
+ ///
+ public string TransferLibToPackingCode { get; set; }
+
+ ///
+ /// 库移目标批次供应商批次
+ ///
+ public string TransferLibToSupplierBatch { get; set; }
+
+ ///
+ /// 库移目标批次到货时间
+ ///
+ public DateTime TransferLibToArriveDate { get; set; }
+
+ ///
+ /// 库移目标批次生产时间
+ ///
+ public DateTime TransferLibToProduceDate { get; set; }
+
+ ///
+ /// 库移目标批次过期时间
+ ///
+ public DateTime TransferLibToExpireDate { get; set; }
+
+ ///
+ /// 库移目标批次排序
+ ///
+ public string TransferLibToLot { get; set; }
+
+ ///
+ /// 库移目标库位
+ ///
+ public string TransferLibToLocationCode { get; set; }
+
+ ///
+ /// 库移目标库区
+ ///
+ public string TransferLibToLocationArea { get; set; }
+
+ ///
+ /// 库移目标库位组
+ ///
+ public string TransferLibToLocationGroup { get; set; }
+
+ ///
+ /// 库移目标ERP库位
+ ///
+ public string TransferLibToLocationErpCode { get; set; }
+
+ ///
+ /// 库移目标仓库
+ ///
+ public string TransferLibToWarehouseCode { get; set; }
+
+ ///
+ /// 库移目标数量
+ ///
+ public decimal TransferLibToQty { get; set; }
+
+ #endregion
+
+ #region 实际来源
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledFromContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledFromPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledFromSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledFromArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledFromProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledFromExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledFromLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledFromLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledFromLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledFromLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledFromLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledFromWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledFromQty { get; set; }
+
+ #endregion
+
+ #region 实际目标
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledToContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledToPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledToSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledToArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledToProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledToExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledToLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledToLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledToLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledToLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledToLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledToWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledToQty { get; set; }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs
new file mode 100644
index 000000000..318b19bd7
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobAppService.cs
@@ -0,0 +1,14 @@
+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 IKittingIssueJobAppService
+ : ISfsJobAppServiceBase
+{
+ Task CancelByMaterialRequestAsync(string requestNumber);
+
+ Task> GetByRequestNumberAsync(string requestNumber);
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobCheckInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobCheckInput.cs
new file mode 100644
index 000000000..b3ecb9bc1
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobCheckInput.cs
@@ -0,0 +1,6 @@
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueJobCheckInput : SfsJobCheckInputBase
+{
+
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobDetailInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobDetailInput.cs
new file mode 100644
index 000000000..61ae0694b
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobDetailInput.cs
@@ -0,0 +1,519 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Win_in.Sfs.Shared.Application.Contracts;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueJobDetailInput : SfsDetailInputBase
+{
+ #region 库存基础信息
+
+ ///
+ /// 物品代码
+ ///
+ public string ItemCode { get; set; }
+
+ ///
+ /// 物品名称
+ ///
+ public string ItemName { get; set; }
+
+ ///
+ /// 物品描述1
+ ///
+ public string ItemDesc1 { get; set; }
+
+ ///
+ /// 物品描述2
+ ///
+ public string ItemDesc2 { get; set; }
+
+ ///
+ /// 标包数量
+ ///
+ [Display(Name = "标包数量")]
+ [Column(TypeName = "decimal(18,6)")]
+ public decimal StdPackQty { get; set; }
+
+ ///
+ /// 库存状态
+ ///
+ public EnumInventoryStatus Status { get; set; }
+
+ ///
+ /// 计量单位
+ ///
+ public string Uom { get; set; }
+
+ #endregion
+
+ #region 请求信息
+
+ ///
+ /// 请求库位
+ ///
+ public string RequestLocationCode { get; set; }
+
+ ///
+ /// 到库区
+ ///
+ public string RequestLocationArea { get; set; }
+
+ ///
+ /// 到库位组
+ ///
+ public string RequestLocationGroup { get; set; }
+
+ ///
+ /// 到ERP库位
+ ///
+ public string RequestLocationErpCode { get; set; }
+
+ ///
+ /// 到仓库
+ ///
+ public string RequestWarehouseCode { get; set; }
+
+ ///
+ /// 在途库库位
+ ///
+ public string OnTheWayLocationCode { get; set; }
+
+ ///
+ /// 生产线
+ ///
+ public string ProdLine { get; set; }
+
+ ///
+ /// 位置码
+ ///
+ public string PositionCode { get; set; }
+
+ ///
+ /// 推荐的类型
+ ///
+ public EnumRecommendType RecommendType { get; set; }
+
+ ///
+ /// 需求数量
+ ///
+ public decimal RequestQty { get; set; }
+
+ #endregion
+
+ #region 推荐来源
+
+ ///
+ /// 推荐来源托标签
+ ///
+ public string RecommendFromContainerCode { get; set; }
+
+ ///
+ /// 推荐来源箱标签
+ ///
+ public string RecommendFromPackingCode { get; set; }
+
+ ///
+ /// 推荐来源批次供应商批次
+ ///
+ public string RecommendFromSupplierBatch { get; set; }
+
+ ///
+ /// 推荐来源批次到货时间
+ ///
+ public DateTime RecommendFromArriveDate { get; set; }
+
+ ///
+ /// 推荐来源批次生产时间
+ ///
+ public DateTime RecommendFromProduceDate { get; set; }
+
+ ///
+ /// 推荐来源批次过期时间
+ ///
+ public DateTime RecommendFromExpireDate { get; set; }
+
+ ///
+ /// 推荐来源批次排序
+ ///
+ public string RecommendFromLot { get; set; }
+
+ ///
+ /// 推荐来源库位
+ ///
+ public string RecommendFromLocationCode { get; set; }
+
+ ///
+ /// 推荐来源库区
+ ///
+ public string RecommendFromLocationArea { get; set; }
+
+ ///
+ /// 推荐来源库位组
+ ///
+ public string RecommendFromLocationGroup { get; set; }
+
+ ///
+ /// 推荐来源ERP库位
+ ///
+ public string RecommendFromLocationErpCode { get; set; }
+
+ ///
+ /// 推荐来源仓库
+ ///
+ public string RecommendFromWarehouseCode { get; set; }
+
+ ///
+ /// 推荐来源数量
+ ///
+ public decimal RecommendFromQty { get; set; }
+
+ #endregion
+
+ #region 推荐目标
+
+ ///
+ /// 推荐目标托标签
+ ///
+ public string RecommendToContainerCode { get; set; }
+
+ ///
+ /// 推荐目标箱标签
+ ///
+ public string RecommendToPackingCode { get; set; }
+
+ ///
+ /// 推荐目标批次供应商批次
+ ///
+ public string RecommendToSupplierBatch { get; set; }
+
+ ///
+ /// 推荐目标批次到货时间
+ ///
+ public DateTime RecommendToArriveDate { get; set; }
+
+ ///
+ /// 推荐目标批次生产时间
+ ///
+ public DateTime RecommendToProduceDate { get; set; }
+
+ ///
+ /// 推荐目标批次过期时间
+ ///
+ public DateTime RecommendToExpireDate { get; set; }
+
+ ///
+ /// 推荐目标批次排序
+ ///
+ public string RecommendToLot { get; set; }
+
+ ///
+ /// 推荐目标库位
+ ///
+ public string RecommendToLocationCode { get; set; }
+
+ ///
+ /// 推荐目标库区
+ ///
+ public string RecommendToLocationArea { get; set; }
+
+ ///
+ /// 推荐目标库位组
+ ///
+ public string RecommendToLocationGroup { get; set; }
+
+ ///
+ /// 推荐目标ERP库位
+ ///
+ public string RecommendToLocationErpCode { get; set; }
+
+ ///
+ /// 推荐目标仓库
+ ///
+ public string RecommendToWarehouseCode { get; set; }
+
+ ///
+ /// 推荐目标数量
+ ///
+ public decimal RecommendToQty { get; set; }
+
+ #endregion
+
+ #region 库移来源
+
+ ///
+ /// 库移来源托标签
+ ///
+ public string TransferLibFromContainerCode { get; set; }
+
+ ///
+ /// 库移来源箱标签
+ ///
+ public string TransferLibFromPackingCode { get; set; }
+
+ ///
+ /// 库移来源批次供应商批次
+ ///
+ public string TransferLibFromSupplierBatch { get; set; }
+
+ ///
+ /// 库移来源批次到货时间
+ ///
+ public DateTime TransferLibFromArriveDate { get; set; }
+
+ ///
+ /// 库移来源批次生产时间
+ ///
+ public DateTime TransferLibFromProduceDate { get; set; }
+
+ ///
+ /// 库移来源批次过期时间
+ ///
+ public DateTime TransferLibFromExpireDate { get; set; }
+
+ ///
+ /// 库移来源批次排序
+ ///
+ public string TransferLibFromLot { get; set; }
+
+ ///
+ /// 库移来源库位
+ ///
+ public string TransferLibFromLocationCode { get; set; }
+
+ ///
+ /// 库移来源库区
+ ///
+ public string TransferLibFromLocationArea { get; set; }
+
+ ///
+ /// 库移来源库位组
+ ///
+ public string TransferLibFromLocationGroup { get; set; }
+
+ ///
+ /// 库移来源ERP库位
+ ///
+ public string TransferLibFromLocationErpCode { get; set; }
+
+ ///
+ /// 库移来源仓库
+ ///
+ public string TransferLibFromWarehouseCode { get; set; }
+
+ ///
+ /// 库移来源数量
+ ///
+ public decimal TransferLibFromQty { get; set; }
+
+ #endregion
+
+ #region 库移目标
+
+ ///
+ /// 库移目标托标签
+ ///
+ public string TransferLibToContainerCode { get; set; }
+
+ ///
+ /// 库移目标箱标签
+ ///
+ public string TransferLibToPackingCode { get; set; }
+
+ ///
+ /// 库移目标批次供应商批次
+ ///
+ public string TransferLibToSupplierBatch { get; set; }
+
+ ///
+ /// 库移目标批次到货时间
+ ///
+ public DateTime TransferLibToArriveDate { get; set; }
+
+ ///
+ /// 库移目标批次生产时间
+ ///
+ public DateTime TransferLibToProduceDate { get; set; }
+
+ ///
+ /// 库移目标批次过期时间
+ ///
+ public DateTime TransferLibToExpireDate { get; set; }
+
+ ///
+ /// 库移目标批次排序
+ ///
+ public string TransferLibToLot { get; set; }
+
+ ///
+ /// 库移目标库位
+ ///
+ public string TransferLibToLocationCode { get; set; }
+
+ ///
+ /// 库移目标库区
+ ///
+ public string TransferLibToLocationArea { get; set; }
+
+ ///
+ /// 库移目标库位组
+ ///
+ public string TransferLibToLocationGroup { get; set; }
+
+ ///
+ /// 库移目标ERP库位
+ ///
+ public string TransferLibToLocationErpCode { get; set; }
+
+ ///
+ /// 库移目标仓库
+ ///
+ public string TransferLibToWarehouseCode { get; set; }
+
+ ///
+ /// 库移目标数量
+ ///
+ public decimal TransferLibToQty { get; set; }
+
+ #endregion
+
+ #region 实际来源
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledFromContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledFromPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledFromSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledFromArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledFromProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledFromExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledFromLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledFromLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledFromLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledFromLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledFromLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledFromWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledFromQty { get; set; }
+
+ #endregion
+
+ #region 实际目标
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledToContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledToPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledToSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledToArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledToProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledToExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledToLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledToLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledToLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledToLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledToLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledToWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledToQty { get; set; }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobEditInput.cs
new file mode 100644
index 000000000..8fae44e90
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/Inputs/KittingIssueJobEditInput.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain;
+using Win_in.Sfs.Shared.Domain.Shared;
+using Win_in.Sfs.Shared.Domain.Shared.Enums.Store;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueJobEditInput : 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 KittingRequestNumber { 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 = "使用在途库")]
+ public bool UseOnTheWayLocation { get; set; }
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobPermissions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobPermissions.cs
new file mode 100644
index 000000000..01f485728
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobPermissions.cs
@@ -0,0 +1,24 @@
+using Volo.Abp.Authorization.Permissions;
+using Win_in.Sfs.Wms.Store.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public static class KittingIssueJobPermissions
+{
+
+ public const string Default = StorePermissions.GroupName + "." + nameof(KittingIssueJob);
+ public const string Create = Default + "." + StorePermissions.CreateStr;
+ public const string Update = Default + "." + StorePermissions.UpdateStr;
+ public const string Delete = Default + "." + StorePermissions.DeleteStr;
+
+
+ public static void AddKittingIssueJobPermission(this PermissionGroupDefinition permissionGroup)
+ {
+ var KittingIssueJobPermission = permissionGroup.AddPermission(Default, StorePermissionDefinitionProvider.L(nameof(KittingIssueJob)));
+ KittingIssueJobPermission.AddChild(Create, StorePermissionDefinitionProvider.L(StorePermissions.CreateStr));
+ KittingIssueJobPermission.AddChild(Update, StorePermissionDefinitionProvider.L(StorePermissions.UpdateStr));
+ KittingIssueJobPermission.AddChild(Delete, StorePermissionDefinitionProvider.L(StorePermissions.DeleteStr));
+
+
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/DTOs/KittingIssueNoteDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/DTOs/KittingIssueNoteDTO.cs
new file mode 100644
index 000000000..f9a2f2dba
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/DTOs/KittingIssueNoteDTO.cs
@@ -0,0 +1,47 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueNoteDTO : SfsStoreDTOBase, IHasJobNumber, IHasRequestNumber
+{
+
+ ///
+ /// 任务ID
+ ///
+ [Display(Name = "任务ID")]
+ public string JobNumber { 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/IssueNotes/KittingIssueNotes/DTOs/KittingIssueNoteDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/DTOs/KittingIssueNoteDetailDTO.cs
new file mode 100644
index 000000000..77863aab5
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/DTOs/KittingIssueNoteDetailDTO.cs
@@ -0,0 +1,519 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Win_in.Sfs.Shared.Application.Contracts;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueNoteDetailDTO : SfsDetailDTOBase
+{
+ #region 库存基础信息
+
+ ///
+ /// 物品代码
+ ///
+ public string ItemCode { get; set; }
+
+ ///
+ /// 物品名称
+ ///
+ public string ItemName { get; set; }
+
+ ///
+ /// 物品描述1
+ ///
+ public string ItemDesc1 { get; set; }
+
+ ///
+ /// 物品描述2
+ ///
+ public string ItemDesc2 { get; set; }
+
+ ///
+ /// 标包数量
+ ///
+ [Display(Name = "标包数量")]
+ [Column(TypeName = "decimal(18,6)")]
+ public decimal StdPackQty { get; set; }
+
+ ///
+ /// 库存状态
+ ///
+ public EnumInventoryStatus Status { get; set; }
+
+ ///
+ /// 计量单位
+ ///
+ public string Uom { get; set; }
+
+ #endregion
+
+ #region 请求信息
+
+ ///
+ /// 请求库位
+ ///
+ public string RequestLocationCode { get; set; }
+
+ ///
+ /// 到库区
+ ///
+ public string RequestLocationArea { get; set; }
+
+ ///
+ /// 到库位组
+ ///
+ public string RequestLocationGroup { get; set; }
+
+ ///
+ /// 到ERP库位
+ ///
+ public string RequestLocationErpCode { get; set; }
+
+ ///
+ /// 到仓库
+ ///
+ public string RequestWarehouseCode { get; set; }
+
+ ///
+ /// 在途库库位
+ ///
+ public string OnTheWayLocationCode { get; set; }
+
+ ///
+ /// 生产线
+ ///
+ public string ProdLine { get; set; }
+
+ ///
+ /// 位置码
+ ///
+ public string PositionCode { get; set; }
+
+ ///
+ /// 推荐的类型
+ ///
+ public EnumRecommendType RecommendType { get; set; }
+
+ ///
+ /// 需求数量
+ ///
+ public decimal RequestQty { get; set; }
+
+ #endregion
+
+ #region 推荐来源
+
+ ///
+ /// 推荐来源托标签
+ ///
+ public string RecommendFromContainerCode { get; set; }
+
+ ///
+ /// 推荐来源箱标签
+ ///
+ public string RecommendFromPackingCode { get; set; }
+
+ ///
+ /// 推荐来源批次供应商批次
+ ///
+ public string RecommendFromSupplierBatch { get; set; }
+
+ ///
+ /// 推荐来源批次到货时间
+ ///
+ public DateTime RecommendFromArriveDate { get; set; }
+
+ ///
+ /// 推荐来源批次生产时间
+ ///
+ public DateTime RecommendFromProduceDate { get; set; }
+
+ ///
+ /// 推荐来源批次过期时间
+ ///
+ public DateTime RecommendFromExpireDate { get; set; }
+
+ ///
+ /// 推荐来源批次排序
+ ///
+ public string RecommendFromLot { get; set; }
+
+ ///
+ /// 推荐来源库位
+ ///
+ public string RecommendFromLocationCode { get; set; }
+
+ ///
+ /// 推荐来源库区
+ ///
+ public string RecommendFromLocationArea { get; set; }
+
+ ///
+ /// 推荐来源库位组
+ ///
+ public string RecommendFromLocationGroup { get; set; }
+
+ ///
+ /// 推荐来源ERP库位
+ ///
+ public string RecommendFromLocationErpCode { get; set; }
+
+ ///
+ /// 推荐来源仓库
+ ///
+ public string RecommendFromWarehouseCode { get; set; }
+
+ ///
+ /// 推荐来源数量
+ ///
+ public decimal RecommendFromQty { get; set; }
+
+ #endregion
+
+ #region 推荐目标
+
+ ///
+ /// 推荐目标托标签
+ ///
+ public string RecommendToContainerCode { get; set; }
+
+ ///
+ /// 推荐目标箱标签
+ ///
+ public string RecommendToPackingCode { get; set; }
+
+ ///
+ /// 推荐目标批次供应商批次
+ ///
+ public string RecommendToSupplierBatch { get; set; }
+
+ ///
+ /// 推荐目标批次到货时间
+ ///
+ public DateTime RecommendToArriveDate { get; set; }
+
+ ///
+ /// 推荐目标批次生产时间
+ ///
+ public DateTime RecommendToProduceDate { get; set; }
+
+ ///
+ /// 推荐目标批次过期时间
+ ///
+ public DateTime RecommendToExpireDate { get; set; }
+
+ ///
+ /// 推荐目标批次排序
+ ///
+ public string RecommendToLot { get; set; }
+
+ ///
+ /// 推荐目标库位
+ ///
+ public string RecommendToLocationCode { get; set; }
+
+ ///
+ /// 推荐目标库区
+ ///
+ public string RecommendToLocationArea { get; set; }
+
+ ///
+ /// 推荐目标库位组
+ ///
+ public string RecommendToLocationGroup { get; set; }
+
+ ///
+ /// 推荐目标ERP库位
+ ///
+ public string RecommendToLocationErpCode { get; set; }
+
+ ///
+ /// 推荐目标仓库
+ ///
+ public string RecommendToWarehouseCode { get; set; }
+
+ ///
+ /// 推荐目标数量
+ ///
+ public decimal RecommendToQty { get; set; }
+
+ #endregion
+
+ #region 库移来源
+
+ ///
+ /// 库移来源托标签
+ ///
+ public string TransferLibFromContainerCode { get; set; }
+
+ ///
+ /// 库移来源箱标签
+ ///
+ public string TransferLibFromPackingCode { get; set; }
+
+ ///
+ /// 库移来源批次供应商批次
+ ///
+ public string TransferLibFromSupplierBatch { get; set; }
+
+ ///
+ /// 库移来源批次到货时间
+ ///
+ public DateTime TransferLibFromArriveDate { get; set; }
+
+ ///
+ /// 库移来源批次生产时间
+ ///
+ public DateTime TransferLibFromProduceDate { get; set; }
+
+ ///
+ /// 库移来源批次过期时间
+ ///
+ public DateTime TransferLibFromExpireDate { get; set; }
+
+ ///
+ /// 库移来源批次排序
+ ///
+ public string TransferLibFromLot { get; set; }
+
+ ///
+ /// 库移来源库位
+ ///
+ public string TransferLibFromLocationCode { get; set; }
+
+ ///
+ /// 库移来源库区
+ ///
+ public string TransferLibFromLocationArea { get; set; }
+
+ ///
+ /// 库移来源库位组
+ ///
+ public string TransferLibFromLocationGroup { get; set; }
+
+ ///
+ /// 库移来源ERP库位
+ ///
+ public string TransferLibFromLocationErpCode { get; set; }
+
+ ///
+ /// 库移来源仓库
+ ///
+ public string TransferLibFromWarehouseCode { get; set; }
+
+ ///
+ /// 库移来源数量
+ ///
+ public decimal TransferLibFromQty { get; set; }
+
+ #endregion
+
+ #region 库移目标
+
+ ///
+ /// 库移目标托标签
+ ///
+ public string TransferLibToContainerCode { get; set; }
+
+ ///
+ /// 库移目标箱标签
+ ///
+ public string TransferLibToPackingCode { get; set; }
+
+ ///
+ /// 库移目标批次供应商批次
+ ///
+ public string TransferLibToSupplierBatch { get; set; }
+
+ ///
+ /// 库移目标批次到货时间
+ ///
+ public DateTime TransferLibToArriveDate { get; set; }
+
+ ///
+ /// 库移目标批次生产时间
+ ///
+ public DateTime TransferLibToProduceDate { get; set; }
+
+ ///
+ /// 库移目标批次过期时间
+ ///
+ public DateTime TransferLibToExpireDate { get; set; }
+
+ ///
+ /// 库移目标批次排序
+ ///
+ public string TransferLibToLot { get; set; }
+
+ ///
+ /// 库移目标库位
+ ///
+ public string TransferLibToLocationCode { get; set; }
+
+ ///
+ /// 库移目标库区
+ ///
+ public string TransferLibToLocationArea { get; set; }
+
+ ///
+ /// 库移目标库位组
+ ///
+ public string TransferLibToLocationGroup { get; set; }
+
+ ///
+ /// 库移目标ERP库位
+ ///
+ public string TransferLibToLocationErpCode { get; set; }
+
+ ///
+ /// 库移目标仓库
+ ///
+ public string TransferLibToWarehouseCode { get; set; }
+
+ ///
+ /// 库移目标数量
+ ///
+ public decimal TransferLibToQty { get; set; }
+
+ #endregion
+
+ #region 实际来源
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledFromContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledFromPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledFromSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledFromArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledFromProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledFromExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledFromLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledFromLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledFromLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledFromLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledFromLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledFromWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledFromQty { get; set; }
+
+ #endregion
+
+ #region 实际目标
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledToContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledToPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledToSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledToArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledToProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledToExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledToLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledToLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledToLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledToLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledToLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledToWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledToQty { get; set; }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteAppService.cs
new file mode 100644
index 000000000..105094c18
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteAppService.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 IKittingIssueNoteAppService : ISfsStoreMasterReadOnlyAppServiceBase
+{
+ Task CreateAsync(KittingIssueNoteEditInput 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/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteDetailInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteDetailInput.cs
new file mode 100644
index 000000000..f72ba2435
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteDetailInput.cs
@@ -0,0 +1,519 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Win_in.Sfs.Shared.Application.Contracts;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueNoteDetailInput : SfsDetailInputBase
+{
+ #region 库存基础信息
+
+ ///
+ /// 物品代码
+ ///
+ public string ItemCode { get; set; }
+
+ ///
+ /// 物品名称
+ ///
+ public string ItemName { get; set; }
+
+ ///
+ /// 物品描述1
+ ///
+ public string ItemDesc1 { get; set; }
+
+ ///
+ /// 物品描述2
+ ///
+ public string ItemDesc2 { get; set; }
+
+ ///
+ /// 标包数量
+ ///
+ [Display(Name = "标包数量")]
+ [Column(TypeName = "decimal(18,6)")]
+ public decimal StdPackQty { get; set; }
+
+ ///
+ /// 库存状态
+ ///
+ public EnumInventoryStatus Status { get; set; }
+
+ ///
+ /// 计量单位
+ ///
+ public string Uom { get; set; }
+
+ #endregion
+
+ #region 请求信息
+
+ ///
+ /// 请求库位
+ ///
+ public string RequestLocationCode { get; set; }
+
+ ///
+ /// 到库区
+ ///
+ public string RequestLocationArea { get; set; }
+
+ ///
+ /// 到库位组
+ ///
+ public string RequestLocationGroup { get; set; }
+
+ ///
+ /// 到ERP库位
+ ///
+ public string RequestLocationErpCode { get; set; }
+
+ ///
+ /// 到仓库
+ ///
+ public string RequestWarehouseCode { get; set; }
+
+ ///
+ /// 在途库库位
+ ///
+ public string OnTheWayLocationCode { get; set; }
+
+ ///
+ /// 生产线
+ ///
+ public string ProdLine { get; set; }
+
+ ///
+ /// 位置码
+ ///
+ public string PositionCode { get; set; }
+
+ ///
+ /// 推荐的类型
+ ///
+ public EnumRecommendType RecommendType { get; set; }
+
+ ///
+ /// 需求数量
+ ///
+ public decimal RequestQty { get; set; }
+
+ #endregion
+
+ #region 推荐来源
+
+ ///
+ /// 推荐来源托标签
+ ///
+ public string RecommendFromContainerCode { get; set; }
+
+ ///
+ /// 推荐来源箱标签
+ ///
+ public string RecommendFromPackingCode { get; set; }
+
+ ///
+ /// 推荐来源批次供应商批次
+ ///
+ public string RecommendFromSupplierBatch { get; set; }
+
+ ///
+ /// 推荐来源批次到货时间
+ ///
+ public DateTime RecommendFromArriveDate { get; set; }
+
+ ///
+ /// 推荐来源批次生产时间
+ ///
+ public DateTime RecommendFromProduceDate { get; set; }
+
+ ///
+ /// 推荐来源批次过期时间
+ ///
+ public DateTime RecommendFromExpireDate { get; set; }
+
+ ///
+ /// 推荐来源批次排序
+ ///
+ public string RecommendFromLot { get; set; }
+
+ ///
+ /// 推荐来源库位
+ ///
+ public string RecommendFromLocationCode { get; set; }
+
+ ///
+ /// 推荐来源库区
+ ///
+ public string RecommendFromLocationArea { get; set; }
+
+ ///
+ /// 推荐来源库位组
+ ///
+ public string RecommendFromLocationGroup { get; set; }
+
+ ///
+ /// 推荐来源ERP库位
+ ///
+ public string RecommendFromLocationErpCode { get; set; }
+
+ ///
+ /// 推荐来源仓库
+ ///
+ public string RecommendFromWarehouseCode { get; set; }
+
+ ///
+ /// 推荐来源数量
+ ///
+ public decimal RecommendFromQty { get; set; }
+
+ #endregion
+
+ #region 推荐目标
+
+ ///
+ /// 推荐目标托标签
+ ///
+ public string RecommendToContainerCode { get; set; }
+
+ ///
+ /// 推荐目标箱标签
+ ///
+ public string RecommendToPackingCode { get; set; }
+
+ ///
+ /// 推荐目标批次供应商批次
+ ///
+ public string RecommendToSupplierBatch { get; set; }
+
+ ///
+ /// 推荐目标批次到货时间
+ ///
+ public DateTime RecommendToArriveDate { get; set; }
+
+ ///
+ /// 推荐目标批次生产时间
+ ///
+ public DateTime RecommendToProduceDate { get; set; }
+
+ ///
+ /// 推荐目标批次过期时间
+ ///
+ public DateTime RecommendToExpireDate { get; set; }
+
+ ///
+ /// 推荐目标批次排序
+ ///
+ public string RecommendToLot { get; set; }
+
+ ///
+ /// 推荐目标库位
+ ///
+ public string RecommendToLocationCode { get; set; }
+
+ ///
+ /// 推荐目标库区
+ ///
+ public string RecommendToLocationArea { get; set; }
+
+ ///
+ /// 推荐目标库位组
+ ///
+ public string RecommendToLocationGroup { get; set; }
+
+ ///
+ /// 推荐目标ERP库位
+ ///
+ public string RecommendToLocationErpCode { get; set; }
+
+ ///
+ /// 推荐目标仓库
+ ///
+ public string RecommendToWarehouseCode { get; set; }
+
+ ///
+ /// 推荐目标数量
+ ///
+ public decimal RecommendToQty { get; set; }
+
+ #endregion
+
+ #region 库移来源
+
+ ///
+ /// 库移来源托标签
+ ///
+ public string TransferLibFromContainerCode { get; set; }
+
+ ///
+ /// 库移来源箱标签
+ ///
+ public string TransferLibFromPackingCode { get; set; }
+
+ ///
+ /// 库移来源批次供应商批次
+ ///
+ public string TransferLibFromSupplierBatch { get; set; }
+
+ ///
+ /// 库移来源批次到货时间
+ ///
+ public DateTime TransferLibFromArriveDate { get; set; }
+
+ ///
+ /// 库移来源批次生产时间
+ ///
+ public DateTime TransferLibFromProduceDate { get; set; }
+
+ ///
+ /// 库移来源批次过期时间
+ ///
+ public DateTime TransferLibFromExpireDate { get; set; }
+
+ ///
+ /// 库移来源批次排序
+ ///
+ public string TransferLibFromLot { get; set; }
+
+ ///
+ /// 库移来源库位
+ ///
+ public string TransferLibFromLocationCode { get; set; }
+
+ ///
+ /// 库移来源库区
+ ///
+ public string TransferLibFromLocationArea { get; set; }
+
+ ///
+ /// 库移来源库位组
+ ///
+ public string TransferLibFromLocationGroup { get; set; }
+
+ ///
+ /// 库移来源ERP库位
+ ///
+ public string TransferLibFromLocationErpCode { get; set; }
+
+ ///
+ /// 库移来源仓库
+ ///
+ public string TransferLibFromWarehouseCode { get; set; }
+
+ ///
+ /// 库移来源数量
+ ///
+ public decimal TransferLibFromQty { get; set; }
+
+ #endregion
+
+ #region 库移目标
+
+ ///
+ /// 库移目标托标签
+ ///
+ public string TransferLibToContainerCode { get; set; }
+
+ ///
+ /// 库移目标箱标签
+ ///
+ public string TransferLibToPackingCode { get; set; }
+
+ ///
+ /// 库移目标批次供应商批次
+ ///
+ public string TransferLibToSupplierBatch { get; set; }
+
+ ///
+ /// 库移目标批次到货时间
+ ///
+ public DateTime TransferLibToArriveDate { get; set; }
+
+ ///
+ /// 库移目标批次生产时间
+ ///
+ public DateTime TransferLibToProduceDate { get; set; }
+
+ ///
+ /// 库移目标批次过期时间
+ ///
+ public DateTime TransferLibToExpireDate { get; set; }
+
+ ///
+ /// 库移目标批次排序
+ ///
+ public string TransferLibToLot { get; set; }
+
+ ///
+ /// 库移目标库位
+ ///
+ public string TransferLibToLocationCode { get; set; }
+
+ ///
+ /// 库移目标库区
+ ///
+ public string TransferLibToLocationArea { get; set; }
+
+ ///
+ /// 库移目标库位组
+ ///
+ public string TransferLibToLocationGroup { get; set; }
+
+ ///
+ /// 库移目标ERP库位
+ ///
+ public string TransferLibToLocationErpCode { get; set; }
+
+ ///
+ /// 库移目标仓库
+ ///
+ public string TransferLibToWarehouseCode { get; set; }
+
+ ///
+ /// 库移目标数量
+ ///
+ public decimal TransferLibToQty { get; set; }
+
+ #endregion
+
+ #region 实际来源
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledFromContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledFromPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledFromSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledFromArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledFromProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledFromExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledFromLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledFromLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledFromLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledFromLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledFromLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledFromWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledFromQty { get; set; }
+
+ #endregion
+
+ #region 实际目标
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledToContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledToPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledToSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledToArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledToProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledToExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledToLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledToLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledToLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledToLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledToLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledToWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledToQty { get; set; }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteEditInput.cs
new file mode 100644
index 000000000..b7969e323
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteEditInput.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueNoteEditInput : 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 = "明细列表")]
+ 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/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteImportInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteImportInput.cs
new file mode 100644
index 000000000..52fa8e4a5
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/Inputs/KittingIssueNoteImportInput.cs
@@ -0,0 +1,33 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueNoteImportInput : 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/IssueNotes/KittingIssueNotes/KittingIssueNotePermissions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/KittingIssueNotePermissions.cs
new file mode 100644
index 000000000..9a633fdd9
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Notes/IssueNotes/KittingIssueNotes/KittingIssueNotePermissions.cs
@@ -0,0 +1,24 @@
+using Volo.Abp.Authorization.Permissions;
+using Win_in.Sfs.Wms.Store.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public static class KittingIssueNotePermissions
+{
+
+ public const string Default = StorePermissions.GroupName + "." + nameof(KittingIssueNote);
+ public const string Create = Default + "." + StorePermissions.CreateStr;
+ public const string Update = Default + "." + StorePermissions.UpdateStr;
+ public const string Delete = Default + "." + StorePermissions.DeleteStr;
+
+
+
+ public static void AddKittingIssueNotePermission(this PermissionGroupDefinition permissionGroup)
+ {
+ var injectionNotePermission = permissionGroup.AddPermission(Default, StorePermissionDefinitionProvider.L(nameof(KittingIssueNote)));
+ injectionNotePermission.AddChild(Create, StorePermissionDefinitionProvider.L(StorePermissions.CreateStr));
+ injectionNotePermission.AddChild(Update, StorePermissionDefinitionProvider.L(StorePermissions.UpdateStr));
+ injectionNotePermission.AddChild(Delete, StorePermissionDefinitionProvider.L(StorePermissions.DeleteStr));
+
+ }
+}
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 82c83a21f..5b0aba29d 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
@@ -27,11 +27,13 @@ public class StorePermissionDefinitionProvider : PermissionDefinitionProvider
storeGroup.AddPutawayNotePermission();
storeGroup.AddMaterialRequestPermission();
storeGroup.AddInjectionRequestPermission();
+ storeGroup.AddKittingIssueRequestPermission();
storeGroup.AddAssembleIssueRequestsPermission();
storeGroup.AddThirdLocationRequestPermission();
storeGroup.AddContainerRequestPermission();
storeGroup.AddIssueNotePermission();
storeGroup.AddInjectionNotePermission();
+ storeGroup.AddKittingIssueNotePermission();
storeGroup.AddAssembleNotePermission();
storeGroup.AddThirdLocationNotePermission();
storeGroup.AddContainerNotePermission();
@@ -100,6 +102,7 @@ public class StorePermissionDefinitionProvider : PermissionDefinitionProvider
storeGroup.AddPutawayJobPermission();
storeGroup.AddIssueJobPermission();
storeGroup.AddInjectionJobPermission();
+ storeGroup.AddKittingIssueJobPermission();
storeGroup.AddCoatingIssueJobPermission();
storeGroup.AddAssembleJobPermission();
storeGroup.AddThirdLocationJobPermission();
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/DTOs/KittingIssueRequestDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/DTOs/KittingIssueRequestDTO.cs
new file mode 100644
index 000000000..6cfdb6a79
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/DTOs/KittingIssueRequestDTO.cs
@@ -0,0 +1,34 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueRequestDTO : SfsStoreRequestDTOBase, IHasNumber
+{
+ ///
+ /// 叫料类型
+ ///
+ [Display(Name = "叫料类型")]
+ public string Type { 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/MaterialRequests/KittingIssueRequests/DTOs/KittingIssueRequestDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/DTOs/KittingIssueRequestDetailDTO.cs
new file mode 100644
index 000000000..6981f306d
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/DTOs/KittingIssueRequestDetailDTO.cs
@@ -0,0 +1,55 @@
+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 KittingIssueRequestDetailDTO : 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;
+
+ ///
+ /// 需求箱数量
+ ///
+ [Display(Name = "需求箱数量")]
+ public decimal BoxQty { get; set; }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestAppService.cs
new file mode 100644
index 000000000..4dded00d6
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestAppService.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 IKittingIssueRequestAppService
+ : ISfsStoreRequestMasterAppServiceBase
+
+{
+ Task CreateAndHandleAsync(KittingIssueRequestEditInput input);
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestDetailInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestDetailInput.cs
new file mode 100644
index 000000000..3a4099acf
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestDetailInput.cs
@@ -0,0 +1,91 @@
+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 KittingIssueRequestDetailInput : SfsStoreDetailWithQtyInputBase
+{
+ #region 目标库位信息
+
+ ///
+ /// 目标库位
+ ///
+ [Display(Name = "目标库位")]
+ [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储位")]
+ public string ToLocationErpCode { get; set; }
+
+ ///
+ /// 目标仓库
+ ///
+ [Display(Name = "目标仓库")]
+ public string ToWarehouseCode { get; set; }
+
+ #endregion
+
+ ///
+ /// 生产线
+ ///
+ [Display(Name = "生产线")]
+ [StringLength(SfsEfCorePropertyConst.CodeLength, ErrorMessage = "{0}最多输入{1}个字符")]
+ public string ProdLine { get; set; }
+
+ ///
+ /// 状态
+ ///
+ [Display(Name = "状态")]
+ public EnumRequestStatus RequestStatus { get; set; } = EnumRequestStatus.New;
+
+ ///
+ /// 已发数量
+ ///
+ [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; }
+
+ ///
+ /// 需求箱数量
+ ///
+ [Display(Name = "需求箱数量")]
+ public decimal BoxQty { get; set; }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestEditInput.cs
new file mode 100644
index 000000000..06db7ba73
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestEditInput.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public class KittingIssueRequestEditInput : SfsStoreRequestCreateOrUpdateInputBase
+{
+ #region Base
+
+ ///
+ /// 叫料类型
+ ///
+ [Display(Name = "叫料类型")]
+ public string Type { get; set; }
+
+ ///
+ /// 使用在途库
+ ///
+ [Display(Name = "使用在途库")]
+ public bool UseOnTheWayLocation { get; set; }
+
+ ///
+ /// 明细列表
+ ///
+ [Display(Name = "明细列表")]
+ public List Details { get; set; } = new List();
+ #endregion
+
+ #region Create
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestImportInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestImportInput.cs
new file mode 100644
index 000000000..8a0d5f78b
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/Inputs/KittingIssueRequestImportInput.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 KittingIssueRequestImportInput : 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/MaterialRequests/KittingIssueRequests/KittingIssueRequestPermissions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestPermissions.cs
new file mode 100644
index 000000000..43a7a5de8
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestPermissions.cs
@@ -0,0 +1,22 @@
+using Volo.Abp.Authorization.Permissions;
+using Win_in.Sfs.Wms.Store.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Application.Contracts;
+
+public static class KittingIssueRequestPermissions
+{
+
+ public const string Default = StorePermissions.GroupName + "." + nameof(KittingIssueRequest);
+ public const string Create = Default + "." + StorePermissions.CreateStr;
+ public const string Update = Default + "." + StorePermissions.UpdateStr;
+ public const string Delete = Default + "." + StorePermissions.DeleteStr;
+
+ public static void AddKittingIssueRequestPermission(this PermissionGroupDefinition permissionGroup)
+ {
+ var kittingIssueRequestPermission = permissionGroup.AddPermission(Default, StorePermissionDefinitionProvider.L(nameof(KittingIssueRequest)));
+ kittingIssueRequestPermission.AddChild(Create, StorePermissionDefinitionProvider.L(StorePermissions.CreateStr));
+ kittingIssueRequestPermission.AddChild(Update, StorePermissionDefinitionProvider.L(StorePermissions.UpdateStr));
+ kittingIssueRequestPermission.AddChild(Delete, StorePermissionDefinitionProvider.L(StorePermissions.DeleteStr));
+
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs
new file mode 100644
index 000000000..fe92ae472
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAppService.cs
@@ -0,0 +1,191 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Castle.Components.DictionaryAdapter;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Volo.Abp;
+using Volo.Abp.Application.Dtos;
+using Win_in.Sfs.Basedata.Application.Contracts;
+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;
+using Win_in.Sfs.Wms.Store.Notes;
+
+namespace Win_in.Sfs.Wms.Store.Application;
+
+[Authorize]
+[Route($"{StoreConsts.RootPath}kitting-issue-job")]
+public class KittingIssueJobAppService
+ : SfsJobAppServiceBase,
+ IKittingIssueJobAppService, ITransferLibCallback
+{
+ private readonly IKittingIssueJobManager _kittingIssueJobManager;
+ private readonly ILocationAppService _locationAppService;
+ private readonly ITransferLibJobAppService _transferLibJobAppService;
+
+ public KittingIssueJobAppService(
+ IKittingIssueJobRepository repository, IKittingIssueJobManager kittingIssueJobManager,
+ ILocationAppService locationAppService, ITransferLibJobAppService transferLibJobAppService) : base(repository, kittingIssueJobManager)
+ {
+ _kittingIssueJobManager = kittingIssueJobManager;
+ _locationAppService = locationAppService;
+ _transferLibJobAppService = transferLibJobAppService;
+ }
+
+ [HttpPost("add-many")]
+ public override async Task> CreateManyAsync(List inputs)
+ {
+ foreach (var input in inputs)
+ {
+ await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
+ }
+
+ return await base.CreateManyAsync(inputs).ConfigureAwait(false);
+ }
+
+ [HttpPost("")]
+ public override async Task CreateAsync(KittingIssueJobEditInput input)
+ {
+ await CheckMinRowAndSetStatusAsync(input).ConfigureAwait(false);
+
+ return await base.CreateAsync(input).ConfigureAwait(false);
+ }
+
+ ///
+ /// 判断是不是在最底层 如果不是则把状态变更为等待 并把库移推荐的From和To赋值
+ ///
+ ///
+ ///
+ private async Task CheckMinRowAndSetStatusAsync(KittingIssueJobEditInput input)
+ {
+ var jobDetailInputdetail = input.Details.FirstOrDefault();
+
+ var loctionDto = await _locationAppService.GetByCodeAsync(jobDetailInputdetail.RecommendFromLocationCode)
+ .ConfigureAwait(false);
+
+ if (loctionDto.RowCode != 1)
+ {
+ input.JobStatus = EnumJobStatus.Wait;
+
+ jobDetailInputdetail.TransferLibFromArriveDate = jobDetailInputdetail.RecommendFromArriveDate;
+ jobDetailInputdetail.TransferLibFromContainerCode = jobDetailInputdetail.RecommendFromContainerCode;
+ jobDetailInputdetail.TransferLibFromExpireDate = jobDetailInputdetail.RecommendFromExpireDate;
+ jobDetailInputdetail.TransferLibFromLocationArea = jobDetailInputdetail.RecommendFromLocationArea;
+ jobDetailInputdetail.TransferLibFromLocationCode = jobDetailInputdetail.RecommendFromLocationCode;
+ jobDetailInputdetail.TransferLibFromLocationErpCode = jobDetailInputdetail.RecommendFromLocationErpCode;
+ jobDetailInputdetail.TransferLibFromLocationGroup = jobDetailInputdetail.RecommendFromLocationGroup;
+ jobDetailInputdetail.TransferLibFromLot = jobDetailInputdetail.RecommendFromLot;
+ jobDetailInputdetail.TransferLibFromPackingCode = jobDetailInputdetail.RecommendFromPackingCode;
+ jobDetailInputdetail.TransferLibFromProduceDate = jobDetailInputdetail.RecommendFromProduceDate;
+ jobDetailInputdetail.TransferLibFromQty = jobDetailInputdetail.RecommendFromQty;
+ jobDetailInputdetail.TransferLibFromSupplierBatch = jobDetailInputdetail.RecommendFromSupplierBatch;
+ jobDetailInputdetail.TransferLibFromWarehouseCode = jobDetailInputdetail.RecommendFromWarehouseCode;
+
+ jobDetailInputdetail.TransferLibToArriveDate = jobDetailInputdetail.RecommendToArriveDate;
+ jobDetailInputdetail.TransferLibToContainerCode = jobDetailInputdetail.RecommendToContainerCode;
+ jobDetailInputdetail.TransferLibToExpireDate = jobDetailInputdetail.RecommendToExpireDate;
+ jobDetailInputdetail.TransferLibToLocationArea = jobDetailInputdetail.RecommendToLocationArea;
+ jobDetailInputdetail.TransferLibToLocationCode = jobDetailInputdetail.RecommendToLocationCode;
+ jobDetailInputdetail.TransferLibToLocationErpCode = jobDetailInputdetail.RecommendToLocationErpCode;
+ jobDetailInputdetail.TransferLibToLocationGroup = jobDetailInputdetail.RecommendToLocationGroup;
+ jobDetailInputdetail.TransferLibToLot = jobDetailInputdetail.RecommendToLot;
+ jobDetailInputdetail.TransferLibToPackingCode = jobDetailInputdetail.RecommendToPackingCode;
+ jobDetailInputdetail.TransferLibToProduceDate = jobDetailInputdetail.RecommendToProduceDate;
+ jobDetailInputdetail.TransferLibToQty = jobDetailInputdetail.RecommendToQty;
+ jobDetailInputdetail.TransferLibToSupplierBatch = jobDetailInputdetail.RecommendToSupplierBatch;
+ jobDetailInputdetail.TransferLibToWarehouseCode = jobDetailInputdetail.RecommendToWarehouseCode;
+ }
+ }
+
+ [HttpPost("cancel-by-request/{requestNumber}")]
+ public virtual async Task CancelByMaterialRequestAsync(string requestNumber)
+ {
+ var entities = await _repository.GetListAsync(p => p.KittingRequestNumber == requestNumber)
+ .ConfigureAwait(false);
+ foreach (var entity in entities)
+ {
+ await _kittingIssueJobManager.CancelAsync(entity).ConfigureAwait(false);
+ }
+ }
+
+ [HttpPost("invalid")]
+ public override async Task CancelAsync(Guid id)
+ {
+ var kittingIssueJob = await _repository.GetAsync(id).ConfigureAwait(false);
+ if (kittingIssueJob == null)
+ {
+ throw new UserFriendlyException($"未找到ID为 {id} 的任务");
+ }
+
+ await _kittingIssueJobManager.CancelAsync(kittingIssueJob).ConfigureAwait(false);
+ }
+
+ [HttpPost("by-request-number/{requestNumber}")]
+ public virtual async Task> GetByRequestNumberAsync(string requestNumber)
+ {
+ var entitys = await _repository.GetListAsync(p => p.KittingRequestNumber == requestNumber)
+ .ConfigureAwait(false);
+ return ObjectMapper.Map, List>(entitys);
+ }
+
+ [HttpPost("Do-Call-Back")]
+ public async Task DoTransferLibCallbackAsync(TransferLibJobDTO dto)
+ {
+ var job = await _repository.FindAsync(p => p.Number == dto.CallJobNumber).ConfigureAwait(false);
+
+ var transferLibJobDto= await _transferLibJobAppService.GetByNumberAsync(dto.Number).ConfigureAwait(false);
+
+ var transferLibNoteDetail= dto.Details.First();
+
+ var jobDetail = job.Details.First();
+ job.JobStatus = EnumJobStatus.Open;
+
+ jobDetail.TransferLibFromArriveDate = transferLibNoteDetail.HandledFromArriveDate;
+ jobDetail.TransferLibFromContainerCode=transferLibNoteDetail.HandledFromContainerCode;
+ jobDetail.TransferLibFromExpireDate=transferLibNoteDetail.HandledFromExpireDate;
+ jobDetail.TransferLibFromLocationArea=transferLibNoteDetail.HandledFromLocationArea;
+ jobDetail.TransferLibFromLocationCode=transferLibNoteDetail.HandledFromLocationCode;
+ jobDetail.TransferLibFromLocationErpCode = transferLibNoteDetail.HandledFromLocationErpCode;
+ jobDetail.TransferLibFromLocationGroup=transferLibNoteDetail.HandledFromLocationGroup;
+ jobDetail.TransferLibFromLot=transferLibNoteDetail.HandledFromLot;
+ jobDetail.TransferLibFromPackingCode = transferLibNoteDetail.HandledFromPackingCode;
+ jobDetail.TransferLibFromProduceDate = transferLibNoteDetail.HandledFromProduceDate;
+ jobDetail.TransferLibFromQty=transferLibNoteDetail.HandledFromQty;
+ jobDetail.TransferLibFromSupplierBatch=transferLibNoteDetail.HandledFromSupplierBatch;
+ jobDetail.TransferLibFromWarehouseCode = transferLibNoteDetail.HandledFromWarehouseCode;
+
+ jobDetail.TransferLibToArriveDate = transferLibNoteDetail.HandledToArriveDate;
+ jobDetail.TransferLibToContainerCode = transferLibNoteDetail.HandledToContainerCode;
+ jobDetail.TransferLibToExpireDate = transferLibNoteDetail.HandledToExpireDate;
+ jobDetail.TransferLibToLocationArea = transferLibNoteDetail.HandledToLocationArea;
+ jobDetail.TransferLibToLocationCode = transferLibNoteDetail.HandledToLocationCode;
+ jobDetail.TransferLibToLocationErpCode = transferLibNoteDetail.HandledToLocationErpCode;
+ jobDetail.TransferLibToLocationGroup = transferLibNoteDetail.HandledToLocationGroup;
+ jobDetail.TransferLibToLot = transferLibNoteDetail.HandledToLot;
+ jobDetail.TransferLibToPackingCode = transferLibNoteDetail.HandledToPackingCode;
+ jobDetail.TransferLibToProduceDate = transferLibNoteDetail.HandledToProduceDate;
+ jobDetail.TransferLibToQty = transferLibNoteDetail.HandledToQty;
+ jobDetail.TransferLibToSupplierBatch = transferLibNoteDetail.HandledToSupplierBatch;
+ jobDetail.TransferLibToWarehouseCode = transferLibNoteDetail.HandledToWarehouseCode;
+
+ await _repository.UpdateAsync(job).ConfigureAwait(false);
+
+ return;
+ }
+
+ [HttpPost("test")]
+ public virtual async Task Test()
+ {
+ Console.WriteLine("FuAZCZXVZXVXZVZ");
+ await Task.CompletedTask;
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAutoMapperProfile.cs
new file mode 100644
index 000000000..75badd80c
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobAutoMapperProfile.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 KittingIssueJobAutoMapperProfile()
+ {
+ 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/IssueNotes/KittingIssueNotes/KittingIssueNoteAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteAppService.cs
new file mode 100644
index 000000000..ccbc71b2b
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteAppService.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}kitting-issue-note")]
+public class KittingIssueNoteAppService :
+ SfsStoreWithDetailsAppServiceBase,
+ IKittingIssueNoteAppService
+{
+ private readonly IKittingIssueNoteManager _kittingIssueNoteManager;
+
+ public KittingIssueNoteAppService(
+ IKittingIssueNoteRepository repository,
+ IKittingIssueNoteManager kittingIssueNoteManager
+ ) : base(repository)
+ {
+ _kittingIssueNoteManager = kittingIssueNoteManager;
+ }
+
+ [HttpPost("")]
+ //[Authorize(KittingIssueNotePermissions.Create)]
+ public override async Task CreateAsync(KittingIssueNoteEditInput input)
+ {
+ var entity = ObjectMapper.Map(input);
+ await _kittingIssueNoteManager.CreateAsync(entity).ConfigureAwait(false);
+ var dto = ObjectMapper.Map(entity);
+ return dto;
+ }
+
+ ///
+ /// 确认对应的记录单
+ ///
+ ///
+ ///
+ [HttpPost("confirm/{id}")]
+ public virtual async Task ConfirmAsync(Guid id)
+ {
+ var kittingIssueNote= await _repository.GetAsync(id).ConfigureAwait(false);
+ kittingIssueNote.Confirmed = true;
+ kittingIssueNote=await _repository.UpdateAsync(kittingIssueNote).ConfigureAwait(false);
+ await LocalEventBus.PublishAsync(new SfsConfirmedEntityEventData(kittingIssueNote), false).ConfigureAwait(false);
+ return ObjectMapper.Map(kittingIssueNote);
+ }
+
+ [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(KittingIssueNote));
+ var result = await _kittingIssueNoteManager.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/IssueNotes/KittingIssueNotes/KittingIssueNoteAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteAutoMapperProfile.cs
new file mode 100644
index 000000000..80f97bac9
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteAutoMapperProfile.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 KittingIssueNoteAutoMapperProfile()
+ {
+ 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/MaterialRequests/KittingIssueRequests/KittingIssueRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestAppService.cs
new file mode 100644
index 000000000..8e348599b
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestAppService.cs
@@ -0,0 +1,310 @@
+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;
+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;
+
+///
+/// kitting叫料申请
+///
+[Authorize]
+[Route($"{StoreConsts.RootPath}kitting-issue-request")]
+public class KittingIssueRequestAppService : SfsStoreRequestAppServiceBase,
+ IKittingIssueRequestAppService
+{
+ private readonly IKittingIssueRequestManager _kittingIssueRequestManager;
+ private readonly IItemStoreRelationAppService _itemStoreRelationApp;
+ private readonly IAreaAppService _areaApp;
+ private readonly ILocationAppService _locationAppService;
+ private readonly IItemBasicAppService _itemBasicAppService;
+ private readonly IProductionLineAppService _productionLineAppService;
+
+ private readonly ITransactionTypeAppService _transactionTypeAppService;
+
+ public KittingIssueRequestAppService(
+ IKittingIssueRequestRepository repository,
+ IKittingIssueRequestManager kittingIssueRequestManager,
+ IPreparationPlanManager preparationPlanManager,
+ IItemStoreRelationAppService itemStoreRelationApp,
+ IAreaAppService areaApp,
+ ILocationAppService locationAppService,
+ IItemBasicAppService itemBasicAppService,
+ IProductionLineAppService productionLineAppService,
+ ITransactionTypeAppService transactionTypeAppService
+ )
+ : base(repository, kittingIssueRequestManager)
+ {
+ _kittingIssueRequestManager = kittingIssueRequestManager;
+ _itemStoreRelationApp = itemStoreRelationApp;
+ _areaApp = areaApp;
+ _locationAppService = locationAppService;
+ _itemBasicAppService = itemBasicAppService;
+ _productionLineAppService = productionLineAppService;
+
+ _transactionTypeAppService = transactionTypeAppService;
+ }
+
+
+ #region 东阳V2
+
+ public override async Task HandleAsync(Guid id)
+ {
+ await Task.CompletedTask.ConfigureAwait(false);
+ return null;
+ }
+
+ [HttpPost("")]
+ public override async Task CreateAsync(KittingIssueRequestEditInput 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.ToLocationArea = toLocationDto.AreaCode;
+ detailInput.ToLocationGroup = toLocationDto.LocationGroupCode;
+ detailInput.ToWarehouseCode= toLocationDto.WarehouseCode;
+ detailInput.ProdLine = detailInput.ToLocationCode;
+ detailInput.ToLocationErpCode = toLocationDto.ErpLocationCode;
+
+ detailInput.ItemDesc1 = itemBasicDto.Desc1;
+ detailInput.ItemDesc2 = itemBasicDto.Desc2;
+ detailInput.ItemName = itemBasicDto.Name;
+ detailInput.Uom = itemBasicDto.BasicUom;
+ detailInput.StdPackQty = itemBasicDto.StdPackQty;
+ detailInput.Status = EnumStatus.Open;
+
+ //因为是刚创建的 所以发料数一定是0
+ detailInput.IssuedQty = 0;
+ }
+
+ await SetRequestAutoPropertiesAsync(input).ConfigureAwait(false);
+ var entity = ObjectMapper.Map(input);
+
+ var result = await _kittingIssueRequestManager.CreateByNumberAsync(entity).ConfigureAwait(false);
+
+ var dto = ObjectMapper.Map(result);
+
+ return dto;
+ }
+
+ ///
+ /// 赋值Request业务属性
+ ///
+ ///
+ ///
+ private async Task SetRequestAutoPropertiesAsync(KittingIssueRequestEditInput entity)
+ {
+ var tranType = await _transactionTypeAppService.GetByTransTypeAsync(EnumTransType.Issue, EnumTransSubType.None).ConfigureAwait(false);
+ Check.NotNull(tranType, "事务类型", "事务类型不存在");
+ entity.AutoSubmit = tranType.AutoSubmitRequest;
+ entity.AutoAgree = tranType.AutoAgreeRequest;
+ entity.AutoHandle = tranType.AutoHandleRequest;
+ entity.AutoCompleteJob = tranType.AutoCompleteJob;
+ entity.DirectCreateNote = tranType.DirectCreateNote;
+ }
+
+ [HttpPost("create-and-handle")]
+ public async Task CreateAndHandleAsync(KittingIssueRequestEditInput input)
+ {
+ var kittingIssueRequestDto = await CreateAsync(input).ConfigureAwait(false);
+
+ await HandleAsync(kittingIssueRequestDto.Id).ConfigureAwait(false);
+
+ return kittingIssueRequestDto;
+ }
+
+ #endregion
+
+ #region 导入
+
+ ///
+ /// 用来重写 导入数据时可以加工数据
+ ///
+ ///
+ ///
+ protected override async Task> ImportProcessingEntityAsync(
+ Dictionary dictionary)
+ {
+ var addList = dictionary.Where(p => p.Value == EntityState.Added).Select(p => p.Key);
+
+ foreach (var kittingIssueRequest in addList)
+ {
+ kittingIssueRequest.Worker = CurrentUser.GetUserName();
+ kittingIssueRequest.CreatorId = CurrentUser.Id;
+ if (kittingIssueRequest.Type == EnumTransSubType.Issue_Manual.GetDisplayName())
+ {
+ kittingIssueRequest.Type = EnumTransSubType.Issue_Manual.ToString();
+ }
+
+ foreach (var detail in kittingIssueRequest.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;
+ detail.StdPackQty = itemBasicDto.StdPackQty;
+ }
+ }
+
+ return dictionary;
+ }
+
+ ///
+ /// 导入验证
+ ///
+ ///
+ ///
+ ///
+ protected override async Task ValidateImportModelAsync(KittingIssueRequestImportInput 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);
+ }
+
+ #endregion
+
+ #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 CheckAreaAsync(KittingIssueRequestImportInput 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(KittingIssueRequestImportInput 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[] { "物品库位对应关系" }));
+ }
+ }
+
+ 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()}】类型");
+ }
+ }
+
+ protected async Task CheckItemBasicAsync(KittingIssueRequestImportInput 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(KittingIssueRequestImportInput importInput,
+ List validationRresult)
+ {
+ var location = await _locationAppService.GetByCodeAsync(importInput.ToLocationCode).ConfigureAwait(false);
+ if (location == null)
+ {
+ validationRresult.Add(new ValidationResult($"目标库位{importInput.ToLocationCode}不存在", new[] { "目标库位" }));
+ }
+
+ return location;
+ }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestAutoMapperProfile.cs
new file mode 100644
index 000000000..679bc87b1
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestAutoMapperProfile.cs
@@ -0,0 +1,66 @@
+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 KittingIssueRequestAutoMapperProfile()
+ {
+ CreateMap()
+ .ReverseMap();
+
+ CreateMap()
+ .ReverseMap();
+
+ CreateMap()
+ .IgnoreAuditedObjectProperties()
+ .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.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.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 1bc1e2b70..955e43de7 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
@@ -15,6 +15,7 @@ public partial class StoreApplicationAutoMapperProfile : Profile
ItemTransformRequestAutoMapperProfile();
MaterialRequestAutoMapperProfile();
InjectionRequestAutoMapperProfile();
+ KittingIssueRequestAutoMapperProfile();
AssembleIssueRequestsAutoMapperProfile();
ThirdLocationRequestAutoMapperProfile();
ProductionReturnRequestAutoMapperProfile();
@@ -68,6 +69,7 @@ public partial class StoreApplicationAutoMapperProfile : Profile
IsolationNoteAutoMapperProfile();
IssueNoteAutoMapperProfile();
InjectionNoteAutoMapperProfile();
+ KittingIssueNoteAutoMapperProfile();
AssembleNoteAutoMapperProfile();
ThirdLocationNoteAutoMapperProfile();
ContainerNoteAutoMapperProfile();
@@ -109,6 +111,7 @@ public partial class StoreApplicationAutoMapperProfile : Profile
InspectJobAutoMapperProfile();
IssueJobAutoMapperProfile();
InjectionJobAutoMapperProfile();
+ KittingIssueJobAutoMapperProfile();
AssembleJobAutoMapperProfile();
ThirdLocationJobAutoMapperProfile();
ContainerJobAutoMapperProfile();
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobManager.cs
new file mode 100644
index 000000000..a523d3594
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobManager.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public interface IKittingIssueJobManager : IJobManager
+{
+ Task GetAsync(Expression> expression);
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobRepository.cs
new file mode 100644
index 000000000..b7a219af0
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/IKittingIssueJobRepository.cs
@@ -0,0 +1,6 @@
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public interface IKittingIssueJobRepository : ISfsJobRepositoryBase
+{
+
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJob.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJob.cs
new file mode 100644
index 000000000..74707b71a
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJob.cs
@@ -0,0 +1,47 @@
+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;
+
+///
+/// Kitting发料任务
+///
+[Display(Name = "Kitting发料任务")]
+public class KittingIssueJob : SfsJobAggregateRootBase
+{
+ ///
+ /// 叫料请求类型
+ ///
+ [IgnoreUpdate]
+ public string RequestType { get; set; }
+
+ ///
+ /// 生产线
+ ///
+ [IgnoreUpdate]
+ public string ProdLine { get; set; }
+
+ ///
+ /// 要料单号
+ ///
+ [IgnoreUpdate]
+ public string KittingRequestNumber { get; set; }
+
+ ///
+ /// 使用在途库
+ ///
+ [Display(Name = "使用在途库")]
+ [IgnoreUpdate]
+ 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/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobDetail.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobDetail.cs
new file mode 100644
index 000000000..04918a8c7
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobDetail.cs
@@ -0,0 +1,524 @@
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public class KittingIssueJobDetail : SfsDetailEntityBase
+{
+ #region 库存基础信息
+
+ ///
+ /// 物品代码
+ ///
+ public string ItemCode { get; set; }
+
+ ///
+ /// 物品名称
+ ///
+ public string ItemName { get; set; }
+
+ ///
+ /// 物品描述1
+ ///
+ public string ItemDesc1 { get; set; }
+
+ ///
+ /// 物品描述2
+ ///
+ public string ItemDesc2 { get; set; }
+
+ ///
+ /// 标包数量
+ ///
+ [Display(Name = "标包数量")]
+ [Column(TypeName = "decimal(18,6)")]
+ public decimal StdPackQty { get; set; }
+
+ ///
+ /// 库存状态
+ ///
+ public EnumInventoryStatus Status { get; set; }
+
+ ///
+ /// 计量单位
+ ///
+ public string Uom { get; set; }
+
+ #endregion
+
+ #region 请求信息
+
+ ///
+ /// 请求库位
+ ///
+ public string RequestLocationCode { get; set; }
+
+ ///
+ /// 到库区
+ ///
+ public string RequestLocationArea { get; set; }
+
+ ///
+ /// 到库位组
+ ///
+ public string RequestLocationGroup { get; set; }
+
+ ///
+ /// 到ERP库位
+ ///
+ public string RequestLocationErpCode { get; set; }
+
+ ///
+ /// 到仓库
+ ///
+ public string RequestWarehouseCode { get; set; }
+
+ ///
+ /// 在途库库位
+ ///
+ public string OnTheWayLocationCode { get; set; }
+
+ ///
+ /// 生产线
+ ///
+ public string ProdLine { get; set; }
+
+ ///
+ /// 位置码
+ ///
+ public string PositionCode { get; set; }
+
+ ///
+ /// 推荐的类型
+ ///
+ public EnumRecommendType RecommendType { get; set; }
+
+ ///
+ /// 需求数量
+ ///
+ public decimal RequestQty { get; set; }
+
+ #endregion
+
+ #region 推荐来源
+
+ ///
+ /// 推荐来源托标签
+ ///
+ public string RecommendFromContainerCode { get; set; }
+
+ ///
+ /// 推荐来源箱标签
+ ///
+ public string RecommendFromPackingCode { get; set; }
+
+ ///
+ /// 推荐来源批次供应商批次
+ ///
+ public string RecommendFromSupplierBatch { get; set; }
+
+ ///
+ /// 推荐来源批次到货时间
+ ///
+ public DateTime RecommendFromArriveDate { get; set; }
+
+ ///
+ /// 推荐来源批次生产时间
+ ///
+ public DateTime RecommendFromProduceDate { get; set; }
+
+ ///
+ /// 推荐来源批次过期时间
+ ///
+ public DateTime RecommendFromExpireDate { get; set; }
+
+ ///
+ /// 推荐来源批次排序
+ ///
+ public string RecommendFromLot { get; set; }
+
+ ///
+ /// 推荐来源库位
+ ///
+ public string RecommendFromLocationCode { get; set; }
+
+ ///
+ /// 推荐来源库区
+ ///
+ public string RecommendFromLocationArea { get; set; }
+
+ ///
+ /// 推荐来源库位组
+ ///
+ public string RecommendFromLocationGroup { get; set; }
+
+ ///
+ /// 推荐来源ERP库位
+ ///
+ public string RecommendFromLocationErpCode { get; set; }
+
+ ///
+ /// 推荐来源仓库
+ ///
+ public string RecommendFromWarehouseCode { get; set; }
+
+ ///
+ /// 推荐来源数量
+ ///
+ public decimal RecommendFromQty { get; set; }
+
+ #endregion
+
+ #region 推荐目标
+
+ ///
+ /// 推荐目标托标签
+ ///
+ public string RecommendToContainerCode { get; set; }
+
+ ///
+ /// 推荐目标箱标签
+ ///
+ public string RecommendToPackingCode { get; set; }
+
+ ///
+ /// 推荐目标批次供应商批次
+ ///
+ public string RecommendToSupplierBatch { get; set; }
+
+ ///
+ /// 推荐目标批次到货时间
+ ///
+ public DateTime RecommendToArriveDate { get; set; }
+
+ ///
+ /// 推荐目标批次生产时间
+ ///
+ public DateTime RecommendToProduceDate { get; set; }
+
+ ///
+ /// 推荐目标批次过期时间
+ ///
+ public DateTime RecommendToExpireDate { get; set; }
+
+ ///
+ /// 推荐目标批次排序
+ ///
+ public string RecommendToLot { get; set; }
+
+ ///
+ /// 推荐目标库位
+ ///
+ public string RecommendToLocationCode { get; set; }
+
+ ///
+ /// 推荐目标库区
+ ///
+ public string RecommendToLocationArea { get; set; }
+
+ ///
+ /// 推荐目标库位组
+ ///
+ public string RecommendToLocationGroup { get; set; }
+
+ ///
+ /// 推荐目标ERP库位
+ ///
+ public string RecommendToLocationErpCode { get; set; }
+
+ ///
+ /// 推荐目标仓库
+ ///
+ public string RecommendToWarehouseCode { get; set; }
+
+ ///
+ /// 推荐目标数量
+ ///
+ public decimal RecommendToQty { get; set; }
+
+ #endregion
+
+ #region 库移来源
+
+ ///
+ /// 库移来源托标签
+ ///
+ public string TransferLibFromContainerCode { get; set; }
+
+ ///
+ /// 库移来源箱标签
+ ///
+ public string TransferLibFromPackingCode { get; set; }
+
+ ///
+ /// 库移来源批次供应商批次
+ ///
+ public string TransferLibFromSupplierBatch { get; set; }
+
+ ///
+ /// 库移来源批次到货时间
+ ///
+ public DateTime TransferLibFromArriveDate { get; set; }
+
+ ///
+ /// 库移来源批次生产时间
+ ///
+ public DateTime TransferLibFromProduceDate { get; set; }
+
+ ///
+ /// 库移来源批次过期时间
+ ///
+ public DateTime TransferLibFromExpireDate { get; set; }
+
+ ///
+ /// 库移来源批次排序
+ ///
+ public string TransferLibFromLot { get; set; }
+
+ ///
+ /// 库移来源库位
+ ///
+ public string TransferLibFromLocationCode { get; set; }
+
+ ///
+ /// 库移来源库区
+ ///
+ public string TransferLibFromLocationArea { get; set; }
+
+ ///
+ /// 库移来源库位组
+ ///
+ public string TransferLibFromLocationGroup { get; set; }
+
+ ///
+ /// 库移来源ERP库位
+ ///
+ public string TransferLibFromLocationErpCode { get; set; }
+
+ ///
+ /// 库移来源仓库
+ ///
+ public string TransferLibFromWarehouseCode { get; set; }
+
+ ///
+ /// 库移来源数量
+ ///
+ public decimal TransferLibFromQty { get; set; }
+
+ #endregion
+
+ #region 库移目标
+
+ ///
+ /// 库移目标托标签
+ ///
+ public string TransferLibToContainerCode { get; set; }
+
+ ///
+ /// 库移目标箱标签
+ ///
+ public string TransferLibToPackingCode { get; set; }
+
+ ///
+ /// 库移目标批次供应商批次
+ ///
+ public string TransferLibToSupplierBatch { get; set; }
+
+ ///
+ /// 库移目标批次到货时间
+ ///
+ public DateTime TransferLibToArriveDate { get; set; }
+
+ ///
+ /// 库移目标批次生产时间
+ ///
+ public DateTime TransferLibToProduceDate { get; set; }
+
+ ///
+ /// 库移目标批次过期时间
+ ///
+ public DateTime TransferLibToExpireDate { get; set; }
+
+ ///
+ /// 库移目标批次排序
+ ///
+ public string TransferLibToLot { get; set; }
+
+ ///
+ /// 库移目标库位
+ ///
+ public string TransferLibToLocationCode { get; set; }
+
+ ///
+ /// 库移目标库区
+ ///
+ public string TransferLibToLocationArea { get; set; }
+
+ ///
+ /// 库移目标库位组
+ ///
+ public string TransferLibToLocationGroup { get; set; }
+
+ ///
+ /// 库移目标ERP库位
+ ///
+ public string TransferLibToLocationErpCode { get; set; }
+
+ ///
+ /// 库移目标仓库
+ ///
+ public string TransferLibToWarehouseCode { get; set; }
+
+ ///
+ /// 库移目标数量
+ ///
+ public decimal TransferLibToQty { get; set; }
+
+ #endregion
+
+ #region 实际来源
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledFromContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledFromPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledFromSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledFromArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledFromProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledFromExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledFromLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledFromLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledFromLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledFromLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledFromLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledFromWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledFromQty { get; set; }
+
+ #endregion
+
+ #region 实际目标
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledToContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledToPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledToSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledToArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledToProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledToExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledToLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledToLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledToLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledToLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledToLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledToWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledToQty { get; set; }
+
+ #endregion
+
+ public void SetId(Guid id)
+ {
+ this.Id = id;
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobManager.cs
new file mode 100644
index 000000000..0725bd952
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobManager.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Users;
+using Volo.Abp.Validation;
+using Win_in.Sfs.Shared.Domain.Shared;
+using Win_in.Sfs.Wms.Inventory.Application.Contracts;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public class KittingIssueJobManager : SfsJobManagerBase, IKittingIssueJobManager
+{
+ private readonly IBalanceAppService _balanceAppService;
+ private readonly IExpectOutAppService _expectOutAppService;
+
+ public KittingIssueJobManager(
+ IKittingIssueJobRepository repository, IBalanceAppService balanceAppService, IExpectOutAppService expectOutAppService) : base(repository)
+ {
+ _balanceAppService = balanceAppService;
+ _expectOutAppService = expectOutAppService;
+ }
+
+ ///
+ /// 执行任务 发料任务
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override async Task CompleteAsync(KittingIssueJob input, ICurrentUser user)
+ {
+ var entity = await Repository.FindAsync(input.Id).ConfigureAwait(false);
+
+ var inputDetail = input.Details.First();
+ var detail = entity.Details.First();
+
+ var expectOutDtos = await _expectOutAppService.GetListByItemCodeAndStatusAndPackingCodeAsync(detail.ItemCode, detail.HandledFromLocationCode, detail.HandledFromPackingCode, detail.Status, detail.HandledFromLot).ConfigureAwait(false);
+ if (expectOutDtos.Any())
+ {
+ throw new UserFriendlyException($" 箱码:{detail.HandledFromPackingCode}," +
+ $" 物品代码:{detail.ItemCode}," +
+ $" 库位代码:{detail.HandledFromLocationCode}," +
+ $" 状态:{detail.Status}," +
+ $" 批次:{detail.HandledFromLot}" +
+ $" 的库存被占用【预计出】");
+ }
+
+ var balanceDto=await _balanceAppService.GetRealQtyByPackingCodeAndItemCodeAndLocationCodeAndStatusAsync(inputDetail.HandledFromPackingCode, inputDetail.ItemCode, inputDetail.HandledFromLocationCode, inputDetail.Status, inputDetail.HandledFromLot).ConfigureAwait(false);
+ if (balanceDto.Qty <= 0)
+ {
+ throw new UserFriendlyException($" 箱码:{detail.HandledFromPackingCode}," +
+ $" 物品代码:{detail.ItemCode}," +
+ $" 库位代码:{detail.HandledFromLocationCode}," +
+ $" 状态:{detail.Status}," +
+ $" 批次:{detail.HandledFromLot}" +
+ $" 的可用库存不大于0,现在为{balanceDto.Qty},请检查【库存数量】和【预计出】");
+ }
+
+ detail.HandledFromArriveDate = inputDetail.HandledFromArriveDate;
+ detail.HandledFromContainerCode = inputDetail.HandledFromContainerCode;
+ detail.HandledFromExpireDate = inputDetail.HandledFromExpireDate;
+ detail.HandledFromLocationArea = inputDetail.HandledFromLocationArea;
+ detail.HandledFromLocationCode = inputDetail.HandledFromLocationCode;
+ detail.HandledFromLocationErpCode = inputDetail.HandledFromLocationErpCode;
+ detail.HandledFromLocationGroup = inputDetail.HandledFromLocationGroup;
+ detail.HandledFromLot = inputDetail.HandledFromLot;
+ detail.HandledFromPackingCode = inputDetail.HandledFromPackingCode;
+ detail.HandledFromProduceDate = inputDetail.HandledFromProduceDate;
+ detail.HandledFromQty = inputDetail.HandledFromQty;
+ detail.HandledFromSupplierBatch = inputDetail.HandledFromSupplierBatch;
+ detail.HandledFromWarehouseCode = inputDetail.HandledFromWarehouseCode;
+
+ detail.HandledToArriveDate = inputDetail.HandledToArriveDate;
+ detail.HandledToContainerCode = inputDetail.HandledToContainerCode;
+ detail.HandledToExpireDate = inputDetail.HandledToExpireDate;
+ detail.HandledToLocationArea = inputDetail.HandledToLocationArea;
+ detail.HandledToLocationCode = inputDetail.HandledToLocationCode;
+ detail.HandledToLocationErpCode = inputDetail.HandledToLocationErpCode;
+ detail.HandledToLocationGroup = inputDetail.HandledToLocationGroup;
+ detail.HandledToLot = inputDetail.HandledToLot;
+ detail.HandledToPackingCode = inputDetail.HandledToPackingCode;
+ detail.HandledToProduceDate = inputDetail.HandledToProduceDate;
+ detail.HandledToQty = inputDetail.HandledToQty;
+ detail.HandledToSupplierBatch = inputDetail.HandledToSupplierBatch;
+ detail.HandledToWarehouseCode = inputDetail.HandledToWarehouseCode;
+
+ detail.HandledToPackingCode = string.Empty;
+ detail.HandledToLot = string.Empty;
+ detail.HandledToContainerCode = string.Empty;
+
+ return await base.CompleteAsync(entity, user).ConfigureAwait(false);
+ }
+
+ public async Task GetAsync(Expression> expression)
+ {
+ return await Repository.FindAsync(expression).ConfigureAwait(false);
+ }
+
+ #region 无用
+
+ public override Task> GetWorkingListByPackingAsync(string packingCode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override Task> GetWorkingListByContainerAsync(string containerCode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void CheckDetails(KittingIssueJob entity, AbpValidationResult result)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteManager.cs
new file mode 100644
index 000000000..d0b19e348
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteManager.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public interface IKittingIssueNoteManager : ISfsStoreManager
+{
+ Task ConfirmAsync(Guid id);
+
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteRepository.cs
new file mode 100644
index 000000000..5998c7c9a
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/IKittingIssueNoteRepository.cs
@@ -0,0 +1,6 @@
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public interface IKittingIssueNoteRepository : ISfsStoreRepositoryBase
+{
+
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNote.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNote.cs
new file mode 100644
index 000000000..46394a025
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNote.cs
@@ -0,0 +1,71 @@
+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;
+
+///
+/// Kitting叫料记录
+///
+public class KittingIssueNote : SfsStoreAggregateRootBase, IHasJobNumber, IHasRequestNumber
+{
+ ///
+ /// 任务ID
+ ///
+ [IgnoreUpdate]
+ public string JobNumber { 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/IssueNotes/KittingIssueNotes/KittingIssueNoteDetail.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteDetail.cs
new file mode 100644
index 000000000..cb6d9e012
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteDetail.cs
@@ -0,0 +1,519 @@
+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.Domain;
+
+public class KittingIssueNoteDetail : SfsStoreDetailEntityBase
+{
+ #region 库存基础信息
+
+ ///
+ /// 物品代码
+ ///
+ public string ItemCode { get; set; }
+
+ ///
+ /// 物品名称
+ ///
+ public string ItemName { get; set; }
+
+ ///
+ /// 物品描述1
+ ///
+ public string ItemDesc1 { get; set; }
+
+ ///
+ /// 物品描述2
+ ///
+ public string ItemDesc2 { get; set; }
+
+ ///
+ /// 标包数量
+ ///
+ [Display(Name = "标包数量")]
+ [Column(TypeName = "decimal(18,6)")]
+ public decimal StdPackQty { get; set; }
+
+ ///
+ /// 库存状态
+ ///
+ public EnumInventoryStatus Status { get; set; }
+
+ ///
+ /// 计量单位
+ ///
+ public string Uom { get; set; }
+
+ #endregion
+
+ #region 请求信息
+
+ ///
+ /// 请求库位
+ ///
+ public string RequestLocationCode { get; set; }
+
+ ///
+ /// 到库区
+ ///
+ public string RequestLocationArea { get; set; }
+
+ ///
+ /// 到库位组
+ ///
+ public string RequestLocationGroup { get; set; }
+
+ ///
+ /// 到ERP库位
+ ///
+ public string RequestLocationErpCode { get; set; }
+
+ ///
+ /// 到仓库
+ ///
+ public string RequestWarehouseCode { get; set; }
+
+ ///
+ /// 在途库库位
+ ///
+ public string OnTheWayLocationCode { get; set; }
+
+ ///
+ /// 生产线
+ ///
+ public string ProdLine { get; set; }
+
+ ///
+ /// 位置码
+ ///
+ public string PositionCode { get; set; }
+
+ ///
+ /// 推荐的类型
+ ///
+ public EnumRecommendType RecommendType { get; set; }
+
+ ///
+ /// 需求数量
+ ///
+ public decimal RequestQty { get; set; }
+
+ #endregion
+
+ #region 推荐来源
+
+ ///
+ /// 推荐来源托标签
+ ///
+ public string RecommendFromContainerCode { get; set; }
+
+ ///
+ /// 推荐来源箱标签
+ ///
+ public string RecommendFromPackingCode { get; set; }
+
+ ///
+ /// 推荐来源批次供应商批次
+ ///
+ public string RecommendFromSupplierBatch { get; set; }
+
+ ///
+ /// 推荐来源批次到货时间
+ ///
+ public DateTime RecommendFromArriveDate { get; set; }
+
+ ///
+ /// 推荐来源批次生产时间
+ ///
+ public DateTime RecommendFromProduceDate { get; set; }
+
+ ///
+ /// 推荐来源批次过期时间
+ ///
+ public DateTime RecommendFromExpireDate { get; set; }
+
+ ///
+ /// 推荐来源批次排序
+ ///
+ public string RecommendFromLot { get; set; }
+
+ ///
+ /// 推荐来源库位
+ ///
+ public string RecommendFromLocationCode { get; set; }
+
+ ///
+ /// 推荐来源库区
+ ///
+ public string RecommendFromLocationArea { get; set; }
+
+ ///
+ /// 推荐来源库位组
+ ///
+ public string RecommendFromLocationGroup { get; set; }
+
+ ///
+ /// 推荐来源ERP库位
+ ///
+ public string RecommendFromLocationErpCode { get; set; }
+
+ ///
+ /// 推荐来源仓库
+ ///
+ public string RecommendFromWarehouseCode { get; set; }
+
+ ///
+ /// 推荐来源数量
+ ///
+ public decimal RecommendFromQty { get; set; }
+
+ #endregion
+
+ #region 推荐目标
+
+ ///
+ /// 推荐目标托标签
+ ///
+ public string RecommendToContainerCode { get; set; }
+
+ ///
+ /// 推荐目标箱标签
+ ///
+ public string RecommendToPackingCode { get; set; }
+
+ ///
+ /// 推荐目标批次供应商批次
+ ///
+ public string RecommendToSupplierBatch { get; set; }
+
+ ///
+ /// 推荐目标批次到货时间
+ ///
+ public DateTime RecommendToArriveDate { get; set; }
+
+ ///
+ /// 推荐目标批次生产时间
+ ///
+ public DateTime RecommendToProduceDate { get; set; }
+
+ ///
+ /// 推荐目标批次过期时间
+ ///
+ public DateTime RecommendToExpireDate { get; set; }
+
+ ///
+ /// 推荐目标批次排序
+ ///
+ public string RecommendToLot { get; set; }
+
+ ///
+ /// 推荐目标库位
+ ///
+ public string RecommendToLocationCode { get; set; }
+
+ ///
+ /// 推荐目标库区
+ ///
+ public string RecommendToLocationArea { get; set; }
+
+ ///
+ /// 推荐目标库位组
+ ///
+ public string RecommendToLocationGroup { get; set; }
+
+ ///
+ /// 推荐目标ERP库位
+ ///
+ public string RecommendToLocationErpCode { get; set; }
+
+ ///
+ /// 推荐目标仓库
+ ///
+ public string RecommendToWarehouseCode { get; set; }
+
+ ///
+ /// 推荐目标数量
+ ///
+ public decimal RecommendToQty { get; set; }
+
+ #endregion
+
+ #region 库移来源
+
+ ///
+ /// 库移来源托标签
+ ///
+ public string TransferLibFromContainerCode { get; set; }
+
+ ///
+ /// 库移来源箱标签
+ ///
+ public string TransferLibFromPackingCode { get; set; }
+
+ ///
+ /// 库移来源批次供应商批次
+ ///
+ public string TransferLibFromSupplierBatch { get; set; }
+
+ ///
+ /// 库移来源批次到货时间
+ ///
+ public DateTime TransferLibFromArriveDate { get; set; }
+
+ ///
+ /// 库移来源批次生产时间
+ ///
+ public DateTime TransferLibFromProduceDate { get; set; }
+
+ ///
+ /// 库移来源批次过期时间
+ ///
+ public DateTime TransferLibFromExpireDate { get; set; }
+
+ ///
+ /// 库移来源批次排序
+ ///
+ public string TransferLibFromLot { get; set; }
+
+ ///
+ /// 库移来源库位
+ ///
+ public string TransferLibFromLocationCode { get; set; }
+
+ ///
+ /// 库移来源库区
+ ///
+ public string TransferLibFromLocationArea { get; set; }
+
+ ///
+ /// 库移来源库位组
+ ///
+ public string TransferLibFromLocationGroup { get; set; }
+
+ ///
+ /// 库移来源ERP库位
+ ///
+ public string TransferLibFromLocationErpCode { get; set; }
+
+ ///
+ /// 库移来源仓库
+ ///
+ public string TransferLibFromWarehouseCode { get; set; }
+
+ ///
+ /// 库移来源数量
+ ///
+ public decimal TransferLibFromQty { get; set; }
+
+ #endregion
+
+ #region 库移目标
+
+ ///
+ /// 库移目标托标签
+ ///
+ public string TransferLibToContainerCode { get; set; }
+
+ ///
+ /// 库移目标箱标签
+ ///
+ public string TransferLibToPackingCode { get; set; }
+
+ ///
+ /// 库移目标批次供应商批次
+ ///
+ public string TransferLibToSupplierBatch { get; set; }
+
+ ///
+ /// 库移目标批次到货时间
+ ///
+ public DateTime TransferLibToArriveDate { get; set; }
+
+ ///
+ /// 库移目标批次生产时间
+ ///
+ public DateTime TransferLibToProduceDate { get; set; }
+
+ ///
+ /// 库移目标批次过期时间
+ ///
+ public DateTime TransferLibToExpireDate { get; set; }
+
+ ///
+ /// 库移目标批次排序
+ ///
+ public string TransferLibToLot { get; set; }
+
+ ///
+ /// 库移目标库位
+ ///
+ public string TransferLibToLocationCode { get; set; }
+
+ ///
+ /// 库移目标库区
+ ///
+ public string TransferLibToLocationArea { get; set; }
+
+ ///
+ /// 库移目标库位组
+ ///
+ public string TransferLibToLocationGroup { get; set; }
+
+ ///
+ /// 库移目标ERP库位
+ ///
+ public string TransferLibToLocationErpCode { get; set; }
+
+ ///
+ /// 库移目标仓库
+ ///
+ public string TransferLibToWarehouseCode { get; set; }
+
+ ///
+ /// 库移目标数量
+ ///
+ public decimal TransferLibToQty { get; set; }
+
+ #endregion
+
+ #region 实际来源
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledFromContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledFromPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledFromSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledFromArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledFromProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledFromExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledFromLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledFromLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledFromLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledFromLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledFromLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledFromWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledFromQty { get; set; }
+
+ #endregion
+
+ #region 实际目标
+
+ ///
+ /// 实际目标托标签
+ ///
+ public string HandledToContainerCode { get; set; }
+
+ ///
+ /// 实际箱标签
+ ///
+ public string HandledToPackingCode { get; set; }
+
+ ///
+ /// 实际批次供应商批次
+ ///
+ public string HandledToSupplierBatch { get; set; }
+
+ ///
+ /// 实际批次到货时间
+ ///
+ public DateTime HandledToArriveDate { get; set; }
+
+ ///
+ /// 实际批次生产时间
+ ///
+ public DateTime HandledToProduceDate { get; set; }
+
+ ///
+ /// 实际批次过期时间
+ ///
+ public DateTime HandledToExpireDate { get; set; }
+
+ ///
+ /// 实际批次排序
+ ///
+ public string HandledToLot { get; set; }
+
+ ///
+ /// 实际库位
+ ///
+ public string HandledToLocationCode { get; set; }
+
+ ///
+ /// 实际库区
+ ///
+ public string HandledToLocationArea { get; set; }
+
+ ///
+ /// 实际库位组
+ ///
+ public string HandledToLocationGroup { get; set; }
+
+ ///
+ /// 实际ERP库位
+ ///
+ public string HandledToLocationErpCode { get; set; }
+
+ ///
+ /// 实际仓库
+ ///
+ public string HandledToWarehouseCode { get; set; }
+
+ ///
+ /// 实际数量
+ ///
+ public decimal HandledToQty { get; set; }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteManager.cs
new file mode 100644
index 000000000..d79aaee86
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteManager.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 KittingIssueNoteManager : SfsStoreManagerBase, IKittingIssueNoteManager
+{
+
+ public KittingIssueNoteManager(
+ IKittingIssueNoteRepository 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(KittingIssueNote entity)
+ {
+ try
+ {
+ await LocalEventBus.PublishAsync(new SfsConfirmedEntityEventData(entity), false).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogDebug($"{nameof(KittingIssueNote)} Confirmed Event:{ex.Message}", null);
+ Console.WriteLine(ex.Source);
+ throw;
+ }
+ }
+
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestManager.cs
new file mode 100644
index 000000000..43cda56b6
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestManager.cs
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+using Win_in.Sfs.Shared.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public interface IKittingIssueRequestManager : ISfsStoreRequestManager,
+ IBulkImportService
+{
+
+ Task CompleteAsync(string number);
+
+ Task CreateByNumberAsync(KittingIssueRequest entity);
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestRepository.cs
new file mode 100644
index 000000000..cb2a72561
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/IKittingIssueRequestRepository.cs
@@ -0,0 +1,9 @@
+using Win_in.Sfs.Shared.Domain;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public interface IKittingIssueRequestRepository : ISfsStoreRepositoryBase,
+ ISfsBulkRepositoryBase
+{
+
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequest.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequest.cs
new file mode 100644
index 000000000..35a4ec107
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequest.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain.Entities;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+///
+/// Kitting叫料申请
+///
+public class KittingIssueRequest : SfsStoreRequestAggregateRootBase
+{
+ ///
+ /// 叫料类型
+ ///
+ [Display(Name = "叫料类型")]
+ [IgnoreUpdate]
+ public string Type { 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/MaterialRequests/KittingIssueRequests/KittingIssueRequestDetail.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestDetail.cs
new file mode 100644
index 000000000..c5ddecb64
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestDetail.cs
@@ -0,0 +1,103 @@
+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.Domain;
+
+///
+/// Kitting叫料申请明细
+///
+public class KittingIssueRequestDetail : SfsStoreDetailWithQtyEntityBase, IHasToLocation
+{
+ #region 目标库位信息
+
+ ///
+ /// 目标库位
+ ///
+ [Display(Name = "目标库位")]
+ [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储位")]
+ public string ToLocationErpCode { get; set; }
+
+ ///
+ /// 目标仓库
+ ///
+ [Display(Name = "目标仓库")]
+ public string ToWarehouseCode { get; set; }
+
+ #endregion
+
+
+ ///
+ /// 生产线
+ ///
+ public string ProdLine { 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; }
+
+ ///
+ /// 需求箱数量
+ ///
+ [Display(Name = "需求箱数量")]
+ public decimal BoxQty { get; set; }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestManager.cs
new file mode 100644
index 000000000..743500495
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestManager.cs
@@ -0,0 +1,75 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Win_in.Sfs.Shared.Domain.Shared;
+using Win_in.Sfs.Shared.Event;
+
+namespace Win_in.Sfs.Wms.Store.Domain;
+
+public class KittingIssueRequestManager
+ : SfsStoreRequestManagerBase
+ , IKittingIssueRequestManager
+{
+ private readonly IKittingIssueRequestRepository _repository;
+
+ public KittingIssueRequestManager(
+ IKittingIssueRequestRepository repository
+ , IInjectionJobRepository injectionJobRepository
+ ) : base(repository)
+ {
+ _repository = repository;
+ }
+
+ #region 东阳V2
+
+ #endregion
+
+
+ ///
+ /// 创建 同时 直接赋值Number 为了返回Number
+ ///
+ ///
+ ///
+ public virtual async Task CreateByNumberAsync(KittingIssueRequest entity)
+ {
+ var number = string.IsNullOrEmpty(entity.Number)
+ ? await GenerateNumberAsync(nameof(KittingIssueRequest), 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 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 9ccc99663..b95312077 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
@@ -22,6 +22,7 @@ public interface IStoreDbContext : IEfCoreDbContext
public DbSet ProductReceiptRequests { get; }
public DbSet MaterialRequests { get; }
public DbSet InjectionRequests { get; }
+ public DbSet KittingIssueRequests { get; }
public DbSet AssembleIssueRequests { get; }
public DbSet ThirdLocationRequests { get; }
public DbSet ContainerRequests { get; }
@@ -79,6 +80,7 @@ public interface IStoreDbContext : IEfCoreDbContext
public DbSet WarehouseTransferNotes { get; }
public DbSet IssueNotes { get; }
public DbSet InjectionNotes { get; }
+ public DbSet KittingIssueNotes { get; }
public DbSet AssembleNotes { get; }
public DbSet ThirdLocationNotes { get; }
public DbSet ContainerNotes { get; }
@@ -107,6 +109,7 @@ public interface IStoreDbContext : IEfCoreDbContext
public DbSet PutawayJobs { get; }
public DbSet IssueJobs { get; }
public DbSet InjectionJobs { get; }
+ public DbSet KittingIssueJobs { get; }
public DbSet AssembleJobs { get; }
public DbSet ThirdLocationJobs { get; }
public DbSet ContainerJobs { get; }
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobDbContextModelCreatingExtensions.cs
new file mode 100644
index 000000000..e2ca203f8
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobDbContextModelCreatingExtensions.cs
@@ -0,0 +1,62 @@
+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 KittingIssueJobDbContextModelCreatingExtensions
+{
+ public static void ConfigureKittingIssueJob(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options)
+ {
+ builder.Entity(b =>
+ {
+ //Configure table & schema name
+ b.ToTable(StoreDbProperties.JobDbTablePrefix + nameof(KittingIssueJob), 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.KittingRequestNumber).HasMaxLength(SfsPropertyConst.CodeLength);
+ b.Property(q => q.ProdLine).HasMaxLength(SfsPropertyConst.CodeLength);
+ b.Property(q => q.JobType).HasConversion();
+ b.Property(q => q.JobStatus).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(StoreDbProperties.JobDbTablePrefix + nameof(KittingIssueJobDetail), options.Schema);
+ //Configure ABP properties
+ b.ConfigureByConvention();
+ //Configure Sfs base properties
+ b.ConfigureSfsBase();
+ //Configure Job base properties
+ //b.ConfigureJobRecommendFromDetail();
+ //Properties
+
+ b.Property(q => q.RequestLocationCode).HasMaxLength(SfsPropertyConst.CodeLength);
+ b.Property(q => q.ProdLine).HasMaxLength(SfsPropertyConst.CodeLength);
+ b.Property(q => q.OnTheWayLocationCode).HasMaxLength(SfsPropertyConst.CodeLength);
+ b.Property(q => q.PositionCode).HasMaxLength(SfsPropertyConst.CodeLength);
+ b.Property(q => q.OnTheWayLocationCode).HasMaxLength(SfsPropertyConst.CodeLength);
+ b.Property(q => q.PositionCode).HasMaxLength(SfsPropertyConst.CodeLength).IsRequired(false);
+ b.Property(q => q.RecommendType).HasMaxLength(SfsPropertyConst.CodeLength).HasConversion();
+ b.Property(q => q.Status).IsRequired().HasMaxLength(SfsPropertyConst.NameLength).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/IssueJobs/KittingIssueJobs/KittingIssueJobEfCoreRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobEfCoreRepository.cs
new file mode 100644
index 000000000..b809e0e37
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Jobs/IssueJobs/KittingIssueJobs/KittingIssueJobEfCoreRepository.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 KittingIssueJobEfCoreRepository : SfsJobEfCoreRepositoryBase, IKittingIssueJobRepository
+{
+ public KittingIssueJobEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider)
+ {
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteDbContextModelCreatingExtensions.cs
new file mode 100644
index 000000000..0623b75f4
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteDbContextModelCreatingExtensions.cs
@@ -0,0 +1,57 @@
+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 KittingIssueNoteDbContextModelCreatingExtensions
+{
+ public static void ConfigureKittingIssueNote(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options)
+ {
+ builder.Entity(b =>
+ {
+ //Configure table & schema name
+ b.ToTable(options.TablePrefix + nameof(KittingIssueNote), 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.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(KittingIssueNoteDetail), 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.ProdLine).HasMaxLength(SfsPropertyConst.NameLength);
+ b.Property(q => q.OnTheWayLocationCode).HasMaxLength(SfsPropertyConst.CodeLength);
+ 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.HandledFromPackingCode, q.HandledFromLocationCode, q.HandledToLocationCode }).IsUnique();
+ b.HasIndex(q => new { q.HandledFromPackingCode });
+ });
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteEfCoreRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteEfCoreRepository.cs
new file mode 100644
index 000000000..6da26f185
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Notes/IssueNotes/KittingIssueNotes/KittingIssueNoteEfCoreRepository.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 KittingIssueNoteEfCoreRepository : SfsStoreEfCoreRepositoryBase, IKittingIssueNoteRepository
+{
+ public KittingIssueNoteEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider)
+ {
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestDbContextModelCreatingExtensions.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestDbContextModelCreatingExtensions.cs
new file mode 100644
index 000000000..b8113b843
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestDbContextModelCreatingExtensions.cs
@@ -0,0 +1,62 @@
+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 KittingIssueRequestDbContextModelCreatingExtensions
+{
+ public static void ConfigureKittingIssueRequest(this ModelBuilder builder, StoreModelBuilderConfigurationOptions options)
+ {
+ builder.Entity(b =>
+ {
+ //Configure table & schema name
+ b.ToTable(options.TablePrefix + nameof(KittingIssueRequest), 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.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(KittingIssueRequestDetail), 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.ProdLine).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/MaterialRequests/KittingIssueRequests/KittingIssueRequestEfCoreRepository.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestEfCoreRepository.cs
new file mode 100644
index 000000000..64ba51382
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.EntityFrameworkCore/Requests/MaterialRequests/KittingIssueRequests/KittingIssueRequestEfCoreRepository.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 KittingIssueRequestEfCoreRepository : SfsStoreEfCoreRepositoryBase, IKittingIssueRequestRepository
+{
+ public KittingIssueRequestEfCoreRepository(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 767efd5d1..9bf0daeb2 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
@@ -22,6 +22,7 @@ public class StoreDbContext : AbpDbContext, IStoreDbContext
public DbSet ProductReceiptRequests { get; set; }
public DbSet MaterialRequests { get; set; }
public DbSet InjectionRequests { get; set; }
+ public DbSet KittingIssueRequests { get; set; }
public DbSet AssembleIssueRequests { get; set; }
public DbSet ThirdLocationRequests { get; set; }
public DbSet ContainerRequests { get; set; }
@@ -79,6 +80,7 @@ public class StoreDbContext : AbpDbContext, IStoreDbContext
public DbSet WarehouseTransferNotes { get; set; }
public DbSet IssueNotes { get; set; }
public DbSet InjectionNotes { get; set; }
+ public DbSet KittingIssueNotes { get; set; }
public DbSet AssembleNotes { get; set; }
public DbSet ThirdLocationNotes { get; set; }
public DbSet ContainerNotes { get; set; }
@@ -107,6 +109,7 @@ public class StoreDbContext : AbpDbContext, IStoreDbContext
public DbSet PutawayJobs { get; set; }
public DbSet IssueJobs { get; set; }
public DbSet InjectionJobs { get; set; }
+ public DbSet KittingIssueJobs { get; set; }
public DbSet AssembleJobs { get; set; }
public DbSet ThirdLocationJobs { get; set; }
public DbSet ContainerJobs { 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 164956510..1ddba0b27 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
@@ -48,6 +48,7 @@ public static class StoreDbContextModelCreatingExtensions
builder.ConfigurePurchaseReceiptRequest(options);
builder.ConfigureMaterialRequest(options);
builder.ConfigureInjectionRequest(options);
+ builder.ConfigureKittingIssueRequest(options);
builder.ConfigureAssembleIssueRequests(options);
builder.ConfigureThirdLocationRequest(options);
builder.ConfigureDeliverRequest(options);
@@ -86,6 +87,7 @@ public static class StoreDbContextModelCreatingExtensions
builder.ConfigureWarehouseTransferNote(options);
builder.ConfigureIssueNote(options);
builder.ConfigureInjectionNote(options);
+ builder.ConfigureKittingIssueNote(options);
builder.ConfigureAssembleNote(options);
builder.ConfigureThirdLocationNote(options);
builder.ConfigureContainerNote(options);
@@ -118,6 +120,7 @@ public static class StoreDbContextModelCreatingExtensions
builder.ConfigurePutawayJob(options);
builder.ConfigureIssueJob(options);
builder.ConfigureInjectionJob(options);
+ builder.ConfigureKittingIssueJob(options);
builder.ConfigureAssembleJob(options);
builder.ConfigureThirdLocationJob(options);
builder.ConfigureContainerJob(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 9d8aad808..d3cc602a5 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
@@ -61,6 +61,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();
@@ -104,6 +105,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();
@@ -138,6 +140,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();
@@ -209,10 +212,12 @@ 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));
+ orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details));
options.Entity(orderOptions =>
- orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details));
+ orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details));
options.Entity(orderOptions =>
orderOptions.DefaultWithDetailsFunc = query => query.Include(o => o.Details));
options.Entity(orderOptions =>
@@ -268,6 +273,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 =>
@@ -351,6 +358,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/KittingIssueJobAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Jobs/KittingIssueJobAutoMapperProfile.cs
new file mode 100644
index 000000000..ef4f206d1
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Jobs/KittingIssueJobAutoMapperProfile.cs
@@ -0,0 +1,37 @@
+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 KittingIssueJobAutoMapperProfile()
+ {
+
+ CreateMap()
+ .ForMember(x => x.JobNumber, y => y.MapFrom(d => d.Number))
+ .ForMember(x => x.RequestNumber, y => y.MapFrom(d => d.KittingRequestNumber))
+ .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()
+ ;
+
+ CreateMap()
+ .ForMember(x => x.RequestNumber, y => y.MapFrom(d => d.KittingRequestNumber))
+ .Ignore(x => x.Confirmed)
+ .Ignore(x => x.JobNumber)
+ .Ignore(x => x.ActiveDate)
+ ;
+ CreateMap()
+ ;
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Notes/KittingIssueNoteAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Notes/KittingIssueNoteAutoMapperProfile.cs
new file mode 100644
index 000000000..a71b86737
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Notes/KittingIssueNoteAutoMapperProfile.cs
@@ -0,0 +1,51 @@
+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 KittingIssueNoteAutoMapperProfile()
+ {
+ 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)
+
+ .ForMember(x => x.Qty, y => y.MapFrom(t => t.HandledToQty))
+ .ForMember(x => x.SupplierBatch, y => y.MapFrom(t => t.HandledFromSupplierBatch))
+ .ForMember(x => x.ArriveDate, y => y.MapFrom(t => t.HandledFromArriveDate))
+ .ForMember(x => x.ProduceDate, y => y.MapFrom(t => t.HandledFromProduceDate))
+ .ForMember(x => x.ExpireDate, y => y.MapFrom(t => t.HandledFromExpireDate))
+
+ .ForMember(x => x.FromPackingCode, y => y.MapFrom(t => t.HandledFromPackingCode))
+ .ForMember(x => x.FromContainerCode, y => y.MapFrom(t => t.HandledFromContainerCode))
+
+ .ForMember(x => x.FromLot, y => y.MapFrom(t => t.HandledFromLot))
+ .ForMember(x => x.FromStatus, y => y.MapFrom(t => t.Status))
+
+ .ForMember(x => x.FromLocationCode, y => y.MapFrom(t => t.HandledFromLocationCode))
+ .ForMember(x => x.FromLocationGroup, y => y.MapFrom(t => t.HandledFromLocationGroup))
+ .ForMember(x => x.FromLocationArea, y => y.MapFrom(t => t.HandledFromLocationArea))
+ .ForMember(x => x.FromLocationErpCode, y => y.MapFrom(t => t.HandledFromLocationErpCode))
+ .ForMember(x => x.FromWarehouseCode, y => y.MapFrom(t => t.HandledFromWarehouseCode))
+
+ .ForMember(x => x.ToLot, y => y.MapFrom(t => t.HandledToLot))
+ .ForMember(x => x.ToStatus, y => y.MapFrom(t => t.Status))
+ .ForMember(x => x.ToPackingCode, y => y.MapFrom(t => t.HandledToPackingCode))
+ .ForMember(x => x.ToContainerCode, y => y.MapFrom(t => t.HandledToContainerCode))
+
+ .ForMember(x => x.ToLocationCode, y => y.MapFrom(t => t.HandledToLocationCode))
+ .ForMember(x => x.ToLocationGroup, y => y.MapFrom(t => t.HandledToLocationGroup))
+ .ForMember(x => x.ToLocationArea, y => y.MapFrom(t => t.HandledToLocationArea))
+ .ForMember(x => x.ToLocationErpCode, y => y.MapFrom(t => t.HandledToLocationErpCode))
+ .ForMember(x => x.ToWarehouseCode, y => y.MapFrom(t => t.HandledToWarehouseCode))
+
+ ;
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/KittingIssueRequestAutoMapperProfile.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/KittingIssueRequestAutoMapperProfile.cs
new file mode 100644
index 000000000..fbd3b450c
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/AutoMapperProfiles/Requests/KittingIssueRequestAutoMapperProfile.cs
@@ -0,0 +1,36 @@
+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 KittingIssueRequestAutoMapperProfile()
+ {
+ CreateMap()
+ .ForMember(x => x.KittingRequestNumber, y => y.MapFrom(d => d.Number))
+ .ForMember(x => x.RequestType, y => y.MapFrom(d => d.Type))
+ .Ignore(x => x.WarehouseCode)
+ .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)
+ ;
+ }
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/KittingIssueJobEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/KittingIssueJobEventHandler.cs
new file mode 100644
index 000000000..598fc89f2
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Jobs/KittingIssueJobEventHandler.cs
@@ -0,0 +1,224 @@
+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.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.BusinessJob;
+
+public class KittingIssueJobEventHandler :
+ StoreEventHandlerBase
+ , ILocalEventHandler>
+ , ILocalEventHandler>
+ , ILocalEventHandler>>
+{
+ private readonly IKittingIssueNoteAppService _kittingIssueNoteAppService;
+ private readonly IExpectOutAppService _expectOutAppService;
+ private readonly ILocationAppService _locationAppService;
+ private readonly ITransferLibRequestAppService _transferLibRequestAppService;
+
+ public KittingIssueJobEventHandler(IKittingIssueNoteAppService kittingIssueNoteAppService,
+ IExpectOutAppService expectOutAppService,
+ ILocationAppService locationAppService, ITransferLibRequestAppService transferLibRequestAppService)
+ {
+ _kittingIssueNoteAppService = kittingIssueNoteAppService;
+ _expectOutAppService = expectOutAppService;
+ _locationAppService = locationAppService;
+ _transferLibRequestAppService = transferLibRequestAppService;
+ }
+
+ ///
+ /// 执行后
+ ///
+ ///
+ ///
+ [UnitOfWork]
+ public virtual async Task HandleEventAsync(SfsCompletedEntityEventData eventData)
+ {
+ var entity = eventData.Entity;
+ var kittingIssueNote = await BuildKittingIssueNoteAsync(entity).ConfigureAwait(false);
+ await _kittingIssueNoteAppService.CreateAsync(kittingIssueNote).ConfigureAwait(false);
+ }
+
+ ///
+ /// 创建后
+ ///
+ ///
+ ///
+ public virtual async Task HandleEventAsync(SfsCreatedEntityEventData eventData)
+ {
+ var entity = eventData.Entity;
+
+ await CreateExpectOutAsync(entity).ConfigureAwait(false);
+
+ await CreateTransferLibAsync(entity).ConfigureAwait(false);
+ }
+
+ ///
+ /// 批量创建后
+ ///
+ ///
+ ///
+ public virtual async Task HandleEventAsync(SfsCreatedEntityEventData> eventData)
+ {
+ var entitys = eventData.Entity;
+
+ foreach (var entity in entitys)
+ {
+ await CreateExpectOutAsync(entity).ConfigureAwait(false);
+
+ await CreateTransferLibAsync(entity).ConfigureAwait(false);
+ }
+ }
+
+ #region 私有
+
+ ///
+ /// 创建预计出
+ ///
+ ///
+ ///
+ private async Task CreateExpectOutAsync(KittingIssueJob entity)
+ {
+ var expectOutEditInputs = new List();
+ foreach (var detail in entity.Details)
+ {
+ var inputoExpectOutEditInput = new ExpectOutEditInput();
+ inputoExpectOutEditInput.JobNumber = entity.Number;
+ inputoExpectOutEditInput.ItemCode = detail.ItemCode;
+ inputoExpectOutEditInput.Qty = detail.RecommendFromQty;
+ inputoExpectOutEditInput.LocationCode = detail.RecommendFromLocationCode;
+ inputoExpectOutEditInput.ArriveDate = detail.RecommendFromArriveDate;
+ inputoExpectOutEditInput.ContainerCode = detail.RecommendFromContainerCode;
+ inputoExpectOutEditInput.ExpireDate = detail.RecommendFromExpireDate;
+ inputoExpectOutEditInput.ItemDesc1 = detail.ItemDesc1;
+ inputoExpectOutEditInput.ItemDesc2 = detail.ItemDesc2;
+ inputoExpectOutEditInput.ItemName = detail.ItemName;
+ inputoExpectOutEditInput.LocationArea = detail.RecommendFromLocationArea;
+ inputoExpectOutEditInput.LocationGroup = detail.RecommendFromLocationGroup;
+ inputoExpectOutEditInput.LocationErpCode = detail.RecommendFromLocationErpCode;
+ inputoExpectOutEditInput.PackingCode = detail.RecommendFromPackingCode;
+ inputoExpectOutEditInput.Lot = detail.RecommendFromLot;
+ inputoExpectOutEditInput.ProduceDate = detail.RecommendFromProduceDate;
+ inputoExpectOutEditInput.Status = detail.Status;
+ inputoExpectOutEditInput.Uom = detail.Uom;
+ inputoExpectOutEditInput.SupplierBatch = detail.RecommendFromSupplierBatch;
+ inputoExpectOutEditInput.WarehouseCode = detail.RecommendFromWarehouseCode;
+
+ expectOutEditInputs.Add(inputoExpectOutEditInput);
+ }
+
+ await _expectOutAppService.AddManyAsync(expectOutEditInputs).ConfigureAwait(false);
+
+ await Task.CompletedTask.ConfigureAwait(false);
+ }
+
+ ///
+ /// 根据是否在 第一层 来创建 是否生成库移任务
+ ///
+ ///
+ private async Task CreateTransferLibAsync(KittingIssueJob kittingIssueJob)
+ {
+ if (!await IsMinRowAsync(kittingIssueJob).ConfigureAwait(false))
+ {
+ foreach (var detail in kittingIssueJob.Details)
+ {
+ var input = new TransferLibRequestEditInput();
+ input.CallBusinessType = nameof(IKittingIssueJobAppService);
+ input.CallJobNumber = kittingIssueJob.Number;
+ input.CallRequestNumber = kittingIssueJob.KittingRequestNumber;
+ input.CallServerName = "Win_in.Sfs.Wms.Store.Application.KittingIssueJobAppService";
+ input.Type = "Transfer_Warehouse";
+ input.UseOnTheWayLocation = true;
+
+ var detailInput = new TransferLibRequestDetailInput();
+ detailInput.CallBusinessType = nameof(IKittingIssueJobAppService);
+ detailInput.CallRequestNumber = kittingIssueJob.KittingRequestNumber;
+ detailInput.CallServerName = "Win_in.Sfs.Wms.Store.Application.KittingIssueJobAppService";
+ detailInput.CallJobNumber = kittingIssueJob.Number;
+
+ detailInput.JobStatus = EnumJobStatus.Open;
+ detailInput.ItemCode = detail.ItemCode;
+ detailInput.StdPackQty = detail.StdPackQty;
+ detailInput.Uom = detail.Uom;
+ detailInput.Status = detail.Status;
+
+ detailInput.RecommendFromQty = detail.RecommendFromQty;
+ detailInput.RecommendFromLot = detail.RecommendFromLot;
+ detailInput.RecommendFromPackingCode = detailInput.RecommendFromPackingCode;
+ detailInput.RecommendToLot = detail.RecommendToLot;
+
+ detailInput.RecommendFromArriveDate = detail.RecommendFromArriveDate;
+ detailInput.RecommendFromExpireDate = detail.RecommendFromExpireDate;
+ detailInput.RecommendFromProduceDate = detail.RecommendFromProduceDate;
+ detailInput.RecommendFromSupplierBatch = detail.RecommendFromSupplierBatch;
+
+ detailInput.RecommendFromLocationCode = detail.RecommendFromLocationCode;
+ detailInput.RecommendFromLocationGroup = detail.RecommendFromLocationGroup;
+ detailInput.RecommendFromLocationArea = detail.RecommendFromLocationArea;
+ detailInput.RecommendFromLocationErpCode = detail.RecommendFromLocationErpCode;
+ detailInput.RecommendFromWarehouseCode = detail.RecommendFromWarehouseCode;
+
+ detailInput.RecommendToQty = detail.RecommendToQty;
+ detailInput.RecommendToLot = detail.RecommendToLot;
+ detailInput.RecommendToPackingCode = detailInput.RecommendToPackingCode;
+ detailInput.RecommendToLot = detail.RecommendToLot;
+
+ detailInput.RecommendToArriveDate = detail.RecommendToArriveDate;
+ detailInput.RecommendToExpireDate = detail.RecommendToExpireDate;
+ detailInput.RecommendToProduceDate = detail.RecommendToProduceDate;
+ detailInput.RecommendToSupplierBatch = detail.RecommendToSupplierBatch;
+
+ detailInput.RecommendToLocationCode = detail.RecommendToLocationCode;
+ detailInput.RecommendToLocationGroup = detail.RecommendToLocationGroup;
+ detailInput.RecommendToLocationArea = detail.RecommendToLocationArea;
+ detailInput.RecommendToLocationErpCode = detail.RecommendToLocationErpCode;
+ detailInput.RecommendToWarehouseCode = detail.RecommendToWarehouseCode;
+
+ await _transferLibRequestAppService.CreateAsync(input).ConfigureAwait(false);
+ }
+ }
+ }
+
+ ///
+ /// 创建补料记录实体
+ ///
+ ///
+ ///
+ private async Task BuildKittingIssueNoteAsync(KittingIssueJob entity)
+ {
+ var kittingIssueNoteCreateInput = ObjectMapper.Map(entity);
+ kittingIssueNoteCreateInput.JobNumber = entity.Number;
+
+ await Task.CompletedTask.ConfigureAwait(false);
+
+ return kittingIssueNoteCreateInput;
+ }
+
+ ///
+ /// 判断是不是在最底层 如果不是则把状态变更为等待
+ ///
+ ///
+ ///
+ private async Task IsMinRowAsync(KittingIssueJob kittingIssueJob)
+ {
+ var detail = kittingIssueJob.Details.FirstOrDefault();
+
+ var loctionDto = await _locationAppService.GetByCodeAsync(detail.RecommendFromLocationCode)
+ .ConfigureAwait(false);
+ if (loctionDto.RowCode == 1)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ #endregion
+}
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/KittingIssueRequestEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/KittingIssueRequestEventHandler.cs
new file mode 100644
index 000000000..204731cca
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/KittingIssueRequestEventHandler.cs
@@ -0,0 +1,512 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Castle.Components.DictionaryAdapter;
+using Volo.Abp;
+using Volo.Abp.EventBus;
+using Win_in.Sfs.Basedata.Application.Contracts;
+using Win_in.Sfs.Shared.Domain.Shared;
+using Win_in.Sfs.Shared.Domain.Shared.Enums.Store;
+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 KittingIssueRequestEventHandler
+ : StoreEventHandlerBase
+ , ILocalEventHandler>
+ , ILocalEventHandler>
+ , ILocalEventHandler>
+ , ILocalEventHandler>
+ , ILocalEventHandler>>
+{
+ private readonly IKittingIssueJobAppService _kittingIssueJobAppService;
+ private readonly IProductionLineAppService _productionLineAppService;
+ private readonly IProductionLineItemAppService _productionLineItemAppService;
+ private readonly ILocationAppService _locationAppService;
+ private readonly IBalanceAppService _balanceAppService;
+
+ public KittingIssueRequestEventHandler(
+ IKittingIssueJobAppService kittingIssueJobAppService, IProductionLineAppService productionLineAppService,
+ ILocationAppService locationAppService,
+ IBalanceAppService balanceAppService, IProductionLineItemAppService productionLineItemAppService)
+ {
+ _kittingIssueJobAppService = kittingIssueJobAppService;
+ _productionLineAppService = productionLineAppService;
+ _locationAppService = locationAppService;
+ _balanceAppService = balanceAppService;
+ _productionLineItemAppService = productionLineItemAppService;
+ }
+
+ ///
+ /// 创建后
+ ///
+ /// Event data
+ public virtual async Task HandleEventAsync(SfsCreatedEntityEventData eventData)
+ {
+ await Task.CompletedTask.ConfigureAwait(false);
+ }
+
+ ///
+ /// 批量创建后
+ ///
+ /// Event data
+ public virtual async Task HandleEventAsync(SfsCreatedEntityEventData> eventData)
+ {
+ await Task.CompletedTask.ConfigureAwait(false);
+ }
+
+ ///
+ /// 执行后
+ ///
+ ///
+ ///
+ public virtual async Task HandleEventAsync(SfsHandledEntityEventData eventData)
+ {
+ var entity = eventData.Entity;
+
+ List kittingIssueJobs = new EditableList();
+
+ switch (entity.Type)
+ {
+ case nameof(EnumIssueType.BoxQty):
+ kittingIssueJobs = await CreateKittingIssueJobWithBoxQtyTypeAsync(entity).ConfigureAwait(false);
+ break;
+ case nameof(EnumIssueType.Qty):
+ kittingIssueJobs = await CreateKittingIssueJobWithQtyTypeAsync(entity).ConfigureAwait(false);
+ break;
+ }
+
+ if (kittingIssueJobs.Any())
+ {
+ await _kittingIssueJobAppService.CreateManyAsync(kittingIssueJobs).ConfigureAwait(false);
+ }
+ }
+
+ ///
+ /// 驳回后
+ ///
+ ///
+ ///
+ public virtual async Task HandleEventAsync(SfsAbortedEntityEventData eventData)
+ {
+ await Task.CompletedTask.ConfigureAwait(false);
+ }
+
+ ///
+ /// 完成后
+ ///
+ ///
+ ///
+ public virtual async Task HandleEventAsync(SfsCompletedEntityEventData eventData)
+ {
+ _ = eventData.Entity;
+ // await _kittingIssueJobAppService.CompleteByKittingIssueRequestAsync(entity.Number);
+
+ await Task.CompletedTask.ConfigureAwait(false);
+ }
+
+ #region 私有
+
+ #region 按数量叫料
+
+ ///
+ /// 创建注塑任务
+ ///
+ ///
+ ///
+ ///
+ private async Task> CreateKittingIssueJobWithQtyTypeAsync
+ (KittingIssueRequest kittingIssueRequest)
+ {
+ var jobs = new List();
+
+ var toLocationCodes = kittingIssueRequest.Details.Select(p => p.ToLocationCode).Distinct().ToList(); //所有发送库位的集合
+ var toLocations = await _locationAppService.GetByCodesAsync(toLocationCodes).ConfigureAwait(false); //所有库位的集合
+
+ var kittingIssueRequestDetails = kittingIssueRequest.Details.Where(p => p.ToBeIssuedQty > 0); //所有还没发送物品的集合
+ foreach (var kittingIssueRequestDetail in kittingIssueRequestDetails) //如果有还有剩余未叫料的数量 则创建新的任务
+ {
+ var toLocation =
+ toLocations.FirstOrDefault(p => p.Code == kittingIssueRequestDetail.ToLocationCode); //判断目标库位是否存在
+ Check.NotNull(toLocation, "库位代码", $"库位 {kittingIssueRequestDetail.ToLocationCode} 不存在");
+
+ //创建详情
+ var jobDetails =
+ await CreateKittingIssueJobDetailInputsWithQtyTypeAsync(kittingIssueRequest, kittingIssueRequestDetail,
+ 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.RecommendToLocationCode != kittingIssueRequestDetail.ToLocationCode))
+ {
+ job = await BuildKittingIssueJobCreateInputWithQtyTypeAsync(kittingIssueRequest, fromLocation)
+ .ConfigureAwait(false);
+ jobs.Add(job);
+ }
+
+ job.Details.AddRange(jobDetails);
+ if (kittingIssueRequestDetail.ToBeIssuedQty < 0)
+ {
+ kittingIssueRequestDetail.Status = EnumStatus.Close;
+ }
+ }
+
+ jobs = jobs.Where(p => p.Details.Any()).ToList();
+
+ var openRequestDetails =
+ kittingIssueRequest.Details.Where(p => p.Status != EnumStatus.Close).ToList();
+
+ if (!openRequestDetails.Any())
+ {
+ return jobs;
+ }
+
+
+ var enableMultipleCreateKittingIssueJob = await SettingManager
+ .IsTrueAsync(StoreSettings.MaterialRequest.EnableMultipleCreateIssueJob).ConfigureAwait(false);
+ if (enableMultipleCreateKittingIssueJob)
+ {
+ //kittingIssueRequest.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 async Task BuildKittingIssueJobCreateInputWithQtyTypeAsync(
+ KittingIssueRequest kittingIssueRequest,
+ LocationDTO fromLocation)
+ {
+ KittingIssueJobEditInput job;
+ job = ObjectMapper.Map(kittingIssueRequest);
+ job.JobType = EnumJobType.IssueJob;
+ job.JobStatus = EnumJobStatus.Open;
+ job.WorkGroupCode = fromLocation.WorkGroupCode;
+ job.WarehouseCode = fromLocation.WarehouseCode;
+ job.Worker = kittingIssueRequest.Worker;
+ if (string.IsNullOrEmpty(job.Worker))
+ {
+ job.Worker = "admin";
+ }
+
+ job.KittingRequestNumber = kittingIssueRequest.Number;
+
+ await Task.CompletedTask.ConfigureAwait(false);
+
+ return job;
+ }
+
+ ///
+ /// 创建注塑任务明细
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task> CreateKittingIssueJobDetailInputsWithQtyTypeAsync(
+ KittingIssueRequest kittingIssueRequest,
+ KittingIssueRequestDetail kittingIssueRequestDetail, string toLocationGroupCode)
+ {
+ var jobDetails = new List();
+
+ //获取推荐库存
+ var productionLineDto = await _productionLineAppService
+ .GetByLocationCodeAsync(kittingIssueRequestDetail.ToLocationCode).ConfigureAwait(false);
+ var productionLineItemDtos = await _productionLineItemAppService
+ .GetByProductLineCodeAsync(productionLineDto.Code).ConfigureAwait(false);
+ if (productionLineItemDtos == null)
+ {
+ throw new UserFriendlyException($"物品代码【{kittingIssueRequestDetail.ItemCode}】没有对应的【生产线物品关系】");
+ }
+
+ var productionLineItemDto =
+ productionLineItemDtos.FirstOrDefault(p => p.ItemCode == kittingIssueRequestDetail.ItemCode);
+ var input = new RecommendBalanceRequestInput
+ {
+ ItemCode = kittingIssueRequestDetail.ItemCode,
+ Qty = kittingIssueRequestDetail.ToBeIssuedQty,
+ //LocationTypes = transactionType.OutLocationTypes, productionLineItemDto.RawLocationCodeListJson
+ Statuses = new EditableList { EnumInventoryStatus.OK },
+ Locations = JsonSerializer.Deserialize>(productionLineItemDto.RawLocationCodeListJson)
+ };
+
+ var recommendList = await _balanceAppService.GetRecommendBalancesByLocationsAsync(input).ConfigureAwait(false);
+ //没有推荐库存时 跳过此明细 不生成任务
+ if (recommendList.Count != 0)
+ {
+ foreach (var recommend in recommendList)
+ {
+ //拿走需求量
+ var detail =
+ await BuildKittingIssueJobDetailWithQtyTypeAsync(kittingIssueRequestDetail, recommend,
+ toLocationGroupCode)
+ .ConfigureAwait(false);
+ if (kittingIssueRequest.UseOnTheWayLocation)
+ {
+ //获取在途库
+ var locationDto = await _locationAppService.GetFirstByTypeAsync(EnumLocationType.TRANSPORT)
+ .ConfigureAwait(false);
+
+ detail.OnTheWayLocationCode = locationDto.Code;
+ }
+
+ jobDetails.Add(detail);
+ kittingIssueRequestDetail.IssuedQty += recommend.Qty;
+
+ //await _kittingIssueRequestManager.UpdateDetailsAsync(kittingIssueRequest).ConfigureAwait(false);
+ }
+ }
+
+ return jobDetails;
+ }
+
+ ///
+ /// 构造注塑任务明细
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task BuildKittingIssueJobDetailWithQtyTypeAsync(
+ KittingIssueRequestDetail kittingIssueRequestDetail, BalanceDTO balance, string toLocationGroupCode)
+ {
+ //ProductionLineDTO prodLine = await _productionLineAppService.GetByLocationGroupCodeAsync(toLocationGroupCode).ConfigureAwait(false);
+
+ var detail = ObjectMapper.Map(balance);
+ detail.RequestLocationCode = kittingIssueRequestDetail.ToLocationCode;
+ detail.PositionCode = kittingIssueRequestDetail.PositionCode;
+ detail.RecommendType = kittingIssueRequestDetail.RecommendType;
+
+ detail.RecommendFromPackingCode = balance.PackingCode;
+ detail.RecommendFromContainerCode = balance.ContainerCode;
+ detail.RecommendFromSupplierBatch = balance.SupplierBatch;
+ detail.RecommendFromProduceDate = balance.ProduceDate;
+ detail.RecommendFromExpireDate = balance.ExpireDate;
+ detail.RecommendFromLot = balance.Lot;
+ detail.RecommendFromProduceDate = balance.ProduceDate;
+ detail.RecommendFromArriveDate = balance.ArriveDate;
+ detail.RecommendFromLocationArea = balance.LocationArea;
+ detail.RecommendFromLocationCode = balance.LocationCode;
+ detail.RecommendFromLocationErpCode = balance.LocationErpCode;
+ detail.RecommendFromLocationGroup = balance.LocationGroup;
+ detail.RecommendFromWarehouseCode = balance.WarehouseCode;
+ detail.RecommendFromQty = balance.Qty;
+ detail.Uom = balance.Uom;
+
+ detail.RecommendToLocationCode = kittingIssueRequestDetail.ToLocationCode;
+ detail.RecommendToLocationErpCode = kittingIssueRequestDetail.ToLocationErpCode;
+ detail.RecommendToLocationArea = kittingIssueRequestDetail.ToLocationArea;
+ detail.RecommendToWarehouseCode = kittingIssueRequestDetail.ToWarehouseCode;
+
+ //detail.ProdLine = prodLine == null ? toLocationGroupCode : prodLine.Code;
+ detail.ProdLine = toLocationGroupCode;
+ await Task.CompletedTask.ConfigureAwait(false);
+ return detail;
+ }
+
+ #endregion
+
+ #region 按箱叫料
+
+ ///
+ /// 创建注塑任务
+ ///
+ ///
+ ///
+ ///
+ private async Task> CreateKittingIssueJobWithBoxQtyTypeAsync
+ (KittingIssueRequest kittingIssueRequest)
+ {
+ var inputJobs = new List();
+ var inputExpectOutEditInput = new ExpectOutEditInput();
+ //已用的库存的箱码集合
+ var useBalanceList = new List();
+
+ var groupByItemCodeAndLocationCode =
+ kittingIssueRequest.Details.GroupBy(p => new { p.ItemCode, p.ToLocationCode });
+
+ foreach (var locationCodeItemCodeGroup in groupByItemCodeAndLocationCode)
+ {
+ var inputDetails = kittingIssueRequest.Details.Where(p =>
+ p.ItemCode == locationCodeItemCodeGroup.Key.ItemCode &&
+ p.ToLocationCode == locationCodeItemCodeGroup.Key.ToLocationCode);
+ var inputDetailTemplate = inputDetails.First();
+ //获取请求下 这个零件和这个库位一个需要多少箱
+ var sumBoxQty = inputDetails.Sum(p => p.BoxQty);
+ //获取生产线
+ var productionLineDto = await _productionLineAppService
+ .GetByLocationCodeAsync(inputDetails.First().ToLocationCode).ConfigureAwait(false);
+ if (productionLineDto == null)
+ {
+ throw new UserFriendlyException($"库位【{inputDetailTemplate.ToLocationCode}】没有对应的【生产线】");
+ }
+
+ var productLineCodeAndItemCode = await _productionLineItemAppService
+ .GetByProductLineCodeAndItemCodeAsync(productionLineDto.Code, inputDetailTemplate.ItemCode)
+ .ConfigureAwait(false);
+ if (productLineCodeAndItemCode == null)
+ {
+ throw new UserFriendlyException(
+ $"物品代码【{inputDetailTemplate.ItemCode}】在生产线【{productionLineDto.Code}】中没有对应的【生产线物品关系】");
+ }
+
+ //获取可用库存
+ var input = new RecommendBalanceRequestInput
+ {
+ ItemCode = locationCodeItemCodeGroup.Key.ItemCode,
+ Qty = decimal.MaxValue,
+ Statuses = new EditableList { EnumInventoryStatus.OK },
+ Locations = JsonSerializer.Deserialize>(productLineCodeAndItemCode
+ .RawLocationCodeListJson)
+ };
+ var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false);
+ usableList = usableList.Where(p => !useBalanceList.Contains(p.PackingCode)).ToList();
+ if (usableList.Any())
+ {
+ for (var i = 0; i < sumBoxQty; i++)
+ {
+ var firstUsable = usableList.First();
+ useBalanceList.Add(firstUsable.PackingCode);
+ usableList.Remove(firstUsable);
+
+ var kittingIssueJobEditInput =
+ await BuildKittingIssueJobCreateInputWithBoxQtyTypeAsync(kittingIssueRequest, inputDetailTemplate,
+ firstUsable)
+ .ConfigureAwait(false);
+
+ inputJobs.Add(kittingIssueJobEditInput);
+ }
+ }
+ }
+
+ return inputJobs;
+ }
+
+ ///
+ /// 构造注塑任务
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task BuildKittingIssueJobCreateInputWithBoxQtyTypeAsync(
+ KittingIssueRequest kittingIssueRequest,
+ KittingIssueRequestDetail kittingIssueRequestDetail, BalanceDTO balanceDtos)
+ {
+ var job = ObjectMapper.Map(kittingIssueRequest);
+ job.JobType = EnumJobType.IssueJob;
+ job.JobStatus = EnumJobStatus.Open;
+ job.WorkGroupCode = kittingIssueRequestDetail.ToLocationGroup;
+ job.WarehouseCode = kittingIssueRequestDetail.ToWarehouseCode;
+ job.Worker = kittingIssueRequest.Worker;
+ job.KittingRequestNumber = kittingIssueRequest.Number;
+
+ job.Details.Add(await BuildKittingIssueJobDetailWithBoxQtyTypeAsync(kittingIssueRequestDetail, balanceDtos)
+ .ConfigureAwait(false));
+
+ await Task.CompletedTask.ConfigureAwait(false);
+
+ return job;
+ }
+
+ ///
+ /// 构造注塑任务明细
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task BuildKittingIssueJobDetailWithBoxQtyTypeAsync(
+ KittingIssueRequestDetail kittingIssueRequestDetail, BalanceDTO balance)
+ {
+ var detail = new KittingIssueJobDetailInput();
+ detail.RequestLocationCode = kittingIssueRequestDetail.ToLocationCode;
+ detail.RequestLocationGroup = kittingIssueRequestDetail.ToLocationGroup;
+ detail.RequestLocationArea = kittingIssueRequestDetail.ToLocationArea;
+ detail.RequestLocationErpCode = kittingIssueRequestDetail.ToLocationErpCode;
+ detail.RequestWarehouseCode = kittingIssueRequestDetail.ToWarehouseCode;
+
+ detail.PositionCode = kittingIssueRequestDetail.PositionCode;
+ detail.RecommendType = kittingIssueRequestDetail.RecommendType;
+ detail.ProdLine = kittingIssueRequestDetail.ToLocationCode;
+
+ detail.ItemCode = kittingIssueRequestDetail.ItemCode;
+ detail.ItemName = kittingIssueRequestDetail.ItemName;
+ detail.ItemDesc1 = kittingIssueRequestDetail.ItemDesc1;
+ detail.ItemDesc2 = kittingIssueRequestDetail.ItemDesc2;
+
+ detail.Status = EnumInventoryStatus.OK;
+ detail.Uom = balance.Uom;
+
+ detail.RecommendFromPackingCode = balance.PackingCode;
+ detail.RecommendFromContainerCode = balance.ContainerCode;
+ detail.RecommendFromLot = balance.Lot;
+
+ detail.RecommendFromQty = balance.Qty;
+
+ detail.RecommendFromSupplierBatch = balance.SupplierBatch;
+ detail.RecommendFromProduceDate = balance.ProduceDate;
+ detail.RecommendFromExpireDate = balance.ExpireDate;
+ detail.RecommendFromProduceDate = balance.ProduceDate;
+ detail.RecommendFromArriveDate = balance.ArriveDate;
+
+ detail.RecommendFromLocationArea = balance.LocationArea;
+ detail.RecommendFromLocationCode = balance.LocationCode;
+ detail.RecommendFromLocationErpCode = balance.LocationErpCode;
+ detail.RecommendFromLocationGroup = balance.LocationGroup;
+ detail.RecommendFromWarehouseCode = balance.WarehouseCode;
+
+ detail.RecommendToPackingCode = balance.PackingCode;
+ detail.RecommendToContainerCode = balance.ContainerCode;
+ detail.RecommendToLot = balance.Lot;
+
+ detail.RecommendToQty = balance.Qty;
+
+ detail.RecommendToSupplierBatch = balance.SupplierBatch;
+ detail.RecommendToProduceDate = balance.ProduceDate;
+ detail.RecommendToExpireDate = balance.ExpireDate;
+ detail.RecommendToProduceDate = balance.ProduceDate;
+ detail.RecommendToArriveDate = balance.ArriveDate;
+
+ detail.RecommendToLocationCode = kittingIssueRequestDetail.ToLocationCode;
+ detail.RecommendToLocationErpCode = kittingIssueRequestDetail.ToLocationErpCode;
+ detail.RecommendToLocationArea = kittingIssueRequestDetail.ToLocationArea;
+ detail.RecommendToWarehouseCode = kittingIssueRequestDetail.ToWarehouseCode;
+ detail.RecommendToLocationGroup = kittingIssueRequestDetail.ToLocationGroup;
+
+ await Task.CompletedTask.ConfigureAwait(false);
+ return detail;
+ }
+
+ #endregion
+
+ #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 9d40c7acc..586ded4df 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
@@ -36,6 +36,7 @@ public partial class StoreEventAutoMapperProfile : Profile
InspectJobAutoMapperProfile();
IssueJobAutoMapperProfile();
InjectionJobAutoMapperProfile();
+ KittingIssueJobAutoMapperProfile();
AssembleJobAutoMapperProfile();
ThirdLocationJobAutoMapperProfile();
JisDeliverJobAutoMapperProfile();
@@ -70,6 +71,7 @@ public partial class StoreEventAutoMapperProfile : Profile
IsolationNoteAutoMapperProfile();
IssueNoteAutoMapperProfile();
InjectionNoteAutoMapperProfile();
+ KittingIssueNoteAutoMapperProfile();
AssembleNoteAutoMapperProfile();
ThirdLocationNoteAutoMapperProfile();
ItemTransformNoteAutoMapperProfile();
@@ -77,6 +79,7 @@ public partial class StoreEventAutoMapperProfile : Profile
JisProductReceiptNoteAutoMapperProfile();
MaterialRequestAutoMapperProfile();
InjectionRequestAutoMapperProfile();
+ KittingIssueRequestAutoMapperProfile();
AssembleIssueRequestsAutoMapperProfile();
ThirdLocationRequestAutoMapperProfile();
ProductionReturnRequestAutoMapperProfile();
diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/KittingIssueNoteEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/KittingIssueNoteEventHandler.cs
new file mode 100644
index 000000000..34f28745b
--- /dev/null
+++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/KittingIssueNoteEventHandler.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.EventBus;
+using Volo.Abp.Uow;
+using Win_in.Sfs.Shared.Domain.Shared;
+using Win_in.Sfs.Shared.Event;
+using Win_in.Sfs.Wms.Inventory.Application.Contracts;
+using Win_in.Sfs.Wms.Store.Domain;
+using Win_in.Sfs.Wms.Store.Event.Transaction;
+
+namespace Win_in.Sfs.Wms.Store.Event.Transactions;
+
+public class KittingIssueNoteEventHandler
+ : StoreInventoryEventHandlerBase
+ , ILocalEventHandler