| @@ -71,6 +71,7 @@ import { | |||||
| dayjsToDateTimeString, | dayjsToDateTimeString, | ||||
| } from "@/app/utils/formatUtil"; | } from "@/app/utils/formatUtil"; | ||||
| import { AUTH } from "@/authorities"; | import { AUTH } from "@/authorities"; | ||||
| import { statusChipColor } from "./StockTakeRoundCardList"; | |||||
| const FLOOR_GROUP_UNSET = "__UNSET__"; | const FLOOR_GROUP_UNSET = "__UNSET__"; | ||||
| /** 與 controllQRcodescanWarehouse 選倉相同:樓層 → 倉庫 → 倉位 */ | /** 與 controllQRcodescanWarehouse 選倉相同:樓層 → 倉庫 → 倉位 */ | ||||
| @@ -1264,21 +1265,6 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ | |||||
| return Array.from(sectionSet).sort((a, b) => a.localeCompare(b)); | return Array.from(sectionSet).sort((a, b) => a.localeCompare(b)); | ||||
| }); | }); | ||||
| }, [roundRecords]); | }, [roundRecords]); | ||||
| const getStatusColor = (status: string) => { | |||||
| const statusLower = status.toLowerCase().replace(/_/g, ""); | |||||
| if (statusLower === "completed") return "success"; | |||||
| if ( | |||||
| statusLower === "stocktaking" || | |||||
| statusLower === "inprogress" || | |||||
| statusLower === "processing" | |||||
| ) { | |||||
| return "primary"; // 盤點中 — 藍 | |||||
| } | |||||
| if (statusLower === "approving") return "info"; | |||||
| if (statusLower === "pending") return "warning"; // 待處理 — 橘 | |||||
| if (statusLower === "nocycle") return "default"; | |||||
| return "default"; | |||||
| }; | |||||
| const TimeDisplay: React.FC<{ startTime: string | null; endTime: string | null }> = ({ startTime, endTime }) => { | const TimeDisplay: React.FC<{ startTime: string | null; endTime: string | null }> = ({ startTime, endTime }) => { | ||||
| const [currentTime, setCurrentTime] = useState(dayjs()); | const [currentTime, setCurrentTime] = useState(dayjs()); | ||||
| @@ -1339,10 +1325,6 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ | |||||
| return "-"; | return "-"; | ||||
| } | } | ||||
| }; | }; | ||||
| const getCompletionRate = (session: AllPickedStockTakeListReponse): number => { | |||||
| if (session.totalInventoryLotNumber === 0) return 0; | |||||
| return Math.round((session.currentStockTakeItemNumber / session.totalInventoryLotNumber) * 100); | |||||
| }; | |||||
| const planStartDate = globalRoundPlanStartDate; | const planStartDate = globalRoundPlanStartDate; | ||||
| const closeCreateDialog = () => { | const closeCreateDialog = () => { | ||||
| setOpenConfirmDialog(false); | setOpenConfirmDialog(false); | ||||
| @@ -1732,16 +1714,14 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ | |||||
| ) : ( | ) : ( | ||||
| <Grid container spacing={2}> | <Grid container spacing={2}> | ||||
| {stockTakeSessions.map((session: AllPickedStockTakeListReponse) => { | {stockTakeSessions.map((session: AllPickedStockTakeListReponse) => { | ||||
| const statusColor = getStatusColor(session.status || ""); | |||||
| const lastStockTakeDate = session.lastStockTakeDate | const lastStockTakeDate = session.lastStockTakeDate | ||||
| ? dayjs(session.lastStockTakeDate).format(OUTPUT_DATE_FORMAT) | ? dayjs(session.lastStockTakeDate).format(OUTPUT_DATE_FORMAT) | ||||
| : "-"; | : "-"; | ||||
| const completionRate = getCompletionRate(session); | |||||
| const sectionMeta = [ | const sectionMeta = [ | ||||
| session.stockTakeSectionDescription, | session.stockTakeSectionDescription, | ||||
| session.warehouseArea, | session.warehouseArea, | ||||
| session.storeId, | session.storeId, | ||||
| ].filter((v): v is string => Boolean(v && v.trim())).join(" / "); | |||||
| ].filter((v): v is string => Boolean(v && v.trim())).join(" · "); | |||||
| return ( | return ( | ||||
| <Grid key={session.id} item xs={12} md={6}> | <Grid key={session.id} item xs={12} md={6}> | ||||
| @@ -1751,7 +1731,7 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ | |||||
| display: "flex", | display: "flex", | ||||
| flexDirection: "column", | flexDirection: "column", | ||||
| border: "1px solid", | border: "1px solid", | ||||
| borderColor: statusColor === "success" ? "success.main" : "primary.main", | |||||
| borderColor: "divider", | |||||
| }} | }} | ||||
| > | > | ||||
| <CardContent sx={{ pb: 1, flexGrow: 1 }}> | <CardContent sx={{ pb: 1, flexGrow: 1 }}> | ||||
| @@ -1792,7 +1772,8 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ | |||||
| {t("View Details")} | {t("View Details")} | ||||
| </Button> | </Button> | ||||
| <Button | <Button | ||||
| variant="contained" | |||||
| variant="outlined" | |||||
| color="inherit" | |||||
| sx={{ minHeight: 48, px: 2 }} | sx={{ minHeight: 48, px: 2 }} | ||||
| onClick={() => onReStockTakeClick(session)} | onClick={() => onReStockTakeClick(session)} | ||||
| disabled={!session.reStockTakeTrueFalse} | disabled={!session.reStockTakeTrueFalse} | ||||
| @@ -1802,9 +1783,14 @@ const PickerCardList: React.FC<PickerCardListProps> = ({ | |||||
| </Stack> | </Stack> | ||||
| <Stack direction="row" spacing={0.5} flexWrap="wrap" justifyContent="flex-end"> | <Stack direction="row" spacing={0.5} flexWrap="wrap" justifyContent="flex-end"> | ||||
| {session.reStockTakeTrueFalse ? ( | {session.reStockTakeTrueFalse ? ( | ||||
| <Chip size="small" label={t("notMatch")} color="warning" /> | |||||
| <Chip size="small" variant="outlined" color="warning" label={t("notMatch")} /> | |||||
| ) : null} | ) : null} | ||||
| <Chip size="small" label={t(session.status || "")} color={statusColor as any} /> | |||||
| <Chip | |||||
| size="small" | |||||
| variant="outlined" | |||||
| color={statusChipColor(session.status || "")} | |||||
| label={t(session.status || "")} | |||||
| /> | |||||
| </Stack> | </Stack> | ||||
| </CardActions> | </CardActions> | ||||
| </Card> | </Card> | ||||
| @@ -11,6 +11,7 @@ import { | |||||
| CardContent, | CardContent, | ||||
| Chip, | Chip, | ||||
| CircularProgress, | CircularProgress, | ||||
| LinearProgress, | |||||
| Dialog, | Dialog, | ||||
| DialogActions, | DialogActions, | ||||
| DialogContent, | DialogContent, | ||||
| @@ -205,13 +206,32 @@ const StockTakeRoundCardList: React.FC<StockTakeRoundCardListProps> = ({ | |||||
| return `${t("Stock Take Round")} #${card.stockTakeRoundId}`; | return `${t("Stock Take Round")} #${card.stockTakeRoundId}`; | ||||
| }; | }; | ||||
| const statusColor = (status: string) => { | |||||
| const s = (status || "").toLowerCase().replace(/_/g, ""); | |||||
| if (s === "completed") return "success"; | |||||
| if (s === "approving") return "info"; | |||||
| if (s === "stocktaking" || s === "processing") return "primary"; | |||||
| if (s === "pending") return "warning"; | |||||
| return "default"; | |||||
| const progressRow = (label: string, done: number, total: number, barColor: "primary.main" | "success.main") => { | |||||
| const pct = total > 0 ? Math.min(100, (done / total) * 100) : 0; | |||||
| return ( | |||||
| <Box> | |||||
| <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 1 }}> | |||||
| <Typography variant="caption" color="text.secondary"> | |||||
| {label} | |||||
| </Typography> | |||||
| <Typography variant="body2" fontWeight={600} sx={{ fontVariantNumeric: "tabular-nums" }}> | |||||
| {t("Count of total", { done, total })} | |||||
| </Typography> | |||||
| </Box> | |||||
| <LinearProgress | |||||
| variant="determinate" | |||||
| value={pct} | |||||
| aria-label={`${label} ${t("Count of total", { done, total })}`} | |||||
| sx={{ | |||||
| mt: 0.4, | |||||
| height: 4, | |||||
| borderRadius: 99, | |||||
| bgcolor: "action.hover", | |||||
| "& .MuiLinearProgress-bar": { borderRadius: 99, bgcolor: barColor }, | |||||
| }} | |||||
| /> | |||||
| </Box> | |||||
| ); | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| @@ -309,9 +329,8 @@ const StockTakeRoundCardList: React.FC<StockTakeRoundCardListProps> = ({ | |||||
| const total = isItemRound ? (card.totalInventoryLotNumber || 0) : (card.sectionCount || 0); | const total = isItemRound ? (card.totalInventoryLotNumber || 0) : (card.sectionCount || 0); | ||||
| const taken = card.stockTakenCount || 0; | const taken = card.stockTakenCount || 0; | ||||
| const approved = card.approvedCount || 0; | const approved = card.approvedCount || 0; | ||||
| const progressLegend = isItemRound | |||||
| ? t("Round progress legend lots") | |||||
| : t("Round progress legend"); | |||||
| const floor = card.mainFloor?.trim(); | |||||
| const modeLabel = isItemRound ? t("Create by item") : t("Create by section"); | |||||
| return ( | return ( | ||||
| <Grid key={card.stockTakeRoundId} item xs={12} sm={6} md={4}> | <Grid key={card.stockTakeRoundId} item xs={12} sm={6} md={4}> | ||||
| <Card | <Card | ||||
| @@ -320,64 +339,54 @@ const StockTakeRoundCardList: React.FC<StockTakeRoundCardListProps> = ({ | |||||
| display: "flex", | display: "flex", | ||||
| flexDirection: "column", | flexDirection: "column", | ||||
| border: "1px solid", | border: "1px solid", | ||||
| borderColor: card.open ? "primary.main" : "success.main", | |||||
| borderColor: "divider", | |||||
| }} | }} | ||||
| > | > | ||||
| <CardContent sx={{ pb: 1, flexGrow: 1 }}> | <CardContent sx={{ pb: 1, flexGrow: 1 }}> | ||||
| <Stack direction="row" spacing={1} alignItems="center" sx={{ mb: 0.5 }}> | |||||
| <Typography variant="subtitle1" fontWeight={600}> | |||||
| {roundLabel(card)} | |||||
| </Typography> | |||||
| {card.stockTakeRoundMode === "item" ? ( | |||||
| <Chip size="small" label={t("Create by item")} color="info" /> | |||||
| ) : null} | |||||
| <Stack direction="row" spacing={1} alignItems="flex-start" justifyContent="space-between"> | |||||
| <Box sx={{ minWidth: 0 }}> | |||||
| <Typography variant="subtitle1" fontWeight={600} noWrap> | |||||
| {roundLabel(card)} | |||||
| </Typography> | |||||
| <Typography variant="body2" color="text.secondary"> | |||||
| {floor ? `${modeLabel} · ${floor}` : modeLabel} | |||||
| </Typography> | |||||
| </Box> | |||||
| <Chip | |||||
| size="small" | |||||
| variant="outlined" | |||||
| color={statusChipColor(card.status)} | |||||
| label={t(card.status || " ")} | |||||
| sx={{ flexShrink: 0 }} | |||||
| /> | |||||
| </Stack> | </Stack> | ||||
| <Typography variant="body2" color="text.secondary"> | |||||
| <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}> | |||||
| {t("Plan Start Date")}:{" "} | {t("Plan Start Date")}:{" "} | ||||
| {card.planStartDate ? dayjs(card.planStartDate).format(OUTPUT_DATE_FORMAT) : "-"} | {card.planStartDate ? dayjs(card.planStartDate).format(OUTPUT_DATE_FORMAT) : "-"} | ||||
| </Typography> | </Typography> | ||||
| <Typography variant="body2" color="text.secondary"> | |||||
| {t("Main floor")}: {card.mainFloor?.trim() || "-"} | |||||
| <Typography variant="caption" color="text.secondary" sx={{ display: "block", mt: 1.5 }}> | |||||
| {isItemRound ? t("Round unit lots") : t("Round unit sections")} | |||||
| </Typography> | </Typography> | ||||
| <Stack spacing={0.25}> | |||||
| <Typography variant="body2" color="text.secondary" noWrap> | |||||
| {progressLegend} | |||||
| </Typography> | |||||
| <Typography | |||||
| fontWeight={700} | |||||
| sx={{ | |||||
| fontSize: "1.5rem", | |||||
| lineHeight: 1.2, | |||||
| fontVariantNumeric: "tabular-nums", | |||||
| letterSpacing: 0.5, | |||||
| }} | |||||
| > | |||||
| <Box component="span" sx={{ color: "primary.main" }}>{taken}</Box> | |||||
| <Box component="span" sx={{ color: "text.disabled", mx: 0.75 }}>/</Box> | |||||
| <Box component="span" sx={{ color: "success.main" }}>{approved}</Box> | |||||
| <Box component="span" sx={{ color: "text.disabled", mx: 0.75 }}>/</Box> | |||||
| <Box component="span" sx={{ color: "text.primary" }}>{total}</Box> | |||||
| </Typography> | |||||
| <Stack spacing={1} sx={{ mt: 0.5 }}> | |||||
| {progressRow(t("progressCounted"), taken, total, "primary.main")} | |||||
| {progressRow(t("progressApproved"), approved, total, "success.main")} | |||||
| </Stack> | </Stack> | ||||
| </CardContent> | </CardContent> | ||||
| <CardActions sx={{ pt: 0.5, justifyContent: "space-between", flexWrap: "wrap", gap: 1 }}> | |||||
| <Stack direction="row" spacing={1}> | |||||
| <Button size="small" variant="contained" onClick={() => onEnterRound(card, rounds)}> | |||||
| {t("View Details")} | |||||
| <CardActions sx={{ pt: 0.5, gap: 1 }}> | |||||
| <Button size="small" variant="contained" onClick={() => onEnterRound(card, rounds)}> | |||||
| {t("View Details")} | |||||
| </Button> | |||||
| {isAdmin && card.open ? ( | |||||
| <Button | |||||
| size="small" | |||||
| variant="outlined" | |||||
| color="warning" | |||||
| disabled={closingId === card.stockTakeRoundId} | |||||
| onClick={() => setPendingCloseCard(card)} | |||||
| > | |||||
| {closingId === card.stockTakeRoundId ? <CircularProgress size={16} /> : t("Close round")} | |||||
| </Button> | </Button> | ||||
| {isAdmin && card.open ? ( | |||||
| <Button | |||||
| size="small" | |||||
| variant="outlined" | |||||
| color="warning" | |||||
| disabled={closingId === card.stockTakeRoundId} | |||||
| onClick={() => setPendingCloseCard(card)} | |||||
| > | |||||
| {closingId === card.stockTakeRoundId ? <CircularProgress size={16} /> : t("Close round")} | |||||
| </Button> | |||||
| ) : null} | |||||
| </Stack> | |||||
| <Chip size="small" label={t(card.status || " ")} color={statusColor(card.status) as "success" | "info" | "primary" | "warning"} /> | |||||
| ) : null} | |||||
| </CardActions> | </CardActions> | ||||
| </Card> | </Card> | ||||
| </Grid> | </Grid> | ||||
| @@ -420,4 +429,16 @@ const StockTakeRoundCardList: React.FC<StockTakeRoundCardListProps> = ({ | |||||
| ); | ); | ||||
| }; | }; | ||||
| type StatusChipColor = "default" | "primary" | "secondary" | "error" | "info" | "success" | "warning"; | |||||
| export function statusChipColor(status: string): StatusChipColor { | |||||
| const s = (status || "").toLowerCase().replace(/_/g, ""); | |||||
| if (s === "completed") return "success"; | |||||
| if (s === "pending") return "warning"; | |||||
| if (s === "approving") return "info"; | |||||
| if (s === "stocktaking" || s === "processing" || s === "inprogress") return "primary"; | |||||
| if (s === "notmatch") return "warning"; | |||||
| return "default"; | |||||
| } | |||||
| export default StockTakeRoundCardList; | export default StockTakeRoundCardList; | ||||
| @@ -32,6 +32,11 @@ | |||||
| "Month suffix": "", | "Month suffix": "", | ||||
| "Next month": "Next month", | "Next month": "Next month", | ||||
| "Open rounds this month": "Open rounds", | "Open rounds this month": "Open rounds", | ||||
| "progressCounted": "Counted", | |||||
| "progressApproved": "Approved", | |||||
| "Count of total": "{{done}} of {{total}}", | |||||
| "Round unit sections": "Sections", | |||||
| "Round unit lots": "Lots", | |||||
| "Previous month": "Previous month", | "Previous month": "Previous month", | ||||
| "Round closed": "Round closed", | "Round closed": "Round closed", | ||||
| "Main floor": "Main floor", | "Main floor": "Main floor", | ||||
| @@ -59,7 +64,7 @@ | |||||
| "Confirm create stock take": "Confirm create stock take", | "Confirm create stock take": "Confirm create stock take", | ||||
| "Section create item overlap title": "These items are already in an open item stock-take round; this round will skip them", | "Section create item overlap title": "These items are already in an open item stock-take round; this round will skip them", | ||||
| "Section create item overlap line": "Item {{item}} is in round #{{round}}{{roundName}}; this round will not include it (section {{section}})", | "Section create item overlap line": "Item {{item}} is in round #{{round}}{{roundName}}; this round will not include it (section {{section}})", | ||||
| "Control Time": "Control Time", | |||||
| "Control Time": "Time spent", | |||||
| "Create by item": "By item", | "Create by item": "By item", | ||||
| "Create by section": "By section", | "Create by section": "By section", | ||||
| "Cannot create while both section and item rounds are open": "Cannot create a new round while both section and item rounds are open", | "Cannot create while both section and item rounds are open": "Cannot create a new round while both section and item rounds are open", | ||||
| @@ -77,7 +82,7 @@ | |||||
| "Total selected lots label": "Selected lots", | "Total selected lots label": "Selected lots", | ||||
| "items unit": "item(s)", | "items unit": "item(s)", | ||||
| "lots unit": "lot(s)", | "lots unit": "lot(s)", | ||||
| "Create Stock Take (Select Sections)": "Create stock take (select sections)", | |||||
| "Create Stock Take (Select Sections)": "Create stock take", | |||||
| "Created": "Created", | "Created": "Created", | ||||
| "Creation date": "Creation date", | "Creation date": "Creation date", | ||||
| "Damage": "Damage", | "Damage": "Damage", | ||||
| @@ -179,11 +184,11 @@ | |||||
| "Stock take round name": "Stock take round name", | "Stock take round name": "Stock take round name", | ||||
| "Stock take round name placeholder": "Optional, e.g. May full-site stock take", | "Stock take round name placeholder": "Optional, e.g. May full-site stock take", | ||||
| "Stock take sections in current list": "{{count}} stock take section(s) in current list", | "Stock take sections in current list": "{{count}} stock take section(s) in current list", | ||||
| "Store ID": "Store ID", | |||||
| "Store ID": "Floor", | |||||
| "Submit All Inputted": "Submit All Inputted", | "Submit All Inputted": "Submit All Inputted", | ||||
| "Total": "Total", | "Total": "Total", | ||||
| "Total Adjustments": "Total Adjustments", | "Total Adjustments": "Total Adjustments", | ||||
| "Total Item Kind Number": "Total Item Kind Number", | |||||
| "Total Item Kind Number": "Items", | |||||
| "Total Items": "Total Items", | "Total Items": "Total Items", | ||||
| "Total Lots": "Total Lots", | "Total Lots": "Total Lots", | ||||
| "Total Sections": "Total Sections", | "Total Sections": "Total Sections", | ||||
| @@ -196,7 +201,7 @@ | |||||
| "Variance filter inclusive only": "Within range", | "Variance filter inclusive only": "Within range", | ||||
| "Variance filter inclusive range hint": "Show rows with |variance %| ≤ {{value}}%", | "Variance filter inclusive range hint": "Show rows with |variance %| ≤ {{value}}%", | ||||
| "View Details": "View Details", | "View Details": "View Details", | ||||
| "View ReStockTake": "View ReStockTake", | |||||
| "View ReStockTake": "Re-count", | |||||
| "Warehouse": "Warehouse", | "Warehouse": "Warehouse", | ||||
| "Warehouse code": "Warehouse code", | "Warehouse code": "Warehouse code", | ||||
| "Warehouse Location": "Warehouse Location", | "Warehouse Location": "Warehouse Location", | ||||
| @@ -211,7 +216,7 @@ | |||||
| "book qty": "book qty", | "book qty": "book qty", | ||||
| "completed": "Completed", | "completed": "Completed", | ||||
| "do": "Delivery order", | "do": "Delivery order", | ||||
| "end time": "end time", | |||||
| "end time": "Finished", | |||||
| "jo": "Job order", | "jo": "Job order", | ||||
| "lot_issue": "Lot issue", | "lot_issue": "Lot issue", | ||||
| "material": "Material", | "material": "Material", | ||||
| @@ -224,7 +229,7 @@ | |||||
| "resolved": "Resolved", | "resolved": "Resolved", | ||||
| "sections unit": "area(s)", | "sections unit": "area(s)", | ||||
| "selected stock take qty": "selected stock take qty", | "selected stock take qty": "selected stock take qty", | ||||
| "start time": "start time", | |||||
| "start time": "Started", | |||||
| "Select floor first": "Select floor first", | "Select floor first": "Select floor first", | ||||
| "Select warehouse first": "Select warehouse first", | "Select warehouse first": "Select warehouse first", | ||||
| "Select area first": "Select area first", | "Select area first": "Select area first", | ||||
| @@ -15,6 +15,11 @@ | |||||
| "Month suffix": "月", | "Month suffix": "月", | ||||
| "Next month": "下一個月", | "Next month": "下一個月", | ||||
| "Open rounds this month": "進行中的輪次", | "Open rounds this month": "進行中的輪次", | ||||
| "progressCounted": "已點算", | |||||
| "progressApproved": "已審核", | |||||
| "Count of total": "{{done}}/{{total}}", | |||||
| "Round unit sections": "區域", | |||||
| "Round unit lots": "批號", | |||||
| "Previous month": "上一個月", | "Previous month": "上一個月", | ||||
| "Round closed": "已關閉此輪", | "Round closed": "已關閉此輪", | ||||
| "Main floor": "主要樓層", | "Main floor": "主要樓層", | ||||
| @@ -74,9 +79,9 @@ | |||||
| "Last Stock Take Date": "上次盤點日期", | "Last Stock Take Date": "上次盤點日期", | ||||
| "Stock Taker": "盤點員", | "Stock Taker": "盤點員", | ||||
| "Approver": "審核員", | "Approver": "審核員", | ||||
| "start time": "開始時間", | |||||
| "end time": "結束時間", | |||||
| "Control Time": "操作時間", | |||||
| "start time": "開始", | |||||
| "end time": "結束", | |||||
| "Control Time": "耗時", | |||||
| "Approver stock take record saved successfully": "審核員盤點記錄保存成功", | "Approver stock take record saved successfully": "審核員盤點記錄保存成功", | ||||
| "Stock take record status updated to not match": "盤點狀態更新為要求重點", | "Stock take record status updated to not match": "盤點狀態更新為要求重點", | ||||
| "Batch approver save completed: {{success}} success, {{errors}} errors": "批次審核儲存完成:成功 {{success}} 筆,錯誤 {{errors}} 筆", | "Batch approver save completed: {{success}} success, {{errors}} errors": "批次審核儲存完成:成功 {{success}} 筆,錯誤 {{errors}} 筆", | ||||
| @@ -158,9 +163,9 @@ | |||||
| "Total selected lots label": "已選批號", | "Total selected lots label": "已選批號", | ||||
| "items unit": "項", | "items unit": "項", | ||||
| "lots unit": "筆", | "lots unit": "筆", | ||||
| "Create Stock Take (Select Sections)": "建立盤點(選擇區域)", | |||||
| "Total Item Kind Number": "貨品種類數量", | |||||
| "View ReStockTake": "查看重新盤點", | |||||
| "Create Stock Take (Select Sections)": "建立盤點", | |||||
| "Total Item Kind Number": "貨品種類", | |||||
| "View ReStockTake": "重新盤點", | |||||
| "Warehouse missing stock take section tooltip has": "有 {{count}} 個倉庫未設定盤點區域,點擊查看", | "Warehouse missing stock take section tooltip has": "有 {{count}} 個倉庫未設定盤點區域,點擊查看", | ||||
| "Warehouse missing stock take section tooltip none": "所有倉庫均已設定盤點區域", | "Warehouse missing stock take section tooltip none": "所有倉庫均已設定盤點區域", | ||||
| "Warehouse missing stock take section warn title": "未設定盤點區域的倉庫", | "Warehouse missing stock take section warn title": "未設定盤點區域的倉庫", | ||||