Ver a proveniência

Merge branch 'MergeProblem1' of https://git.2fi-solutions.com/derek/FPSMS-frontend into MergeProblem1

reset-do-picking-order
kelvin.yau há 2 semanas
ascendente
cometimento
c5c6d61af2
2 ficheiros alterados com 193 adições e 177 eliminações
  1. +5
    -5
      src/components/DashboardPage/truckSchedule/TruckScheduleDashboard.tsx
  2. +188
    -172
      src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx

+ 5
- 5
src/components/DashboardPage/truckSchedule/TruckScheduleDashboard.tsx Ver ficheiro

@@ -566,11 +566,6 @@ const TruckScheduleDashboard: React.FC = () => {
{row.numberOfShopsToServe} [{row.numberOfPickTickets}]
</Typography>
</TableCell>
<TableCell align="center">
<Typography variant="body2" sx={{ fontWeight: 500 }}>
{row.totalItemsToPick}
</Typography>
</TableCell>
<TableCell align="center">
<Chip
label={row.numberOfTicketsReleased}
@@ -585,6 +580,11 @@ const TruckScheduleDashboard: React.FC = () => {
color={row.numberOfTicketsCompleted > 0 ? 'success' : 'default'}
/>
</TableCell>
<TableCell align="center">
<Typography variant="body2" sx={{ fontWeight: 500 }}>
{row.totalItemsToPick}
</Typography>
</TableCell>
<TableCell>
{formatDateTime(row.firstTicketStartTime)}
</TableCell>


+ 188
- 172
src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx Ver ficheiro

@@ -768,180 +768,196 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO
// 设置 FG info 到 fgPickOrders(用于显示 FG 信息卡片)
// 修改第 478-509 行的 fgOrder 构建逻辑:

const fgOrder: FGPickOrderResponse = {
doPickOrderId: hierarchicalData.fgInfo.doPickOrderId,
ticketNo: hierarchicalData.fgInfo.ticketNo,
storeId: hierarchicalData.fgInfo.storeId,
shopCode: hierarchicalData.fgInfo.shopCode,
shopName: hierarchicalData.fgInfo.shopName,
truckLanceCode: hierarchicalData.fgInfo.truckLanceCode,
DepartureTime: hierarchicalData.fgInfo.departureTime,
shopAddress: "",
pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "",
// 兼容字段
pickOrderId: mergedPickOrder.pickOrderIds?.[0] || 0,
pickOrderConsoCode: mergedPickOrder.consoCode || "",
pickOrderTargetDate: mergedPickOrder.targetDate || "",
pickOrderStatus: mergedPickOrder.status || "",
deliveryOrderId: mergedPickOrder.doOrderIds?.[0] || 0,
deliveryNo: mergedPickOrder.deliveryOrderCodes?.[0] || "",
deliveryDate: "",
shopId: 0,
shopPoNo: "",
numberOfCartons: mergedPickOrder.pickOrderLines?.length || 0,
qrCodeData: hierarchicalData.fgInfo.doPickOrderId,
// 新增:多个 pick orders 信息 - 保持数组格式,不要 join
numberOfPickOrders: mergedPickOrder.pickOrderIds?.length || 0,
pickOrderIds: mergedPickOrder.pickOrderIds || [],
pickOrderCodes: Array.isArray(mergedPickOrder.pickOrderCodes)
? mergedPickOrder.pickOrderCodes
: [], // 改:保持数组
deliveryOrderIds: mergedPickOrder.doOrderIds || [],
deliveryNos: Array.isArray(mergedPickOrder.deliveryOrderCodes)
? mergedPickOrder.deliveryOrderCodes
: [], // 改:保持数组
lineCountsPerPickOrder: Array.isArray(mergedPickOrder.lineCountsPerPickOrder)
? mergedPickOrder.lineCountsPerPickOrder
: []
};
setFgPickOrders([fgOrder]);
console.log(" DEBUG fgOrder.lineCountsPerPickOrder:", fgOrder.lineCountsPerPickOrder);
console.log(" DEBUG fgOrder.pickOrderCodes:", fgOrder.pickOrderCodes);
console.log(" DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
// 移除:不需要 doPickOrderDetail 和 switcher 逻辑
// if (hierarchicalData.pickOrders.length > 1) { ... }
// 直接使用合并后的 pickOrderLines
console.log("🎯 Displaying merged pick order lines");
// 将层级数据转换为平铺格式(用于表格显示)
const flatLotData: any[] = [];
mergedPickOrder.pickOrderLines.forEach((line: any) => {
// ✅ FIXED: 处理 lots(如果有)
if (line.lots && line.lots.length > 0) {
// 修复:先对 lots 按 lotId 去重并合并 requiredQty
const lotMap = new Map<number, any>();
line.lots.forEach((lot: any) => {
const lotId = lot.id;
if (lotMap.has(lotId)) {
// 如果已存在,合并 requiredQty
const existingLot = lotMap.get(lotId);
existingLot.requiredQty = (existingLot.requiredQty || 0) + (lot.requiredQty || 0);
// 保留其他字段(使用第一个遇到的 lot 的字段)
} else {
// 首次遇到,添加到 map
lotMap.set(lotId, { ...lot });
}
});
// 遍历去重后的 lots
lotMap.forEach((lot: any) => {
flatLotData.push({
// 使用合并后的数据
pickOrderConsoCode: mergedPickOrder.consoCode,
pickOrderTargetDate: mergedPickOrder.targetDate,
pickOrderStatus: mergedPickOrder.status,
pickOrderId: line.pickOrderId || mergedPickOrder.pickOrderIds?.[0] || 0, // 使用第一个 pickOrderId
pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "",
pickOrderLineId: line.id,
pickOrderLineRequiredQty: line.requiredQty,
pickOrderLineStatus: line.status,
itemId: line.item.id,
itemCode: line.item.code,
itemName: line.item.name,
uomDesc: line.item.uomDesc,
uomShortDesc: line.item.uomShortDesc,
lotId: lot.id,
lotNo: lot.lotNo,
expiryDate: lot.expiryDate,
location: lot.location,
stockUnit: lot.stockUnit,
availableQty: lot.availableQty,
requiredQty: lot.requiredQty, // 使用合并后的 requiredQty
actualPickQty: lot.actualPickQty,
inQty: lot.inQty,
outQty: lot.outQty,
holdQty: lot.holdQty,
lotStatus: lot.lotStatus,
lotAvailability: lot.lotAvailability,
processingStatus: lot.processingStatus,
suggestedPickLotId: lot.suggestedPickLotId,
stockOutLineId: lot.stockOutLineId,
stockOutLineStatus: lot.stockOutLineStatus,
stockOutLineQty: lot.stockOutLineQty,
stockInLineId: lot.stockInLineId,
routerId: lot.router?.id,
routerIndex: lot.router?.index,
routerRoute: lot.router?.route,
routerArea: lot.router?.area,
noLot: false,
});
const fgOrder: FGPickOrderResponse = {
doPickOrderId: hierarchicalData.fgInfo.doPickOrderId,
ticketNo: hierarchicalData.fgInfo.ticketNo,
storeId: hierarchicalData.fgInfo.storeId,
shopCode: hierarchicalData.fgInfo.shopCode,
shopName: hierarchicalData.fgInfo.shopName,
truckLanceCode: hierarchicalData.fgInfo.truckLanceCode,
DepartureTime: hierarchicalData.fgInfo.departureTime,
shopAddress: "",
pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "",
// 兼容字段(注意 consoCodes 是数组)
pickOrderId: mergedPickOrder.pickOrderIds?.[0] || 0,
pickOrderConsoCode: Array.isArray(mergedPickOrder.consoCodes)
? mergedPickOrder.consoCodes[0] || ""
: "",
pickOrderTargetDate: mergedPickOrder.targetDate || "",
pickOrderStatus: mergedPickOrder.status || "",
deliveryOrderId: mergedPickOrder.doOrderIds?.[0] || 0,
deliveryNo: mergedPickOrder.deliveryOrderCodes?.[0] || "",
deliveryDate: "",
shopId: 0,
shopPoNo: "",
numberOfCartons: mergedPickOrder.pickOrderLines?.length || 0,
qrCodeData: hierarchicalData.fgInfo.doPickOrderId,
// 多个 pick orders 信息:全部保留为数组
numberOfPickOrders: mergedPickOrder.pickOrderIds?.length || 0,
pickOrderIds: mergedPickOrder.pickOrderIds || [],
pickOrderCodes: Array.isArray(mergedPickOrder.pickOrderCodes)
? mergedPickOrder.pickOrderCodes
: [],
deliveryOrderIds: mergedPickOrder.doOrderIds || [],
deliveryNos: Array.isArray(mergedPickOrder.deliveryOrderCodes)
? mergedPickOrder.deliveryOrderCodes
: [],
lineCountsPerPickOrder: Array.isArray(mergedPickOrder.lineCountsPerPickOrder)
? mergedPickOrder.lineCountsPerPickOrder
: [],
};
setFgPickOrders([fgOrder]);
console.log(" DEBUG fgOrder.lineCountsPerPickOrder:", fgOrder.lineCountsPerPickOrder);
console.log(" DEBUG fgOrder.pickOrderCodes:", fgOrder.pickOrderCodes);
console.log(" DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
// 直接使用合并后的 pickOrderLines
console.log("🎯 Displaying merged pick order lines");
// 将层级数据转换为平铺格式(用于表格显示)
const flatLotData: any[] = [];
mergedPickOrder.pickOrderLines.forEach((line: any) => {
// 用来记录这一行已经通过 lots 出现过的 lotId
const lotIdSet = new Set<number>();
// ✅ lots:按 lotId 去重并合并 requiredQty
if (line.lots && line.lots.length > 0) {
const lotMap = new Map<number, any>();
line.lots.forEach((lot: any) => {
const lotId = lot.id;
if (lotMap.has(lotId)) {
const existingLot = lotMap.get(lotId);
existingLot.requiredQty =
(existingLot.requiredQty || 0) + (lot.requiredQty || 0);
} else {
lotMap.set(lotId, { ...lot });
}
});
lotMap.forEach((lot: any) => {
if (lot.id != null) {
lotIdSet.add(lot.id);
}
flatLotData.push({
pickOrderConsoCode: Array.isArray(mergedPickOrder.consoCodes)
? mergedPickOrder.consoCodes[0] || ""
: "",
pickOrderTargetDate: mergedPickOrder.targetDate,
pickOrderStatus: mergedPickOrder.status,
pickOrderId: line.pickOrderId || mergedPickOrder.pickOrderIds?.[0] || 0,
pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "",
pickOrderLineId: line.id,
pickOrderLineRequiredQty: line.requiredQty,
pickOrderLineStatus: line.status,
itemId: line.item.id,
itemCode: line.item.code,
itemName: line.item.name,
uomDesc: line.item.uomDesc,
uomShortDesc: line.item.uomShortDesc,
lotId: lot.id,
lotNo: lot.lotNo,
expiryDate: lot.expiryDate,
location: lot.location,
stockUnit: lot.stockUnit,
availableQty: lot.availableQty,
requiredQty: lot.requiredQty,
actualPickQty: lot.actualPickQty,
inQty: lot.inQty,
outQty: lot.outQty,
holdQty: lot.holdQty,
lotStatus: lot.lotStatus,
lotAvailability: lot.lotAvailability,
processingStatus: lot.processingStatus,
suggestedPickLotId: lot.suggestedPickLotId,
stockOutLineId: lot.stockOutLineId,
stockOutLineStatus: lot.stockOutLineStatus,
stockOutLineQty: lot.stockOutLineQty,
stockInLineId: lot.stockInLineId,
routerId: lot.router?.id,
routerIndex: lot.router?.index,
routerRoute: lot.router?.route,
routerArea: lot.router?.area,
noLot: false,
});
}
// ✅ FIXED: 同时处理 stockouts(无论是否有 lots)
if (line.stockouts && line.stockouts.length > 0) {
// ✅ FIXED: 处理所有 stockouts,而不仅仅是第一个
line.stockouts.forEach((stockout: any) => {
flatLotData.push({
pickOrderConsoCode: mergedPickOrder.consoCodes?.[0] || "",
pickOrderTargetDate: mergedPickOrder.targetDate,
pickOrderStatus: mergedPickOrder.status,
pickOrderId: line.pickOrderId || mergedPickOrder.pickOrderIds?.[0] || 0,
pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "",
pickOrderLineId: line.id,
pickOrderLineRequiredQty: line.requiredQty,
pickOrderLineStatus: line.status,
itemId: line.item.id,
itemCode: line.item.code,
itemName: line.item.name,
uomDesc: line.item.uomDesc,
uomShortDesc: line.item.uomShortDesc,
// Null stock 字段 - 从 stockouts 数组中获取
lotId: stockout.lotId || null,
lotNo: stockout.lotNo || null,
expiryDate: null,
location: stockout.location || null,
stockUnit: line.item.uomDesc,
availableQty: stockout.availableQty || 0,
requiredQty: line.requiredQty,
actualPickQty: stockout.qty || 0,
inQty: 0,
outQty: 0,
holdQty: 0,
lotStatus: 'unavailable',
lotAvailability: 'insufficient_stock',
processingStatus: stockout.status || 'pending',
suggestedPickLotId: null,
stockOutLineId: stockout.id || null, // 使用 stockouts 数组中的 id
stockOutLineStatus: stockout.status || null,
stockOutLineQty: stockout.qty || 0,
routerId: null,
routerIndex: 999999,
routerRoute: null,
routerArea: null,
noLot: true,
});
});
}
// ✅ stockouts:只保留“真正无批次 / 未在 lots 出现过”的行
if (line.stockouts && line.stockouts.length > 0) {
line.stockouts.forEach((stockout: any) => {
const hasLot = stockout.lotId != null;
const lotAlreadyInLots =
hasLot && lotIdSet.has(stockout.lotId as number);
// 有批次 & 已经通过 lots 渲染过 → 跳过,避免一条变两行
if (!stockout.noLot && lotAlreadyInLots) {
return;
}
// 只渲染:
// - noLot === true 的 Null stock 行
// - 或者 lotId 在 lots 中不存在的特殊情况
flatLotData.push({
pickOrderConsoCode: Array.isArray(mergedPickOrder.consoCodes)
? mergedPickOrder.consoCodes[0] || ""
: "",
pickOrderTargetDate: mergedPickOrder.targetDate,
pickOrderStatus: mergedPickOrder.status,
pickOrderId: line.pickOrderId || mergedPickOrder.pickOrderIds?.[0] || 0,
pickOrderCode: mergedPickOrder.pickOrderCodes?.[0] || "",
pickOrderLineId: line.id,
pickOrderLineRequiredQty: line.requiredQty,
pickOrderLineStatus: line.status,
itemId: line.item.id,
itemCode: line.item.code,
itemName: line.item.name,
uomDesc: line.item.uomDesc,
uomShortDesc: line.item.uomShortDesc,
lotId: stockout.lotId || null,
lotNo: stockout.lotNo || null,
expiryDate: null,
location: stockout.location || null,
stockUnit: line.item.uomDesc,
availableQty: stockout.availableQty || 0,
requiredQty: line.requiredQty,
actualPickQty: stockout.qty || 0,
inQty: 0,
outQty: 0,
holdQty: 0,
lotStatus: stockout.noLot ? "unavailable" : "available",
lotAvailability: stockout.noLot ? "insufficient_stock" : "available",
processingStatus: stockout.status || "pending",
suggestedPickLotId: null,
stockOutLineId: stockout.id || null,
stockOutLineStatus: stockout.status || null,
stockOutLineQty: stockout.qty || 0,
routerId: null,
routerIndex: stockout.noLot ? 999999 : null,
routerRoute: null,
routerArea: null,
noLot: !!stockout.noLot,
});
}
});

console.log(" Transformed flat lot data:", flatLotData);
console.log(" Total items (including null stock):", flatLotData.length);
setCombinedLotData(flatLotData);
setOriginalCombinedData(flatLotData);
checkAllLotsCompleted(flatLotData);
});
}
});
console.log(" Transformed flat lot data:", flatLotData);
console.log(" Total items (including null stock):", flatLotData.length);
setCombinedLotData(flatLotData);
setOriginalCombinedData(flatLotData);
checkAllLotsCompleted(flatLotData);
} catch (error) {
console.error(" Error fetching combined lot data:", error);
setCombinedLotData([]);


Carregando…
Cancelar
Guardar