Browse Source

update

reset-do-picking-order
CANCERYS\kw093 2 weeks ago
parent
commit
2b3752d64f
12 changed files with 408 additions and 73 deletions
  1. +6
    -0
      src/app/api/jo/actions.ts
  2. +51
    -0
      src/app/api/pickOrder/actions.ts
  3. +1
    -0
      src/app/api/stockTake/actions.ts
  4. +222
    -3
      src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx
  5. +1
    -1
      src/components/FinishedGoodSearch/GoodPickExecution.tsx
  6. +1
    -1
      src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx
  7. +2
    -1
      src/components/JoSearch/JoSearch.tsx
  8. +5
    -0
      src/components/Jodetail/JoPickOrderList.tsx
  9. +71
    -30
      src/components/Jodetail/newJobPickExecution.tsx
  10. +15
    -5
      src/components/StockTakeManagement/PickerCardList.tsx
  11. +14
    -13
      src/components/StockTakeManagement/PickerReStockTake.tsx
  12. +19
    -19
      src/components/StockTakeManagement/PickerStockTake.tsx

+ 6
- 0
src/app/api/jo/actions.ts View File

@@ -508,6 +508,11 @@ export interface ProductProcessLineInfoResponse {
startTime: string,
endTime: string
}
export interface FloorPickCount {
floor: string;
finishedCount: number;
totalCount: number;
}
export interface AllJoPickOrderResponse {
id: number;
pickOrderId: number | null;
@@ -523,6 +528,7 @@ export interface AllJoPickOrderResponse {
uomName: string;
jobOrderStatus: string;
finishedPickOLineCount: number;
floorPickCounts: FloorPickCount[];
}
export interface UpdateJoPickOrderHandledByRequest {
pickOrderId: number;


+ 51
- 0
src/app/api/pickOrder/actions.ts View File

@@ -1384,4 +1384,55 @@ export const fetchReleasedDoPickOrders = async (): Promise<ReleasedDoPickOrderRe
},
);
return response;
};
// 新增:Released Do Pick Order 列表項目(對應後端 ReleasedDoPickOrderListItem)
export interface ReleasedDoPickOrderListItem {
id: number;
requiredDeliveryDate: string | null;
shopCode: string | null;
shopName: string | null;
storeId: string | null;
truckLanceCode: string | null;
truckDepartureTime: string | null;
deliveryOrderCodes: string[];
}

// 修改:fetchReleasedDoPickOrders 支援 shopName 篩選,並回傳新結構
export const fetchReleasedDoPickOrdersForSelection = async (
shopName?: string,
storeId?: string,
truck?: string
): Promise<ReleasedDoPickOrderListItem[]> => {
const params = new URLSearchParams();
if (shopName?.trim()) params.append("shopName", shopName.trim());
if (storeId?.trim()) params.append("storeId", storeId.trim());
if (truck?.trim()) params.append("truck", truck.trim());
const query = params.toString();
const url = `${BASE_API_URL}/doPickOrder/released${query ? `?${query}` : ""}`;
const response = await serverFetchJson<ReleasedDoPickOrderListItem[]>(url, {
method: "GET",
});
return response ?? [];
};
export const fetchReleasedDoPickOrderCountByStore = async (
storeId: string
): Promise<number> => {
const list = await fetchReleasedDoPickOrdersForSelection(undefined, storeId);
return list.length;
};
// 新增:依 doPickOrderId 分配
export const assignByDoPickOrderId = async (
userId: number,
doPickOrderId: number
): Promise<PostPickOrderResponse> => {
const response = await serverFetchJson<PostPickOrderResponse>(
`${BASE_API_URL}/doPickOrder/assign-by-id`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId, doPickOrderId }),
}
);
revalidateTag("pickorder");
return response;
};

+ 1
- 0
src/app/api/stockTake/actions.ts View File

@@ -95,6 +95,7 @@ export interface AllPickedStockTakeListReponse {
totalItemNumber: number;
startTime: string | null;
endTime: string | null;
planStartDate: string | null;
reStockTakeTrueFalse: boolean;
}



+ 222
- 3
src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx View File

@@ -5,9 +5,10 @@ import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import { fetchStoreLaneSummary, assignByLane, type StoreLaneSummary } from "@/app/api/pickOrder/actions";
import { fetchStoreLaneSummary,fetchReleasedDoPickOrdersForSelection,fetchReleasedDoPickOrderCountByStore, assignByLane, type StoreLaneSummary } from "@/app/api/pickOrder/actions";
import Swal from "sweetalert2";
import dayjs from "dayjs";
import ReleasedDoPickOrderSelectModal from "./ReleasedDoPickOrderSelectModal";

interface Props {
onPickOrderAssigned?: () => void;
@@ -18,7 +19,11 @@ const FinishedGoodFloorLanePanel: React.FC<Props> = ({ onPickOrderAssigned, onSw
const { t } = useTranslation("pickOrder");
const { data: session } = useSession() as { data: SessionWithTokens | null };
const currentUserId = session?.id ? parseInt(session.id) : undefined;

const [selectedStore, setSelectedStore] = useState<string>("2/F");
const [selectedTruck, setSelectedTruck] = useState<string>("");
const [modalOpen, setModalOpen] = useState(false);
const [truckCounts2F, setTruckCounts2F] = useState<{ truck: string; count: number }[]>([]);
const [truckCounts4F, setTruckCounts4F] = useState<{ truck: string; count: number }[]>([]);
const [summary2F, setSummary2F] = useState<StoreLaneSummary | null>(null);
const [summary4F, setSummary4F] = useState<StoreLaneSummary | null>(null);
const [isLoadingSummary, setIsLoadingSummary] = useState(false);
@@ -56,7 +61,33 @@ const FinishedGoodFloorLanePanel: React.FC<Props> = ({ onPickOrderAssigned, onSw
useEffect(() => {
loadSummaries();
}, [loadSummaries]);

useEffect(() => {
const loadCounts = async () => {
try {
const [list2F, list4F] = await Promise.all([
fetchReleasedDoPickOrdersForSelection(undefined, "2/F"),
fetchReleasedDoPickOrdersForSelection(undefined, "4/F"),
]);
const groupByTruck = (list: { truckLanceCode?: string | null }[]) => {
const map: Record<string, number> = {};
list.forEach((item) => {
const t = item.truckLanceCode || "-";
map[t] = (map[t] || 0) + 1;
});
return Object.entries(map)
.map(([truck, count]) => ({ truck, count }))
.sort((a, b) => a.truck.localeCompare(b.truck));
};
setTruckCounts2F(groupByTruck(list2F));
setTruckCounts4F(groupByTruck(list4F));
} catch (e) {
console.error("Error loading counts:", e);
setTruckCounts2F([]);
setTruckCounts4F([]);
}
};
loadCounts();
}, [loadSummaries]);
const handleAssignByLane = useCallback(async (
storeId: string,
truckDepartureTime: string,
@@ -468,6 +499,194 @@ const getDateLabel = (offset: number) => {
</Box>
</Stack>
</Grid>
{/* 2/F 未完成已放單 - 與上方相同 UI */}
<Grid item xs={12}>
<Box
sx={{
py: 2,
mt: 1,
mb: 0.5,
borderTop: "1px solid #e0e0e0",
}}
>
<Typography
variant="subtitle1"
sx={{ fontWeight: 600, mb: 0.5 }}
>
{t("Not yet finished released do pick orders")}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("Released orders not yet completed - click lane to select and assign")}
</Typography>
</Box>
</Grid>
<Grid item xs={12}>
<Stack direction="row" spacing={2} alignItems="flex-start">
<Typography variant="h6" sx={{ fontWeight: 600, minWidth: 60, pt: 1 }}>
2/F
</Typography>
<Box
sx={{
border: "1px solid #e0e0e0",
borderRadius: 1,
p: 1,
backgroundColor: "#fafafa",
flex: 1,
}}
>
{truckCounts2F.length === 0 ? (
<Typography
variant="body2"
color="text.secondary"
sx={{
fontWeight: 600,
fontSize: "1rem",
textAlign: "center",
py: 1,
}}
>
{t("No entries available")}
</Typography>
) : (
<Grid container spacing={1}>
{truckCounts2F.map(({ truck, count }) => (
<Grid item xs={6} sm={4} md={3} key={`2F-${truck}`} sx={{ display: "flex" }}>

<Button
variant="outlined"
size="medium"
onClick={() => {
setSelectedStore("2/F");
setSelectedTruck(truck);
setModalOpen(true);
}}
sx={{
flex: 1,
fontSize: "1.1rem",
py: 1,
px: 1.5,
borderWidth: 1,
borderColor: "#ccc",
fontWeight: 500,
"&:hover": {
borderColor: "#999",
backgroundColor: "#f5f5f5",
},
}}
>
{`${truck} (${count})`}
</Button>
</Grid>
))}
</Grid>
)}
</Box>
</Stack>
</Grid>

{/* 4/F 未完成已放單 - 與上方相同 UI */}
<Grid item xs={12}>
<Stack direction="row" spacing={2} alignItems="flex-start">
<Typography variant="h6" sx={{ fontWeight: 600, minWidth: 60, pt: 1 }}>
4/F
</Typography>
<Box
sx={{
border: "1px solid #e0e0e0",
borderRadius: 1,
p: 1,
backgroundColor: "#fafafa",
flex: 1,
}}
>
{truckCounts4F.length === 0 ? (
<Typography
variant="body2"
color="text.secondary"
sx={{
fontWeight: 600,
fontSize: "1rem",
textAlign: "center",
py: 1,
}}
>
{t("No entries available")}
</Typography>
) : (
<Grid container spacing={1}>
{truckCounts4F.map(({ truck, count }) => (
<Grid item xs={6} sm={4} md={3} key={`4F-${truck}`} sx={{ display: "flex" }}>
<Button
variant="outlined"
size="medium"
onClick={() => {
setSelectedStore("4/F");
setSelectedTruck(truck);
setModalOpen(true);
}}
sx={{
flex: 1,
fontSize: "1.1rem",
py: 1,
px: 1.5,
borderWidth: 1,
borderColor: "#ccc",
fontWeight: 500,
"&:hover": {
borderColor: "#999",
backgroundColor: "#f5f5f5",
},
}}
>
{`${truck} (${count})`}
</Button>
</Grid>
))}
</Grid>
)}
</Box>
</Stack>
</Grid>
<ReleasedDoPickOrderSelectModal
open={modalOpen}
storeId={selectedStore}
truck={selectedTruck}
onClose={() => setModalOpen(false)}
onAssigned={() => {
loadSummaries();
const loadCounts = async () => {
try {
const [list2F, list4F] = await Promise.all([
fetchReleasedDoPickOrdersForSelection(undefined, "2/F"),
fetchReleasedDoPickOrdersForSelection(undefined, "4/F"),
]);
const groupByTruck = (list: { truckLanceCode?: string | null }[]) => {
const map: Record<string, number> = {};
list.forEach((item) => {
const t = item.truckLanceCode || "-";
map[t] = (map[t] || 0) + 1;
});
return Object.entries(map)
.map(([truck, count]) => ({ truck, count }))
.sort((a, b) => a.truck.localeCompare(b.truck));
};
setTruckCounts2F(groupByTruck(list2F));
setTruckCounts4F(groupByTruck(list4F));
} catch (e) {
setTruckCounts2F([]);
setTruckCounts4F([]);
}
};
loadCounts();
onPickOrderAssigned?.();
onSwitchToDetailTab?.();
}}
/>
</Grid>




+ 1
- 1
src/components/FinishedGoodSearch/GoodPickExecution.tsx View File

@@ -1097,7 +1097,7 @@ const fetchFgPickOrdersData = useCallback(async () => {
const paginatedData = useMemo(() => {
// ✅ Fix: Add safety check to ensure combinedLotData is an array
if (!Array.isArray(combinedLotData)) {
console.warn("⚠️ combinedLotData is not an array:", combinedLotData);
console.warn(" combinedLotData is not an array:", combinedLotData);
return [];
}


+ 1
- 1
src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx View File

@@ -3124,7 +3124,7 @@ paginatedData.map((lot, index) => {
}}
>
{lot.lotNo ||
t('No Stock Available')}
t('This lot is not available, please scan another lot.')}
</Typography>
</Box>
</TableCell>


+ 2
- 1
src/components/JoSearch/JoSearch.tsx View File

@@ -72,7 +72,7 @@ const JoSearch: React.FC<Props> = ({ defaultInputs, bomCombo, printerCombo, jobT
}
return response.json();
};
/*
useEffect(() => {
const fetchDetailedJos = async () => {
const detailedMap = new Map<number, JobOrder>();
@@ -98,6 +98,7 @@ const JoSearch: React.FC<Props> = ({ defaultInputs, bomCombo, printerCombo, jobT
fetchDetailedJos();
}
}, [filteredJos]);
*/
/*
useEffect(() => {
const fetchInventoryData = async () => {


+ 5
- 0
src/components/Jodetail/JoPickOrderList.tsx View File

@@ -140,6 +140,11 @@ const JoPickOrderList: React.FC<Props> = ({ onSwitchToRecordTab }) =>{
<Typography variant="body2" color="text.secondary">
{t("Required Qty")}: {pickOrder.reqQty} ({pickOrder.uomName})
</Typography>
{pickOrder.floorPickCounts?.map(({ floor, finishedCount, totalCount }) => (
<Typography key={floor} variant="body2" color="text.secondary" component="span" sx={{ mr: 1 }}>
{floor}: {finishedCount}/{totalCount}
</Typography>
))}
{statusLower !== "pending" && finishedCount > 0 && (
<Box sx={{ mt: 1 }}>
<Typography variant="body2" fontWeight={600}>


+ 71
- 30
src/components/Jodetail/newJobPickExecution.tsx View File

@@ -186,7 +186,8 @@ const QrCodeModal: React.FC<{
const { t } = useTranslation("jo");
const { values: qrValues, isScanning, startScan, stopScan, resetScan } = useQrCodeScannerContext();
const [manualInput, setManualInput] = useState<string>('');
// 楼层筛选状态
const [selectedFloor, setSelectedFloor] = useState<string | null>(null);
const [manualInputSubmitted, setManualInputSubmitted] = useState<boolean>(false);
const [manualInputError, setManualInputError] = useState<boolean>(false);
const [isProcessingQr, setIsProcessingQr] = useState<boolean>(false);
@@ -474,7 +475,7 @@ const JobPickExecution: React.FC<Props> = ({ filterArgs, onBackToList }) => {
// Add QR modal states
const [qrModalOpen, setQrModalOpen] = useState(false);
const [selectedLotForQr, setSelectedLotForQr] = useState<any | null>(null);
const [selectedFloor, setSelectedFloor] = useState<string | null>(null);
// Add GoodPickExecutionForm states
const [pickExecutionFormOpen, setPickExecutionFormOpen] = useState(false);
const [selectedLotForExecutionForm, setSelectedLotForExecutionForm] = useState<any | null>(null);
@@ -545,6 +546,17 @@ const JobPickExecution: React.FC<Props> = ({ filterArgs, onBackToList }) => {
return allLots;
}, []);
const extractFloor = (lot: any): string => {
const raw = lot.routerRoute || lot.routerArea || lot.location || '';
const match = raw.match(/^(\d+F?)/i) || raw.split('-')[0];
return (match?.[1] || match || raw || '').toUpperCase().replace(/(\d)F?/i, '$1F');
};
// 楼层排序权重:4F > 3F > 2F(数字越大越靠前)
const floorSortOrder = (floor: string): number => {
const n = parseInt(floor.replace(/\D/g, ''), 10);
return isNaN(n) ? 0 : n;
};
const combinedLotData = useMemo(() => {
return getAllLotsFromHierarchical(jobOrderData);
}, [jobOrderData, getAllLotsFromHierarchical]);
@@ -1910,23 +1922,31 @@ const JobPickExecution: React.FC<Props> = ({ filterArgs, onBackToList }) => {
const scannedItemsCount = useMemo(() => {
return combinedLotData.filter(lot => lot.stockOutLineStatus === 'checked').length;
}, [combinedLotData]);

// Progress bar data (align with Finished Good execution detail)
const progress = useMemo(() => {
if (combinedLotData.length === 0) {
return { completed: 0, total: 0 };
}

const nonPendingCount = combinedLotData.filter((lot) => {
const status = lot.stockOutLineStatus?.toLowerCase();
return status !== 'pending';
}).length;

return {
completed: nonPendingCount,
total: combinedLotData.length,
};
// 先定义 filteredByFloor 和 availableFloors
const availableFloors = useMemo(() => {
const floors = new Set<string>();
combinedLotData.forEach(lot => {
const f = extractFloor(lot);
if (f) floors.add(f);
});
return Array.from(floors).sort((a, b) => floorSortOrder(b) - floorSortOrder(a));
}, [combinedLotData]);
const filteredByFloor = useMemo(() => {
if (!selectedFloor) return combinedLotData;
return combinedLotData.filter(lot => extractFloor(lot) === selectedFloor);
}, [combinedLotData, selectedFloor]);
// Progress bar data - 现在可以正确引用 filteredByFloor
const progress = useMemo(() => {
const data = selectedFloor ? filteredByFloor : combinedLotData;
if (data.length === 0) return { completed: 0, total: 0 };
const nonPendingCount = data.filter(lot =>
lot.stockOutLineStatus?.toLowerCase() !== 'pending'
).length;
return { completed: nonPendingCount, total: data.length };
}, [selectedFloor, filteredByFloor, combinedLotData]);
// Handle reject lot
const handleRejectLot = useCallback(async (lot: any) => {
if (!lot.stockOutLineId) {
@@ -2057,15 +2077,18 @@ const JobPickExecution: React.FC<Props> = ({ filterArgs, onBackToList }) => {

// Pagination data with sorting by routerIndex
const paginatedData = useMemo(() => {
// Sort by routerIndex first, then by other criteria
const sortedData = [...combinedLotData].sort((a, b) => {
const aIndex = a.routerIndex || 0;
const bIndex = b.routerIndex || 0;
// Primary sort: by routerIndex
if (aIndex !== bIndex) {
return aIndex - bIndex;
}

const sourceData = selectedFloor ? filteredByFloor : combinedLotData;
const sortedData = [...sourceData].sort((a, b) => {
const floorA = extractFloor(a);
const floorB = extractFloor(b);
const orderA = floorSortOrder(floorA);
const orderB = floorSortOrder(floorB);
if (orderA !== orderB) return orderB - orderA; // 4F, 3F, 2F
// 同楼层再按 routerIndex、pickOrderCode、lotNo
const aIndex = a.routerIndex ?? 0;
const bIndex = b.routerIndex ?? 0;
if (aIndex !== bIndex) return aIndex - bIndex;
// Secondary sort: by pickOrderCode if routerIndex is the same
if (a.pickOrderCode !== b.pickOrderCode) {
@@ -2079,7 +2102,7 @@ const JobPickExecution: React.FC<Props> = ({ filterArgs, onBackToList }) => {
const startIndex = paginationController.pageNum * paginationController.pageSize;
const endIndex = startIndex + paginationController.pageSize;
return sortedData.slice(startIndex, endIndex);
}, [combinedLotData, paginationController]);
}, [selectedFloor, filteredByFloor, combinedLotData, paginationController]);

// Add these functions for manual scanning
const handleStartScan = useCallback(() => {
@@ -2188,7 +2211,25 @@ const JobPickExecution: React.FC<Props> = ({ filterArgs, onBackToList }) => {
successMessage={t("QR code verified.")}
/>
</Box>

<Box sx={{ display: 'flex', gap: 1, alignItems: 'center', flexWrap: 'wrap' }}>
<Button
variant={selectedFloor === null ? 'contained' : 'outlined'}
size="small"
onClick={() => setSelectedFloor(null)}
>
{t("All")}
</Button>
{availableFloors.map(floor => (
<Button
key={floor}
variant={selectedFloor === floor ? 'contained' : 'outlined'}
size="small"
onClick={() => setSelectedFloor(floor)}
>
{floor}
</Button>
))}
</Box>
{/* Job Order Header */}
{jobOrderData && (
<Paper sx={{ p: 2 }}>
@@ -2479,7 +2520,7 @@ const JobPickExecution: React.FC<Props> = ({ filterArgs, onBackToList }) => {
<TablePagination
component="div"
count={combinedLotData.length}
count={selectedFloor ? filteredByFloor.length : combinedLotData.length}
page={paginationController.pageNum}
rowsPerPage={paginationController.pageSize}
onPageChange={handlePageChange}


+ 15
- 5
src/components/StockTakeManagement/PickerCardList.tsx View File

@@ -165,7 +165,11 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ onCardClick, onReStockT
if (session.totalInventoryLotNumber === 0) return 0;
return Math.round((session.currentStockTakeItemNumber / session.totalInventoryLotNumber) * 100);
};

const planStartDate = (() => {
const first = stockTakeSessions.find(s => s.planStartDate);
if (!first?.planStartDate) return null;
return dayjs(first.planStartDate).format(OUTPUT_DATE_FORMAT);
})();
if (loading) {
return (
<Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
@@ -177,9 +181,15 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ onCardClick, onReStockT
return (
<Box>
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2 }}>


<Typography variant="body2" color="text.secondary">
{t("Total Sections")}: {stockTakeSessions.length}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("Start Stock Take Date")}: {planStartDate || "-"}
</Typography>

<Button
variant="contained"
color="primary"
@@ -214,12 +224,12 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ onCardClick, onReStockT
<Typography variant="subtitle1" fontWeight={600}>
{t("Section")}: {session.stockTakeSession}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
{t("Last Stock Take Date")}: {lastStockTakeDate || "-"}
</Typography>
</Stack>

<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
{t("Last Stock Take Date")}: {lastStockTakeDate || "-"}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>{t("Stock Taker")}: {session.stockTakerName}</Typography>
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ mb: 1 }}>


+ 14
- 13
src/components/StockTakeManagement/PickerReStockTake.tsx View File

@@ -390,9 +390,9 @@ const PickerReStockTake: React.FC<PickerReStockTakeProps> = ({
<TableCell>{t("Item-lotNo-ExpiryDate")}</TableCell>
<TableCell>{t("UOM")}</TableCell>
<TableCell>{t("Stock Take Qty(include Bad Qty)= Available Qty")}</TableCell>
<TableCell>{t("Action")}</TableCell>
<TableCell>{t("Remark")}</TableCell>
<TableCell>{t("Record Status")}</TableCell>
<TableCell>{t("Action")}</TableCell>
</TableRow>
</TableHead>
<TableBody>
@@ -562,6 +562,18 @@ const PickerReStockTake: React.FC<PickerReStockTakeProps> = ({
)}
</Stack>
</TableCell>
<TableCell>
<Stack direction="row" spacing={1}>
<Button
size="small"
variant="contained"
onClick={() => handleSaveStockTake(detail)}
disabled={saving || submitDisabled }
>
{t("Save")}
</Button>
</Stack>
</TableCell>
<TableCell sx={{ width: 180 }}>
{!submitDisabled && isSecondSubmit ? (
<>
@@ -595,18 +607,7 @@ const PickerReStockTake: React.FC<PickerReStockTakeProps> = ({
<Chip size="small" label={t(detail.stockTakeRecordStatus || "")} color="default" />
)}
</TableCell>
<TableCell>
<Stack direction="row" spacing={1}>
<Button
size="small"
variant="contained"
onClick={() => handleSaveStockTake(detail)}
disabled={saving || submitDisabled }
>
{t("Save")}
</Button>
</Stack>
</TableCell>
</TableRow>
);
})


+ 19
- 19
src/components/StockTakeManagement/PickerStockTake.tsx View File

@@ -517,10 +517,10 @@ const PickerStockTake: React.FC<PickerStockTakeProps> = ({
<TableCell>{t("Item-lotNo-ExpiryDate")}</TableCell>
<TableCell>{t("UOM")}</TableCell>
<TableCell>{t("Stock Take Qty(include Bad Qty)= Available Qty")}</TableCell>
<TableCell>{t("Action")}</TableCell>
<TableCell>{t("Remark")}</TableCell>
<TableCell>{t("Record Status")}</TableCell>
<TableCell>{t("Action")}</TableCell>
</TableRow>
</TableHead>
<TableBody>
@@ -728,7 +728,21 @@ const PickerStockTake: React.FC<PickerStockTakeProps> = ({
)}
</Stack>
</TableCell>

<TableCell>
<Stack direction="row" spacing={1}>
<Button
size="small"
variant="contained"
onClick={() => handleSaveStockTake(detail)}
disabled={saving || submitDisabled}
>
{t("Save")}
</Button>
</Stack>
</TableCell>
{/* Remark */}
<TableCell sx={{ width: 180 }}>
{!submitDisabled && isSecondSubmit ? (
@@ -755,7 +769,7 @@ const PickerStockTake: React.FC<PickerStockTakeProps> = ({
</TableCell>

<TableCell>
{detail.stockTakeRecordStatus === "completed" ? (
<Chip
@@ -784,21 +798,7 @@ const PickerStockTake: React.FC<PickerStockTakeProps> = ({
)}
</TableCell>

<TableCell>
<Stack direction="row" spacing={1}>
<Button
size="small"
variant="contained"
onClick={() => handleSaveStockTake(detail)}
disabled={saving || submitDisabled}
>
{t("Save")}
</Button>
</Stack>
</TableCell>

</TableRow>
);
})


Loading…
Cancel
Save