diff --git a/src/app/api/do/actions.tsx b/src/app/api/do/actions.tsx index 03c64fb..4be8783 100644 --- a/src/app/api/do/actions.tsx +++ b/src/app/api/do/actions.tsx @@ -19,6 +19,7 @@ export interface DoDetail { code: string; supplierCode: string; shopCode: string; + shopName: string; currencyCode: string; orderDate: string; estimatedArrivalDate: string; diff --git a/src/components/DoDetail/DoInfoCard.tsx b/src/components/DoDetail/DoInfoCard.tsx index 1e2b23e..9da2846 100644 --- a/src/components/DoDetail/DoInfoCard.tsx +++ b/src/components/DoDetail/DoInfoCard.tsx @@ -41,8 +41,8 @@ const DoInfoCard: React.FC = ({ diff --git a/src/components/DoSearch/DoSearch.tsx b/src/components/DoSearch/DoSearch.tsx index 9b2ab7e..0a61b52 100644 --- a/src/components/DoSearch/DoSearch.tsx +++ b/src/components/DoSearch/DoSearch.tsx @@ -452,14 +452,14 @@ if(orderStartDate != ""){ alignItems="end" > - + */} {hasSearched && hasResults && ( - {errors.pickErr && ({t("Please make sure all required items are picked")})} + {/* {errors.pickErr && ({t("Please make sure all required items are picked")})} {errors.scanErr && ({t("Please scan the item qr code")})} - {errors.qtyErr && ({t("Please make sure the qty is enough")})} + {errors.qtyErr && ({t("Please make sure the qty is enough")})} */} )} diff --git a/src/components/JoSearch/JoSearch.tsx b/src/components/JoSearch/JoSearch.tsx index be7308b..6815a0a 100644 --- a/src/components/JoSearch/JoSearch.tsx +++ b/src/components/JoSearch/JoSearch.tsx @@ -28,7 +28,10 @@ interface Props { bomCombo: BomCombo[] } -type SearchQuery = Partial>; +type SearchQuery = Partial> & { + planStartFrom?: string; + planStartTo?: string; +}; type SearchParamNames = keyof SearchQuery; @@ -46,6 +49,8 @@ const JoSearch: React.FC = ({ defaultInputs, bomCombo }) => { const searchCriteria: Criterion[] = useMemo(() => [ { label: t("Code"), paramName: "code", type: "text" }, { label: t("Item Name"), paramName: "itemName", type: "text" }, + { label: t("Estimated Production Date From"), paramName: "planStartFrom", type: "date" }, + { label: t("Estimated Production Date To"), paramName: "planStartTo", type: "date" }, ], [t]) const columns = useMemo[]>( @@ -58,14 +63,14 @@ const JoSearch: React.FC = ({ defaultInputs, bomCombo }) => { name: "item", label: t("Item Code"), renderCell: (row) => { - return t(row.item.code) + return row.item ? t(row.item.code) : '-' } }, { name: "itemName", label: t("Item Name"), renderCell: (row) => { - return t(row.item.name) + return row.item ? t(row.item.name) : '-' } }, { @@ -83,14 +88,22 @@ const JoSearch: React.FC = ({ defaultInputs, bomCombo }) => { align: "left", headerAlign: "left", renderCell: (row) => { - return t(row.item.uom.udfudesc) + return row.item?.uom ? t(row.item.uom.udfudesc) : '-' } }, { name: "status", label: t("Status"), + renderCell: (row) => { // TODO improve + return + {t(upperFirst(row.status))} + + } + },{ + name: "planStart", + label: t("Estimated Production Date"), renderCell: (row) => { - return t(upperFirst(row.status)) + return row.planStart ? arrayToDateString(row.planStart, "output") : '-' } }, { @@ -195,7 +208,7 @@ const JoSearch: React.FC = ({ defaultInputs, bomCombo }) => { // case "storing": btnSx = {label: t("view putaway"), color:"secondary.main"}; break; case "storing": switch (silStatus) { - case "pending": btnSx = {label: t("process epqc"), color:"primary.main"}; break; + case "pending": btnSx = {label: t("process epqc"), color:"success.main"}; break; case "received": btnSx = {label: t("view putaway"), color:"secondary.main"}; break; case "escalated": if (sessionToken?.id == jo.silHandlerId) { @@ -225,6 +238,7 @@ const JoSearch: React.FC = ({ defaultInputs, bomCombo }) => { if (record.stockInLineId != null) { const data = { id: record.stockInLineId, + expiryDate: arrayToDateString(dayjs().add(1, "month"), "input"), } setModalInfo(data); setOpenModal(true); diff --git a/src/components/PoDetail/PutAwayForm.tsx b/src/components/PoDetail/PutAwayForm.tsx index 646d59a..64c2441 100644 --- a/src/components/PoDetail/PutAwayForm.tsx +++ b/src/components/PoDetail/PutAwayForm.tsx @@ -39,6 +39,7 @@ import { GridEditInputCell } from "@mui/x-data-grid"; import { StockInLine } from "@/app/api/stockIn"; import { WarehouseResult } from "@/app/api/warehouse"; import { + arrayToDateString, arrayToDateTimeString, OUTPUT_DATE_FORMAT, stockInLineStatusMap, @@ -382,11 +383,7 @@ const PutAwayForm: React.FC = ({ itemDetail, warehouse=[], disabled, setR diff --git a/src/components/PoDetail/QcComponent.tsx b/src/components/PoDetail/QcComponent.tsx index eb227a3..915ecc3 100644 --- a/src/components/PoDetail/QcComponent.tsx +++ b/src/components/PoDetail/QcComponent.tsx @@ -48,8 +48,10 @@ import { NEXT_PUBLIC_API_URL } from "@/config/api"; import axiosInstance from "@/app/(main)/axios/axiosInstance"; import EscalationComponent from "./EscalationComponent"; import QcDataGrid from "./QCDatagrid"; -import { dummyEscalationHistory, dummyQCData } from "./dummyQcTemplate"; -import { escape, min } from "lodash"; +import { dummyEscalationHistory, + dummyQcData_A1, dummyQcData_E1, dummyQcData_E2, + dummyQcHeader_A1, dummyQcHeader_E1, dummyQcHeader_E2 } from "./dummyQcTemplate"; +import { escape, isNull, min } from "lodash"; import { PanoramaSharp } from "@mui/icons-material"; import EscalationLogTable from "../DashboardPage/escalation/EscalationLogTable"; import { EscalationResult } from "@/app/api/escalation"; @@ -389,7 +391,7 @@ const QcComponent: React.FC = ({ itemDetail, disabled = false }) => { useEffect(() => { console.log("%c Qc Record updated:", "color:green", qcRecord); if (qcRecord.length < 1) { // New QC - const fetchedQcData = dummyQCData; //TODO fetch from DB + const fetchedQcData = dummyQcData; //TODO fetch from DB setValue("qcResult", fetchedQcData); } else { if (itemDetail?.status == "escalated") { // Copy the previous QC data for editing @@ -470,6 +472,33 @@ const QcComponent: React.FC = ({ itemDetail, disabled = false }) => { } else { return 60} }; + // For DEMO + const dummyQcData = useMemo(() => { + const d = itemDetail; + if (d.itemId == 23239 || d.itemNo == "PP2277" || d.itemName == "烚意粉") { + return dummyQcData_E2; + } else { + if (d.jobOrderId === null) { + return dummyQcData_A1; + } else { + return dummyQcData_E1; + } + } + }, [itemDetail]) + + const dummyQcHeader = useMemo(() => { + const d = itemDetail;console.log("I am checking now", d); + if (d.itemId == 23239 || d.itemNo == "PP2277" || d.itemName == "烚意粉") { + return dummyQcHeader_E2; + } else { + if (d.jobOrderId === null) { + return dummyQcHeader_A1; + } else { + return dummyQcHeader_E1; + } + } + }, [itemDetail]) + return ( <> @@ -498,14 +527,13 @@ const QcComponent: React.FC = ({ itemDetail, disabled = false }) => { - Group A - 急凍貨類 (QCA1-MEAT01) + {dummyQcHeader.name} - 品檢類型:IQC + 品檢類型:{dummyQcHeader.type} - 記錄探測溫度的時間,請在1小時内完成卸貨盤點入庫,以保障食品安全
- 監察方法:目視檢查、嗅覺檢查和使用適當的食物溫度計,檢查食物溫度是否符合指標 + {dummyQcHeader.description}
{/* @@ -545,16 +573,15 @@ const QcComponent: React.FC = ({ itemDetail, disabled = false }) => { - - Group A - 急凍貨類 (QCA1-MEAT01) - - - 品檢類型:IQC - - - 記錄探測溫度的時間,請在1小時内完成卸貨盤點入庫,以保障食品安全
- 監察方法:目視檢查、嗅覺檢查和使用適當的食物溫度計,檢查食物溫度是否符合指標 -
+ + {dummyQcHeader.name} + + + 品檢類型:{dummyQcHeader.type} + + + {dummyQcHeader.description} +
= ({ itemDetail, disabled = false }) => { } sx={{"& .Mui-checked": {color: "red"}}} - label= {detailMode ? "全部拒絕並退貨" : "不接受並退貨"} /> + label= {detailMode ? "全部拒絕並退貨" : "不接受並需要退貨"} /> {(itemDetail.status == "pending" || disabled) && (<> = ({ const res = await fetchStockInLineInfo(stockInLineId); if (res) { console.log("%c Fetched Stock In Line: ", "color:orange", res); - setStockInLineInfo({...inputDetail, ...res}); + setStockInLineInfo({...inputDetail, ...res, expiryDate: inputDetail?.expiryDate}); // TODO review to overwrite res with inputDetail instead (revise PO fetching data) fetchQcResultData(stockInLineId); } else throw("Result is undefined"); diff --git a/src/components/PoDetail/dummyQcTemplate.tsx b/src/components/PoDetail/dummyQcTemplate.tsx index 2e6bfa8..22233e7 100644 --- a/src/components/PoDetail/dummyQcTemplate.tsx +++ b/src/components/PoDetail/dummyQcTemplate.tsx @@ -10,7 +10,7 @@ import { QcData } from "@/app/api/qc" // remarks: string | undefined // } -export const dummyQCData: QcData[] = [ +export const dummyQcData_A1: QcData[] = [ { id: 1, qcItemId: 4, @@ -63,6 +63,154 @@ export const dummyQCData: QcData[] = [ }, ] +export const dummyQcHeader_A1: any = { + name: "收貨要求 A1 - 急凍貨類 (QCA1-MEAT01)", + type: "IQC", + description: <>記錄探測溫度的時間,請在1小時内完成卸貨盤點入庫,以保障食品安全
監察方法:目視檢查、嗅覺檢查和使用適當的食物溫度計,檢查食物溫度是否符合指標, + +} + +export const dummyQcHeader_E1: any = { + name: "收貨要求 E1 - 通過加熱製成的醬汁或食物 (QCE1-HEAT01)", + type: "EPQC", + description: "包裝後需用冷卻水池降溫", + +} + +export const dummyQcHeader_E2: any = { + name: "收貨要求 E2 - 室溫攪拌混合製成的醬汁或食物(無需加熱烹調) (QCA1-MIX01)", + type: "EPQC", + description: "不需使用冷卻水池降溫", + +} + +// For DEMO 2025/10/03 +export const dummyQcData_E1: QcData[] = [ + { + id: 1, + qcItemId: 25, + code: "包裝", + description: "包裝不嚴密,液體滲漏。包裝不乾淨,則不合格", + name: "包裝", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 2, + qcItemId: 26, + code: "標籤", + description: "標籤名稱或日期錯誤、不清晰或缺失,則不合格", + name: "標籤", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 3, + qcItemId: 27, + code: "肉質", + description: "肉質生熟程度不一致,或裁切尺寸不一致,則不合格", + name: "肉質", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 4, + qcItemId: 28, + code: "異物", + description: "有異物,無法通過金屬探測器,則不合格", + name: "異物", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 5, + qcItemId: 29, + code: "重量", + description: "超過製程要求的誤差+/-5%,則不合格", + name: "重量", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 6, + qcItemId: 30, + code: "冷卻水池", + description: "未能於2小時內冷卻至20°C以下。冷卻水池水溫太高,或冷卻池中的成品太多,則不合格", + name: "冷卻水池", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 7, + qcItemId: 31, + code: "冷庫", + description: "2小時內,未能及時入冷庫,冷卻至4°C或以下,則不合格", + name: "冷庫", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, +] +// For PP2277 - 23293 +export const dummyQcData_E2: QcData[] = [ + { + id: 1, + qcItemId: 25, + code: "包裝", + description: "包裝不嚴密,液體滲漏。包裝不乾淨,則不合格", + name: "包裝", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 2, + qcItemId: 26, + code: "標籤", + description: "標籤名稱或日期錯誤、不清晰或缺失,則不合格", + name: "標籤", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 3, + qcItemId: 32, + code: "顔色", + description: "食材有破損、缺口、變質或醬汁有異常顏色狀態,則不合格", + name: "顔色", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 4, + qcItemId: 28, + code: "異物", + description: "有異物,無法通過金屬探測器,則不合格", + name: "異物", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, + { + id: 5, + qcItemId: 33, + code: "重量", + description: "沒有達到或超出重量要求,則不合格", + name: "重量", + qcPassed: undefined, + failQty: undefined, + remarks: undefined, + }, +] + export interface EscalationData { id: number, escalation: string, diff --git a/src/i18n/zh/common.json b/src/i18n/zh/common.json index 401e38c..7d6ac34 100644 --- a/src/i18n/zh/common.json +++ b/src/i18n/zh/common.json @@ -18,7 +18,7 @@ "Dashboard": "資訊展示面板", "Store Management": "原材料", "Store Management": "倉庫管理", - "Delivery": "交貨單", + "Delivery": "送貨訂單", "Scheduling": "排程", "Settings": "設定", "User": "用戶", @@ -33,7 +33,7 @@ "Purchase Order":"採購單", "Demand Forecast":"需求預測", "Pick Order": "提料單", - "Deliver Order":"交貨單", + "Deliver Order":"送貨訂單", "Project":"專案", "Product":"產品", "Material":"材料", @@ -46,7 +46,7 @@ "FG":"成品", "FG & Material Demand Forecast Detail":"成品及材料需求預測詳情", "View item In-out And inventory Ledger":"查看物料出入庫及庫存日誌", - "Delivery Order":"交貨單", + "Delivery Order":"送貨訂單", "Detail Scheduling":"詳細排程", "Customer":"客戶", "QC Check Item":"QC檢查項目", @@ -83,7 +83,7 @@ "min": "分鐘", "mins": "分鐘", "Job Order": "工單", - "Edit Job Order": "編輯工單", + "Edit Job Order": "工單詳情", "Production": "生產流程", "Put Away": "上架", "Put Away Scan": "上架掃碼", diff --git a/src/i18n/zh/do.json b/src/i18n/zh/do.json index 9802e58..e21ebc7 100644 --- a/src/i18n/zh/do.json +++ b/src/i18n/zh/do.json @@ -1,13 +1,13 @@ { - "Delivery Order": "交貨單", + "Delivery Order": "送貨訂單", "Shop Name": "店鋪名稱", - "Delivery Order No.": "交貨單編號", - "Delivery Order Date": "交貨單日期", - "Delivery Order Status": "交貨單狀態", + "Delivery Order No.": "送貨訂單編號", + "Delivery Order Date": "送貨訂單日期", + "Delivery Order Status": "送貨訂單狀態", "Order Date": "訂單日期", - "Estimated Arrival": "預計到貨日期", - "Estimated Arrival From": "預計到貨日期", - "Estimated Arrival To": "預計到貨日期至", + "Estimated Arrival": "預計送貨日期", + "Estimated Arrival From": "預計送貨日期", + "Estimated Arrival To": "預計送貨日期至", "Status": "來貨狀態", "Order Date From": "訂單日期", "Order Date To": "訂單日期至", @@ -27,7 +27,7 @@ "Releasing": "處理中", "Shop Code": "店鋪編號", "Supplier Code": "供應商編號", - "Estimated Arrival Date": "預計到貨日期", + "Estimated Arrival Date": "預計送貨日期", "Item No.": "商品編號", "Item Name": "商品名稱", "Quantity": "數量", @@ -43,8 +43,8 @@ "Back": "返回", "Batch Release": "批量放單", "Batch release completed successfully.": "已完成批量放單", - "Edit Delivery Order Detail": "編輯交貨單詳情", - "DO released successfully! Pick orders created.": "交貨單放單成功!提料單已建立。", + "Edit Delivery Order Detail": "編輯送貨訂單詳情", + "DO released successfully! Pick orders created.": "送貨訂單放單成功!提料單已建立。", "Stock Available": "庫存可用", "row selected": "行已選擇", "An error has occurred. Please try again later.": "發生錯誤,請稍後再試。", diff --git a/src/i18n/zh/jo.json b/src/i18n/zh/jo.json index 046bd31..1b783b2 100644 --- a/src/i18n/zh/jo.json +++ b/src/i18n/zh/jo.json @@ -1,7 +1,7 @@ { "Job Order": "工單", "Create Job Order": "創建工單", - "Edit Job Order Detail": "編輯工單", + "Edit Job Order Detail": "工單詳情", "Details": "細節", "Actions": "操作", "Code": "工單編號", diff --git a/src/i18n/zh/purchaseOrder.json b/src/i18n/zh/purchaseOrder.json index b69bb24..34fc35c 100644 --- a/src/i18n/zh/purchaseOrder.json +++ b/src/i18n/zh/purchaseOrder.json @@ -33,7 +33,7 @@ "Item Name": "貨品名稱", "Item Qty": "貨品數量", "Item": "貨品", - "Item Accepted Qty": "貨品已收貨數量", + "Item Accepted Qty": "收貨數量", "Item Purchase UoM": "貨品採購單位", "qty": "訂單數量", "uom": "採購單位",