V13-FE-011: finalize search list layout slice

This commit is contained in:
2026-08-09 02:57:26 +09:00
parent 9efd202e76
commit 6422cb2b13
984 changed files with 120811 additions and 1498 deletions
@@ -0,0 +1,76 @@
namespace Modules.WMS.Picking.Shared;
public enum PickingScanDecisionKind
{
RejectLocation,
AcceptLocation,
RejectItem,
AcceptItem
}
public sealed record PickingScanState(
bool LocationConfirmed,
string LocationCode,
string LocationBarcode,
string ItemBarcode,
decimal RequiredQty,
decimal PickedQty);
public sealed record PickingScanDecision(
PickingScanDecisionKind Kind,
bool Accepted,
string Feedback,
string Message,
decimal? NewPickedQty = null,
bool LineCompleted = false)
{
public string AuditAction => Kind switch
{
PickingScanDecisionKind.RejectLocation => "LocationRejected",
PickingScanDecisionKind.AcceptLocation => "LocationAccepted",
PickingScanDecisionKind.RejectItem => "ItemRejected",
PickingScanDecisionKind.AcceptItem => "ItemAccepted",
_ => "BarcodeScanned"
};
}
public static class PickingScanStateMachine
{
public static PickingScanDecision Decide(PickingScanState state, string scannedBarcode)
{
var barcode = scannedBarcode.Trim();
if (!state.LocationConfirmed)
{
if (!string.Equals(barcode, state.LocationBarcode, StringComparison.OrdinalIgnoreCase))
return new(
PickingScanDecisionKind.RejectLocation,
false,
"error",
$"잘못된 위치입니다. {state.LocationCode} 위치로 이동하세요.");
return new(
PickingScanDecisionKind.AcceptLocation,
true,
"success",
"위치를 확인했습니다. 상품을 스캔하세요.");
}
if (!string.Equals(barcode, state.ItemBarcode, StringComparison.OrdinalIgnoreCase))
return new(
PickingScanDecisionKind.RejectItem,
false,
"error",
"다른 상품입니다. 화면의 품목과 바코드를 확인하세요.");
var nextQty = Math.Min(state.PickedQty + 1m, state.RequiredQty);
var completed = nextQty >= state.RequiredQty;
return new(
PickingScanDecisionKind.AcceptItem,
true,
"success",
completed ? "현재 품목을 완료했습니다. 다음 작업을 진행하세요." : "1개 피킹했습니다.",
nextQty,
completed);
}
}