From a3e64c16c5390b552816b8e619b3d58acfd960c8 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期一, 17 十一月 2025 08:41:14 +0800
Subject: [PATCH] 提交
---
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs | 350 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 313 insertions(+), 37 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
index 82df3f5..06a4835 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
@@ -1,4 +1,8 @@
-锘縰sing System;
+锘縰sing Dm.filter;
+using MailKit.Search;
+using Microsoft.AspNetCore.Http;
+using SqlSugar;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -9,6 +13,7 @@
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
+using WIDESEA_Core.Helper;
using WIDESEA_DTO.Outbound;
using WIDESEA_IBasicService;
using WIDESEA_IOutboundService;
@@ -31,10 +36,12 @@
private readonly IStockInfoDetailService _stockInfoDetailService;
private readonly ILocationInfoService _locationInfoService;
private readonly IOutboundOrderDetailService _outboundOrderDetailService;
+ private readonly IOutboundOrderService _outboundOrderService;
private readonly ISplitPackageService _splitPackageService;
-
+ private readonly IRepository<Dt_Task> _taskRepository;
- public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService, IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService) : base(BaseDal)
+
+ public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService, IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService, IRepository<Dt_Task> taskRepository) : base(BaseDal)
{
_unitOfWorkManage = unitOfWorkManage;
_stockInfoService = stockInfoService;
@@ -44,9 +51,11 @@
_locationInfoService = locationInfoService;
_outboundOrderDetailService = outboundOrderDetailService;
_splitPackageService = splitPackageService;
+ _outboundOrderService = outboundOrderService;
+ _taskRepository = taskRepository;
}
-
+
#region 鏌ヨ鍑哄簱璇︽儏鍒楄〃
public async Task<List<OutStockLockListResp>> GetOutStockLockListAsync(string orderNo)
{
@@ -57,13 +66,13 @@
return locks.Select(t => new OutStockLockListResp
{
Id = t.Id,
- // TaskNum = t.TaskNum,
+ // TaskNum = t.TaskNum,
PalletCode = t.PalletCode,
CurrentBarcode = t.CurrentBarcode,
AssignQuantity = t.AssignQuantity,
PickedQty = t.PickedQty,
Status = t.Status,
- // IsSplitted = t.IsSplitted
+ // IsSplitted = t.IsSplitted
}).ToList();
}
#endregion
@@ -87,13 +96,13 @@
return WebResponseContent.Instance.Error("鏉$爜涓嶅瓨鍦�");
}
-
+
var result = new
{
Barcode = barcode,
MaterielCode = stockDetail.MaterielCode,
-
+
BatchNo = stockDetail.BatchNo,
AvailableQuantity = stockDetail.StockQuantity - stockDetail.OutboundQuantity,
LocationCode = stockDetail.StockInfo?.LocationCode,
@@ -109,8 +118,7 @@
}
/// <summary>
- /// 鎵爜鎷i�夌‘璁� - 绠�鍖栫増鏈�
- /// 鍙鐞嗗疄闄呮嫞閫夌殑搴撳瓨鎵e噺
+ /// 鎵爜鎷i�夌‘璁�
/// </summary>
public async Task<WebResponseContent> ConfirmPicking(PickingConfirmRequest request)
{
@@ -203,6 +211,158 @@
}
}
+ public async Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.OrderNo == orderNo &&
+ it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
+ it.PalletCode == palletCode &&
+ it.CurrentBarcode == barcode)
+ .FirstAsync();
+
+ if (lockInfo == null)
+ throw new Exception($"鏉$爜{barcode}涓嶅睘浜庢墭鐩榹palletCode}鎴栦笉瀛樺湪寰呭垎鎷h褰�");
+
+
+
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .Where(x => x.Barcode == barcode && x.StockId == lockInfo.StockId)
+ .FirstAsync();
+
+ if (stockDetail == null)
+ return WebResponseContent.Instance.Error("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
+
+
+ decimal actualQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+
+ // 4. 鏇存柊搴撳瓨
+ stockDetail.StockQuantity -= actualQty;
+ stockDetail.OutboundQuantity -= actualQty;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+ lockInfo.PickedQty += actualQty;
+ lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(it => it.PickedQty == it.PickedQty + actualQty)
+ .Where(it => it.Id == lockInfo.OrderDetailId)
+ .ExecuteCommandAsync();
+
+
+ await CheckAndUpdateOrderStatus(orderNo);
+
+ //鏌ヨ浠诲姟琛�
+ var task = _taskRepository.QueryData(x => x.OrderNo == orderNo && x.PalletCode == palletCode).FirstOrDefault();
+ // 9. 璁板綍鎷i�夊巻鍙�
+ var pickingHistory = new Dt_PickingRecord
+ {
+ FactoryArea = lockInfo.FactoryArea,
+ TaskNo = task?.TaskNum ?? 0,
+ LocationCode = task?.SourceAddress ?? "",
+ StockId = stockDetail.Id,
+ OrderNo = orderNo,
+ OrderDetailId = lockInfo.OrderDetailId,
+ PalletCode = palletCode,
+ Barcode = barcode,
+ MaterielCode = lockInfo.MaterielCode,
+ PickQuantity = lockInfo.AssignQuantity,
+ PickTime = DateTime.Now,
+ Operator = App.User.UserName,
+ OutStockLockId = lockInfo.Id
+ };
+ await Db.Insertable(pickingHistory).ExecuteCommandAsync();
+
+ _unitOfWorkManage.CommitTran();
+ return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�");
+
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error($"鎷i�夌‘璁ゅけ璐ワ細{ex.Message}");
+ }
+ }
+ // 妫�鏌ュ苟鏇存柊璁㈠崟鐘舵��
+ private async Task CheckAndUpdateOrderStatus(string orderNo)
+ {
+
+
+ var orderDetails = await _stockInfoDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .Where(x => x.OrderId == orderNo.ObjToInt())
+ .ToListAsync();
+
+ bool allCompleted = true;
+ foreach (var detail in orderDetails)
+ {
+ if (detail.OverOutQuantity < detail.NeedOutQuantity)
+ {
+ allCompleted = false;
+ break;
+ }
+ }
+
+ if (allCompleted)
+ {
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.OrderStatus == 2) // 宸插畬鎴�
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+ }
+ // 鍙栨秷鎷i�夊姛鑳�
+ public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+ // 鏌ユ壘鎷i�夎褰�
+ var outStockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.CurrentBarcode == barcode &&
+ x.Status == 2)
+ .FirstAsync();
+
+ if (outStockInfo == null)
+ return WebResponseContent.Instance.Error("鏈壘鍒板凡鎷i�夎褰�");
+
+ // 杩樺師鍑哄簱璇︽儏鐘舵��
+ outStockInfo.PickedQty = 0;
+ outStockInfo.Status = 1;
+ await _outStockLockInfoService.Db.Updateable(outStockInfo).ExecuteCommandAsync();
+
+ //// 杩樺師搴撳瓨鍑哄簱鏁伴噺
+ //await _stockInfoDetailService.Db.Updateable<Dt_StockInfoDetail>()
+ // .SetColumns(x => x.OutboundQuantity == x.OutboundQuantity - outStockInfo.AssignQuantity)
+ // .Where(x => x.Barcode == barcode)
+ // .ExecuteCommandAsync();
+
+ // 杩樺師鍑哄簱鍗曟槑缁�
+ var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .Where(x => x.Id == outStockInfo.OrderDetailId)
+ .FirstAsync();
+
+ orderDetail.OverOutQuantity -= outStockInfo.AssignQuantity;
+ await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+
+ // 鍒犻櫎鎷i�夊巻鍙�
+ await Db.Deleteable<Dt_PickingRecord>()
+ .Where(x => x.OutStockLockId == outStockInfo.Id)
+ .ExecuteCommandAsync();
+
+ _unitOfWorkManage.CommitTran();
+ return WebResponseContent.Instance.OK("鍙栨秷鎷i�夋垚鍔�");
+
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error($"鍙栨秷鎷i�夊け璐ワ細{ex.Message}");
+ }
+ }
/// <summary>
/// 鏍规嵁鏉$爜鏌ユ壘閿佸畾淇℃伅
/// </summary>
@@ -217,6 +377,86 @@
.FirstAsync();
}
+ // 鑾峰彇鏈嫞閫夊垪琛�
+ public async Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode)
+ {
+ var list = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.Status == 1)
+ .ToListAsync();
+ return list.Where(x => x.RemainQuantity > 0).ToList();
+ }
+
+ // 鑾峰彇宸叉嫞閫夊垪琛�
+ public async Task<List<Dt_OutStockLockInfo>> GetPickedList(string orderNo, string palletCode)
+ {
+ var list = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.Status == 2)
+ .ToListAsync();
+ return list;
+ }
+
+ public async Task<object> GetPickingSummary(string orderNo, string palletCode)
+ {
+ var summary = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode && x.Status == 1)
+ .GroupBy(x => new { x.PalletCode, x.MaterielCode })
+ .Select(x => new
+ {
+ PalletCode = x.PalletCode,
+ MaterielCode = x.MaterielCode,
+ UnpickedCount = SqlFunc.AggregateCount(x.Id),
+ UnpickedQuantity = SqlFunc.AggregateSum(x.AssignQuantity) - SqlFunc.AggregateSum(x.PickedQty)
+ })
+ .FirstAsync();
+
+ return summary;
+ }
+
+ // 鑾峰彇鎷i�夋眹鎬�
+ public async Task<object> GetPickingSummary(ConfirmPickingDto dto)
+ {
+ var picked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.OrderNo == dto.OrderNo)
+ .WhereIF(!string.IsNullOrEmpty(dto.PalletCode), x => x.PalletCode == dto.PalletCode)
+ .Where(x => x.Status == 2)
+ .GroupBy(x => new { x.PalletCode, x.MaterielCode })
+ .Select(x => new SummaryPickingDto
+ {
+ PalletCode = x.PalletCode,
+ MaterielCode = x.MaterielCode,
+ pickedCount = SqlFunc.AggregateCount(x.Id)
+ }).FirstAsync();
+ if (picked == null)
+ {
+ picked = new SummaryPickingDto { pickedCount = 0 };
+ }
+
+ var summary = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .WhereIF(!string.IsNullOrEmpty(dto.OrderNo), x => x.OrderNo == dto.OrderNo)
+ .WhereIF(!string.IsNullOrEmpty(dto.PalletCode), x => x.PalletCode == dto.PalletCode)
+ .Where(x => x.Status == 1)
+ .GroupBy(x => new { x.PalletCode, x.MaterielCode })
+ .Select(x => new SummaryPickingDto
+ {
+ PalletCode = x.PalletCode,
+ MaterielCode = x.MaterielCode,
+ UnpickedCount = SqlFunc.AggregateCount(x.Id),
+ UnpickedQuantity = SqlFunc.AggregateSum(x.AssignQuantity) - SqlFunc.AggregateSum(x.PickedQty),
+
+ }).FirstAsync();
+ if (summary == null)
+ {
+ summary = new SummaryPickingDto { pickedCount = 0 };
+ }
+ summary.pickedCount = picked.pickedCount;
+
+ return summary;
+ }
/// <summary>
/// 鑾峰彇鎷i�夊巻鍙�
/// </summary>
@@ -234,6 +474,25 @@
.OrderByDescending(p => p.PickTime)
.ToListAsync();
}
+
+ public async Task GetPalletPickingSummary(string orderNo, string palletCode)
+ {
+ var summary = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .GroupBy(x => new { x.PalletCode, x.Status })
+ .Select(x => new
+ {
+ PalletCode = x.PalletCode,
+ Status = x.Status,
+ TotalAssignQty = SqlFunc.AggregateSum(x.AssignQuantity),
+ TotalPickedQty = SqlFunc.AggregateSum(x.PickedQty)
+ })
+ .ToListAsync();
+
+ // return summary;
+ }
+
+
/// <summary>
/// 鎾ら攢鎷i��
@@ -368,50 +627,59 @@
{
_unitOfWorkManage.BeginTran();
- // 1. 鑾峰彇鎵樼洏搴撳瓨淇℃伅
var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
.Includes(x => x.Details)
- .Where(x => x.PalletCode == request.PalletCode)
- .FirstAsync();
+ .Where(x => x.PalletCode == request.PalletCode).FirstAsync();
if (stockInfo == null)
return WebResponseContent.Instance.Error("鏈壘鍒版墭鐩樺簱瀛樹俊鎭�");
- // 2. 鑾峰彇鐩稿叧鐨勫嚭搴撻攣瀹氫俊鎭�
+
var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(x => x.PalletCode == request.PalletCode &&
- x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+ .Where(x => x.OrderNo == request.OrderNo && x.PalletCode == request.PalletCode)
.ToListAsync();
- // 3. 鏁翠釜鎵樼洏鍑哄簱 - 璁剧疆鍑哄簱鏁伴噺绛変簬搴撳瓨鏁伴噺
- foreach (var detail in stockInfo.Details)
- {
- decimal outboundQuantity = detail.StockQuantity - detail.OutboundQuantity;
- detail.OutboundQuantity = detail.StockQuantity; // 鍏ㄩ儴鍑哄簱
- await _stockInfoDetailService.Db.Updateable(detail).ExecuteCommandAsync();
- }
- // 4. 鏇存柊鍑哄簱閿佸畾淇℃伅
foreach (var lockInfo in lockInfos)
{
- decimal unpicked = lockInfo.AssignQuantity - lockInfo.PickedQty;
- lockInfo.PickedQty += unpicked; // 鏍囪涓哄叏閮ㄦ嫞閫�
+ if (lockInfo.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+ {
+ lockInfo.PickedQty = lockInfo.AssignQuantity;
+ }
lockInfo.Status = (int)OutLockStockStatusEnum.宸插嚭搴�;
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- // 鏇存柊鍑哄簱鍗曟槑缁�
var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
- .Where(x => x.Id == lockInfo.OrderDetailId)
- .FirstAsync();
- orderDetail.OverOutQuantity += unpicked;
- orderDetail.LockQuantity -= unpicked;
- orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
- orderDetail.LockQuantity = 0;
-
- await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+ .Where(x => x.Id == lockInfo.OrderDetailId)
+ .FirstAsync();
+ if (orderDetail != null)
+ {
+ orderDetail.OverOutQuantity += lockInfo.PickedQty;
+ orderDetail.LockQuantity -= lockInfo.PickedQty;
+ orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
+ orderDetail.LockQuantity = 0;
+ await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+ }
+ }
+ var groupDetails = lockInfos.GroupBy(x => x.OrderDetailId).Select(x => new
+ {
+ OrderDetailId = x.Key,
+ TotalQuantity = x.Sum(o => o.PickedQty)
+ }).ToList();
+ foreach (var item in groupDetails)
+ {
+ var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>().Where(x => x.Id == item.OrderDetailId).FirstAsync();
+ if (orderDetail != null)
+ {
+ orderDetail.OverOutQuantity = item.TotalQuantity;
+ orderDetail.LockQuantity = 0;
+ orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
+ await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+ }
}
- // 5. 鏇存柊鎷嗗寘璁板綍鐘舵��
+ await CheckAndUpdateOrderStatus(request.OrderNo);
+
var lockInfoIds = lockInfos.Select(x => x.Id).ToList();
var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
.Where(x => lockInfoIds.Contains(x.OutStockLockInfoId) &&
@@ -424,7 +692,7 @@
await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
}
- // 6. 娓呯┖璐т綅
+
var location = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
.Where(x => x.LocationCode == stockInfo.LocationCode)
.FirstAsync();
@@ -434,6 +702,14 @@
await _locationInfoService.Db.Updateable(location).ExecuteCommandAsync();
}
+ foreach (var detail in stockInfo.Details)
+ {
+ await _stockInfoDetailService.Db.Deleteable(detail).ExecuteCommandAsync();
+ }
+ await _stockInfoService.Db.Deleteable(stockInfo).ExecuteCommandAsync();
+
+
+
_unitOfWorkManage.CommitTran();
return WebResponseContent.Instance.OK("鐩存帴鍑哄簱鎴愬姛");
}
--
Gitblit v1.9.3