diff --git a/.vs/WMS/v17/.wsuo b/.vs/WMS/v17/.wsuo new file mode 100644 index 000000000..308a39d56 Binary files /dev/null and b/.vs/WMS/v17/.wsuo differ diff --git a/.vs/WMS/v17/DocumentLayout.json b/.vs/WMS/v17/DocumentLayout.json new file mode 100644 index 000000000..a80109f71 --- /dev/null +++ b/.vs/WMS/v17/DocumentLayout.json @@ -0,0 +1,39 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\89237\\source\\repos\\WMS\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": -1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}" + }, + { + "$type": "Bookmark", + "Name": "ST:131:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:130:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:133:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:132:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/be/Modules/Shared/src/Win_in.Sfs.Shared.Domain.Shared/Enums/Store/EnumUnplannedIssueType.cs b/be/Modules/Shared/src/Win_in.Sfs.Shared.Domain.Shared/Enums/Store/EnumUnplannedIssueType.cs index b3f978c88..57d1d6c01 100644 --- a/be/Modules/Shared/src/Win_in.Sfs.Shared.Domain.Shared/Enums/Store/EnumUnplannedIssueType.cs +++ b/be/Modules/Shared/src/Win_in.Sfs.Shared.Domain.Shared/Enums/Store/EnumUnplannedIssueType.cs @@ -12,4 +12,11 @@ public enum EnumUnplannedIssueType Raw = 1,//原料 非生产领料 [Display(Name = "线边 非生产领料")] Wip =2,//线边 非生产领料 + [Display(Name = "OA 非生产领料")] + OA = 3,//原料 非生产领料 + [Display(Name = "导入 非生产领料")] + IMPORT = 4,//原料 非生产领料 + + + } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDTO.cs index 5eaedb099..2738abfcd 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDTO.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDTO.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Win_in.Sfs.Shared.Domain; using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; +using Win_in.Sfs.Wms.Store.Domain; namespace Win_in.Sfs.Wms.Store.Application.Contracts; @@ -48,4 +50,11 @@ public class UnplannedIssueJobDTO : SfsJobDTOBase [StringLength(SfsEfCorePropertyConst.NameLength, ErrorMessage = "{0}最多输入{1}个字符")] public string OANumber { get; set; } + /// + /// 实际明细 + /// + [Display(Name = "实际明细")] + public List FacDetails; + + } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDetailDTO.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDetailDTO.cs index c5e5a72ba..06803f8fa 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDetailDTO.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/DTOs/UnplannedIssueJobDetailDTO.cs @@ -35,3 +35,39 @@ public class UnplannedIssueJobDetailDTO : SfsJobRecommendFromDetailDTOBase [Display(Name = "说明")] public string Explain { get; set; } } + +public class UnplannedIssueJobFacDetailDTO : SfsJobRecommendFromDetailDTOBase +{ + /// + /// 原因代码 + /// + [Display(Name = "原因代码")] + public string ReasonCode { get; set; } + + /// + /// 专案 + /// + [Display(Name = "专案")] + public string CaseCode { get; set; } + + /// + /// 项目分类 + /// + [Display(Name = "项目分类")] + public string ProjCapacityCode { get; set; } + + /// + /// 次交易码 + /// + [Display(Name = "次交易码")] + public string OnceBusiCode { get; set; } + + /// + /// 说明 + /// + [Display(Name = "说明")] + public string Explain { get; set; } +} + + + diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/IUnplannedIssueJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/IUnplannedIssueJobAppService.cs index c8e90b994..7b698d394 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/IUnplannedIssueJobAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Jobs/UnplannedIssueJobs/IUnplannedIssueJobAppService.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Win_in.Sfs.Wms.Store.Domain; namespace Win_in.Sfs.Wms.Store.Application.Contracts; @@ -6,4 +7,7 @@ public interface IUnplannedIssueJobAppService : ISfsJobAppServiceBase { Task CancelByRequestNumberAsync(string number); + + Task CreateByRecommendAsync(UnplannedIssueRequest requestDto); + } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/UnplannedIssueRequests/Inputs/UnplannedIssueRequestEditInput.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/UnplannedIssueRequests/Inputs/UnplannedIssueRequestEditInput.cs index b4b108ba5..4f5bbe640 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/UnplannedIssueRequests/Inputs/UnplannedIssueRequestEditInput.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application.Contracts/Requests/UnplannedIssueRequests/Inputs/UnplannedIssueRequestEditInput.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Win_in.Sfs.Shared.Domain; +using Win_in.Sfs.Shared.Domain.Entities; using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; namespace Win_in.Sfs.Wms.Store.Application.Contracts; @@ -55,3 +56,64 @@ public class UnplannedIssueRequestEditInput : SfsStoreRequestCreateOrUpdateInput public string OANumber { get; set; } } + + +public class UnplannedIssueRequestImportDto +{ + /// + /// 部门代码 + /// + [Display(Name = "部门代码")] + public string DeptCode { get; set; } + + /// + /// 部门名称 + /// + [Display(Name = "部门名称")] + public string DeptName { get; set; } + + /// + /// 料号 + /// + [Display(Name = "料号")] + [Required(ErrorMessage = "{0}是必填项")] + public string ItemCode { get; set; } + [Display(Name = "数量")] + [Required(ErrorMessage = "{0}是必填项")] + public decimal Qty { get; set; } + /// + /// 调出库位 + /// + [Display(Name = "调出库位")] + [Required(ErrorMessage = "{0}是必填项")] + public string LocationErpCode { get; set; } + /// + /// 专案 + /// + [Display(Name = "专案")] + [Required(ErrorMessage = "{0}是必填项")] + public string CaseCode { get; set; } + /// + /// 项目分类 + /// + [Display(Name = "项目分类")] + [Required(ErrorMessage = "{0}是必填项")] + public string ProjCapacityCode { get; set; } + + /// + /// 次交易码 + /// + [Display(Name = "次交易码")] + [Required(ErrorMessage = "{0}是必填项")] + public string OnceBusiCode { get; set; } + /// + /// 说明 + /// + [Display(Name = "说明")] + public string Explain { get; set; } +} + + + + + diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/UnplannedIssueJobs/UnplannedIssueJobAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/UnplannedIssueJobs/UnplannedIssueJobAppService.cs index 9eeb6fd15..ce0a0f5b4 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/UnplannedIssueJobs/UnplannedIssueJobAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Jobs/UnplannedIssueJobs/UnplannedIssueJobAppService.cs @@ -1,6 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; using System.Threading.Tasks; +using Castle.Components.DictionaryAdapter; +using Irony; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Omu.ValueInjecter; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.ObjectMapping; +using Win_in.Sfs.Basedata.Application.Contracts; +using Win_in.Sfs.Shared.Domain.Entities; +using Win_in.Sfs.Shared.Domain.Shared; +using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; +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; @@ -15,13 +30,21 @@ public class UnplannedIssueJobAppService IUnplannedIssueJobAppService { - private readonly IUnplannedIssueJobManager _unplannedIssueJobManager; + private readonly IUnplannedIssueJobManager _unplannedIssueJobManager; + private readonly ILocationAppService _locationAppService; + private readonly IBalanceAppService _balanceAppService; + private readonly IExpectOutAppService _expectOutAppService; + public UnplannedIssueJobAppService( - IUnplannedIssueJobRepository repository, IUnplannedIssueJobManager unplannedIssueJobManager + IUnplannedIssueJobRepository repository, IUnplannedIssueJobManager unplannedIssueJobManager, ILocationAppService locationAppService, IBalanceAppService balanceAppService, IExpectOutAppService expectOutAppService ) : base(repository, unplannedIssueJobManager) { _unplannedIssueJobManager = unplannedIssueJobManager; -} + _locationAppService = locationAppService; + _balanceAppService = balanceAppService; + _expectOutAppService = expectOutAppService; + + } /// /// 根据申请单号作废任务 @@ -38,133 +61,270 @@ public class UnplannedIssueJobAppService } } - ///// - ///// 根据储位推荐 - ///// - ///// - //[HttpPost("create-by-recommend")] - //public async Task CreateByRecommendAsync(UnplannedReceiptRequestDTO requestDto) - //{ - // List useBalancesOut = new EditableList(); - // var jobs = await BuildUnplannedIssueJobAsync(requestDto, useBalancesOut).ConfigureAwait(false); - // await _repository.InsertManyAsync(jobs).ConfigureAwait(false); - // var outEditInputs = await BuildExpectOutAsync(useBalancesOut).ConfigureAwait(false); - // await _expectOutAppService.AddManyAsync(outEditInputs).ConfigureAwait(false); - //} - - //private async Task> BuildUnplannedIssueJobAsync(UnplannedReceiptRequestDTO requestDto, List useBalancesOut) - //{ - // List jobs = new EditableList(); - - // foreach (var requestDtoDetail in requestDto.Details) - // { - // var locationCodes = await _locationAppService.GetListByErpLocationCodes(new StringList(requestDtoDetail.ErpLocationCode)).ConfigureAwait(false); - // var input = new RecommendBalanceRequestInput - // { - // ItemCode = requestDtoDetail.ItemCode, - // Qty = requestDtoDetail.Qty, - // Statuses = new EditableList { EnumInventoryStatus.OK }, - // Locations = locationCodes.Select(p => p.Code).ToList(), - // IsPackingCode = false - // }; - // var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false); - // usableList = usableList - // .OrderBy(p => p.Lot) - // .ThenBy(p => p.PutInTime) - // .ThenBy(p => p.Qty) //2023-9-14 苑静雯 从小数开始发料 - // .ThenBy(p => p.LocationCode) - // .ThenBy(p => p.PackingCode) - // .ToList(); - - // decimal qty = 0; - // //实际要用库存 - // List useBalances = new List(); - // foreach (var balanceDto in usableList) - // { - // if (qty >= requestDtoDetail.Qty) - // { - // break; - // } - - // if (qty + balanceDto.Qty > requestDtoDetail.Qty) - // { - // qty += requestDtoDetail.Qty - balanceDto.Qty; - // } - // else - // { - // qty += balanceDto.Qty; - // } - - // useBalances.Add(balanceDto); - // useBalancesOut.Add(balanceDto); - // } - - // foreach (var balanceDtoGroup in useBalances.GroupBy(p => p.LocationCode)) - // { - // var locationDto = await _locationAppService.GetByCodeAsync(balanceDtoGroup.Key).ConfigureAwait(false); - // var job = new UnplannedReceiptJob(); - - // job.UnplannedReceiptRequestNumber = requestDto.Number; - // job.JobType = EnumJobType.UnplannedReceiptJob; - // job.JobStatus = EnumJobStatus.Open; - // job.IsAutoComplete = false; - // job.OANumber = requestDto.OANumber; - // job.Details = new List(); - // job.WarehouseCode = balanceDtoGroup.First().WarehouseCode; - - // foreach (var balanceDto in balanceDtoGroup) - // { - // var jobDetail = new UnplannedReceiptJobDetail(); - // jobDetail.CaseCode = requestDtoDetail.CaseCode; - // jobDetail.Explain = requestDtoDetail.Explain; - // jobDetail.OnceBusiCode = requestDtoDetail.OnceBusiCode; - // jobDetail.ProjCapacityCode = requestDtoDetail.ProjCapacityCode; - // jobDetail.ReasonCode = requestDtoDetail.ReasonCode; - // jobDetail.ItemCode = requestDtoDetail.ItemCode; - // jobDetail.ItemDesc1 = requestDtoDetail.ItemDesc1; - // jobDetail.ItemDesc2 = requestDtoDetail.ItemDesc2; - // jobDetail.ItemName = requestDtoDetail.ItemName; - // jobDetail.RecommendArriveDate = balanceDto.ArriveDate; - // jobDetail.RecommendContainerCode = string.Empty; - // jobDetail.RecommendExpireDate = balanceDto.ExpireDate; - // jobDetail.RecommendLot = balanceDto.Lot; - // jobDetail.RecommendPackingCode = balanceDto.PackingCode; - // jobDetail.RecommendProduceDate = balanceDto.ProduceDate; - // jobDetail.RecommendQty = balanceDto.Qty; - // jobDetail.RecommendSupplierBatch = balanceDto.SupplierBatch; - // jobDetail.RecommendToLocationArea = balanceDto.LocationArea; - // jobDetail.RecommendToLocationCode = balanceDto.LocationCode; - // jobDetail.RecommendToLocationErpCode = balanceDto.LocationErpCode; - // jobDetail.RecommendToLocationGroup = balanceDto.LocationGroup; - // jobDetail.RecommendToWarehouseCode = balanceDto.WarehouseCode; - - // job.Details.Add(jobDetail); - // } - - // if (locationDto.Type == EnumLocationType.DimensionalStorehouse)//如果是立库的 - // { - // await SendDimensionalStorehouseAsync().ConfigureAwait(false); - // job.JobStatus = EnumJobStatus.Wait; - // } - - // jobs.Add(job); - // } - // } - - // return jobs; - //} - - //private async Task> BuildExpectOutAsync(List balanceDtos) - //{ - // return ObjectMapper.Map, List>(balanceDtos); - //} - - ///// - ///// 给立体库发送 - ///// - ///// - //public async Task SendDimensionalStorehouseAsync() - //{ - // throw new System.NotImplementedException(); - //} + + /// + /// 根据储位推荐 + /// + /// + [HttpPost("create-by-recommend")] + public async Task CreateByRecommendAsync(UnplannedIssueRequest requestDto) + { + List useBalancesOut = new EditableList(); + var jobs = await BuildUnplannedIssueJobAsync(requestDto, useBalancesOut).ConfigureAwait(false); + await _unplannedIssueJobManager.AddManyAsync(jobs).ConfigureAwait(false); + //await _repository.InsertManyAsync(jobs.ToList()).ConfigureAwait(false); + var first = jobs.FirstOrDefault(); + var outEditInputs = await BuildExpectOutAsync(useBalancesOut).ConfigureAwait(false); + foreach (var itm in outEditInputs) + { + itm.JobNumber = first.Number; + } + await _expectOutAppService.AddManyAsync(outEditInputs).ConfigureAwait(false); + } + + + + private List DeductInventory(List inventory, decimal quantityToDeduct) + { + List balanceDTOs = new List(); + decimal totalDeducted = 0; + foreach (var item in inventory) + { + decimal availableToDeduct = Math.Min(item.Qty, quantityToDeduct - totalDeducted); + item.Qty -= availableToDeduct; + totalDeducted += availableToDeduct; + BalanceDTO dto = new BalanceDTO(); + dto.InjectFrom(item); + dto.Qty = availableToDeduct; + balanceDTOs.Add(dto); + // 如果已经扣减达到所需数量,退出循环 + if (totalDeducted >= quantityToDeduct) + { + break; + } + } + // 返回实际扣减的库存数量 + return balanceDTOs; + } + + + + + + + + + + + + + private async Task> BuildUnplannedIssueJobAsync(UnplannedIssueRequest requestDto, List useBalancesOut) + { + List jobs = new EditableList(); + + foreach (var requestDtoDetail in requestDto.Details)//非计划领料明细 + { + var locationCodes = await _locationAppService.GetListByErpLocationCodes(new StringList(requestDtoDetail.LocationErpCode)).ConfigureAwait(false);//获取存放库位 + var input = new RecommendBalanceRequestInput + { + ItemCode = requestDtoDetail.ItemCode, + Qty = requestDtoDetail.Qty, + Statuses = new EditableList { EnumInventoryStatus.OK }, + Locations = locationCodes.Select(p => p.Code).ToList(), + IsPackingCode = false + }; + var usableList = await _balanceAppService.GetUsableListAsync(input).ConfigureAwait(false);//获取推荐库存 + usableList = usableList + .OrderBy(p => p.Lot) + .ThenBy(p => p.PutInTime) + .ThenBy(p => p.Qty) //2023-9-14 苑静雯 从小数开始发料 + .ThenBy(p => p.LocationCode) + .ThenBy(p => p.PackingCode) + .ToList(); + + decimal qty = 0; + //实际要用库存 + List useBalances = new List(); + var returnlist=DeductInventory(usableList, requestDtoDetail.Qty); + useBalances.AddRange(returnlist); + useBalancesOut.AddRange(returnlist); + + + + //foreach (var balanceDto in usableList) + //{ + // decimal availableToDeduct = Math.Min(balanceDto.Qty, balanceDto.Qty - qty); + // balanceDto.Qty -= availableToDeduct; + // qty += availableToDeduct; + // if (qty >= balanceDto.Qty) + // break; + // if (qty >= requestDtoDetail.Qty) + // { + // break; + // } + // if (qty + balanceDto.Qty > requestDtoDetail.Qty) + // { + // qty += requestDtoDetail.Qty - balanceDto.Qty; + // } + // else + // { + // qty += balanceDto.Qty; + // } + // if (qty > 0) + // { + // useBalances.Add(balanceDto); + // useBalancesOut.Add(balanceDto); + // } + //} + if (returnlist.Count == 0) + { + throw new UserFriendlyException("库存余额不够!"); + } + + foreach (var balanceDtoGroup in useBalances.GroupBy(p => p.LocationCode)) + { + var locationDto = await _locationAppService.GetByCodeAsync(balanceDtoGroup.Key).ConfigureAwait(false); + var job = new UnplannedIssueJob(); + job.SetId(GuidGenerator.Create()); + job.UnplannedIssueRequestNumber= requestDto.Number; + job.JobType = EnumJobType.UnplannedIssueJob; + job.JobStatus = EnumJobStatus.Open; + job.IsAutoComplete = false; + job.OANumber = requestDto.OANumber; + job.Number =await _unplannedIssueJobManager.GetNumber().ConfigureAwait(true); + job.Details = new List(); + job.FacDetails = new List(); + job.WarehouseCode = balanceDtoGroup.First().WarehouseCode; + + foreach (var balanceDto in balanceDtoGroup) + { + var jobDetail = new UnplannedIssueJobDetail(); + + jobDetail.Number = job.Number; + jobDetail.SetIdAndNumber(GuidGenerator,job.Id,job.Number); + + jobDetail.CaseCode = requestDtoDetail.CaseCode; + jobDetail.Explain = requestDtoDetail.Explain; + jobDetail.OnceBusiCode = requestDtoDetail.OnceBusiCode; + jobDetail.ProjCapacityCode = requestDtoDetail.ProjCapacityCode; + //jobDetail.ReasonCode = requestDtoDetail.ReasonCode; + jobDetail.ItemCode = requestDtoDetail.ItemCode; + jobDetail.ItemDesc1 = requestDtoDetail.ItemDesc1; + jobDetail.ItemDesc2 = requestDtoDetail.ItemDesc2; + jobDetail.ItemName = requestDtoDetail.ItemName; + jobDetail.RecommendArriveDate = balanceDto.ArriveDate; + jobDetail.RecommendContainerCode = string.Empty; + jobDetail.RecommendExpireDate = balanceDto.ExpireDate; + jobDetail.RecommendLot = balanceDto.Lot; + jobDetail.RecommendPackingCode = balanceDto.PackingCode; + jobDetail.RecommendProduceDate = balanceDto.ProduceDate; + jobDetail.RecommendQty = balanceDto.Qty; + jobDetail.RecommendSupplierBatch = balanceDto.SupplierBatch; + jobDetail.StdPackQty = requestDtoDetail.StdPackQty; + jobDetail.RecommendPackingCode = balanceDto.PackingCode; + jobDetail.HandledPackingCode = balanceDto.PackingCode; + jobDetail.RecommendFromLocationArea = balanceDto.LocationArea; + jobDetail.RecommendFromLocationCode = balanceDto.LocationCode; + jobDetail.RecommendFromLocationErpCode = balanceDto.LocationErpCode; + jobDetail.RecommendFromLocationGroup = balanceDto.LocationGroup; + jobDetail.RecommendFromWarehouseCode = balanceDto.WarehouseCode; + jobDetail.HandledQty = balanceDto.Qty; + + + + var jobfacDetail = new UnplannedIssueJobFacDetail(); + + jobfacDetail.Number = job.Number; + jobfacDetail.SetIdAndNumber(GuidGenerator, job.Id, job.Number); + jobfacDetail.CaseCode = requestDtoDetail.CaseCode; + jobfacDetail.Explain = requestDtoDetail.Explain; + jobfacDetail.OnceBusiCode = requestDtoDetail.OnceBusiCode; + jobfacDetail.ProjCapacityCode = requestDtoDetail.ProjCapacityCode; + //jobfacDetail.ReasonCode = requestDtoDetail.ReasonCode; + jobfacDetail.ItemCode = requestDtoDetail.ItemCode; + jobfacDetail.ItemDesc1 = requestDtoDetail.ItemDesc1; + jobfacDetail.ItemDesc2 = requestDtoDetail.ItemDesc2; + jobfacDetail.ItemName = requestDtoDetail.ItemName; + jobfacDetail.RecommendArriveDate = balanceDto.ArriveDate; + jobfacDetail.RecommendContainerCode = string.Empty; + jobfacDetail.RecommendExpireDate = balanceDto.ExpireDate; + jobfacDetail.RecommendLot = balanceDto.Lot; + jobfacDetail.RecommendPackingCode = balanceDto.PackingCode; + jobfacDetail.RecommendProduceDate = balanceDto.ProduceDate; + jobfacDetail.RecommendQty = balanceDto.Qty; + jobfacDetail.RecommendSupplierBatch = balanceDto.SupplierBatch; + jobfacDetail.StdPackQty = requestDtoDetail.StdPackQty; + jobfacDetail.RecommendPackingCode = balanceDto.PackingCode; + jobfacDetail.HandledPackingCode = balanceDto.PackingCode; + + jobfacDetail.RecommendFromLocationArea = balanceDto.LocationArea; + jobfacDetail.RecommendFromLocationCode = balanceDto.LocationCode; + jobfacDetail.RecommendFromLocationErpCode = balanceDto.LocationErpCode; + jobfacDetail.RecommendFromLocationGroup = balanceDto.LocationGroup; + jobfacDetail.RecommendFromWarehouseCode = balanceDto.WarehouseCode; + jobfacDetail.HandledQty = balanceDto.Qty; + + + job.Details.Add(jobDetail); + job.FacDetails.Add(jobfacDetail); + } + if (locationDto.Type == EnumLocationType.DimensionalStorehouse)//如果是立库的 + { + await SendDimensionalStorehouseAsync().ConfigureAwait(false); + job.JobStatus = EnumJobStatus.Wait; + } + + jobs.Add(job); + } + } + + return jobs; + } + + private async Task> BuildExpectOutAsync(List balanceDtos) + { + return ObjectMapper.Map, List>(balanceDtos); + } + + /// + /// 给立体库发送 + /// + /// + private async Task SendDimensionalStorehouseAsync() + { + throw new System.NotImplementedException(); + } + /// + /// 创建补料记录实体 + /// + /// + /// + private async Task BuildUnplannedIssueNoteAsync(UnplannedIssueJob unplannedIssueJobDto) + { + //var createInput = + // ObjectMapper.Map(unplannedIssueJobDto); + var issuenote = new UnplannedIssueNoteEditInput(); + + issuenote.DeptCode = unplannedIssueJobDto.DeptCode; + issuenote.DeptName = unplannedIssueJobDto.DeptName; + issuenote.BuildDate = unplannedIssueJobDto.BuildDate; + issuenote.UnplannedIssueRequestNumber = unplannedIssueJobDto.UnplannedIssueRequestNumber; + issuenote.JobNumber = unplannedIssueJobDto.Number; + issuenote.UnplannedIssueType = issuenote.UnplannedIssueType; + issuenote.OANumber = issuenote.OANumber; + issuenote.Details = new List(); + foreach (var detail in unplannedIssueJobDto.FacDetails) + { + var entity=new UnplannedIssueNoteDetailInput(); + entity.InjectFrom(detail); + entity.Qty = detail.HandledQty; + issuenote.Details.Add(entity); + } + await Task.CompletedTask.ConfigureAwait(false); + return issuenote; + } + + + + } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestAppService.cs index 563028731..a46cd917a 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestAppService.cs @@ -1,14 +1,26 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Win_in.Sfs.Basedata.Application.Contracts; +using Win_in.Sfs.Basedata.Domain; +using Win_in.Sfs.Basedata.Kittings.Inputs; +using Win_in.Sfs.Shared.Application.Contracts; using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; 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.Shared.Application.Contracts.ExportAndImport; +using System.Linq; namespace Win_in.Sfs.Wms.Store.Application; - -[Authorize] +[AllowAnonymous] +//[Authorize] [Route($"{StoreConsts.RootPath}unplanned-issue-request")] public abstract class UnplannedIssueRequestAppService : @@ -18,13 +30,18 @@ public abstract class UnplannedIssueRequestAppService : { private readonly IUnplannedIssueRequestManager _unplannedIssueRequestManager; + protected readonly IExportImportService _excelService; + + public UnplannedIssueRequestAppService( IUnplannedIssueRequestRepository repository, - IUnplannedIssueRequestManager unplannedIssueRequestManager + IUnplannedIssueRequestManager unplannedIssueRequestManager, + IExportImportService excelService ) : base(repository, unplannedIssueRequestManager) { _unplannedIssueRequestManager = unplannedIssueRequestManager; + _excelService = excelService; } /// @@ -59,4 +76,9 @@ public abstract class UnplannedIssueRequestAppService : var dto = ObjectMapper.Map(entity); return dto; } + + + + + } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestForDongyangAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestForDongyangAppService.cs index a0678442f..463d655ff 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestForDongyangAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/UnplannedIssueRequests/UnplannedIssueRequestForDongyangAppService.cs @@ -1,16 +1,24 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.IO; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Omu.ValueInjecter; using Volo.Abp; using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; using Volo.Abp.Users; using Win_in.Sfs.Auth.Application.Contracts; using Win_in.Sfs.Basedata.Application.Contracts; +using Win_in.Sfs.Basedata.Domain; +using Win_in.Sfs.Basedata.Kittings.Inputs; +using Win_in.Sfs.Shared.Application.Contracts; +using Win_in.Sfs.Shared.Application.Contracts.ExportAndImport; using Win_in.Sfs.Shared.Domain; using Win_in.Sfs.Shared.Domain.Shared; using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; @@ -28,13 +36,14 @@ public class UnplannedIssueRequestForDongyangAppService : UnplannedIssueRequestA private readonly IBalanceAppService _balanceAppService; private readonly ILocationAppService _locationAppService; private readonly ITransactionTypeAclService _transactionTypeAclService; + //private readonly IExportImportService _excelService; public UnplannedIssueRequestForDongyangAppService(IUnplannedIssueRequestRepository repository, IUnplannedIssueRequestManager unplannedIssueRequestManager, - IDepartmentAppService departmentApp, IBalanceAppService balanceAppService, ILocationAppService locationAppService, - ITransactionTypeAclService transactionTypeAclService - ) : base(repository, unplannedIssueRequestManager) + IDepartmentAppService departmentApp, IBalanceAppService balanceAppService, ILocationAppService locationAppService, IExportImportService excelService, + ITransactionTypeAclService transactionTypeAclService + ) : base( repository, unplannedIssueRequestManager, excelService) { _unplannedIssueRequestManager = unplannedIssueRequestManager; _departmentApp = departmentApp; @@ -62,19 +71,149 @@ public class UnplannedIssueRequestForDongyangAppService : UnplannedIssueRequestA entity.AutoAgree = true; entity.AutoHandle = true; entity.DirectCreateNote = false; - //if (entity.UnplannedIssueType == EnumUnplannedIssueType.Wip) - //{ - // entity.DirectCreateNote = true; - //} - //else - //{ - - //} await _unplannedIssueRequestManager.CreateAsync(entity).ConfigureAwait(false); var dto = ObjectMapper.Map(entity); return dto; } + /// + /// 自定义导入接口 + /// + /// + /// + /// + /// + [HttpPost("import-dongyang")] + public async Task ImportDYAsync([FromForm] SfsImportRequestInput requestInput, [Required] IFormFile file) + { + + try + { + using var ms = new MemoryStream(); + await file.OpenReadStream().CopyToAsync(ms).ConfigureAwait(false); + var inputFileBytes = ms.GetAllBytes(); + var importList = _excelService.Import(inputFileBytes).ToList(); + await CreateByDYOAsync(importList, EnumUnplannedIssueType.IMPORT).ConfigureAwait(false); + + + //if (errors.Count > 0) + //{ + // var fileContent = _excelService.Export(errors); + // return new TestResult(fileContent.FileContents, ExportImportService.ContentType) { FileDownloadName = "错误信息" }; + //} + + var fileContent1 = _excelService.Export(importList); + // return new TestResult(fileContent1.FileContents, ExportImportService.ContentType) { FileDownloadName = "Kitting导入文件" }; + return new JsonResult(new { Code = 200, FileDownloadName = fileContent1.FileDownloadName }); + } + catch (Exception e) + { + throw new UserFriendlyException(e.Message); + } + } + + + /// + /// OA接口 + /// + /// + /// + [HttpPost("create-dongyang")] + + public async Task CreateByAsync(List p_list) + { + + return await CreateByDYOAsync(p_list, EnumUnplannedIssueType.OA, true).ConfigureAwait(false); + } + + + + + protected async Task CreateByDYOAsync(List p_list, EnumUnplannedIssueType type, bool isAutoSubmit=false) + { + + UnplannedIssueRequest request = new UnplannedIssueRequest(); + if (p_list.Count == 0) + { + throw new UserFriendlyException("导入内容为空请填写!"); + } + + var first = p_list.FirstOrDefault(); + request.UnplannedIssueType = type; + request.SetId(GuidGenerator.Create()); + request.AutoCompleteJob = false; + request.AutoSubmit = isAutoSubmit; + request.AutoAgree = false; + request.AutoHandle = false; + request.DirectCreateNote = false; + request.DeptCode = first.DeptCode; + request.DeptName = first.DeptName; + + + + List detailList = new List(); + foreach (var itm in p_list) + { + var detail = new UnplannedIssueRequestDetail(); + detail.ItemCode = itm.ItemCode; + detail.Qty = itm.Qty; + + detail.LocationErpCode = itm.LocationErpCode; + + detail.LocationCode = "Random"; + detail.WarehouseCode ="Random"; + detail.LocationGroup ="Random"; + detail.LocationArea = "Random"; + + + detail.CaseCode = first.CaseCode; + detail.ProjCapacityCode = first.ProjCapacityCode; + detail.OnceBusiCode = first.OnceBusiCode; + detail.Explain = first.Explain; + + + + await SetDetailPropertiesAsync(detail).ConfigureAwait(false); + detailList.Add(detail); + } + + request.Details = detailList; + await _unplannedIssueRequestManager.CreateAsync(request).ConfigureAwait(false); + var dto = ObjectMapper.Map(request); + return dto; + + } + private async Task SetDetailPropertiesAsync(UnplannedIssueRequestDetail detail) + { + var itemBasic = await ItemBasicAclService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false); + CheckItemBasic(itemBasic, detail.ItemCode); + //await CheckOnceBusiCodeAsync(detail).ConfigureAwait(false); + if (itemBasic != null) + { + detail.ItemCode = itemBasic.Code; + detail.ItemName = itemBasic.Name; + detail.ItemDesc1 = itemBasic.Desc1; + detail.ItemDesc2 = itemBasic.Desc2; + detail.StdPackQty = itemBasic.StdPackQty; + detail.Uom = itemBasic.BasicUom; + } + + string packingcode = string.Empty; + + packingcode =string.IsNullOrEmpty(detail.PackingCode)?"99999999":detail.PackingCode; + + detail.PackingCode = packingcode; + + } + + + + + + + + + /// /// 用来重写 导入数据时可以加工数据 /// diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJob.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJob.cs index 7090ef78a..922a5f395 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJob.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJob.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Volo.Abp.Data; +using Win_in.Sfs.Shared.Domain; using Win_in.Sfs.Shared.Domain.Entities; using Win_in.Sfs.Shared.Domain.Shared.Enums.Store; @@ -53,6 +54,17 @@ public class UnplannedIssueJob : SfsJobAggregateRootBase Details { get; set; } = new List(); + + /// + /// 任务明细 + /// + [IgnoreUpdate] + public List FacDetails { get; set; } = new List(); + + + + + /// /// 设置任务明细的实际库位和实际数量 /// diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobDetail.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobDetail.cs index b582ac4af..2c8b04501 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobDetail.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobDetail.cs @@ -35,6 +35,43 @@ public class UnplannedIssueJobDetail : SfsJobRecommendFromDetailEntityBase, IHas public ExtraPropertyDictionary ExtraProperties { get; set; } = new ExtraPropertyDictionary(); + /// + /// 说明 + /// + [Display(Name = "说明")] + public string Explain { get; set; } +} +public class UnplannedIssueJobFacDetail : SfsJobRecommendFromDetailEntityBase, IHasExtraProperties +{ + /// + /// 原因代码 + /// + public string ReasonCode { get; set; } + + /// + /// 专案 + /// + [Display(Name = "专案")] + public string CaseCode { get; set; } + + /// + /// 项目分类 + /// + [Display(Name = "项目分类")] + public string ProjCapacityCode { get; set; } + + /// + /// 次交易码 + /// + [Display(Name = "次交易码")] + public string OnceBusiCode { get; set; } + + /// + /// 扩展属性 + /// + public ExtraPropertyDictionary ExtraProperties { get; set; } = new ExtraPropertyDictionary(); + + /// /// 说明 /// diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobManager.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobManager.cs index 1f01d454f..b065dcbf9 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobManager.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Domain/Jobs/UnplannedIssueJobs/UnplannedIssueJobManager.cs @@ -35,7 +35,7 @@ public class UnplannedIssueJobManager : SfsJobManagerBase q.UnplannedIssueRequestNumber).HasMaxLength(SfsPropertyConst.CodeLength); //Relations b.HasMany(q => q.Details).WithOne().HasForeignKey(d => d.MasterID).IsRequired(); + b.HasMany(q => q.FacDetails).WithOne().HasForeignKey(d => d.MasterID).IsRequired(); + + //Indexes b.HasIndex(q => new { q.Number }).IsUnique(); }); @@ -48,5 +51,26 @@ public static class UnplannedIssueJobDbContextModelCreatingExtensions //Indexes //b.HasIndex(q => new { q.PackingCode }).IsUnique(); }); + builder.Entity(b => + { + //Configure table & schema name + b.ToTable(StoreDbProperties.JobDbTablePrefix + nameof(UnplannedIssueJobFacDetail), options.Schema); + //Configure ABP properties + b.ConfigureByConvention(); + //Configure Sfs base properties + b.ConfigureSfsBase(); + //Configure Job base properties + b.ConfigureJobRecommendFromDetail(); + //Properties + + //Relations + //None + + //Indexes + //b.HasIndex(q => new { q.PackingCode }).IsUnique(); + }); + + + } } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/UnplannedIssueRequestEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/UnplannedIssueRequestEventHandler.cs index 233965ef9..db0b9bf9f 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/UnplannedIssueRequestEventHandler.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Requests/UnplannedIssueRequestEventHandler.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; +using System.Text.Json.Nodes; using System.Threading.Tasks; +using Omu.ValueInjecter; using Volo.Abp.Domain.Entities; using Volo.Abp.EventBus; using Volo.Abp.ObjectMapping; @@ -93,8 +95,21 @@ public class UnplannedIssueRequestEventHandler } else { - var job = await BuildUnplannedIssueJobCreateInputAsync(entity).ConfigureAwait(false); - await _unplannedIssueJobApp.CreateAsync(job).ConfigureAwait(false); + if (entity.UnplannedIssueType == EnumUnplannedIssueType.OA || entity.UnplannedIssueType == EnumUnplannedIssueType.IMPORT) + { + //var job = await BuildUnplannedIssueJobCreateInputAsync(entity).ConfigureAwait(false); + + var request= new UnplannedIssueRequest(); + request.InjectFrom(entity); + + await _unplannedIssueJobApp.CreateByRecommendAsync(request).ConfigureAwait(false); + } + else + { + var job = await BuildUnplannedIssueJobCreateInputAsync(entity).ConfigureAwait(false); + await _unplannedIssueJobApp.CreateAsync(job).ConfigureAwait(false); + } + } } public virtual async Task HandleEventAsync(SfsRefusedEntityEventData eventData) @@ -171,19 +186,26 @@ public class UnplannedIssueRequestEventHandler { await Task.CompletedTask.ConfigureAwait(false); var createInput = ObjectMapper.Map(entity); + + + + createInput.UnplannedIssueRequestNumber = entity.Number; createInput.JobType = EnumJobType.UnplannedIssueJob; createInput.JobStatus = EnumJobStatus.Open; createInput.IsAutoComplete = entity.AutoCompleteJob; + createInput.Worker = string.IsNullOrEmpty(createInput.Worker)?"导入":createInput.Worker; + createInput.Details = new List(); foreach (var inputDetail in entity.Details) { var detail = ObjectMapper.Map(inputDetail); - + detail.ExtraProperties = inputDetail.ExtraProperties; - + detail.HandledLot = string.IsNullOrEmpty(detail.HandledLot) ? "导入" : detail.HandledLot; + detail.RecommendLot = string.IsNullOrEmpty(detail.RecommendLot) ? "导入" : detail.RecommendLot; createInput.Details.Add(detail); } createInput.WarehouseCode = createInput.Details[0].RecommendFromWarehouseCode;