Browse Source

update

master
CANCERYS\kw093 3 weeks ago
parent
commit
39e9fc4fe3
17 changed files with 425 additions and 66 deletions
  1. +1
    -1
      src/app/(main)/jo/page.tsx
  2. +1
    -1
      src/app/(main)/po/page.tsx
  3. +8
    -1
      src/components/JoSave/JoSave.tsx
  4. +17
    -1
      src/components/Jodetail/JodetailSearch.tsx
  5. +140
    -38
      src/components/Jodetail/completeJobOrderRecord.tsx
  6. +1
    -1
      src/components/PoDetail/PoDetail.tsx
  7. +1
    -1
      src/components/PoDetail/PoInputGrid.tsx
  8. +2
    -2
      src/components/PoDetail/QCDatagrid.tsx
  9. +1
    -1
      src/components/PoSearch/PoSearch.tsx
  10. +19
    -2
      src/components/ProductionProcess/ProductionProcessDetail.tsx
  11. +15
    -4
      src/components/ProductionProcess/ProductionProcessJobOrderDetail.tsx
  12. +2
    -0
      src/components/ProductionProcess/ProductionProcessStepExecution.tsx
  13. +14
    -7
      src/i18n/zh/common.json
  14. +1
    -0
      src/i18n/zh/dashboard.json
  15. +2
    -1
      src/i18n/zh/home.json
  16. +197
    -4
      src/i18n/zh/jo.json
  17. +3
    -1
      src/i18n/zh/purchaseOrder.json

+ 1
- 1
src/app/(main)/jo/page.tsx View File

@@ -26,7 +26,7 @@ const jo: React.FC = async () => {
{t("Job Order")}
</Typography>
</Stack>
<I18nProvider namespaces={["jo", "common", "purchaseOrder", "dashboard"]}> {/* TODO: Improve */}
<I18nProvider namespaces={["jo", "common", "purchaseOrder", "dashboard","common"]}> {/* TODO: Improve */}
<Suspense fallback={<JoSearch.Loading />}>
<JoSearch />
</Suspense>


+ 1
- 1
src/app/(main)/po/page.tsx View File

@@ -17,7 +17,7 @@ const PurchaseOrder: React.FC = async () => {
// preloadClaims();
return (
<>
<I18nProvider namespaces={["purchaseOrder", "common", "items"]}>
<I18nProvider namespaces={["purchaseOrder", "common", "items","dashboard"]}>
<Stack
direction="row"
justifyContent="space-between"


+ 8
- 1
src/components/JoSave/JoSave.tsx View File

@@ -16,7 +16,7 @@ import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerP
import { fetchStockInLineInfo } from "@/app/api/po/actions";
import JoRelease from "./JoRelease";
import { submitDialog } from "../Swal/CustomAlerts";
import ProductionProcessJobOrderDetail from "../ProductionProcess/ProductionProcessJobOrderDetail";
type Props = {
id?: number;
defaultValues: Partial<JoDetail> | undefined;
@@ -192,10 +192,16 @@ const JoSave: React.FC<Props> = ({
{serverError}
</Typography>
)}
{/*
<ActionButtons handleRelease={handleRelease} handleStart={handleStart}/>
<InfoCard />
<JoRelease pickLines={pickLines} handleRelease={handleRelease}/>
<PickTable />
*/}
{id ? (
<ProductionProcessJobOrderDetail jobOrderId={id} onBack={handleBack} fromJosave={true}/>
) : null}
{/*
<Stack direction="row" justifyContent="flex-end" gap={1}>
<Button
variant="outlined"
@@ -205,6 +211,7 @@ const JoSave: React.FC<Props> = ({
{t("Back")}
</Button>
</Stack>
*/}
</Stack>
</FormProvider>
</>


+ 17
- 1
src/components/Jodetail/JodetailSearch.tsx View File

@@ -33,6 +33,8 @@ import {
fetchCompletedJobOrderPickOrders,
fetchCompletedJobOrderPickOrderRecords
} from "@/app/api/jo/actions";
import { fetchPrinterCombo } from "@/app/api/settings/printer";
import { PrinterCombo } from "@/app/api/settings/printer";
interface Props {
pickOrders: PickOrderResult[];
}
@@ -63,6 +65,7 @@ const [hasAssignedJobOrders, setHasAssignedJobOrders] = useState(false);
const [hasDataTab0, setHasDataTab0] = useState(false);
const [hasDataTab1, setHasDataTab1] = useState(false);
const hasAnyAssignedData = hasDataTab0 || hasDataTab1;
const [printers, setPrinters] = useState<PrinterCombo[]>([]);
const [hideCompletedUntilNext, setHideCompletedUntilNext] = useState<boolean>(
typeof window !== 'undefined' && localStorage.getItem('hideCompletedUntilNext') === 'true'
);
@@ -92,6 +95,19 @@ const hasAnyAssignedData = hasDataTab0 || hasDataTab1;
window.removeEventListener('jobOrderDataStatus', handleJobOrderDataChange as EventListener);
};
}, []);
useEffect(() => {
const fetchPrinters = async () => {
try {
// 需要创建一个客户端版本的 fetchPrinterCombo
// 或者使用 API 路由
// const printersData = await fetch('/api/printers/combo').then(r => r.json());
// setPrinters(printersData);
} catch (error) {
console.error("Error fetching printers:", error);
}
};
fetchPrinters();
}, []);
useEffect(() => {
const onAssigned = () => {
localStorage.removeItem('hideCompletedUntilNext');
@@ -466,7 +482,7 @@ const hasAnyAssignedData = hasDataTab0 || hasDataTab1;
p: 2
}}>
{tabIndex === 0 && <JobPickExecution filterArgs={filterArgs} />}
{tabIndex === 1 && <CompleteJobOrderRecord filterArgs={filterArgs} />}
{tabIndex === 1 && <CompleteJobOrderRecord filterArgs={filterArgs} printerCombo={printers} />}
{tabIndex === 2 && <JobPickExecutionsecondscan filterArgs={filterArgs} />}
{/* {tabIndex === 3 && <FInishedJobOrderRecord filterArgs={filterArgs} />} */}
</Box>


+ 140
- 38
src/components/Jodetail/completeJobOrderRecord.tsx View File

@@ -25,6 +25,7 @@ import {
AccordionSummary,
AccordionDetails,
Checkbox,
Autocomplete,
} from "@mui/material";
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { useCallback, useEffect, useState, useRef, useMemo } from "react";
@@ -44,9 +45,10 @@ import SearchBox, { Criterion } from "../SearchBox";
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import Swal from "sweetalert2";
import { PrinterCombo } from "@/app/api/settings/printer";
interface Props {
filterArgs: Record<string, any>;
printerCombo: PrinterCombo[];
}

// 修改:已完成的 Job Order Pick Order 接口
@@ -99,7 +101,7 @@ interface LotDetail {
uomDesc: string;
}

const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs }) => {
const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs ,printerCombo=[]}) => {
const { t } = useTranslation("jo");
const router = useRouter();
const { data: session } = useSession() as { data: SessionWithTokens | null };
@@ -119,7 +121,24 @@ const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs }) => {
// 修改:搜索状态
const [searchQuery, setSearchQuery] = useState<Record<string, any>>({});
const [filteredJobOrderPickOrders, setFilteredJobOrderPickOrders] = useState<CompletedJobOrderPickOrder[]>([]);
//const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]);
const defaultDemoPrinter: PrinterCombo = {
id: 2,
value: 2,
name: "2fi",
label: "2fi",
code: "2fi"
};
const availablePrinters = useMemo(() => {
if (printerCombo.length === 0) {
return [defaultDemoPrinter];
}
return printerCombo;
}, [printerCombo]);
const [selectedPrinter, setSelectedPrinter] = useState<PrinterCombo | null>(
printerCombo && printerCombo.length > 0 ? printerCombo[0] : null
);
const [printQty, setPrintQty] = useState<number>(1);
// 修改:分页状态
const [paginationController, setPaginationController] = useState({
pageNum: 0,
@@ -297,44 +316,84 @@ const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs }) => {
}));
}, []);

const handlePickRecord = useCallback(async () =>{
try{
if (!selectedJobOrderPickOrder) {
const handlePickRecord = useCallback(async (jobOrderPickOrder: CompletedJobOrderPickOrder) => {
try {
if (!jobOrderPickOrder) {
console.error("No selected job order pick order available");
return;
}
const pickOrderId = selectedJobOrderPickOrder.pickOrderId;
console.log("Pick Order ID:", pickOrderId);

const printRequest = {
pickOrderId: pickOrderId,
printerId: 2,
printQty: 1
};
// 检查是否已选择打印机
if (!selectedPrinter) {
Swal.fire({
position: "bottom-end",
icon: "warning",
text: t("Please select a printer first"),
showConfirmButton: false,
timer: 1500
});
return;
}

// 检查打印数量是否有效
if (!printQty || printQty < 1) {
Swal.fire({
position: "bottom-end",
icon: "warning",
text: t("Please enter a valid print quantity (at least 1)"),
showConfirmButton: false,
timer: 1500
});
return;
}

const pickOrderId = jobOrderPickOrder.pickOrderId;
console.log("Pick Order ID:", pickOrderId);

console.log("Printing Pick Record with request: ", printRequest);
// 使用已选择的打印机和数量
const printerId = selectedPrinter.id;

const response = await PrintPickRecord(printRequest)
const printRequest = {
pickOrderId: pickOrderId,
printerId: printerId,
printQty: printQty
};

console.log("Print Pick Record response: ", response);
console.log("Printing Pick Record with request: ", printRequest);

if(response.success){
Swal.fire({
const response = await PrintPickRecord(printRequest);

console.log("Print Pick Record response: ", response);

if (response.success) {
Swal.fire({
position: "bottom-end",
icon: "success",
text: t("Printed Successfully."),
showConfirmButton: false,
timer: 1500
});
} else {
console.error("Print failed: ", response.message);
Swal.fire({
position: "bottom-end",
icon: "error",
text: response.message || t("Print failed"),
showConfirmButton: false,
timer: 1500
});
}
} catch (error) {
console.error("error: ", error);
Swal.fire({
position: "bottom-end",
icon: "error",
text: t("An error occurred while printing"),
showConfirmButton: false,
timer: 1500
});
} else {
console.error("Print failed: ", response.message);
}
}catch(error){
console.error("error: ", error)
}

},[t, selectedJobOrderPickOrder]);

}, [t, selectedPrinter, printQty]);
// 修改:如果显示详情视图,渲染 Job Order 详情和 Lot 信息
if (showDetailView && selectedJobOrderPickOrder) {
return (
@@ -373,16 +432,18 @@ const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs }) => {
<strong>{t("Required Qty")}:</strong> {selectedJobOrderPickOrder.reqQty} {selectedJobOrderPickOrder.uom}
</Typography>
</Stack>
{/*
<Stack direction="row" spacing={4} useFlexGap flexWrap="wrap" sx={{ mt: 2 }}>
<Button
variant="contained"
color="primary"
onClick={handlePickRecord}
onClick={() => handlePickRecord(selectedJobOrderPickOrder)}
sx={{ mt: 1 }}
>
{t("Print Pick Record")}
</Button>
</Stack>
*/}
</CardContent>
</Card>

@@ -538,26 +599,56 @@ const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs }) => {
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
{t("Total")}: {filteredJobOrderPickOrders.length} {t("completed Job Order pick orders with matching")}
</Typography>

<Box sx={{ mb: 2, p: 2, border: '1px solid #e0e0e0', borderRadius: 1, bgcolor: 'background.paper' }}>
<Stack direction="row" spacing={2} alignItems="center" flexWrap="wrap">
<Typography variant="subtitle1" sx={{ minWidth: 'fit-content' }}>
{t("Select Printer")}:
</Typography>
<Autocomplete
options={availablePrinters}
getOptionLabel={(option) => option.name || option.label || option.code || `Printer ${option.id}`}
value={selectedPrinter}
onChange={(_, newValue) => setSelectedPrinter(newValue)}
sx={{ minWidth: 250 }}
size="small"
renderInput={(params) => <TextField {...params} label={t("Printer")} />}
/>
<Typography variant="subtitle1" sx={{ minWidth: 'fit-content' }}>
{t("Print Quantity")}:
</Typography>
<TextField
type="number"
label={t("Print Quantity")}
value={printQty}
onChange={(e) => {
const value = parseInt(e.target.value) || 1;
setPrintQty(Math.max(1, value));
}}
inputProps={{ min: 1, step: 1 }}
sx={{ width: 120 }}
size="small"
/>
</Stack>
</Box>
{/* 列表 */}
{filteredJobOrderPickOrders.length === 0 ? (
<Box sx={{ p: 3, textAlign: 'center' }}>
<Typography variant="body2" color="text.secondary">
{t("No completed Job Order pick orders with matching found")}
</Typography>
</Box>
) : (
<Stack spacing={2}>
{paginatedData.map((jobOrderPickOrder) => (
<Box sx={{ p: 3, textAlign: 'center' }}>
<Typography variant="body2" color="text.secondary">
{t("No completed Job Order pick orders with matching found")}
</Typography>
</Box>
) : (
<Stack spacing={2}>
{paginatedData.map((jobOrderPickOrder) => (
<Card key={jobOrderPickOrder.id}>
<CardContent>
<Stack direction="row" justifyContent="space-between" alignItems="center">
<Box>
<Typography variant="h6">
{jobOrderPickOrder.pickOrderCode}
{jobOrderPickOrder.jobOrderCode}
</Typography>
<Typography variant="body2" color="text.secondary">
{jobOrderPickOrder.jobOrderName} - {jobOrderPickOrder.jobOrderCode}
{jobOrderPickOrder.jobOrderName} - {jobOrderPickOrder.pickOrderCode}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("Completed")}: {new Date(jobOrderPickOrder.completedDate).toLocaleString()}
@@ -566,6 +657,7 @@ const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs }) => {
{t("Target Date")}: {jobOrderPickOrder.pickOrderTargetDate}
</Typography>
</Box>
<Box>
<Chip
label={t(jobOrderPickOrder.pickOrderStatus) }
@@ -592,6 +684,16 @@ const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs }) => {
>
{t("View Details")}
</Button>

<Button
variant="contained"
color="primary"
onClick={() => handlePickRecord(jobOrderPickOrder)}
sx={{ mt: 1 }}
>
{t("Print Pick Record")}
</Button>

</CardActions>
</Card>
))}


+ 1
- 1
src/components/PoDetail/PoDetail.tsx View File

@@ -101,7 +101,7 @@ const PoSearchList: React.FC<{
selectedPoId: number;
onSelect: (po: PoResult) => void;
}> = ({ poList, selectedPoId, onSelect }) => {
const { t } = useTranslation("purchaseOrder");
const { t } = useTranslation(["purchaseOrder", "dashboard"]);
const [searchTerm, setSearchTerm] = useState('');

const filteredPoList = useMemo(() => {


+ 1
- 1
src/components/PoDetail/PoInputGrid.tsx View File

@@ -963,7 +963,7 @@ const closeNewModal = useCallback(() => {
);
}
const NoRowsOverlay: React.FC = () => {
const { t } = useTranslation("home");
const { t } = useTranslation("purchaseOrder");
return (
<Box
display="flex"


+ 2
- 2
src/components/PoDetail/QCDatagrid.tsx View File

@@ -112,7 +112,7 @@ function InputDataGrid<T, V, E>({
const {
t,
// i18n: { language },
} = useTranslation("purchaseOrder");
} = useTranslation(["purchaseOrder","dashboard"]);
const formKey = _formKey.toString();
const { setValue, getValues } = useFormContext();
const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
@@ -380,7 +380,7 @@ const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => {
return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>;
};
const NoRowsOverlay: React.FC = () => {
const { t } = useTranslation("home");
const { t } = useTranslation("purchaseOrder");
return (
<Box
display="flex"


+ 1
- 1
src/components/PoSearch/PoSearch.tsx View File

@@ -39,7 +39,7 @@ const PoSearch: React.FC<Props> = ({
const [selectAll, setSelectAll] = useState(false);
const [filteredPo, setFilteredPo] = useState<PoResult[]>(po);
const [filterArgs, setFilterArgs] = useState<Record<string, any>>({estimatedArrivalDate : dayjsToDateString(dayjs(), "input")});
const { t } = useTranslation("purchaseOrder");
const { t } = useTranslation(["purchaseOrder", "dashboard"]);
const router = useRouter();
const [pagingController, setPagingController] = useState(
defaultPagingController,


+ 19
- 2
src/components/ProductionProcess/ProductionProcessDetail.tsx View File

@@ -489,10 +489,25 @@ const ProductionProcessDetail: React.FC<ProductProcessDetailProps> = ({
<TableCell>{t("Description")}</TableCell>
<TableCell>{t("Equipment Type/Code")}</TableCell>
<TableCell>{t("Operator")}</TableCell>
{/*}
<TableCell>{t("Processing Time (mins)")}</TableCell>
<TableCell>{t("Setup Time (mins)")}</TableCell>
<TableCell>{t("Changeover Time (mins)")}</TableCell>
*/}

<TableCell>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
<Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
{t("Time Information(mins)")}
</Typography>
<Typography variant="caption" sx={{ color: 'text.secondary' }}>
{t("Processing Time")}-
</Typography>
<Typography variant="caption" sx={{ color: 'text.secondary' }}>
{t("Setup Time")} - {t("Changeover Time")}
</Typography>
</Box>
</TableCell>
<TableCell align="center">{t("Status")}</TableCell>
<TableCell align="center">{t("Action")}</TableCell>
</TableRow>
@@ -516,10 +531,12 @@ const ProductionProcessDetail: React.FC<ProductProcessDetailProps> = ({
<TableCell><Typography fontWeight={500}>{line.description || "-"}</Typography></TableCell>
<TableCell><Typography fontWeight={500}>{equipmentName}</Typography></TableCell>
<TableCell><Typography fontWeight={500}>{line.operatorName}</Typography></TableCell>
{/*
<TableCell><Typography fontWeight={500}>{line.durationInMinutes} </Typography></TableCell>
<TableCell><Typography fontWeight={500}>{line.prepTimeInMinutes} </Typography></TableCell>
<TableCell><Typography fontWeight={500}>{line.postProdTimeInMinutes} </Typography></TableCell>
*/}
<TableCell><Typography fontWeight={500}>{line.durationInMinutes} - {line.prepTimeInMinutes} - {line.postProdTimeInMinutes} </Typography></TableCell>
<TableCell align="center">
{isCompleted ? (
<Chip label={t("Completed")} color="success" size="small"


+ 15
- 4
src/components/ProductionProcess/ProductionProcessJobOrderDetail.tsx View File

@@ -46,11 +46,13 @@ interface JobOrderLine {
interface ProductProcessJobOrderDetailProps {
jobOrderId: number;
onBack: () => void;
fromJosave?: boolean;
}

const ProductionProcessJobOrderDetail: React.FC<ProductProcessJobOrderDetailProps> = ({
jobOrderId,
onBack,
fromJosave,
}) => {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
@@ -363,7 +365,7 @@ const handleRelease = useCallback(() => {
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
{t("Lines with insufficient stock: ")}<strong style={{ color: "red" }}>{stockCounts.insufficient}</strong>
</Typography>
{!fromJosave && (
<Button
variant="contained"
color="primary"
@@ -372,6 +374,7 @@ const handleRelease = useCallback(() => {
>
{t("Release")}
</Button>
)}
</Stack>
</CardContent>
</Card>
@@ -414,9 +417,15 @@ const handleRelease = useCallback(() => {
<Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable">
<Tab label={t("Job Order Info")} />
<Tab label={t("BoM Material")} />
<Tab label={t("Production Process")} />
<Tab label={t("Production Process Line Remark")} />
<Tab label={t("Matching Stock")} />
{!fromJosave && (
<Tab label={t("Production Process")} />
)}
{!fromJosave && (
<Tab label={t("Production Process Line Remark")} />
)}
{!fromJosave && (
<Tab label={t("Matching Stock")} />
)}
</Tabs>
</Box>

@@ -424,6 +433,7 @@ const handleRelease = useCallback(() => {
<Box sx={{ p: 2 }}>
{tabIndex === 0 && <InfoCardContent />}
{tabIndex === 1 && <PickTableContent />}
{tabIndex === 2 && (
<ProductionProcessDetail
jobOrderId={jobOrderId}
@@ -435,6 +445,7 @@ const handleRelease = useCallback(() => {
)}
{tabIndex === 3 && <ProductionProcessesLineRemarkTableContent />}
{tabIndex === 4 && <JobPickExecutionsecondscan filterArgs={{ jobOrderId: jobOrderId }} />}
</Box>
</Box>
);


+ 2
- 0
src/components/ProductionProcess/ProductionProcessStepExecution.tsx View File

@@ -347,6 +347,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
</Typography>

<Stack direction="row" spacing={2} justifyContent="center" sx={{ mt: 2 }}>
{/*
<Button
variant="contained"
color="error"
@@ -374,6 +375,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro
{t("Continue")}
</Button>
)}
*/}
<Button
sx={{ mt: 2, alignSelf: "flex-end" }}
variant="outlined"


+ 14
- 7
src/i18n/zh/common.json View File

@@ -25,9 +25,14 @@
"user": "用戶",
"User Group": "用戶群組",
"Items": "物料",
"Release": "放單",
"Demand Forecast Setting": "需求預測設定",
"Equipment Type/Code": "使用設備-編號",
"Equipment": "設備",
"Time Information(mins)": "時間信息(分鐘)",
"Processing Time": "生產時間",
"Setup Time": "生產前預備時間",
"Changeover Time": "生產後轉換時間",
"Warehouse": "倉庫",
"Supplier": "供應商",
"Purchase Order":"採購單",
@@ -127,9 +132,9 @@
"Date": "日期",
"Failed to submit scan data. Please try again.": "掃碼數據提交失敗. 請重試.",
"In Progress": "進行中",
"Is Dark": "是否黑暗",
"Is Dense": "是否密集",
"Is Float": "是否浮動",
"Is Dark": " 顔色深淺度",
"Is Dense": "濃淡",
"Is Float": "浮沉",
"Job Order Code": "工單編號",
"Operator": "操作員",
"Output Qty": "輸出數量",
@@ -152,7 +157,7 @@
"In_Progress": "進行中",
"inProgress": "進行中",
"Step Name": "步驟名稱",
"Step Name": "名稱",
"Stop QR Scan": "停止掃碼",
"Submit & Start": "提交並開始",
"Total Steps": "總步驟數",
@@ -161,7 +166,7 @@
"View": "查看",
"Back": "返回",
"BoM Material": "物料清單",
"Is Dark | Dense | Float": "是否黑暗 | 密集 | 浮動",
"Is Dark | Dense | Float": "顔色深淺度 | 濃淡 | 浮沉",
"Item Code": "物料編號",
"Item Name": "物料名稱",
"Job Order Info": "工單信息",
@@ -193,6 +198,8 @@
"Production Output Data": "生產輸出數據",
"Step Information": "步驟信息",
"Stop": "停止",
"Putaway Detail": "上架詳情"

"Putaway Detail": "上架詳情",
"Lines with sufficient stock: ": "足夠庫存:",
"Lines with insufficient stock: ": "庫存不足:",
"Total lines: ": "總數量:"
}

+ 1
- 0
src/i18n/zh/dashboard.json View File

@@ -7,6 +7,7 @@
"Warehouse temperature record": "倉庫溫度記錄",
"Warehouse type": "倉庫類型",
"Last 6 hours": "過去6小時",
"Add some entries!": "添加一些物料!",
"Last 24 hours": "過去24小時",
"Cold storage": "冷藏倉",
"Normal temperature storage": "常溫倉",


+ 2
- 1
src/i18n/zh/home.json View File

@@ -1,4 +1,5 @@
{
"Demand Qty": "需求數量"
"Demand Qty": "需求數量",
"Add some entries!": "添加一些物料!"
}

+ 197
- 4
src/i18n/zh/jo.json View File

@@ -1,6 +1,6 @@
{
"Job Order": "工單",
"Create Job Order": "建工單",
"Create Job Order": "建工單",
"Edit Job Order Detail": "工單詳情",
"Details": "細節",
"Actions": "操作",
@@ -11,7 +11,7 @@
"UoM": "銷售單位",
"Status": "工單狀態",
"Lot No.": "批號",
"Bom": "物料清單",
"Bom": "半成品/成品編號",
"Release": "放單",
"Pending": "待掃碼",
"Pending for pick": "待提料",
@@ -82,7 +82,11 @@
"Lot Availability": "批號可用性",
"Pick Order Id": "提料單編號",
"Pick Order Code": "提料單編號",
"Select a printer": "選擇打印機",
"Please select a printer": "請選擇打印機",
"Next": "下一步",
"Pick Order Conso Code": "提料單組合編號",
"Enter the number of cartons": "請輸入箱數",
"Pick Order Target Date": "提料單需求日期",
"Pick Order Status": "提料單狀態",
"Second Scan Status": "對料狀態",
@@ -244,7 +248,7 @@
"productionDate": "生產日期",
"warehouse": "倉庫",
"Add Record": "添加記錄",
"Add some entries!": "添加一些條目!",
"Add some entries!": "添加一些物料!",
"Clean Record": "清空記錄",
"Escalation History": "升級歷史",
"Escalation Info": "升級信息",
@@ -274,5 +278,194 @@
"Estimated Production Date": "預計生產日期及時間",
"Plan Start": "預計生產日期及時間",
"Plan Start From": "預計生產日期及時間",
"Plan Start To": "預計生產日期及時間至"
"Plan Start To": "預計生產日期及時間至",
"By-product": "副產品",
"Complete Step": "完成步驟",
"Defect": "缺陷",
"Output from Process": "流程輸出",
"Quantity": "數量",
"Scrap": "廢料",
"Unit": "單位",
"Back to List": "返回列表",
"Production Output Data Entry": "生產輸出數據輸入",
"Step": "步驟",
"Quality Check": "品質檢查",
"Action": "操作",
"Changeover Time (mins)": "生產後轉換時間(分鐘)",
"Completed": "完成",
"completed": "完成",
"Date": "日期",
"Failed to submit scan data. Please try again.": "掃碼數據提交失敗. 請重試.",
"In Progress": "進行中",
"Is Dark": " 顔色深淺度",
"Is Dense": "濃淡",
"Is Float": "浮沉",
"Job Order Code": "工單編號",
"Operator": "操作員",
"Output Qty": "輸出數量",
"Pending": "待處理",
"pending": "待處理",

"Please scan equipment code (optional if not required)": "請掃描設備編號(可選)",
"Please scan operator code": "請掃描操作員編號",
"Please scan operator code first": "請先掃描操作員編號",
"Processing Time (mins)": "步驟時間(分鐘)",
"Production Process Information": "生產流程信息",
"Production Process Steps": "生產流程步驟",
"Scan Operator & Equipment": "掃描操作員和設備",
"Seq": "序號",
"Setup Time (mins)": "生產前預備時間(分鐘)",
"Start": "開始",
"Start QR Scan": "開始掃碼",
"Status": "狀態",
"in_progress": "進行中",
"In_Progress": "進行中",
"inProgress": "進行中",
"Step Name": "名稱",
"Stop QR Scan": "停止掃碼",
"Submit & Start": "提交並開始",
"Total Steps": "總步驟數",
"Unknown": "",
"Validation failed. Please check operator and equipment.": "驗證失敗. 請檢查操作員和設備.",
"View": "查看",
"Back": "返回",
"BoM Material": "半成品/成品清單",
"Is Dark | Dense | Float": "顔色深淺度 | 濃淡 | 浮沉",
"Item Code": "物料編號",
"Item Name": "物料名稱",
"Enter the number of cartons: ": "請輸入箱數:",
"Number of cartons": "箱數",
"You need to enter a number": "您需要輸入一個數字",
"Number must be at least 1": "數字必須至少為1",
"Confirm": "確認",
"Cancel": "取消",
"Print Pick Record": "打印板頭紙",
"Printed Successfully.": "成功列印",
"Job Order Info": "工單信息",
"Matching Stock": "匹配庫存",
"No data found": "沒有找到資料",
"Print Quantity": "打印數量",
"Select Printer": "選擇打印機",
"Printer": "打印機",
"Enter print quantity": "請輸入打印數量",
"Production Priority": "生產優先級",
"Please select a printer first": "請先選擇打印機",
"Production Process": "工藝流程",
"Production Process Line Remark": "工藝明細",
"Remark": "明細",
"Req. Qty": "需求數量",
"Seq No": "序號",
"Seq No Remark": "序號明細",
"Stock Available": "庫存可用",
"Stock Status": "庫存狀態",
"Target Production Date": "目標生產日期",
"Description": "描述",

"id": "ID",
"Finished lines": "完成行",
"Invalid Stock In Line Id": "無效庫存行ID",
"Production date": "生產日期",
"Required Qty": "需求數量",
"Total processes": "總流程數",
"View Details": "查看詳情",
"view stockin": "查看入庫",
"Completed Step": "完成步驟",
"Continue": "繼續",
"Executing": "執行中",
"Order Complete": "訂單完成",
"Pause": "暫停",
"Production Output Data": "生產輸出數據",
"Step Information": "步驟信息",
"Stop": "停止",
"Putaway Detail": "上架詳情",
"Lines with sufficient stock: ": "足夠庫存:",
"Lines with insufficient stock: ": "庫存不足:",
"Total lines: ": "總數量:",
"Demand Forecast Setting": "需求預測設定",
"Equipment Type/Code": "使用設備-編號",
"Equipment": "設備",
"Time Information(mins)": "時間信息(分鐘)",
"Processing Time": "生產時間",
"Setup Time": "生產前預備時間",
"Changeover Time": "生產後轉換時間",
"Warehouse": "倉庫",
"Supplier": "供應商",
"Purchase Order":"採購單",
"Demand Forecast":"需求預測",
"Pick Order": "提料單",
"Deliver Order":"送貨訂單",
"Project":"專案",
"Product":"產品",
"Material":"材料",
"mat":"原料",
"consumables": "消耗品",
"non-consumables": "非消耗品",
"fg": "成品",
"sfg": "半成品",
"item": "貨品",
"FG":"成品",
"FG & Material Demand Forecast Detail":"成品及材料需求預測詳情",
"View item In-out And inventory Ledger":"查看物料出入庫及庫存日誌",
"Delivery Order":"送貨訂單",
"Detail Scheduling":"詳細排程",
"Customer":"客戶",
"qcItem":"品檢項目",
"QC Check Item":"QC品檢項目",
"QC Category":"QC品檢模板",
"qcCategory":"品檢模板",
"QC Check Template":"QC檢查模板",
"Mail":"郵件",
"Import Testing":"匯入測試",
"Overview": "總覽",
"Projects": "專案",
"Create Project": "新增專案",
"Task Template": "任務範本",
"Create Task Template": "新增任務範本",
"Qc Item": "QC 項目",
"FG Production Schedule": "FG 生產排程",
"Inventory": "庫存",
"scheduling":"排程",
"settings": "設定",
"items": "物料",
"edit":"編輯",
"Edit Equipment Type":"設備類型詳情",
"Edit Equipment":"設備詳情",
"equipmentType":"設備類型",
"Description":"描述",
"Details": "詳情",
"Equipment Type Details":"設備類型詳情",
"Save":"儲存",
"Cancel":"取消",
"Equipment Details":"設備詳情",
"Exclude Date":"排除日期",
"Finished Goods Name":"成品名稱",
"create": "新增",
"hr": "小時",
"hrs": "小時",
"min": "分鐘",
"mins": "分鐘",
"Job Order": "工單",
"Edit Job Order": "工單詳情",
"Production": "生產流程",
"Put Away": "上架",
"Put Away Scan": "上架掃碼",
"Finished Good Order": "成品出倉",
"finishedGood": "成品",
"Router": "執貨路線",
"Job Order Pickexcution": "工單提料",
"No data available": "沒有資料",
"Start Scan": "開始掃碼",
"Stop Scan": "停止掃碼",
"Scan Result": "掃碼結果",
"Expiry Date": "有效期",
"Pick Order Code": "提料單編號",
"Target Date": "需求日期",
"Lot Required Pick Qty": "批號需求數量",
"Job Order Match": "工單匹配",
"All Pick Order Lots": "所有提料單批號",
"Rows per page": "每頁行數",
"No data available": "沒有資料",
"jodetail": "工單細節",
"Sign out": "登出"
}

+ 3
- 1
src/i18n/zh/purchaseOrder.json View File

@@ -2,6 +2,8 @@
"Purchase Order": "採購訂單",
"Purchase Receipt": "處理採購來貨",
"Code": "編號",
"row per page": "每頁行數",
"Rows per page": "每頁行數",
"OrderDate": "下單日期",
"Order Date": "下單日期",
"Order Date To": "下單日期至",
@@ -63,7 +65,7 @@
"qty cannot be greater than remaining qty": "數量不能大於剩餘數量",
"acceptQty must not greater than": "揀收數量不能大於",
"Record pol": "記錄採購訂單",
"Add some entries!": "添加條目!",
"Add some entries!": "添加一些物料!",
"draft": "草稿",
"pending": "待處理",
"determine1": "上報1",


Loading…
Cancel
Save