Ver a proveniência

update qc

update escalation log table
master
kelvinsuen há 23 horas
ascendente
cometimento
2d11d5d536
13 ficheiros alterados com 141 adições e 87 eliminações
  1. +1
    -0
      src/app/api/escalation/index.ts
  2. +2
    -1
      src/app/api/po/actions.ts
  3. +2
    -1
      src/app/api/qc/index.ts
  4. +1
    -1
      src/app/api/user/actions.ts
  5. +16
    -2
      src/components/DashboardPage/escalation/EscalationLogTable.tsx
  6. +15
    -2
      src/components/PoDetail/EscalationComponent.tsx
  7. +1
    -3
      src/components/PoDetail/PoDetail.tsx
  8. +1
    -3
      src/components/PoDetail/PoDetailWrapper.tsx
  9. +0
    -4
      src/components/PoDetail/PoInputGrid.tsx
  10. +72
    -40
      src/components/PoDetail/QcComponent.tsx
  11. +17
    -24
      src/components/PoDetail/QcStockInModalVer2.tsx
  12. +10
    -5
      src/components/PoDetail/dummyQcTemplate.tsx
  13. +3
    -1
      src/i18n/zh/dashboard.json

+ 1
- 0
src/app/api/escalation/index.ts Ver ficheiro

@@ -7,6 +7,7 @@ import { cache } from "react";

export interface EscalationResult {
id: number;
submitter?: string;
handler?: string;
handlerDepartment?: string;
handlerName?: string;


+ 2
- 1
src/app/api/po/actions.ts Ver ficheiro

@@ -38,7 +38,8 @@ export interface StockInLineEntry {
}

export interface PurchaseQcResult{
id: number;
id?: number;
qcItemId: number;
qcPassed?: boolean;
failQty?: number;
remarks?: string;


+ 2
- 1
src/app/api/qc/index.ts Ver ficheiro

@@ -16,7 +16,8 @@ export interface QcItemWithChecks {
}

export interface QcData {
id: number,
id?: number,
qcItemId: number,
code: string,
name: string,
qcDescription: string,


+ 1
- 1
src/app/api/user/actions.ts Ver ficheiro

@@ -104,7 +104,7 @@ export const adminChangePassword = async (data: any) => {
};

export const fetchEscalationCombo = async () => {
return serverFetchJson<EscalationCombo>(`${BASE_API_URL}/user/escalation-combo`, {
return serverFetchJson<EscalationCombo[]>(`${BASE_API_URL}/user/escalation-combo`, {
next: { tags: ["escalationCombo"]}
})
};

+ 16
- 2
src/components/DashboardPage/escalation/EscalationLogTable.tsx Ver ficheiro

@@ -89,6 +89,13 @@ const EscalationLogTable: React.FC<Props> = ({

const columns_dashboard = useMemo<Column<EscalationResult>[]>(
() => [
{
name: "submitter",
label: t("escalateFrom"),
align: "left",
headerAlign: "left",
sx: { width: "15%", minWidth: 100 },
},
{
name: "poCode",
label: t("Po Code"),
@@ -138,6 +145,13 @@ const EscalationLogTable: React.FC<Props> = ({
const columns_qc = useMemo<Column<EscalationResult>[]>(
() => [
{
name: "submitter",
label: t("escalateFrom"),
align: "left",
headerAlign: "left",
sx: { width: "15%", minWidth: 100 },
},
{
name: "handler",
label: t("Responsible for handling colleagues"),
@@ -153,12 +167,12 @@ const EscalationLogTable: React.FC<Props> = ({
},
{
name: "recordDate",
label: t("escalated date"),
label: t("escalated datetime"),
align: "right",
headerAlign: "right",
sx: { width: "10%", minWidth: 100 },
renderCell: (params) => {
return arrayToDateString(params.recordDate);
return arrayToDateTimeString(params.recordDate);
}
},
{


+ 15
- 2
src/components/PoDetail/EscalationComponent.tsx Ver ficheiro

@@ -24,6 +24,7 @@ import { useTranslation } from 'react-i18next';
import { Controller, useFormContext } from 'react-hook-form';
import { EscalationInput, ModalFormInput } from '@/app/api/po/actions';
import { EscalationCombo } from "@/app/api/user";
import { fetchEscalationCombo } from "@/app/api/user/actions";
import { FireExtinguisher } from '@mui/icons-material';

interface NameOption {
@@ -41,14 +42,14 @@ interface Props {
forSupervisor: boolean
isCollapsed: boolean
setIsCollapsed: Dispatch<React.SetStateAction<boolean>>
escalationCombo: EscalationCombo[]
// escalationCombo: EscalationCombo[]
}

const EscalationComponent: React.FC<Props> = ({
forSupervisor,
isCollapsed,
setIsCollapsed,
escalationCombo
// escalationCombo
}) => {
const { t } = useTranslation("purchaseOrder");

@@ -58,6 +59,18 @@ const EscalationComponent: React.FC<Props> = ({
message: '',
});

const [escalationCombo, setEscalationCombo] = useState<EscalationCombo[]>([]);

useEffect(() => {
async function fetchData() {
if (escalationCombo.length < 1) {
const escCombo = await fetchEscalationCombo();
setEscalationCombo(escCombo);
}
}
fetchData();
}, [])

const nameOptions: NameOption[] = [
{ value: '', label: '請選擇姓名...' },
{ value: 'john', label: '張大明' },


+ 1
- 3
src/components/PoDetail/PoDetail.tsx Ver ficheiro

@@ -89,7 +89,6 @@ type Props = {
qc: QcItemWithChecks[];
warehouse: WarehouseResult[];
printerCombo: PrinterCombo[];
escalationCombo: EscalationCombo[];
};

type EntryError =
@@ -192,7 +191,7 @@ interface PolInputResult {
dnQty: number,
}

const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo, escalationCombo }) => {
const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo }) => {
const cameras = useContext(CameraContext);
// console.log(cameras);
const { t } = useTranslation("purchaseOrder");
@@ -865,7 +864,6 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo, escalation
fetchPoDetail={fetchPoDetail}
handleMailTemplateForStockInLine={handleMailTemplateForStockInLine}
printerCombo={printerCombo}
escalationCombo={escalationCombo}
/>
</Box>
</TableCell>


+ 1
- 3
src/components/PoDetail/PoDetailWrapper.tsx Ver ficheiro

@@ -27,17 +27,15 @@ const PoDetailWrapper: React.FC<Props> & SubComponents = async ({ id }) => {
warehouse,
qc,
printerCombo,
escalationCombo,
] = await Promise.all([
fetchPoWithStockInLines(id),
fetchWarehouseList(),
fetchQcItemCheck(),
fetchPrinterCombo(),
fetchEscalationCombo()
]);
// const poWithStockInLine = await fetchPoWithStockInLines(id)
console.log("%c pol:", "color:green", poWithStockInLine);
return <PoDetail po={poWithStockInLine} qc={qc} warehouse={warehouse} printerCombo={printerCombo} escalationCombo={escalationCombo}/>;
return <PoDetail po={poWithStockInLine} qc={qc} warehouse={warehouse} printerCombo={printerCombo} />;
};

PoDetailWrapper.Loading = PoDetailLoading;


+ 0
- 4
src/components/PoDetail/PoInputGrid.tsx Ver ficheiro

@@ -83,7 +83,6 @@ interface Props {
fetchPoDetail: (poId: string) => void;
handleMailTemplateForStockInLine: (stockInLineId: number) => void;
printerCombo: PrinterCombo[];
escalationCombo: EscalationCombo[];
}

export type StockInLineEntryError = {
@@ -125,7 +124,6 @@ function PoInputGrid({
fetchPoDetail,
handleMailTemplateForStockInLine,
printerCombo,
escalationCombo
}: Props) {

const { t } = useTranslation("purchaseOrder");
@@ -307,7 +305,6 @@ const closeNewModal = useCallback(() => {
const handleNewQC = useCallback(
(id: GridRowId, params: any) => async() => {
// console.log(id)
console.log("params", params.row)
// setBtnIsLoading(true);
setRowModesModel((prev) => ({
...prev,
@@ -955,7 +952,6 @@ const closeNewModal = useCallback(() => {
itemDetail={modalInfo}
handleMailTemplateForStockInLine={handleMailTemplateForStockInLine}
printerCombo={printerCombo}
escalationCombo={escalationCombo}
/>
</>
)


+ 72
- 40
src/components/PoDetail/QcComponent.tsx Ver ficheiro

@@ -60,9 +60,8 @@ import CollapsibleCard from "../CollapsibleCard/CollapsibleCard";

interface Props {
itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] };
qc: QcItemWithChecks[];
// qc: QcItemWithChecks[];
disabled: boolean;
escalationCombo: EscalationCombo[];
// qcItems: QcData[]
// setQcItems: Dispatch<SetStateAction<QcData[]>>
}
@@ -75,7 +74,7 @@ type EntryError =

type QcRow = TableRow<Partial<QcData>, EntryError>;
// fetchQcItemCheck
const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escalationCombo }) => {
const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => {
const { t } = useTranslation("purchaseOrder");
const apiRef = useGridApiRef();
const {
@@ -94,12 +93,16 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
const [tabIndex, setTabIndex] = useState(0);
const [rowSelectionModel, setRowSelectionModel] = useState<GridRowSelectionModel>();
const [escalationHistory, setEscalationHistory] = useState(dummyEscalationHistory);
// const [qcResult, setQcResult] = useState();
const qcAccept = watch("qcAccept");
const qcDecision = watch("qcDecision"); //WIP
// const qcResult = useMemo(() => [...watch("qcResult")], [watch("qcResult")]);
const qcResult = [...watch("qcResult")];

const qcRecord = useMemo(() => { // Need testing
const value = watch('qcResult'); console.log("%c QC update!", "color:green", value);
return Array.isArray(value) ? [...value] : [];
}, [watch('qcResult')]);
const [qcHistory, setQcHistory] = useState<PurchaseQcResult[]>([]);
const [qcResult, setQcResult] = useState<PurchaseQcResult[]>([]);

// const [qcAccept, setQcAccept] = useState(true);
// const [qcItems, setQcItems] = useState(dummyQCData)
@@ -118,12 +121,16 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
},
], []
)
const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
(_e, newValue) => {
setTabIndex(newValue);
},
[],
);
const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
(_e, newValue) => {
setTabIndex(newValue);
},
[],
);

const isExist = (data : string | number | undefined) => {
return (data !== null && data !== undefined);
}

// W I P //
const validateFieldFail = (field : FieldPath<PurchaseQCInput>, condition: boolean, message: string) : boolean => {
@@ -225,6 +232,10 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
return <Checkbox checked={!!value} onChange={handleChange} sx={{ p: 0 }} />;
}

const qcDisabled = (row : PurchaseQcResult) => {
return disabled || isExist(row.escalationLogId);
};

const qcColumns: GridColDef[] = useMemo(() => [
{
field: "code",
@@ -245,7 +256,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
flex: 1.5,
renderCell: (params) => {
const rowValue = params.row;
const index = params.api.getRowIndexRelativeToVisibleRows(params.id);
const index = Number(params.id);//params.api.getRowIndexRelativeToVisibleRows(params.id);
// console.log(rowValue.row);
return (
<FormControl>
@@ -267,7 +278,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
value="true"
control={<Radio />}
label="合格"
disabled={disabled || itemDetail.status == "escalated"}
disabled={qcDisabled(rowValue)}
sx={{
color: rowValue.qcPassed === true ? "green" : "inherit",
"& .Mui-checked": {color: "green"}
@@ -277,7 +288,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
value="false"
control={<Radio />}
label="不合格"
disabled={disabled || itemDetail.status == "escalated"}
disabled={qcDisabled(rowValue)}
sx={{
color: rowValue.qcPassed === false ? "red" : "inherit",
"& .Mui-checked": {color: "red"}
@@ -294,22 +305,27 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
flex: 1,
// editable: true,
renderCell: (params) => {
const index = params.api.getRowIndexRelativeToVisibleRows(params.id);
const index = Number(params.id);//params.api.getRowIndexRelativeToVisibleRows(params.id);
return (
<TextField
type="number"
size="small"
value={!params.row.qcPassed? params.value : '0'}
disabled={params.row.qcPassed || disabled || itemDetail.status == "escalated"}
onBlur={(e) => {
disabled={params.row.qcPassed || qcDisabled(params.row)}
/* TODO improve */
/* Reference: https://grok.com/share/c2hhcmQtNA%3D%3D_10787069-3eec-40af-a7cc-bacbdb86bf05 */
onChange={(e) => {
const v = e.target.value;
const next = v === '' ? undefined : Number(v);
if (Number.isNaN(next)) return;
// setQcItems((prev) =>
// prev.map((r) => (r.id === params.id ? { ...r, failQty: next } : r))
// );
setValue(`qcResult.${index}.failQty`, next);
}}
// onBlur={(e) => {
// const v = e.target.value;
// const next = v === '' ? undefined : Number(v);
// if (Number.isNaN(next)) return;
// setValue(`qcResult.${index}.failQty`, next);
// }}
onClick={(e) => e.stopPropagation()}
onMouseDown={(e) => e.stopPropagation()}
onKeyDown={(e) => e.stopPropagation()}
@@ -324,12 +340,12 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
headerName: t("remarks"),
flex: 2,
renderCell: (params) => {
const index = params.api.getRowIndexRelativeToVisibleRows(params.id);
const index = Number(params.id);//params.api.getRowIndexRelativeToVisibleRows(params.id);
return (
<TextField
size="small"
defaultValue={params.value}
disabled={disabled || itemDetail.status == "escalated"}
disabled={qcDisabled(params.row)}
onBlur={(e) => {
const value = e.target.value;
setValue(`qcResult.${index}.remarks`, value);
@@ -365,15 +381,31 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
}, [itemDetail?.demandQty, itemDetail?.acceptedQty, setValue]);

useEffect(() => {
// console.log("Qc Result updated:", qcResult);
if (qcResult.length < 1) { // New QC
const mutableQcData = dummyQCData;
// const mutableQcData = JSON.parse(JSON.stringify(dummyQCData));
// replace([mutableQcData]);
setValue("qcResult", mutableQcData);
// setValue("qcResult.0.qcPassed", false);
console.log("%c Qc Record updated:", "color:red", qcRecord);
if (qcRecord.length < 1) { // New QC
const fetchedQcData = dummyQCData; //TODO fetch from DB
setValue("qcResult", fetchedQcData);
} else {
if (itemDetail.status == "escalated") { // Copy the previous QC data for editing
if (qcRecord.find((qc) => !isExist(qc.escalationLogId)) === undefined) {
const copiedQcData = qcRecord.map(qc => ({ ...qc, escalationLogId: undefined }));
const mutableQcData = [...qcRecord, ...copiedQcData];
setValue("qcResult", mutableQcData);
}
}

if (qcRecord.length > 0) {
if (qcResult.length < 1) { // Set QC Result
const filteredQcResult = qcRecord.filter((qc) => !isExist(qc.escalationLogId));
setQcResult(filteredQcResult);
}
if (qcHistory.length < 1) { // Set QC History
const filteredQcHistory = qcRecord.filter((qc) => isExist(qc.escalationLogId));
setQcHistory(filteredQcHistory);
}
}
}
}, [qcResult, setValue])
}, [qcRecord, setValue])

// const [openCollapse, setOpenCollapse] = useState(false)
const [isCollapsed, setIsCollapsed] = useState<boolean>(true);
@@ -415,16 +447,16 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
}
}

useEffect(() => {
if (qcHistory.length < 1) {
setQcHistory(qcResult.filter((qc) => {qc.escalationLogId != null}));
console.log("QC History updated:", qcHistory);
}
}, [watch("qcResult")]);
// }, [watch("qcResult")]);
// useEffect(() => {
// // onFailedOpenCollapse(qcItems)
// }, [qcItems]);

const getRowId = (row :any) => {
return qcRecord.findIndex(qc => qc == row);
// return row.id || `${row.name}-${Math.random().toString(36).substr(2, 9)}`;
};

return (
<>
<Grid container justifyContent="flex-start" alignItems="flex-start">
@@ -475,6 +507,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
// rows={disabled? qcResult:qcItems}
autoHeight
sortModel={[]}
getRowId={getRowId}
/>
</Grid>
</>
@@ -497,7 +530,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
<CollapsibleCard title={t("QC Record")}>
<StyledDataGrid
columns={qcColumns}
rows={qcResult}
rows={qcHistory}
// rows={qcResult && qcResult.length > 0 ? qcResult : qcItems}
// rows={disabled? qcResult:qcItems}
autoHeight
@@ -536,8 +569,8 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
onChange={(e) => {
const value = e.target.value.toString();// === 'true';

const input = document.getElementById('accQty') as HTMLInputElement;
console.log("%c Error", "color:pink", errors.acceptQty);
const input = document.getElementById('accQty') as HTMLInputElement; //TODO improve
console.log("%c AccQty Error", "color:pink", errors.acceptQty);
if (input) { // Selected Reject in new flow with Error
if (value == "1") { // Selected Accept
input.value = Number(accQty).toString();
@@ -641,7 +674,6 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala
forSupervisor={false}
isCollapsed={isCollapsed}
setIsCollapsed={setIsCollapsed}
escalationCombo={escalationCombo}
/>
</Grid>)}
{/* {qcAccept && <Grid item xs={12}>


+ 17
- 24
src/components/PoDetail/QcStockInModalVer2.tsx Ver ficheiro

@@ -67,7 +67,6 @@ interface CommonProps extends Omit<ModalProps, "children"> {
// type: "qc" | "stockIn" | "escalation" | "putaway" | "reject";
handleMailTemplateForStockInLine: (stockInLineId: number) => void;
printerCombo: PrinterCombo[];
escalationCombo: EscalationCombo[];
onClose: () => void;
}
interface Props extends CommonProps {
@@ -87,7 +86,6 @@ const PoQcStockInModalVer2: React.FC<Props> = ({
warehouse,
handleMailTemplateForStockInLine,
printerCombo,
escalationCombo
}) => {
const {
t,
@@ -110,9 +108,10 @@ const defaultNewValue = useMemo(() => {
escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [],
productionDate: itemDetail.productionDate ? arrayToDateString(itemDetail.productionDate, "input") : undefined,
expiryDate: itemDetail.expiryDate ? arrayToDateString(itemDetail.expiryDate, "input") : undefined,
receiptDate: itemDetail.receiptDate ?? dayjs().add(0, "month").format(INPUT_DATE_FORMAT),
receiptDate: itemDetail.receiptDate ? arrayToDateString(itemDetail.receiptDate, "input")
: dayjs().add(0, "month").format(INPUT_DATE_FORMAT),
acceptQty: itemDetail.demandQty?? itemDetail.acceptedQty,
warehouseId: itemDetail.defaultWarehouseId ?? 1
warehouseId: itemDetail.defaultWarehouseId ?? 1,
}
)
},[itemDetail])
@@ -153,10 +152,6 @@ const [qcItems, setQcItems] = useState(dummyQCData)
}, [itemDetail]);

useEffect(() => {
const qcRes = itemDetail?.qcResult;
// if (!qcRes || qcRes?.length <= 0) {
// itemDetail.qcResult = dummyQCData;
// }
formProps.reset({
...defaultNewValue
})
@@ -220,7 +215,7 @@ const [qcItems, setQcItems] = useState(dummyQCData)
const qcAccept = data.qcDecision == 1;
// const qcAccept = data.qcAccept;
let acceptQty = Number(data.acceptQty);
const qcResults = data.qcResult || dummyQCData; // qcItems;
const qcResults = data.qcResult?.filter((qc) => qc.escalationLogId === undefined) || []; // Remove old QC data
// const qcResults = data.qcResult as PurchaseQcResult[]; // qcItems;
// const qcResults = viewOnly? data.qcResult as PurchaseQcResult[] : qcItems;
@@ -290,16 +285,17 @@ const [qcItems, setQcItems] = useState(dummyQCData)
qcAccept: qcAccept? qcAccept : false,
acceptQty: acceptQty? acceptQty : 0,
qcResult: itemDetail.status != "escalated" ? qcResults.map(item => ({
id: item.id,
qcItemId: item.id,
// qcResult: itemDetail.status != "escalated" ? qcResults.map(item => ({
qcResult: qcResults.map(item => ({
// id: item.id,
qcItemId: item.qcItemId,
// code: item.code,
// qcDescription: item.qcDescription,
qcPassed: item.qcPassed? item.qcPassed : false,
failQty: (item.failQty && !item.qcPassed) ? item.failQty : 0,
// failedQty: (typeof item.failedQty === "number" && !item.isPassed) ? item.failedQty : 0,
remarks: item.remarks || ''
})) : [],
remarks: item.remarks || '',
})),
};
// const qcData = data;

@@ -389,7 +385,7 @@ const [qcItems, setQcItems] = useState(dummyQCData)
status: data.status, //TODO Fix it!
// ...data,
dnDate : data.dnDate? arrayToDateString(data.dnDate) : dayjsToInputDateString(dayjs()),
dnDate : data.dnDate? arrayToDateString(data.dnDate, "input") : dayjsToInputDateString(dayjs()),
productionDate : arrayToDateString(data.productionDate, "input"),
expiryDate : arrayToDateString(data.expiryDate, "input"),
receiptDate : arrayToDateString(data.receiptDate, "input"),
@@ -406,8 +402,6 @@ const [qcItems, setQcItems] = useState(dummyQCData)
alert("請新增上架資料!");
return;
}
console.log(typeof data.putAwayLines!![0].qty + " = 'number'");
console.log(typeof data.putAwayLines!![0].qty !== "number");
if (data.putAwayLines!!.filter((line) => /[^0-9]/.test(String(line.qty))).length > 0) { //TODO Improve
alert("上架數量不正確!");
return;
@@ -471,11 +465,11 @@ const [qcItems, setQcItems] = useState(dummyQCData)
return isPassed
}, [acceptQty, formProps])

useEffect(() => {
// maybe check if submitted before
console.log("Modal QC Items updated:", qcItems);
// checkQcIsPassed(qcItems)
}, [qcItems, checkQcIsPassed])
// useEffect(() => {
// // maybe check if submitted before
// console.log("Modal QC Items updated:", qcItems);
// // checkQcIsPassed(qcItems)
// }, [qcItems, checkQcIsPassed])
return (
<>
@@ -576,10 +570,9 @@ const [qcItems, setQcItems] = useState(dummyQCData)
alignItems="flex-start"
>
<QcComponent
qc={qc!}
// qc={qc!}
itemDetail={itemDetail}
disabled={viewOnly}
escalationCombo={escalationCombo}
// qcItems={qcItems}
// setQcItems={setQcItems}
/>


+ 10
- 5
src/components/PoDetail/dummyQcTemplate.tsx Ver ficheiro

@@ -12,7 +12,8 @@ import { QcData } from "@/app/api/qc"

export const dummyQCData: QcData[] = [
{
id: 4,
id: 1,
qcItemId: 4,
code: "包裝",
qcDescription: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格",
name: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格",
@@ -21,7 +22,8 @@ export const dummyQCData: QcData[] = [
remarks: undefined,
},
{
id: 5,
id: 2,
qcItemId: 5,
code: "肉質",
qcDescription: "肉質鬆散,則不合格",
name: "肉質鬆散,則不合格",
@@ -30,7 +32,8 @@ export const dummyQCData: QcData[] = [
remarks: undefined,
},
{
id: 6,
id: 3,
qcItemId: 6,
code: "顔色",
qcDescription: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格",
name: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格",
@@ -39,7 +42,8 @@ export const dummyQCData: QcData[] = [
remarks: undefined,
},
{
id: 7,
id: 4,
qcItemId: 7,
code: "狀態",
qcDescription: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格",
name: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格",
@@ -48,7 +52,8 @@ export const dummyQCData: QcData[] = [
remarks: undefined,
},
{
id: 8,
id: 5,
qcItemId: 8,
code: "異物",
qcDescription: "有不屬於本食材的雜質,則不合格",
name: "有不屬於本食材的雜質,則不合格",


+ 3
- 1
src/i18n/zh/dashboard.json Ver ficheiro

@@ -34,6 +34,7 @@
"Pending application": "待處理提料申請",
"pending inspection material": "待品檢物料",
"rejected": "已拒絕",
"accepted": "已收貨",
"escalated": "已上報",
"inspected material": "已品檢物料",
"total material": "物料總數",
@@ -50,5 +51,6 @@
"QC Completed Count": "品檢完成數量",
"QC Fail-Total Count": "品檢不合格/總數",
"escalationStatus": "上報狀態",
"escalated datetime": "上報時間"
"escalated datetime": "上報時間",
"escalateFrom": "上報同事"
}

Carregando…
Cancelar
Guardar