From d0d6c1d7e511c5c86b0e28cf1164b2d393286099 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Fri, 11 Jul 2025 16:50:36 +0800 Subject: [PATCH] [Prod Schedule] Update Prod Schedule (e.g. rename & update detail page) --- .../(main)/scheduling/detail/edit/page.tsx | 57 - .../{detail => detailed}/edit/not-found.tsx | 0 .../(main)/scheduling/detailed/edit/page.tsx | 57 + .../scheduling/{detail => detailed}/page.tsx | 8 +- src/app/(main)/scheduling/rough/edit/page.tsx | 4 +- src/app/api/scheduling/actions.ts | 23 +- src/app/api/scheduling/index.ts | 178 +- src/app/utils/formatUtil.ts | 30 + src/components/DetailSchedule/index.ts | 1 - .../DetailScheduleDetailWrapper.tsx | 37 - .../DetailScheduleDetail/ViewByBomDetails.tsx | 1496 ------------- src/components/DetailScheduleDetail/index.ts | 1 - .../DetailedScheduleLoading.tsx} | 4 +- .../DetailedScheduleSearchView.tsx} | 10 +- .../DetailedScheduleWrapper.tsx} | 12 +- src/components/DetailedSchedule/index.ts | 1 + .../DetailInfoCard.tsx | 43 +- .../DetailedScheduleDetailView.tsx} | 100 +- .../DetailedScheduleDetailWrapper.tsx | 46 + .../DetailedScheduleDetail/ProdTimeColumn.tsx | 50 + .../DetailedScheduleDetail/TempRecords.tsx | 1878 +++++++++++++++++ .../ViewByFGDetails.tsx | 226 ++ .../DetailedScheduleDetail/index.ts | 1 + .../NavigationContent/NavigationContent.tsx | 2 +- .../RoughScheduleDetailWrapper.tsx | 4 +- .../RoughScheudleDetailView.tsx | 8 +- .../ScheduleTable/BomMaterialTable.tsx | 3 +- .../ScheduleTable/ScheduleTable.tsx | 658 +++--- src/i18n/zh/schedule.json | 3 +- 29 files changed, 2835 insertions(+), 2106 deletions(-) delete mode 100644 src/app/(main)/scheduling/detail/edit/page.tsx rename src/app/(main)/scheduling/{detail => detailed}/edit/not-found.tsx (100%) create mode 100644 src/app/(main)/scheduling/detailed/edit/page.tsx rename src/app/(main)/scheduling/{detail => detailed}/page.tsx (80%) delete mode 100644 src/components/DetailSchedule/index.ts delete mode 100644 src/components/DetailScheduleDetail/DetailScheduleDetailWrapper.tsx delete mode 100644 src/components/DetailScheduleDetail/ViewByBomDetails.tsx delete mode 100644 src/components/DetailScheduleDetail/index.ts rename src/components/{DetailSchedule/DetailScheduleLoading.tsx => DetailedSchedule/DetailedScheduleLoading.tsx} (91%) rename src/components/{DetailSchedule/DetailScheduleSearchView.tsx => DetailedSchedule/DetailedScheduleSearchView.tsx} (94%) rename src/components/{DetailSchedule/DetailScheduleWrapper.tsx => DetailedSchedule/DetailedScheduleWrapper.tsx} (53%) create mode 100644 src/components/DetailedSchedule/index.ts rename src/components/{DetailScheduleDetail => DetailedScheduleDetail}/DetailInfoCard.tsx (68%) rename src/components/{DetailScheduleDetail/DetailScheudleDetailView.tsx => DetailedScheduleDetail/DetailedScheduleDetailView.tsx} (64%) create mode 100644 src/components/DetailedScheduleDetail/DetailedScheduleDetailWrapper.tsx create mode 100644 src/components/DetailedScheduleDetail/ProdTimeColumn.tsx create mode 100644 src/components/DetailedScheduleDetail/TempRecords.tsx create mode 100644 src/components/DetailedScheduleDetail/ViewByFGDetails.tsx create mode 100644 src/components/DetailedScheduleDetail/index.ts diff --git a/src/app/(main)/scheduling/detail/edit/page.tsx b/src/app/(main)/scheduling/detail/edit/page.tsx deleted file mode 100644 index 1212996..0000000 --- a/src/app/(main)/scheduling/detail/edit/page.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Metadata } from "next"; -// import { getServerI18n, I18nProvider } from "@/i18n"; -import { getServerI18n, I18nProvider } from "../../../../../i18n"; -import Typography from "@mui/material/Typography"; -// import { fetchQcItemDetails, preloadQcItem } from "@/app/api/settings/qcItem"; -// import QcItemSave from "@/components/QcItemSave"; -import { - fetchQcItemDetails, - preloadQcItem, -} from "../../../../../app/api/settings/qcItem"; -import QcItemSave from "../../../../../components/QcItemSave"; -import { isArray } from "lodash"; -import { notFound } from "next/navigation"; -// import { ServerFetchError } from "@/app/utils/fetchUtil"; -// import DetailScheduleDetail from "@/components/DetailScheduleDetail"; -import { ServerFetchError } from "../../../../../app/utils/fetchUtil"; -import DetailScheduleDetail from "../../../../../components/DetailScheduleDetail"; - -export const metadata: Metadata = { - title: "Qc Item", -}; - -interface Props { - searchParams: { [key: string]: string | string[] | undefined }; -} - -const DetailScheduling: React.FC = async ({ searchParams }) => { - const { t } = await getServerI18n("schedule"); - - const id = searchParams["id"]; - - if (!id || isArray(id)) { - notFound(); - } - - // try { - // await fetchQcItemDetails(id) - // } catch (e) { - // if (e instanceof ServerFetchError && (e.response?.status === 404 || e.response?.status === 400)) { - // console.log(e) - // notFound(); - // } - // } - - return ( - <> - - {t("FG Production Schedule")} - - - - - - ); -}; - -export default DetailScheduling; diff --git a/src/app/(main)/scheduling/detail/edit/not-found.tsx b/src/app/(main)/scheduling/detailed/edit/not-found.tsx similarity index 100% rename from src/app/(main)/scheduling/detail/edit/not-found.tsx rename to src/app/(main)/scheduling/detailed/edit/not-found.tsx diff --git a/src/app/(main)/scheduling/detailed/edit/page.tsx b/src/app/(main)/scheduling/detailed/edit/page.tsx new file mode 100644 index 0000000..35d18db --- /dev/null +++ b/src/app/(main)/scheduling/detailed/edit/page.tsx @@ -0,0 +1,57 @@ +import { Metadata } from "next"; +import { getServerI18n, I18nProvider } from "@/i18n"; +// import { getServerI18n, I18nProvider } from "../../../../../i18n"; +import Typography from "@mui/material/Typography"; +import { isArray, parseInt } from "lodash"; +import { notFound } from "next/navigation"; +import { SearchParams, ServerFetchError } from "@/app/utils/fetchUtil"; +import DetailedScheduleDetail from "@/components/DetailedScheduleDetail"; +import { type } from "os"; +import { fetchDetailedProdScheduleDetail } from "@/app/api/scheduling"; +import { Suspense } from "react"; +// import { ServerFetchError } from "../../../../../app/utils/fetchUtil"; +// import DetailedScheduleDetail from "../../../../../components/DetailedScheduleDetail"; + +export const metadata: Metadata = { + title: "FG Production Schedule", +}; + +// interface Props { +// searchParams: { [key: string]: string | string[] | undefined }; +// } + +type Props = SearchParams; + +const DetailScheduling: React.FC = async ({ searchParams }) => { + const { t } = await getServerI18n("schedule"); + const id = searchParams["id"]; + const type = "detailed" + + if (!id || isArray(id) || !isFinite(parseInt(id))) { + notFound(); + } + + try { + await fetchDetailedProdScheduleDetail(parseInt(id)) + } catch (e) { + if (e instanceof ServerFetchError && (e.response?.status === 404 || e.response?.status === 400)) { + console.log(e) + notFound(); + } + } + + return ( + <> + + {t("FG Production Schedule")} + + + }> + + + + + ); +}; + +export default DetailScheduling; diff --git a/src/app/(main)/scheduling/detail/page.tsx b/src/app/(main)/scheduling/detailed/page.tsx similarity index 80% rename from src/app/(main)/scheduling/detail/page.tsx rename to src/app/(main)/scheduling/detailed/page.tsx index 52da5b9..b60e7ea 100644 --- a/src/app/(main)/scheduling/detail/page.tsx +++ b/src/app/(main)/scheduling/detailed/page.tsx @@ -1,8 +1,8 @@ // import { TypeEnum } from "@/app/utils/typeEnum"; -// import DetailSchedule from "@/components/DetailSchedule"; +// import DetailedSchedule from "@/components/DetailedSchedule"; // import { getServerI18n } from "@/i18n"; -import DetailSchedule from "../../../../components/DetailSchedule"; +import DetailedSchedule from "../../../../components/DetailedSchedule"; import { getServerI18n } from "../../../../i18n"; import { I18nProvider } from "@/i18n"; import Stack from "@mui/material/Stack"; @@ -32,8 +32,8 @@ const DetailScheduling: React.FC = async () => { - }> - + }> + diff --git a/src/app/(main)/scheduling/rough/edit/page.tsx b/src/app/(main)/scheduling/rough/edit/page.tsx index 1096da1..9ac1a04 100644 --- a/src/app/(main)/scheduling/rough/edit/page.tsx +++ b/src/app/(main)/scheduling/rough/edit/page.tsx @@ -12,7 +12,7 @@ import RoughScheduleDetailView from "@/components/RoughScheduleDetail"; import { SearchParams, ServerFetchError } from "@/app/utils/fetchUtil"; import { isArray, parseInt } from "lodash"; import { notFound } from "next/navigation"; -import { fetchProdScheduleDetail } from "@/app/api/scheduling"; +import { fetchRoughProdScheduleDetail } from "@/app/api/scheduling"; export const metadata: Metadata = { title: "Demand Forecast Detail", @@ -30,7 +30,7 @@ const roughSchedulingDetail: React.FC = async ({ searchParams }) => { } try { - await fetchProdScheduleDetail(parseInt(id)); + await fetchRoughProdScheduleDetail(parseInt(id)); } catch (e) { if ( e instanceof ServerFetchError && diff --git a/src/app/api/scheduling/actions.ts b/src/app/api/scheduling/actions.ts index 4265533..4798c1b 100644 --- a/src/app/api/scheduling/actions.ts +++ b/src/app/api/scheduling/actions.ts @@ -31,6 +31,11 @@ export interface ProdScheduleResultByPage { records: ProdScheduleResult[]; } +export interface ReleaseDetailProdScheduleInputs { + id: number; + demandQty: number; +} + export const fetchProdSchedules = cache( async (data: SearchProdSchedule | null) => { const params = convertObjToURLSearchParams(data); @@ -61,9 +66,9 @@ export const testRoughSchedule = cache(async () => { ); }); -export const testDetailSchedule = cache(async () => { +export const testDetailedSchedule = cache(async () => { return serverFetchJson( - `${BASE_API_URL}/productionSchedule/testDetailSchedule`, + `${BASE_API_URL}/productionSchedule/testDetailedSchedule`, { method: "GET", headers: { "Content-Type": "application/json" }, @@ -73,3 +78,17 @@ export const testDetailSchedule = cache(async () => { }, ); }); + +export const releaseProdScheduleLine = cache(async (data: ReleaseDetailProdScheduleInputs) => { + return serverFetchJson( + `${BASE_API_URL}/productionSchedule/releaseLine`, + { + method: "POST", + body: JSON.stringify(data), + headers: { "Content-Type": "application/json" }, + next: { + tags: ["prodSchedules"], + }, + } + ) +}) \ No newline at end of file diff --git a/src/app/api/scheduling/index.ts b/src/app/api/scheduling/index.ts index 6a19d35..5f55b86 100644 --- a/src/app/api/scheduling/index.ts +++ b/src/app/api/scheduling/index.ts @@ -5,85 +5,129 @@ import "server-only"; export type ScheduleType = "all" | "rough" | "detailed" | "manual"; +// Rough export interface RoughProdScheduleResult { - id: number; - scheduleAt: number[]; - schedulePeriod: number[]; - schedulePeriodTo: number[]; - totalEstProdCount: number; - totalFGType: number; - type: string; - prodScheduleLinesByFg: RoughProdScheduleLineResultByFg[]; - prodScheduleLinesByFgByDate: { - [assignDate: number]: RoughProdScheduleLineResultByFg[]; - }; - prodScheduleLinesByBom: RoughProdScheduleLineResultByBom[]; - prodScheduleLinesByBomByDate: { - [assignDate: number]: RoughProdScheduleLineResultByBomByDate[]; - }; + id: number; + scheduleAt: number[]; + schedulePeriod: number[]; + schedulePeriodTo: number[]; + totalEstProdCount: number; + totalFGType: number; + type: string; + prodScheduleLinesByFg: RoughProdScheduleLineResultByFg[]; + prodScheduleLinesByFgByDate: { + [assignDate: number]: RoughProdScheduleLineResultByFg[]; + }; + prodScheduleLinesByBom: RoughProdScheduleLineResultByBom[]; + prodScheduleLinesByBomByDate: { + [assignDate: number]: RoughProdScheduleLineResultByBomByDate[]; + }; } export interface RoughProdScheduleLineResultByFg { - id: number; - code: string; - name: string; - type: string; - availableQty: number; - prodQty: number; - lastMonthAvgSales: number; - estCloseBal: number; - priority: number; - assignDate: number; - bomMaterials: RoughProdScheduleLineBomMaterialResult[]; + id: number; + code: string; + name: string; + type: string; + availableQty: number; + prodQty: number; + lastMonthAvgSales: number; + estCloseBal: number; + priority: number; + assignDate: number; + bomMaterials: RoughProdScheduleLineBomMaterialResult[]; } export interface RoughProdScheduleLineBomMaterialResult { - id: number; - code: string; - name: string; - type: string; - availableQty: number; - demandQty: number; - uomName: string; + id: number; + code: string; + name: string; + type: string; + availableQty: number; + demandQty: number; + uomName: string; } export interface RoughProdScheduleLineResultByBom { - id: number; - code: string; - name: string; - type: string; - availableQty: number; - totalDemandQty: number; - demandQty1: number; - demandQty2: number; - demandQty3: number; - demandQty4: number; - demandQty5: number; - demandQty6: number; - demandQty7: number; - uomName: string; + id: number; + code: string; + name: string; + type: string; + availableQty: number; + totalDemandQty: number; + demandQty1: number; + demandQty2: number; + demandQty3: number; + demandQty4: number; + demandQty5: number; + demandQty6: number; + demandQty7: number; + uomName: string; } export interface RoughProdScheduleLineResultByBomByDate { - id: number; - code: string; - name: string; - type: string; - availableQty: number; - demandQty: number; - assignDate: number; - uomName: string; + id: number; + code: string; + name: string; + type: string; + availableQty: number; + demandQty: number; + assignDate: number; + uomName: string; } -export const fetchProdScheduleDetail = cache(async (id: number) => { - return serverFetchJson( - `${BASE_API_URL}/productionSchedule/detail/${id}`, - { - method: "GET", - headers: { "Content-Type": "application/json" }, - next: { - tags: ["prodSchedule"], - }, - }, - ); -}); +// Detailed +export interface DetailedProdScheduleResult { + id: number; + scheduleAt: number[]; + totalEstProdCount: number; + totalFGType: number; + prodScheduleLines: DetailedProdScheduleLineResult[]; +} + +export interface DetailedProdScheduleLineResult { + id: number; + bomMaterials: DetailedProdScheduleLineBomMaterialResult[]; + jobNo: string; + code: string; + name: string; + type: string; + demandQty: number; + prodTimeInMinute: DetailedProdScheduleLineProdTimeResult[]; + priority: number; +} + +export interface DetailedProdScheduleLineBomMaterialResult { + id: number; + code: string; + name: string; + type: string; + availableQty: number; + demandQty: number; +} + +export interface DetailedProdScheduleLineProdTimeResult { + equipName: string; + totalMinutes: number; +} + +// API +export const fetchRoughProdScheduleDetail = cache(async (id: number) => { + return serverFetchJson(`${BASE_API_URL}/productionSchedule/detail/rough/${id}`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + next: { + tags: ["prodSchedule"] + } + }) +}) + +export const fetchDetailedProdScheduleDetail = cache(async (id: number) => { + return serverFetchJson(`${BASE_API_URL}/productionSchedule/detail/detailed/${id}`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + next: { + tags: ["prodSchedule"] + } + }) +}) \ No newline at end of file diff --git a/src/app/utils/formatUtil.ts b/src/app/utils/formatUtil.ts index 040e5de..b5f7084 100644 --- a/src/app/utils/formatUtil.ts +++ b/src/app/utils/formatUtil.ts @@ -66,6 +66,36 @@ export const dayjsToDateString = (date: Dayjs) => { return date.format(OUTPUT_DATE_FORMAT); }; +export const minutesToHoursMinutes = (minutes: number): string => { + const defaultHrStr = "hr" + const defaultMinStr = "min" + + if (minutes == 0) { + return `0 ${defaultMinStr}` + } + + const hrs = Math.floor(minutes / 60) + const mins = minutes % 60 + + let finalHrStr: string = "" + if (hrs > 1) { + finalHrStr = `${hrs} ${defaultHrStr}s` + } else if (hrs == 1) { + finalHrStr = `1 ${defaultHrStr}` + } + + let finalMinStr: string = "" + if (mins > 1) { + finalMinStr = `${mins} ${defaultMinStr}s` + } else if (mins == 1) { + finalMinStr = `1 ${defaultMinStr}` + } + + let colon = finalHrStr.length > 0 && finalMinStr.length > 0 ? ":" : "" + + return `${finalHrStr} ${colon} ${finalMinStr}`.trim() +} + export const stockInLineStatusMap: { [status: string]: number } = { draft: 0, pending: 1, diff --git a/src/components/DetailSchedule/index.ts b/src/components/DetailSchedule/index.ts deleted file mode 100644 index e6a0aee..0000000 --- a/src/components/DetailSchedule/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./DetailScheduleWrapper"; diff --git a/src/components/DetailScheduleDetail/DetailScheduleDetailWrapper.tsx b/src/components/DetailScheduleDetail/DetailScheduleDetailWrapper.tsx deleted file mode 100644 index d359468..0000000 --- a/src/components/DetailScheduleDetail/DetailScheduleDetailWrapper.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { CreateItemInputs } from "@/app/api/settings/item/actions"; -import { fetchItem } from "@/app/api/settings/item"; -import GeneralLoading from "@/components/General/GeneralLoading"; -import DetailScheduleDetailView from "@/components/DetailScheduleDetail/DetailScheudleDetailView"; - -interface SubComponents { - Loading: typeof GeneralLoading; -} - -type EditDetailScheduleDetailProps = { - id?: string | number; -}; - -type Props = EditDetailScheduleDetailProps; - -const DetailScheduleDetailWrapper: React.FC & SubComponents = async ({ - id, -}) => { - const defaultValues = { - id: 1, - productionDate: "2025-05-07", - totalJobOrders: 13, - totalProductionQty: 21000, - }; - - return ( - - ); -}; - -DetailScheduleDetailWrapper.Loading = GeneralLoading; - -export default DetailScheduleDetailWrapper; diff --git a/src/components/DetailScheduleDetail/ViewByBomDetails.tsx b/src/components/DetailScheduleDetail/ViewByBomDetails.tsx deleted file mode 100644 index f9abf8c..0000000 --- a/src/components/DetailScheduleDetail/ViewByBomDetails.tsx +++ /dev/null @@ -1,1496 +0,0 @@ -"use client"; - -import { CreateItemInputs } from "@/app/api/settings/item/actions"; -import { - GridColDef, - GridRowModel, - GridRenderEditCellParams, - GridEditInputCell, - GridRowSelectionModel, - useGridApiRef, -} from "@mui/x-data-grid"; -import { - MutableRefObject, - useCallback, - useEffect, - useMemo, - useState, -} from "react"; -import { useFormContext } from "react-hook-form"; -import { useTranslation } from "react-i18next"; -import InputDataGrid, { TableRow } from "../InputDataGrid/InputDataGrid"; -import { Box, Grid, Tooltip, Typography } from "@mui/material"; -import { ItemQc } from "@/app/api/settings/item"; -import { QcChecksInputs } from "@/app/api/settings/qcCheck/actions"; -import { GridApiCommunity } from "@mui/x-data-grid/internals"; -import { RiceBowl } from "@mui/icons-material"; -import EditableSearchResults, { - Column, -} from "@/components/SearchResults/EditableSearchResults"; -import { decimalFormatter } from "@/app/utils/formatUtil"; -import { GridRenderCellParams } from "@mui/x-data-grid"; - -type Props = { - apiRef: MutableRefObject; - isEdit: boolean; -}; -type EntryError = - | { - [field in keyof QcChecksInputs]?: string; - } - | undefined; - -export type FGRecord = { - id: string | number; - code: string; - name: string; - inStockQty: number; - purchaseQty: number; -}; - -export type FGOverallRecord = { - id: string | number; - code: string; - name: string; - type: string; - inStockQty?: number; - purchaseQty?: number; - purchaseQty1?: number; - purchaseQty2?: number; - purchaseQty3?: number; - purchaseQty4?: number; - purchaseQty5?: number; - purchaseQty6?: number; - purchaseQty7?: number; - overallPurchaseQty?: number; -}; - -const ViewByBomDetails: React.FC = ({ apiRef, isEdit }) => { - const { - t, - i18n: { language }, - } = useTranslation("schedule"); - - const { - formState: { errors, defaultValues, touchedFields }, - } = useFormContext(); - // const apiRef = useGridApiRef(); - - const dayPeriod = [ - "2025-05-11", - "2025-05-12", - "2025-05-13", - "2025-05-14", - "2025-05-15", - "2025-05-16", - "2025-05-17", - ]; - - const fakeRecords = useMemo( - () => [ - [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty: 972.12, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty: 3175.2, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty: 90, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty: 60.4, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty: 66.45, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty: 78.55, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty: 972.12, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty: 3175.2, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty: 90, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty: 60.4, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty: 66.45, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty: 78.55, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty: 972.12, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty: 3175.2, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty: 90, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty: 60.4, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty: 66.45, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty: 78.55, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty: 972.12, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty: 3175.2, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty: 90, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty: 60.4, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty: 66.45, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty: 78.55, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty: 972.12, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty: 3175.2, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty: 90, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty: 60.4, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty: 66.45, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty: 78.55, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty: 972.12, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty: 3175.2, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty: 90, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty: 60.4, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty: 66.45, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty: 78.55, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty: 972.12, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty: 3175.2, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty: 90, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty: 60.4, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty: 66.45, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty: 78.55, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - ], - [], - ); - - // const updatePagingController = (updatedObj: { index: number, pageNum: number, pageSize: number, totalCount: number }) => { - // setPagingController((prevState) => { - // return prevState.map((item, index) => { - // if (index === updatedObj?.index){ - // return { - // ...item, - // pageNum: item.pageNum, - // pageSize: item.pageSize, - // totalCount: item.totalCount, - // }; - // } - // else - // return item - // }); - // }); - // }; - const fakeOverallRecords = useMemo( - () => [ - { - id: 1, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 54.44, - purchaseQty1: 972.12, - purchaseQty2: 972.12, - purchaseQty3: 972.12, - purchaseQty4: 972.12, - purchaseQty5: 972.12, - purchaseQty6: 972.12, - purchaseQty7: 972.12, - overallPurchaseQty: 6804.84, - }, - { - id: 2, - code: "GI3236", - type: "Material", - name: "清水(煮過牛腩)", - inStockQty: 317.52, - purchaseQty1: 3175.2, - purchaseQty2: 3175.2, - purchaseQty3: 3175.2, - purchaseQty4: 3175.2, - purchaseQty5: 3175.2, - purchaseQty6: 3175.2, - purchaseQty7: 3175.2, - overallPurchaseQty: 22226.4, - }, - { - id: 3, - code: "MG1700", - type: "Material", - name: "STERILTOM 意大利茄粒", - inStockQty: 9.0, - purchaseQty1: 90, - purchaseQty2: 90, - purchaseQty3: 90, - purchaseQty4: 90, - purchaseQty5: 90, - purchaseQty6: 90, - purchaseQty7: 90, - overallPurchaseQty: 630, - }, - { - id: 4, - code: "FA0533", - type: "Material", - name: "乾蔥茸", - inStockQty: 6.04, - purchaseQty1: 60.4, - purchaseQty2: 60.4, - purchaseQty3: 60.4, - purchaseQty4: 60.4, - purchaseQty5: 60.4, - purchaseQty6: 60.4, - purchaseQty7: 60.4, - overallPurchaseQty: 422.8, - }, - { - id: 5, - code: "FA0210", - type: "Material", - name: "薑茸", - inStockQty: 6.04, - purchaseQty1: 66.45, - purchaseQty2: 66.45, - purchaseQty3: 66.45, - purchaseQty4: 66.45, - purchaseQty5: 66.45, - purchaseQty6: 66.45, - purchaseQty7: 66.45, - overallPurchaseQty: 465.15, - }, - { - id: 6, - code: "FA0608", - type: "Material", - name: "粗蒜茸", - inStockQty: 6.04, - purchaseQty1: 78.55, - purchaseQty2: 78.55, - purchaseQty3: 78.55, - purchaseQty4: 78.55, - purchaseQty5: 78.55, - purchaseQty6: 78.55, - purchaseQty7: 78.55, - overallPurchaseQty: 549.85, - }, - { - id: 7, - code: "FA0056", - type: "Material", - name: "洋蔥肉", - inStockQty: 241.98, - purchaseQty: 2419.8, - }, - { - id: 8, - code: "PP1188", - type: "Material", - name: "咖喱膽", - inStockQty: 36.0, - purchaseQty: 0, - }, - { - id: 9, - code: "PP8001", - type: "Material", - name: "咖哩汁箱料粉", - inStockQty: 77.42, - purchaseQty: 774.2, - }, - { - id: 10, - code: "PP1096", - type: "Material", - name: "白麵撈", - inStockQty: 60.0, - purchaseQty: 0, - }, - { - id: 11, - code: "NA0476", - type: "Material", - name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", - inStockQty: 600.0, - purchaseQty: 6000, - }, - { - id: 12, - code: "MH0040", - type: "Material", - name: "大豆油(1噸/桶)", - inStockQty: 0, - purchaseQty: 972.12, - }, - { - id: 13, - code: "FA0161", - type: "Material", - name: "洋蔥粒", - inStockQty: 0, - purchaseQty: 28.15, - }, - { - id: 14, - code: "MG1288", - type: "Material", - name: "炸紅蔥頭", - inStockQty: 0, - purchaseQty: 6.05, - }, - { - id: 15, - code: "MG0066", - type: "Material", - name: "咖哩料(5斤x16包+2斤/包)", - inStockQty: 0, - purchaseQty: 241.98, - }, - { - id: 16, - code: "MH0040", - type: "Material", - name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", - inStockQty: 0, - purchaseQty: 250.0, - }, - ], - [], - ); - - const [pagingController, setPagingController] = useState([ - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - { - pageNum: 1, - pageSize: 10, - totalCount: 0, - }, - ]); - - const updatePagingController = (updatedObj: any) => { - setPagingController((prevState) => { - return prevState.map((item, index) => { - if (index === updatedObj?.index) { - return { - ...item, - pageNum: item.pageNum, - pageSize: item.pageSize, - totalCount: item.totalCount, - }; - } else return item; - }); - }); - }; - - const overallColumns = useMemo[]>( - () => [ - { - field: "code", - label: t("code"), - type: "read-only", - // editable: true, - }, - { - field: "name", - label: t("name"), - type: "read-only", - }, - { - field: "type", - label: t("type"), - type: "read-only", - // editable: true, - }, - { - field: "inStockQty", - label: t("Available Qty"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.inStockQty == "number") { - return decimalFormatter.format(row.inStockQty); - } - return row.inStockQty; - }, - // editable: true, - }, - { - field: "overallPurchaseQty", - label: t("Total Demand Qty"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.overallPurchaseQty == "number") { - return decimalFormatter.format(row.overallPurchaseQty); - } - return row.overallPurchaseQty; - }, - }, - { - field: "purchaseQty1", - label: t("Demand Qty (Day1)"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.purchaseQty1 == "number") { - return decimalFormatter.format(row.purchaseQty1); - } - return row.purchaseQty1; - }, - }, - { - field: "purchaseQty2", - label: t("Demand Qty (Day2)"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.purchaseQty2 == "number") { - return decimalFormatter.format(row.purchaseQty2); - } - return row.purchaseQty2; - }, - }, - { - field: "purchaseQty3", - label: t("Demand Qty (Day3)"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.purchaseQty3 == "number") { - return decimalFormatter.format(row.purchaseQty3); - } - return row.purchaseQty3; - }, - }, - { - field: "purchaseQty4", - label: t("Demand Qty (Day4)"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.purchaseQty4 == "number") { - return decimalFormatter.format(row.purchaseQty4); - } - return row.purchaseQty4; - }, - }, - { - field: "purchaseQty5", - label: t("Demand Qty (Day5)"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.purchaseQty5 == "number") { - return decimalFormatter.format(row.purchaseQty5); - } - return row.purchaseQty5; - }, - }, - { - field: "purchaseQty6", - label: t("Demand Qty (Day6)"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.purchaseQty6 == "number") { - return decimalFormatter.format(row.purchaseQty6); - } - return row.purchaseQty6; - }, - }, - { - field: "purchaseQty7", - label: t("Demand Qty (Day7)"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGOverallRecord) => { - if (typeof row.purchaseQty7 == "number") { - return decimalFormatter.format(row.purchaseQty7); - } - return row.purchaseQty7; - }, - }, - ], - [], - ); - - const columns = useMemo[]>( - () => [ - { - field: "code", - label: t("code"), - type: "read-only", - // editable: true, - }, - { - field: "name", - label: t("name"), - type: "read-only", - }, - { - field: "type", - label: t("type"), - type: "read-only", - }, - { - field: "inStockQty", - label: t("Available Qty"), - type: "read-only", - // editable: true, - style: { - textAlign: "right", - }, - renderCell: (row: FGRecord) => { - if (typeof row.inStockQty == "number") { - return decimalFormatter.format(row.inStockQty); - } - return row.inStockQty; - }, - }, - { - field: "purchaseQty", - label: t("Demand Qty"), - type: "read-only", - style: { - textAlign: "right", - }, - renderCell: (row: FGRecord) => { - if (typeof row.purchaseQty == "number") { - return decimalFormatter.format(row.purchaseQty); - } - return row.purchaseQty; - }, - }, - ], - [], - ); - - return ( - - - - {t("Material Demand List (7 Days)")} - - - index={7} - items={fakeOverallRecords as FGRecord[]} - hasCollapse - // isMockUp={true} - columns={overallColumns} - setPagingController={updatePagingController} - pagingController={pagingController[7]} - isAutoPaging={true} - isEditable={false} - isEdit={false} - /> - - {dayPeriod.map((date, index) => ( - - - {`${t("Material Demand Date")}: ${date}`} - - - hasCollapse - index={index} - items={fakeRecords[index]} // Use the corresponding records for the day - columns={columns} - setPagingController={updatePagingController} - pagingController={pagingController[index]} - isAutoPaging={true} - isEditable={false} - isEdit={isEdit} - /> - - ))} - - ); -}; -export default ViewByBomDetails; diff --git a/src/components/DetailScheduleDetail/index.ts b/src/components/DetailScheduleDetail/index.ts deleted file mode 100644 index e8e5b2f..0000000 --- a/src/components/DetailScheduleDetail/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./DetailScheduleDetailWrapper"; diff --git a/src/components/DetailSchedule/DetailScheduleLoading.tsx b/src/components/DetailedSchedule/DetailedScheduleLoading.tsx similarity index 91% rename from src/components/DetailSchedule/DetailScheduleLoading.tsx rename to src/components/DetailedSchedule/DetailedScheduleLoading.tsx index eb5ae41..88954f2 100644 --- a/src/components/DetailSchedule/DetailScheduleLoading.tsx +++ b/src/components/DetailedSchedule/DetailedScheduleLoading.tsx @@ -5,7 +5,7 @@ import Stack from "@mui/material/Stack"; import React from "react"; // Can make this nicer -export const DetailScheduleLoading: React.FC = () => { +export const DetailedScheduleLoading: React.FC = () => { return ( <> @@ -37,4 +37,4 @@ export const DetailScheduleLoading: React.FC = () => { ); }; -export default DetailScheduleLoading; +export default DetailedScheduleLoading; diff --git a/src/components/DetailSchedule/DetailScheduleSearchView.tsx b/src/components/DetailedSchedule/DetailedScheduleSearchView.tsx similarity index 94% rename from src/components/DetailSchedule/DetailScheduleSearchView.tsx rename to src/components/DetailedSchedule/DetailedScheduleSearchView.tsx index b666d4c..492a13b 100644 --- a/src/components/DetailSchedule/DetailScheduleSearchView.tsx +++ b/src/components/DetailedSchedule/DetailedScheduleSearchView.tsx @@ -2,18 +2,10 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import SearchBox, { Criterion } from "../SearchBox"; -import { ItemsResult } from "@/app/api/settings/item"; import SearchResults, { Column } from "../SearchResults"; import { EditNote } from "@mui/icons-material"; import { useRouter, useSearchParams } from "next/navigation"; -import { GridDeleteIcon } from "@mui/x-data-grid"; -import { TypeEnum } from "@/app/utils/typeEnum"; -import axios from "axios"; -import { BASE_API_URL, NEXT_PUBLIC_API_URL } from "@/config/api"; import { useTranslation } from "react-i18next"; -import axiosInstance from "@/app/(main)/axios/axiosInstance"; -import Qs from "qs"; -import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs import { ScheduleType } from "@/app/api/scheduling"; import { ProdScheduleResult, @@ -107,7 +99,7 @@ const DSOverview: React.FC = ({ type, defaultInputs }) => { const onDetailClick = (record: ProdScheduleResult) => { console.log("[debug] record", record); - router.push(`/scheduling/detail/edit?id=${record.id}`); + router.push(`/scheduling/detailed/edit?id=${record.id}`); }; const columns = useMemo[]>( diff --git a/src/components/DetailSchedule/DetailScheduleWrapper.tsx b/src/components/DetailedSchedule/DetailedScheduleWrapper.tsx similarity index 53% rename from src/components/DetailSchedule/DetailScheduleWrapper.tsx rename to src/components/DetailedSchedule/DetailedScheduleWrapper.tsx index 2d7037d..263fcbe 100644 --- a/src/components/DetailSchedule/DetailScheduleWrapper.tsx +++ b/src/components/DetailedSchedule/DetailedScheduleWrapper.tsx @@ -1,18 +1,18 @@ import React from "react"; -import { DetailScheduleLoading } from "./DetailScheduleLoading"; -import DSOverview from "./DetailScheduleSearchView"; +import { DetailedScheduleLoading } from "./DetailedScheduleLoading"; +import DSOverview from "./DetailedScheduleSearchView"; import { ScheduleType } from "@/app/api/scheduling"; import { SearchProdSchedule } from "@/app/api/scheduling/actions"; interface SubComponents { - Loading: typeof DetailScheduleLoading; + Loading: typeof DetailedScheduleLoading; } type Props = { type: ScheduleType; }; -const DetailScheduleWrapper: React.FC & SubComponents = async ({ +const DetailedScheduleWrapper: React.FC & SubComponents = async ({ type, }) => { const defaultInputs: SearchProdSchedule = { @@ -22,6 +22,6 @@ const DetailScheduleWrapper: React.FC & SubComponents = async ({ return ; }; -DetailScheduleWrapper.Loading = DetailScheduleLoading; +DetailedScheduleWrapper.Loading = DetailedScheduleLoading; -export default DetailScheduleWrapper; +export default DetailedScheduleWrapper; diff --git a/src/components/DetailedSchedule/index.ts b/src/components/DetailedSchedule/index.ts new file mode 100644 index 0000000..3b109ab --- /dev/null +++ b/src/components/DetailedSchedule/index.ts @@ -0,0 +1 @@ +export { default } from "./DetailedScheduleWrapper"; diff --git a/src/components/DetailScheduleDetail/DetailInfoCard.tsx b/src/components/DetailedScheduleDetail/DetailInfoCard.tsx similarity index 68% rename from src/components/DetailScheduleDetail/DetailInfoCard.tsx rename to src/components/DetailedScheduleDetail/DetailInfoCard.tsx index 76e973d..8ee780b 100644 --- a/src/components/DetailScheduleDetail/DetailInfoCard.tsx +++ b/src/components/DetailedScheduleDetail/DetailInfoCard.tsx @@ -17,13 +17,14 @@ import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; import { TypeEnum } from "@/app/utils/typeEnum"; import { CreateItemInputs } from "@/app/api/settings/item/actions"; import { NumberInputProps } from "@/components/CreateItem/NumberInputProps"; -import { integerFormatter } from "@/app/utils/formatUtil"; -import { SaveDetailSchedule } from "./DetailScheudleDetailView"; +import { arrayToDateString, integerFormatter } from "@/app/utils/formatUtil"; +import { DetailedProdScheduleResult } from "@/app/api/scheduling"; +// import { SaveDetailedSchedule } from "./DetailedScheduleDetailView"; // temp interface input type Props = { - // recordDetails: SaveDetailSchedule; + // recordDetails: SaveDetailedSchedule; isEditing: boolean; }; @@ -39,14 +40,15 @@ const DetailInfoCard: React.FC = ({ const { control, register, + getValues, formState: { errors, defaultValues, touchedFields }, - } = useFormContext(); + } = useFormContext(); - const [details, setDetails] = useState(undefined); + // const [details, setDetails] = useState(undefined); useEffect(() => { console.log("[debug] record details", defaultValues) - setDetails(defaultValues as SaveDetailSchedule); + // setDetails(defaultValues as DetailedProdScheduleResult); }, [defaultValues]) useEffect(() => { @@ -65,9 +67,10 @@ const DetailInfoCard: React.FC = ({ = ({ = ({ ( = ({ label={t("Total Production Qty")} fullWidth disabled={!isEditing} - value={ + // TODO: May update by table demand qty + defaultValue={ typeof field.value == "number" ? integerFormatter.format(field.value) : field.value } + // value={ + // typeof field.value == "number" + // ? integerFormatter.format(field.value) + // : field.value + // } // defaultValue={typeof (details?.productionCount) == "number" ? integerFormatter.format(details?.productionCount) : details?.productionCount} // error={Boolean(errors.type)} // helperText={errors.type?.message} diff --git a/src/components/DetailScheduleDetail/DetailScheudleDetailView.tsx b/src/components/DetailedScheduleDetail/DetailedScheduleDetailView.tsx similarity index 64% rename from src/components/DetailScheduleDetail/DetailScheudleDetailView.tsx rename to src/components/DetailedScheduleDetail/DetailedScheduleDetailView.tsx index 124048e..7b03a57 100644 --- a/src/components/DetailScheduleDetail/DetailScheudleDetailView.tsx +++ b/src/components/DetailedScheduleDetail/DetailedScheduleDetailView.tsx @@ -3,17 +3,12 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { useTranslation } from "react-i18next"; -import { - //SaveDetailSchedule, - saveItem, -} from "@/app/api/settings/item/actions"; import { FormProvider, SubmitErrorHandler, SubmitHandler, useForm, } from "react-hook-form"; -import { deleteDialog } from "../Swal/CustomAlerts"; import { Box, Button, @@ -26,38 +21,35 @@ import { Typography, } from "@mui/material"; import { Add, Check, Close, EditNote } from "@mui/icons-material"; -import { ItemQc, ItemsResult } from "@/app/api/settings/item"; import { useGridApiRef } from "@mui/x-data-grid"; -import ProductDetails from "@/components/CreateItem/ProductDetails"; -import DetailInfoCard from "@/components/DetailScheduleDetail/DetailInfoCard"; +import DetailInfoCard from "@/components/DetailedScheduleDetail/DetailInfoCard"; import ViewByFGDetails, { - FGRecord, -} from "@/components/DetailScheduleDetail/ViewByFGDetails"; -import ViewByBomDetails from "@/components/DetailScheduleDetail/ViewByBomDetails"; -import EditableSearchResults, { - Column, -} from "@/components/SearchResults/EditableSearchResults"; + // FGRecord, +} from "@/components/DetailedScheduleDetail/ViewByFGDetails"; +import { DetailedProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; // temp interface input -export interface SaveDetailSchedule { - id: number; - productionDate: string; - totalJobOrders: number; - totalProductionQty: number; -} +// export interface SaveDetailedSchedule { +// id: number; +// productionDate: string; +// totalJobOrders: number; +// totalProductionQty: number; +// } type Props = { isEditMode: boolean; // type: TypeEnum; - defaultValues: Partial | undefined; + defaultValues: Partial | undefined; // qcChecks: ItemQc[] + type: ScheduleType; }; -const DetailScheduleDetailView: React.FC = ({ +const DetailedScheduleDetailView: React.FC = ({ isEditMode, // type, defaultValues, - // qcChecks + // qcChecks, + type }) => { // console.log(type) const apiRef = useGridApiRef(); @@ -67,43 +59,11 @@ const DetailScheduleDetailView: React.FC = ({ const [tabIndex, setTabIndex] = useState(0); const { t } = useTranslation("schedule"); const router = useRouter(); - const [isEdit, setIsEdit] = useState(false); - //const title = "Demand Forecast Detail" - const [mode, redirPath] = useMemo(() => { - // var typeId = TypeEnum.CONSUMABLE_ID - let title = ""; - let mode = ""; - let redirPath = ""; - // if (type === TypeEnum.MATERIAL) { - // typeId = TypeEnum.MATERIAL_ID - // title = "Material"; - // redirPath = "/settings/material"; - // } - // if (type === TypeEnum.PRODUCT) { - // typeId = TypeEnum.PRODUCT_ID - title = "Product"; - redirPath = "scheduling/detail/edit"; - // } - // if (type === TypeEnum.BYPRODUCT) { - // typeId = TypeEnum.BYPRODUCT_ID - // title = "By-Product"; - // redirPath = "/settings/byProduct"; - // } - if (isEditMode) { - mode = "Edit"; - } else { - mode = "Create"; - } - return [mode, redirPath]; - }, [isEditMode]); +const [isEdit, setIsEdit] = useState(false); + // console.log(typeId) - const formProps = useForm({ - defaultValues: defaultValues ? defaultValues : { - id: 1, - productionDate: "2025-05-07", - totalJobOrders: 13, - totalProductionQty: 21000, - } as SaveDetailSchedule, + const formProps = useForm({ + defaultValues: defaultValues }); const errors = formProps.formState.errors; @@ -114,17 +74,17 @@ const DetailScheduleDetailView: React.FC = ({ [], ); - const [pagingController, setPagingController] = useState({ - pageNum: 1, - pageSize: 10, - totalCount: 0, - }); + // const [pagingController, setPagingController] = useState({ + // pageNum: 1, + // pageSize: 10, + // totalCount: 0, + // }); const handleCancel = () => { router.replace(`/scheduling/Detail`); }; - const onSubmit = useCallback>( + const onSubmit = useCallback>( async (data, event) => { const hasErrors = false; console.log(errors); @@ -145,7 +105,7 @@ const DetailScheduleDetailView: React.FC = ({ ); // multiple tabs - const onSubmitError = useCallback>( + const onSubmitError = useCallback>( (errors) => {}, [], ); @@ -154,6 +114,10 @@ const DetailScheduleDetailView: React.FC = ({ setIsEdit(!isEdit); }; + const onReleaseClick = useCallback(() => { + + }, []) + return ( <> @@ -198,7 +162,7 @@ const DetailScheduleDetailView: React.FC = ({ )} {/* {tabIndex === 0 && } */} - + {/* {tabIndex === 1 && } */}