@@ -0,0 +1,17 @@ | |||||
import { getServerI18n } from "@/i18n"; | |||||
import { Stack, Typography, Link } from "@mui/material"; | |||||
import NextLink from "next/link"; | |||||
export default async function NotFound() { | |||||
const { t } = await getServerI18n("schedule", "common"); | |||||
return ( | |||||
<Stack spacing={2}> | |||||
<Typography variant="h4">{t("Not Found")}</Typography> | |||||
<Typography variant="body1">{t("The production schedule detail page was not found!")}</Typography> | |||||
<Link href="/settings/scheduling" component={NextLink} variant="body2"> | |||||
{t("Return to all scheduling")} | |||||
</Link> | |||||
</Stack> | |||||
); | |||||
} |
@@ -8,15 +8,35 @@ import Typography from "@mui/material/Typography"; | |||||
import { Metadata } from "next"; | import { Metadata } from "next"; | ||||
import Link from "next/link"; | import Link from "next/link"; | ||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
import RoughScheduleDetailView from "@/components/RoughScheduleDetail/RoughScheudleDetailView"; | |||||
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"; | |||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Demand Forecast Detail", | title: "Demand Forecast Detail", | ||||
}; | }; | ||||
const roughSchedulingDetail: React.FC = async () => { | |||||
// const project = TypeEnum.PRODUCT | |||||
const { t } = await getServerI18n("project"); | |||||
type Props = SearchParams | |||||
const roughSchedulingDetail: React.FC<Props> = async ({ searchParams }) => { | |||||
const { t } = await getServerI18n("schedule"); | |||||
const id = searchParams["id"] | |||||
const type = "rough" | |||||
if (!id || isArray(id) || !isFinite(parseInt(id))) { | |||||
notFound() | |||||
} | |||||
try { | |||||
await fetchProdScheduleDetail(parseInt(id)) | |||||
} catch(e) { | |||||
if (e instanceof ServerFetchError && (e.response?.status === 404 || e.response?.status === 400)) { | |||||
console.log(e) | |||||
notFound(); | |||||
} | |||||
} | |||||
// preloadClaims(); | // preloadClaims(); | ||||
return ( | return ( | ||||
@@ -39,9 +59,9 @@ const roughSchedulingDetail: React.FC = async () => { | |||||
{t("Create product")} | {t("Create product")} | ||||
</Button> */} | </Button> */} | ||||
</Stack> | </Stack> | ||||
<I18nProvider namespaces={["schedule","project","common"]}> | |||||
<I18nProvider namespaces={["schedule","common"]}> | |||||
<Suspense fallback={<RoughScheduleDetailView.Loading />}> | <Suspense fallback={<RoughScheduleDetailView.Loading />}> | ||||
<RoughScheduleDetailView /> | |||||
<RoughScheduleDetailView type={type} id={parseInt(id)}/> | |||||
</Suspense> | </Suspense> | ||||
</I18nProvider> | </I18nProvider> | ||||
</> | </> | ||||
@@ -19,6 +19,7 @@ export const metadata: Metadata = { | |||||
const roughScheduling: React.FC = async () => { | const roughScheduling: React.FC = async () => { | ||||
// const project = TypeEnum.PRODUCT | // const project = TypeEnum.PRODUCT | ||||
const { t } = await getServerI18n("schedule"); | const { t } = await getServerI18n("schedule"); | ||||
const type = "rough" | |||||
// preloadClaims(); | // preloadClaims(); | ||||
return ( | return ( | ||||
@@ -44,7 +45,7 @@ const roughScheduling: React.FC = async () => { | |||||
</Stack> | </Stack> | ||||
<I18nProvider namespaces={["schedule", "common","items","project"]}> | <I18nProvider namespaces={["schedule", "common","items","project"]}> | ||||
<Suspense fallback={<RoughSchedule.Loading />}> | <Suspense fallback={<RoughSchedule.Loading />}> | ||||
<RoughSchedule /> | |||||
<RoughSchedule type={type}/> | |||||
</Suspense> | </Suspense> | ||||
</I18nProvider> | </I18nProvider> | ||||
</> | </> | ||||
@@ -0,0 +1,43 @@ | |||||
"use server" | |||||
import { convertObjToURLSearchParams } from "@/app/utils/commonUtil"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil" | |||||
import { BASE_API_URL } from "@/config/api" | |||||
import { cache } from "react" | |||||
export interface SearchProdSchedule { | |||||
scheduleAt?: string; | |||||
schedulePeriod?: string; | |||||
schedulePeriodTo?: string; | |||||
totalEstProdCount?: number; | |||||
type?: "manual" | "detailed" | "rough"; | |||||
pageSize?: number; | |||||
pageNum?: number; | |||||
} | |||||
export interface ProdScheduleResult { | |||||
id: number; | |||||
scheduleAt: number[]; | |||||
schedulePeriod: number[]; | |||||
schedulePeriodTo: number[]; | |||||
totalEstProdCount: number; | |||||
totalFGType: number; | |||||
type: string; | |||||
} | |||||
export interface ProdScheduleResultByPage { | |||||
total: number; | |||||
records: ProdScheduleResult[]; | |||||
} | |||||
export const fetchProdSchedules = cache(async (data: SearchProdSchedule | null) => { | |||||
const params = convertObjToURLSearchParams<SearchProdSchedule>(data) | |||||
// console.log(params) | |||||
return serverFetchJson<ProdScheduleResultByPage>(`${BASE_API_URL}/productionSchedule/getRecordByPage?${params}`, { | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedules"] | |||||
} | |||||
}) | |||||
}) |
@@ -0,0 +1,82 @@ | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil" | |||||
import { BASE_API_URL } from "@/config/api" | |||||
import { cache } from "react" | |||||
import "server-only" | |||||
export type ScheduleType = "rough" | "detail"; | |||||
export interface ProdScheduleResult { | |||||
id: number; | |||||
scheduleAt: number[]; | |||||
schedulePeriod: number[]; | |||||
schedulePeriodTo: number[]; | |||||
totalEstProdCount: number; | |||||
totalFGType: number; | |||||
type: string; | |||||
prodScheduleLinesByFg: ProdScheduleLineResultByFg[]; | |||||
prodScheduleLinesByFgByDate: { [assignDate: number]: ProdScheduleLineResultByFg[] }; | |||||
prodScheduleLinesByBom: ProdScheduleLineResultByBom[]; | |||||
prodScheduleLinesByBomByDate: { [assignDate: number]: ProdScheduleLineResultByBomByDate[] }; | |||||
} | |||||
export interface ProdScheduleLineResultByFg { | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
prodQty: number; | |||||
lastMonthAvgSales: number; | |||||
estCloseBal: number; | |||||
priority: number; | |||||
assignDate: number; | |||||
bomMaterials: ProdScheduleLineBomMaterialResult[]; | |||||
} | |||||
export interface ProdScheduleLineBomMaterialResult { | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
demandQty: number; | |||||
uomName: string; | |||||
} | |||||
export interface ProdScheduleLineResultByBom { | |||||
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 ProdScheduleLineResultByBomByDate { | |||||
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<ProdScheduleResult>(`${BASE_API_URL}/productionSchedule/detail/${id}`, { | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedule"] | |||||
} | |||||
}) | |||||
}) |
@@ -1,65 +1,60 @@ | |||||
"use client"; | "use client"; | ||||
import React, {useCallback, useEffect, useMemo, useState} from "react"; | |||||
import React, { useCallback, useEffect, useMemo, useState } from "react"; | |||||
import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
import { ItemsResult} from "@/app/api/settings/item"; | |||||
import { ItemsResult } from "@/app/api/settings/item"; | |||||
import SearchResults, { Column } from "../SearchResults"; | import SearchResults, { Column } from "../SearchResults"; | ||||
import { EditNote } from "@mui/icons-material"; | import { EditNote } from "@mui/icons-material"; | ||||
import { useRouter, useSearchParams } from "next/navigation"; | import { useRouter, useSearchParams } from "next/navigation"; | ||||
import { GridDeleteIcon } from "@mui/x-data-grid"; | import { GridDeleteIcon } from "@mui/x-data-grid"; | ||||
import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
import axios from "axios"; | import axios from "axios"; | ||||
import {BASE_API_URL, NEXT_PUBLIC_API_URL} from "@/config/api"; | |||||
import { BASE_API_URL, NEXT_PUBLIC_API_URL } from "@/config/api"; | |||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import axiosInstance from "@/app/(main)/axios/axiosInstance"; | import axiosInstance from "@/app/(main)/axios/axiosInstance"; | ||||
import Qs from 'qs'; | import Qs from 'qs'; | ||||
import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs | import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs | ||||
type RecordStructure ={ | |||||
id: number, | |||||
schedulePeriod: string, | |||||
scheduleAt: string | |||||
}; | |||||
import { ProdScheduleResult, ProdScheduleResultByPage, SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions"; | |||||
import { arrayToDateString, decimalFormatter } from "@/app/utils/formatUtil"; | |||||
import { isEqual, uniqBy } from "lodash"; | |||||
import dayjs from "dayjs"; | |||||
import { defaultPagingController } from "../SearchResults/SearchResults"; | |||||
// type RecordStructure ={ | |||||
// id: number, | |||||
// schedulePeriod: string, | |||||
// scheduleAt: string | |||||
// }; | |||||
type Props = { | type Props = { | ||||
records: RecordStructure[]; | |||||
type: SearchProdSchedule["type"]; | |||||
// initProdSchedules: ProdScheduleResultByPage; | |||||
defaultInputs: SearchProdSchedule; | |||||
}; | }; | ||||
type SearchQuery = Partial<Omit<ItemsResult, "id">>; | |||||
type SearchQuery = Partial<Omit<SearchProdSchedule, "id" | "type" | "pageSize" | "pageNum">>; | |||||
type SearchParamNames = keyof SearchQuery; | type SearchParamNames = keyof SearchQuery; | ||||
const RSOverview: React.FC<Props> = ({ records }) => { | |||||
const [filteredItems, setFilteredItems] = useState<Object[]>(records ?? []); | |||||
const { t } = useTranslation("items"); | |||||
const RSOverview: React.FC<Props> = ({ type, defaultInputs }) => { | |||||
const [filteredSchedules, setFilteredSchedules] = useState<ProdScheduleResult[]>([]); | |||||
const { t } = useTranslation("scheduling"); | |||||
const router = useRouter(); | const router = useRouter(); | ||||
const [filterObj, setFilterObj] = useState({}); | |||||
const [tempSelectedValue, setTempSelectedValue] = useState({}); | |||||
const [pagingController, setPagingController] = useState({ | |||||
pageNum: 1, | |||||
pageSize: 10, | |||||
totalCount: 0, | |||||
}) | |||||
const [mode, redirPath] = useMemo(() => { | |||||
// var typeId = TypeEnum.CONSUMABLE_ID | |||||
var title = ""; | |||||
var mode = "Search"; | |||||
var redirPath = ""; | |||||
title = "Product"; | |||||
redirPath = "/scheduling/rough"; | |||||
return [mode, redirPath]; | |||||
}, []); | |||||
// const [filterObj, setFilterObj] = useState({}); | |||||
// const [tempSelectedValue, setTempSelectedValue] = useState({}); | |||||
const [pagingController, setPagingController] = useState(defaultPagingController) | |||||
const [totalCount, setTotalCount] = useState(0) | |||||
const [inputs, setInputs] = useState(defaultInputs) | |||||
const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | ||||
() => { | () => { | ||||
var searchCriteria: Criterion<SearchParamNames>[] = [ | var searchCriteria: Criterion<SearchParamNames>[] = [ | ||||
{ label: t("Schedule Period"), paramName: "schedulePeriod", type: "dateRange" }, | |||||
{ label: t("Schedule Period"), label2: t("Schedule Period To"), paramName: "schedulePeriod", type: "dateRange" }, | |||||
{ label: t("Scheduled At"), paramName: "scheduleAt", type: "date" }, | { label: t("Scheduled At"), paramName: "scheduleAt", type: "date" }, | ||||
{ label: t("Product Count"), paramName: "productCount", type: "input" }, | |||||
{ label: t("Product Count"), paramName: "totalEstProdCount", type: "text" }, | |||||
] | ] | ||||
return searchCriteria | return searchCriteria | ||||
}, | }, | ||||
[t, records] | |||||
[t] | |||||
); | ); | ||||
// const onDetailClick = useCallback( | // const onDetailClick = useCallback( | ||||
@@ -70,7 +65,7 @@ const RSOverview: React.FC<Props> = ({ records }) => { | |||||
// ); | // ); | ||||
const onDeleteClick = useCallback( | const onDeleteClick = useCallback( | ||||
(item: ItemsResult) => {}, | |||||
(item: ItemsResult) => { }, | |||||
[router] | [router] | ||||
); | ); | ||||
@@ -79,25 +74,36 @@ const RSOverview: React.FC<Props> = ({ records }) => { | |||||
router.push(`/scheduling/rough/edit?id=${record.id}`); | router.push(`/scheduling/rough/edit?id=${record.id}`); | ||||
} | } | ||||
const columns = useMemo<Column<ItemsResult>[]>( | |||||
const columns = useMemo<Column<ProdScheduleResult>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
name: "id", | name: "id", | ||||
label: t("Details"), | label: t("Details"), | ||||
onClick: (record)=>onDetailClick(record), | |||||
onClick: (record) => onDetailClick(record), | |||||
buttonIcon: <EditNote />, | buttonIcon: <EditNote />, | ||||
}, | }, | ||||
{ | { | ||||
name: "scheduledPeriod", | |||||
name: "schedulePeriod", | |||||
label: t("Demand Forecast Period"), | label: t("Demand Forecast Period"), | ||||
renderCell: (params) => { | |||||
return `${arrayToDateString(params.schedulePeriod)} - ${arrayToDateString(params.schedulePeriodTo)}` | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
name: "scheduledAt", | |||||
label: t("Scheduled At"), | |||||
name: "scheduleAt", | |||||
label: t("Schedule At"), | |||||
renderCell: (params) => { | |||||
return arrayToDateString(params.scheduleAt) | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
name: "productCount", | |||||
name: "totalEstProdCount", | |||||
label: t("Product Count(s)"), | label: t("Product Count(s)"), | ||||
headerAlign: "right", | |||||
align: "right", | |||||
renderCell: (params) => { | |||||
return decimalFormatter.format(params.totalEstProdCount) | |||||
} | |||||
}, | }, | ||||
// { | // { | ||||
// name: "action", | // name: "action", | ||||
@@ -106,92 +112,134 @@ const RSOverview: React.FC<Props> = ({ records }) => { | |||||
// onClick: onDeleteClick, | // onClick: onDeleteClick, | ||||
// }, | // }, | ||||
], | ], | ||||
[filteredItems] | |||||
[filteredSchedules] | |||||
); | ); | ||||
useEffect(() => { | |||||
refetchData(filterObj); | |||||
}, [filterObj, pagingController.pageNum, pagingController.pageSize]); | |||||
const refetchData = async (filterObj: SearchQuery) => { | |||||
const authHeader = axiosInstance.defaults.headers['Authorization']; | |||||
if (!authHeader) { | |||||
return; // Exit the function if the token is not set | |||||
// useEffect(() => { | |||||
// refetchData(filterObj); | |||||
// }, [filterObj, pagingController.pageNum, pagingController.pageSize]); | |||||
const refetchData = useCallback(async (query: Record<SearchParamNames, string> | SearchProdSchedule, actionType: "reset" | "search" | "paging") => { | |||||
// console.log(query) | |||||
const params: SearchProdSchedule = { | |||||
scheduleAt: dayjs(query?.scheduleAt).isValid() ? query?.scheduleAt : undefined, | |||||
schedulePeriod: dayjs(query?.schedulePeriod).isValid() ? query?.schedulePeriod : undefined, | |||||
schedulePeriodTo: dayjs(query?.schedulePeriodTo).isValid() ? query?.schedulePeriodTo : undefined, | |||||
totalEstProdCount: query?.totalEstProdCount ? Number(query?.totalEstProdCount) : undefined, | |||||
type: "rough", | |||||
pageNum: pagingController.pageNum - 1, | |||||
pageSize: pagingController.pageSize | |||||
} | } | ||||
const params ={ | |||||
pageNum: pagingController.pageNum, | |||||
pageSize: pagingController.pageSize, | |||||
...filterObj, | |||||
...tempSelectedValue, | |||||
const response = await fetchProdSchedules(params) | |||||
// console.log(response) | |||||
if (response) { | |||||
setTotalCount(response.total) | |||||
switch (actionType) { | |||||
case "reset": | |||||
case "search": | |||||
setFilteredSchedules(() => response.records) | |||||
break; | |||||
case "paging": | |||||
setFilteredSchedules((fs) => uniqBy([...fs, ...response.records], "id")) | |||||
break; | |||||
} | |||||
} | } | ||||
}, [pagingController, setPagingController]) | |||||
try { | |||||
const response = await axiosInstance.get<ItemsResult[]>(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, { | |||||
params, | |||||
paramsSerializer: (params) => { | |||||
return Qs.stringify(params, { arrayFormat: 'repeat' }); | |||||
}, | |||||
}); | |||||
//setFilteredItems(response.data.records); | |||||
setFilteredItems([ | |||||
{ | |||||
id: 1, | |||||
scheduledPeriod: "2025-05-11 to 2025-05-17", | |||||
scheduledAt: "2025-05-07", | |||||
productCount: 13, | |||||
}, | |||||
{ | |||||
id: 2, | |||||
scheduledPeriod: "2025-05-18 to 2025-05-24", | |||||
scheduledAt: "2025-05-14", | |||||
productCount: 15, | |||||
}, | |||||
{ | |||||
id: 3, | |||||
scheduledPeriod: "2025-05-25 to 2025-05-31", | |||||
scheduledAt: "2025-05-21", | |||||
productCount: 13, | |||||
}, | |||||
]) | |||||
setPagingController({ | |||||
...pagingController, | |||||
totalCount: response.data.total | |||||
}) | |||||
return response; // Return the data from the response | |||||
} catch (error) { | |||||
console.error('Error fetching items:', error); | |||||
throw error; // Rethrow the error for further handling | |||||
} | |||||
}; | |||||
useEffect(() => { | |||||
refetchData(inputs, "paging") | |||||
}, [pagingController]) | |||||
// const refetchData = async (filterObj: SearchQuery) => { | |||||
// const authHeader = axiosInstance.defaults.headers['Authorization']; | |||||
// if (!authHeader) { | |||||
// return; // Exit the function if the token is not set | |||||
// } | |||||
// const params ={ | |||||
// pageNum: pagingController.pageNum, | |||||
// pageSize: pagingController.pageSize, | |||||
// ...filterObj, | |||||
// ...tempSelectedValue, | |||||
// } | |||||
// try { | |||||
// // const response = await axiosInstance.get<ItemsResult[]>(`${NEXT_PUBLIC_API_URL}/items/getRecordByPage`, { | |||||
// // params, | |||||
// // paramsSerializer: (params) => { | |||||
// // return Qs.stringify(params, { arrayFormat: 'repeat' }); | |||||
// // }, | |||||
// // }); | |||||
// //setFilteredSchedules(response.data.records); | |||||
// // setFilteredSchedules([ | |||||
// // { | |||||
// // id: 1, | |||||
// // scheduledPeriod: "2025-05-11 to 2025-05-17", | |||||
// // scheduledAt: "2025-05-07", | |||||
// // productCount: 13, | |||||
// // }, | |||||
// // { | |||||
// // id: 2, | |||||
// // scheduledPeriod: "2025-05-18 to 2025-05-24", | |||||
// // scheduledAt: "2025-05-14", | |||||
// // productCount: 15, | |||||
// // }, | |||||
// // { | |||||
// // id: 3, | |||||
// // scheduledPeriod: "2025-05-25 to 2025-05-31", | |||||
// // scheduledAt: "2025-05-21", | |||||
// // productCount: 13, | |||||
// // }, | |||||
// // ]) | |||||
// setPagingController({ | |||||
// ...pagingController, | |||||
// // totalCount: response.data.total | |||||
// }) | |||||
// // return response; // Return the data from the response | |||||
// } catch (error) { | |||||
// console.error('Error fetching items:', error); | |||||
// throw error; // Rethrow the error for further handling | |||||
// } | |||||
// }; | |||||
const onReset = useCallback(() => { | const onReset = useCallback(() => { | ||||
//setFilteredItems(items ?? []); | |||||
setFilterObj({}); | |||||
setTempSelectedValue({}); | |||||
refetchData(); | |||||
}, [records]); | |||||
// setFilteredSchedules(items ?? []); | |||||
// setFilterObj({}); | |||||
// setTempSelectedValue({}); | |||||
refetchData(inputs, "reset"); | |||||
}, []); | |||||
return ( | return ( | ||||
<> | <> | ||||
<SearchBox | <SearchBox | ||||
criteria={searchCriteria} | criteria={searchCriteria} | ||||
onSearch={(query) => { | onSearch={(query) => { | ||||
setFilterObj({ | |||||
...query | |||||
}) | |||||
// resetPagingController() | |||||
setInputs(() => ( | |||||
{ | |||||
scheduleAt: query?.scheduleAt, | |||||
schedulePeriod: query?.schedulePeriod, | |||||
schedulePeriodTo: query?.schedulePeriodTo, | |||||
totalEstProdCount: Number(query?.totalEstProdCount) | |||||
} | |||||
)) | |||||
refetchData(query, "search") | |||||
// setFilterObj({ | |||||
// ...query | |||||
// }) | |||||
}} | }} | ||||
onReset={onReset} | onReset={onReset} | ||||
/> | /> | ||||
<SearchResults<ItemsResult> | |||||
items={filteredItems} | |||||
<SearchResults<ProdScheduleResult> | |||||
items={filteredSchedules} | |||||
columns={columns} | columns={columns} | ||||
setPagingController={setPagingController} | setPagingController={setPagingController} | ||||
pagingController={pagingController} | pagingController={pagingController} | ||||
isAutoPaging={false} | |||||
hasCollapse={false} | |||||
totalCount={totalCount} | |||||
// isAutoPaging={false} | |||||
/> | /> | ||||
</> | </> | ||||
); | ); | ||||
@@ -1,21 +1,35 @@ | |||||
import { fetchAllItems } from "@/app/api/settings/item"; | import { fetchAllItems } from "@/app/api/settings/item"; | ||||
import { RoughScheduleLoading } from "./RoughScheduleLoading"; | import { RoughScheduleLoading } from "./RoughScheduleLoading"; | ||||
import RSOverview from "./RoughSchedileSearchView"; | import RSOverview from "./RoughSchedileSearchView"; | ||||
import { SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions"; | |||||
interface SubComponents { | interface SubComponents { | ||||
Loading: typeof RoughScheduleLoading; | Loading: typeof RoughScheduleLoading; | ||||
} | } | ||||
type Props = {}; | |||||
type Props = { | |||||
type: SearchProdSchedule["type"] | |||||
}; | |||||
const RoughScheduleWrapper: React.FC<Props> & SubComponents = async ( | const RoughScheduleWrapper: React.FC<Props> & SubComponents = async ( | ||||
{ | { | ||||
// type, | |||||
type | |||||
} | } | ||||
) => { | ) => { | ||||
// console.log(type) | // console.log(type) | ||||
var result = await fetchAllItems(); | |||||
return <RSOverview records={[]} />; | |||||
const defaultInputs: SearchProdSchedule = { | |||||
type: "rough" | |||||
} | |||||
// const [ | |||||
// items, | |||||
// prodSchedules | |||||
// ] = await Promise.all([ | |||||
// fetchAllItems(), | |||||
// fetchProdSchedules(defaultInputs) | |||||
// ]) | |||||
return <RSOverview type={type} defaultInputs={defaultInputs}/>; | |||||
}; | }; | ||||
RoughScheduleWrapper.Loading = RoughScheduleLoading; | RoughScheduleWrapper.Loading = RoughScheduleLoading; | ||||
@@ -3,48 +3,53 @@ import { | |||||
Box, | Box, | ||||
Card, | Card, | ||||
CardContent, | CardContent, | ||||
FormControl, | |||||
Grid, | Grid, | ||||
Stack, | Stack, | ||||
TextField, | TextField, | ||||
Typography, | Typography, | ||||
} from "@mui/material"; | } from "@mui/material"; | ||||
import { useFormContext } from "react-hook-form"; | |||||
import { Controller, useFormContext } from "react-hook-form"; | |||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import InputDataGrid from "../InputDataGrid"; | import InputDataGrid from "../InputDataGrid"; | ||||
import {useCallback, useEffect, useMemo, useState} from "react"; | |||||
import { useCallback, useEffect, useMemo, useState } from "react"; | |||||
import { GridColDef, GridRowModel } from "@mui/x-data-grid"; | import { GridColDef, GridRowModel } from "@mui/x-data-grid"; | ||||
import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | import { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid"; | ||||
import { TypeEnum } from "@/app/utils/typeEnum"; | 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 { NumberInputProps } from "@/components/CreateItem/NumberInputProps"; | |||||
import { arrayToDateString, integerFormatter } from "@/app/utils/formatUtil"; | |||||
import { ProdScheduleResult } from "@/app/api/scheduling"; | |||||
import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; | |||||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | |||||
type Props = { | type Props = { | ||||
// isEditMode: boolean; | |||||
// type: TypeEnum; | |||||
isEditing: boolean; | |||||
}; | }; | ||||
const DetailInfoCard: React.FC<Props> = ({ recordDetails, isEditing}) => { | |||||
const DetailInfoCard: React.FC<Props> = ({ isEditing }) => { | |||||
const { | const { | ||||
t, | t, | ||||
i18n: { language }, | i18n: { language }, | ||||
} = useTranslation(); | } = useTranslation(); | ||||
const { | const { | ||||
control, | |||||
register, | register, | ||||
getValues, | |||||
watch, | |||||
formState: { errors, defaultValues, touchedFields }, | formState: { errors, defaultValues, touchedFields }, | ||||
} = useFormContext<CreateItemInputs>(); | |||||
} = useFormContext<ProdScheduleResult>(); | |||||
const [details, setDetails] = useState(null); | |||||
// const [details, setDetails] = useState(null); | |||||
useEffect(()=>{ | |||||
console.log("[debug] record details", recordDetails) | |||||
setDetails(recordDetails); | |||||
},[recordDetails]) | |||||
useEffect(() => { | |||||
console.log("[debug] record details", getValues) | |||||
// setDetails(recordDetails); | |||||
}, [getValues]) | |||||
useEffect(()=>{ | |||||
useEffect(() => { | |||||
console.log("[debug] isEdit", isEditing) | console.log("[debug] isEdit", isEditing) | ||||
},[isEditing]) | |||||
}, [isEditing]) | |||||
return ( | return ( | ||||
<Card sx={{ display: "block" }}> | <Card sx={{ display: "block" }}> | ||||
@@ -58,39 +63,39 @@ const DetailInfoCard: React.FC<Props> = ({ recordDetails, isEditing}) => { | |||||
<TextField | <TextField | ||||
label={t("Date")} | label={t("Date")} | ||||
fullWidth | fullWidth | ||||
{...register("scheduledPeriod", { | |||||
required: "name required!", | |||||
})} | |||||
defaultValue={details?.scheduledPeriod} | |||||
// {...register("scheduledPeriod", { | |||||
// required: "name required!", | |||||
// })} | |||||
defaultValue={`${arrayToDateString(getValues("schedulePeriod"))} - ${arrayToDateString(getValues("schedulePeriodTo"))}`} | |||||
disabled={!isEditing} | disabled={!isEditing} | ||||
error={Boolean(errors.name)} | |||||
helperText={errors.name?.message} | |||||
// error={Boolean(errors.name)} | |||||
// helperText={errors.name?.message} | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
<Grid item xs={6}> | <Grid item xs={6}> | ||||
<TextField | <TextField | ||||
label={t("Total FG Item")} | label={t("Total FG Item")} | ||||
fullWidth | fullWidth | ||||
{...register("productCount", { | |||||
required: "code required!", | |||||
})} | |||||
defaultValue={details?.productCount} | |||||
// {...register("totalFGType", { | |||||
// required: "Total FG Item required!", | |||||
// })} | |||||
defaultValue={typeof (getValues("totalFGType")) == "number" ? integerFormatter.format(getValues("totalFGType")) : getValues("totalFGType")} | |||||
disabled={!isEditing} | disabled={!isEditing} | ||||
error={Boolean(errors.code)} | |||||
helperText={errors.code?.message} | |||||
// error={Boolean(errors.code)} | |||||
// helperText={errors.code?.message} | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
<Grid item xs={6}> | <Grid item xs={6}> | ||||
<TextField | <TextField | ||||
label={t("Total Estimated Demand Qty")} | |||||
fullWidth | |||||
{...register("productionCount", { | |||||
required: "type required!", | |||||
})} | |||||
disabled={!isEditing} | |||||
defaultValue={typeof(details?.productionCount) == "number" ? integerFormatter.format(details?.productionCount) : details?.productionCount} | |||||
error={Boolean(errors.type)} | |||||
helperText={errors.type?.message} | |||||
label={t("Total Estimated Demand Qty")} | |||||
fullWidth | |||||
// {...register("totalEstProdCount", { | |||||
// required: "Qty required!", | |||||
// })} | |||||
disabled={!isEditing} | |||||
defaultValue={typeof (getValues("totalFGType")) == "number" ? integerFormatter.format(getValues("totalEstProdCount")) : getValues("totalEstProdCount")} | |||||
// error={Boolean(errors.type)} | |||||
// helperText={errors.type?.message} | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
</Grid> | </Grid> | ||||
@@ -2,46 +2,25 @@ import { CreateItemInputs } from "@/app/api/settings/item/actions"; | |||||
import { fetchItem } from "@/app/api/settings/item"; | import { fetchItem } from "@/app/api/settings/item"; | ||||
import GeneralLoading from "@/components/General/GeneralLoading"; | import GeneralLoading from "@/components/General/GeneralLoading"; | ||||
import RoughScheduleDetailView from "@/components/RoughScheduleDetail/RoughScheudleDetailView"; | import RoughScheduleDetailView from "@/components/RoughScheduleDetail/RoughScheudleDetailView"; | ||||
import React from "react"; | |||||
import { ScheduleType, fetchProdScheduleDetail } from "@/app/api/scheduling"; | |||||
interface SubComponents { | interface SubComponents { | ||||
Loading: typeof GeneralLoading; | Loading: typeof GeneralLoading; | ||||
} | } | ||||
type Props = { | type Props = { | ||||
id?: number | id?: number | ||||
// type: TypeEnum; | |||||
type: ScheduleType; | |||||
}; | }; | ||||
const RoughScheduleDetailWrapper: (id: { id: any }) => Promise<JSX.Element> = async ({ id: any }) => { | |||||
var result | |||||
var defaultValues: Partial<CreateItemInputs> | undefined | |||||
// console.log(type) | |||||
var qcChecks | |||||
if (id) { | |||||
result = await fetchItem(id); | |||||
const item = result.item | |||||
qcChecks = result.qcChecks | |||||
const activeRows = qcChecks.filter(it => it.isActive).map(i => i.id) | |||||
console.log(qcChecks) | |||||
defaultValues = { | |||||
type: item?.type, | |||||
id: item?.id, | |||||
code: item?.code, | |||||
name: item?.name, | |||||
description: item?.description, | |||||
remarks: item?.remarks, | |||||
shelfLife: item?.shelfLife, | |||||
countryOfOrigin: item?.countryOfOrigin, | |||||
maxQty: item?.maxQty, | |||||
qcChecks: qcChecks, | |||||
qcChecks_active: activeRows | |||||
}; | |||||
} | |||||
const RoughScheduleDetailWrapper: React.FC<Props> & SubComponents = async ({ id, type }) => { | |||||
const prodSchedule = id ? await fetchProdScheduleDetail(id) : undefined | |||||
return ( | return ( | ||||
<RoughScheduleDetailView | <RoughScheduleDetailView | ||||
isEditMode={Boolean(id)} | isEditMode={Boolean(id)} | ||||
defaultValues={defaultValues} | |||||
qcChecks={qcChecks || []} | |||||
type={type} | |||||
defaultValues={prodSchedule} | |||||
/> | /> | ||||
); | ); | ||||
}; | }; | ||||
@@ -14,28 +14,30 @@ import { | |||||
useForm, | useForm, | ||||
} from "react-hook-form"; | } from "react-hook-form"; | ||||
import { deleteDialog } from "../Swal/CustomAlerts"; | import { deleteDialog } from "../Swal/CustomAlerts"; | ||||
import {Box, Button, Grid, Link, Stack, Tab, Tabs, TabsProps, Typography} from "@mui/material"; | |||||
import {Add, Check, Close, EditNote} from "@mui/icons-material"; | |||||
import {ItemQc, ItemsResult} from "@/app/api/settings/item"; | |||||
import { Box, Button, Grid, Link, Stack, Tab, Tabs, TabsProps, 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 { useGridApiRef } from "@mui/x-data-grid"; | ||||
import ProductDetails from "@/components/CreateItem/ProductDetails"; | import ProductDetails from "@/components/CreateItem/ProductDetails"; | ||||
import DetailInfoCard from "@/components/RoughScheduleDetail/DetailInfoCard"; | import DetailInfoCard from "@/components/RoughScheduleDetail/DetailInfoCard"; | ||||
import ViewByFGDetails, {FGRecord} from "@/components/RoughScheduleDetail/ViewByFGDetails"; | |||||
import ViewByFGDetails from "@/components/RoughScheduleDetail/ViewByFGDetails"; | |||||
import ViewByBomDetails from "@/components/RoughScheduleDetail/ViewByBomDetails"; | import ViewByBomDetails from "@/components/RoughScheduleDetail/ViewByBomDetails"; | ||||
import EditableSearchResults, {Column} from "@/components/SearchResults/EditableSearchResults"; | |||||
import ScheduleTable from "@/components/ScheduleTable"; | |||||
import { Column } from "@/components/ScheduleTable/ScheduleTable"; | |||||
import { ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import { arrayToDayjs, dayjsToDateString } from "@/app/utils/formatUtil"; | |||||
type Props = { | type Props = { | ||||
isEditMode: boolean; | isEditMode: boolean; | ||||
// type: TypeEnum; | |||||
defaultValues: Partial<CreateItemInputs> | undefined; | |||||
qcChecks: ItemQc[] | |||||
type: ScheduleType; | |||||
defaultValues: Partial<ProdScheduleResult> | undefined; | |||||
// qcChecks: ItemQc[] | |||||
}; | }; | ||||
const RoughScheduleDetailView: React.FC<Props> = ({ | const RoughScheduleDetailView: React.FC<Props> = ({ | ||||
isEditMode, | isEditMode, | ||||
// type, | |||||
type, | |||||
defaultValues, | defaultValues, | ||||
qcChecks | |||||
}) => { | }) => { | ||||
// console.log(type) | // console.log(type) | ||||
const apiRef = useGridApiRef(); | const apiRef = useGridApiRef(); | ||||
@@ -47,35 +49,9 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
const router = useRouter(); | const router = useRouter(); | ||||
const [isEdit, setIsEdit] = useState(false); | const [isEdit, setIsEdit] = useState(false); | ||||
//const title = "Demand Forecast Detail" | //const title = "Demand Forecast Detail" | ||||
const [mode, redirPath] = useMemo(() => { | |||||
// var typeId = TypeEnum.CONSUMABLE_ID | |||||
var title = ""; | |||||
var mode = ""; | |||||
var 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/rough/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]); | |||||
// console.log(typeId) | // console.log(typeId) | ||||
const formProps = useForm<CreateItemInputs>({ | |||||
const formProps = useForm<ProdScheduleResult>({ | |||||
defaultValues: defaultValues ? defaultValues : { | defaultValues: defaultValues ? defaultValues : { | ||||
}, | }, | ||||
}); | }); | ||||
@@ -88,7 +64,18 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
[], | [], | ||||
); | ); | ||||
const dayPeriod = useMemo<string[]>(() => { | |||||
const from = arrayToDayjs(formProps.getValues("schedulePeriod")) | |||||
const to = arrayToDayjs(formProps.getValues("schedulePeriodTo")) | |||||
const diffDays = Math.abs(from.diff(to, "day")) | |||||
let result: string[] = [] | |||||
for (let i = 0; i <= diffDays; i++) { | |||||
result.push(dayjsToDateString(from.add(i, "day"))) | |||||
} | |||||
return result; | |||||
}, []) | |||||
const [pagingController, setPagingController] = useState({ | const [pagingController, setPagingController] = useState({ | ||||
pageNum: 1, | pageNum: 1, | ||||
@@ -101,7 +88,7 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
router.replace(`/scheduling/rough`); | router.replace(`/scheduling/rough`); | ||||
}; | }; | ||||
const onSubmit = useCallback<SubmitHandler<CreateItemInputs & {}>>( | |||||
const onSubmit = useCallback<SubmitHandler<ProdScheduleResult>>( | |||||
async (data, event) => { | async (data, event) => { | ||||
let hasErrors = false; | let hasErrors = false; | ||||
console.log(errors) | console.log(errors) | ||||
@@ -122,12 +109,12 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
); | ); | ||||
// multiple tabs | // multiple tabs | ||||
const onSubmitError = useCallback<SubmitErrorHandler<CreateItemInputs>>( | |||||
(errors) => {}, | |||||
const onSubmitError = useCallback<SubmitErrorHandler<ProdScheduleResult>>( | |||||
(errors) => { }, | |||||
[] | [] | ||||
); | ); | ||||
const onClickEdit = () =>{ | |||||
const onClickEdit = () => { | |||||
setIsEdit(!isEdit) | setIsEdit(!isEdit) | ||||
} | } | ||||
@@ -139,57 +126,57 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
component="form" | component="form" | ||||
onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} | onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} | ||||
> | > | ||||
{/*<Grid>*/} | |||||
{/* <Typography mb={2} variant="h4">*/} | |||||
{/* {t(`${mode} ${title}`)}*/} | |||||
{/* </Typography>*/} | |||||
{/*</Grid>*/} | |||||
<DetailInfoCard | |||||
recordDetails={{ | |||||
id: 1, | |||||
scheduledPeriod: "2025-05-11 to 2025-05-17", | |||||
scheduledAt: "2025-05-07", | |||||
productCount: 13, | |||||
productionCount: 21000 | |||||
}} | |||||
{/*<Grid>*/} | |||||
{/* <Typography mb={2} variant="h4">*/} | |||||
{/* {t(`${mode} ${title}`)}*/} | |||||
{/* </Typography>*/} | |||||
{/*</Grid>*/} | |||||
<DetailInfoCard | |||||
// recordDetails={{ | |||||
// id: 1, | |||||
// scheduledPeriod: "2025-05-11 to 2025-05-17", | |||||
// scheduledAt: "2025-05-07", | |||||
// productCount: 13, | |||||
// productionCount: 21000 | |||||
// }} | |||||
isEditing={isEdit} | isEditing={isEdit} | ||||
/> | |||||
<Stack | |||||
/> | |||||
{/* <Stack | |||||
direction="row" | direction="row" | ||||
justifyContent="space-between" | justifyContent="space-between" | ||||
flexWrap="wrap" | flexWrap="wrap" | ||||
rowGap={2} | rowGap={2} | ||||
> | |||||
<Button | |||||
> | |||||
<Button | |||||
variant="contained" | variant="contained" | ||||
onClick={onClickEdit} | onClick={onClickEdit} | ||||
// startIcon={<Add />} | |||||
//LinkComponent={Link} | |||||
//href="qcCategory/create" | |||||
> | |||||
{isEdit ? t("Save") : t("Edit")} | |||||
</Button> | |||||
</Stack> | |||||
// startIcon={<Add />} | |||||
//LinkComponent={Link} | |||||
//href="qcCategory/create" | |||||
> | |||||
{isEdit ? t("Save") : t("Edit")} | |||||
</Button> | |||||
</Stack> */} | |||||
<Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | |||||
<Tab label={t("View By FG") + (tabIndex === 0 ? t(" (Selected)") : "")} iconPosition="end"/> | |||||
<Tab label={t("View By Material") + (tabIndex === 1 ? t(" (Selected)") : "")} iconPosition="end" /> | |||||
</Tabs> | |||||
<Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | |||||
<Tab label={t("View By FG") + (tabIndex === 0 ? t(" (Selected)") : "")} iconPosition="end" /> | |||||
<Tab label={t("View By Material") + (tabIndex === 1 ? t(" (Selected)") : "")} iconPosition="end" /> | |||||
</Tabs> | |||||
{serverError && ( | {serverError && ( | ||||
<Typography variant="body2" color="error" alignSelf="flex-end"> | <Typography variant="body2" color="error" alignSelf="flex-end"> | ||||
{serverError} | {serverError} | ||||
</Typography> | </Typography> | ||||
)} | )} | ||||
{tabIndex === 0 && <ViewByFGDetails isEdit={isEdit} apiRef={apiRef}/>} | |||||
{tabIndex === 1 && <ViewByBomDetails isEdit={isEdit} apiRef={apiRef} isHideButton={true} />} | |||||
<Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
{tabIndex === 0 && <ViewByFGDetails type={type} isEdit={isEdit} apiRef={apiRef} dayPeriod={dayPeriod} />} | |||||
{tabIndex === 1 && <ViewByBomDetails type={type} isEdit={isEdit} apiRef={apiRef} dayPeriod={dayPeriod}/>} | |||||
{/* <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
<Button | <Button | ||||
name="submit" | name="submit" | ||||
variant="contained" | variant="contained" | ||||
startIcon={<Check />} | startIcon={<Check />} | ||||
type="submit" | type="submit" | ||||
// disabled={submitDisabled} | |||||
// disabled={submitDisabled} | |||||
> | > | ||||
{isEditMode ? t("Save") : t("Confirm")} | {isEditMode ? t("Save") : t("Confirm")} | ||||
</Button> | </Button> | ||||
@@ -200,7 +187,7 @@ const RoughScheduleDetailView: React.FC<Props> = ({ | |||||
> | > | ||||
{t("Cancel")} | {t("Cancel")} | ||||
</Button> | </Button> | ||||
</Stack> | |||||
</Stack> */} | |||||
</Stack> | </Stack> | ||||
</FormProvider> | </FormProvider> | ||||
</> | </> | ||||
@@ -0,0 +1,592 @@ | |||||
// View By Bom Details | |||||
const dayPeriod = [ | |||||
'2025-05-11', | |||||
'2025-05-12', | |||||
'2025-05-13', | |||||
'2025-05-14', | |||||
'2025-05-15', | |||||
'2025-05-16', | |||||
'2025-05-17', | |||||
]; | |||||
// const fakeRecordLine = useMemo<FGRecord[][]>( | |||||
const fakeRecordLine = [ | |||||
[ | |||||
{ id: 1, code: "mt1", name: "material 1", inStockQty: 10, purchaseQty: 1 }, | |||||
{ id: 2, code: "mt2", name: "material 2", inStockQty: 20, purchaseQty: 199 }, | |||||
], | |||||
[ | |||||
{ id: 3, code: "mt3", name: "material 3", inStockQty: 30, purchaseQty: 3 }, | |||||
{ id: 4, code: "mt4", name: "material 4", inStockQty: 40, purchaseQty: 499 }, | |||||
], | |||||
[ | |||||
{ id: 5, code: "mt5", name: "material 5", inStockQty: 50, purchaseQty: 5 }, | |||||
{ id: 6, code: "mt6", name: "material 6", inStockQty: 60, purchaseQty: 699 }, | |||||
], | |||||
[ | |||||
{ id: 7, code: "mt7", name: "material 7", inStockQty: 70, purchaseQty: 7 }, | |||||
{ id: 8, code: "mt8", name: "material 8", inStockQty: 80, purchaseQty: 899 }, | |||||
], | |||||
[ | |||||
{ id: 9, code: "mt9", name: "material 9", inStockQty: 90, purchaseQty: 9 }, | |||||
{ id: 10, code: "mt10", name: "material 10", inStockQty: 100, purchaseQty: 999 }, | |||||
], | |||||
[ | |||||
{ id: 11, code: "mt11", name: "material 11", inStockQty: 110, purchaseQty: 11 }, | |||||
{ id: 12, code: "mt12", name: "material 12", inStockQty: 120, purchaseQty: 1299 }, | |||||
], | |||||
[ | |||||
{ id: 13, code: "mt13", name: "material 13", inStockQty: 130, purchaseQty: 13 }, | |||||
{ id: 14, code: "mt14", name: "material 14", inStockQty: 140, purchaseQty: 1499 }, | |||||
], | |||||
]; | |||||
// const fakeRecords = useMemo<FGRecord[][]>( | |||||
const fakeRecords = [ | |||||
[ | |||||
{ | |||||
id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ | |||||
id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ | |||||
id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ | |||||
id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ | |||||
id: 1, code: "PP1080", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", name: "粗蒜茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", name: "白麵撈", inStockQty: 60.00, purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 200.00 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ | |||||
id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ | |||||
id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
]; | |||||
// const fakeOverallRecords = useMemo<FGRecord[]>( | |||||
const fakeOverallRecords = [ | |||||
{ | |||||
id: 1, code: "PP1080", type: "FG", name: "咖哩汁", lastMonthAvgStock: 2400, safetyStock: 2400, inStockQty: 2400, productionQty: 8400.0 * 7, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 54.44, purchaseQty: 544.4 * 7 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52, purchaseQty: 3175.2 * 7 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00, purchaseQty: 90 * 7 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04, purchaseQty: 60.4 * 7 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 6.04, purchaseQty: 60.4 * 7 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 6.04, purchaseQty: 60.4 * 7 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98, purchaseQty: 2419.8 * 7 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00, purchaseQty: 360 * 7 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 * 7 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 600 * 7 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, purchaseQty: 6000 * 7 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", lastMonthAvgStock: 1320, safetyStock: 1322, inStockQty: 1322, productionQty: 4627, | |||||
lines: [ | |||||
{ id: 2, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 * 7 }, | |||||
{ id: 3, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 * 7 } | |||||
] | |||||
}, | |||||
{ | |||||
id: 3, code: " PP1188", type: "FG", name: "咖喱膽", lastMonthAvgStock: 1017, safetyStock: 1017, inStockQty: 1016.2, productionQty: 3556.7, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 * 7 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 * 7 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 * 7 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 * 7 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 * 7 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 * 7 }, | |||||
] | |||||
}, | |||||
{ | |||||
id: 4, code: " PP1096", type: "FG", name: "白麵撈", lastMonthAvgStock: 1040, safetyStock: 1040, inStockQty: 1040, productionQty: 3640, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 * 7 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 * 7 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
] | |||||
// View By Bom Details | |||||
const dayPeriod1 = [ | |||||
'2025-05-11', | |||||
'2025-05-12', | |||||
'2025-05-13', | |||||
'2025-05-14', | |||||
'2025-05-15', | |||||
'2025-05-16', | |||||
'2025-05-17', | |||||
]; | |||||
// const fakeOverallRecords = useMemo<FGOverallRecord[]>( | |||||
const fakeOverallRecords1 = [ | |||||
{ | |||||
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.00, | |||||
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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
] | |||||
// const fakeRecords = useMemo<FGRecord[][]>( | |||||
const fakeRecords1 = [ | |||||
[ | |||||
{ 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.00, 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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00, 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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00, 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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00, 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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00, 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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00, 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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00, 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.00, purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42, purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00, purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00, 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.00 }, | |||||
], | |||||
] |
@@ -9,248 +9,67 @@ import { | |||||
GridRowSelectionModel, | GridRowSelectionModel, | ||||
useGridApiRef, | useGridApiRef, | ||||
} from "@mui/x-data-grid"; | } from "@mui/x-data-grid"; | ||||
import {MutableRefObject, useCallback, useEffect, useMemo, useState} from "react"; | |||||
import { useFormContext } from "react-hook-form"; | |||||
import { MutableRefObject, useCallback, useEffect, useMemo, useState } from "react"; | |||||
import { useFieldArray, useFormContext } from "react-hook-form"; | |||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import InputDataGrid, { TableRow } from "../InputDataGrid/InputDataGrid"; | import InputDataGrid, { TableRow } from "../InputDataGrid/InputDataGrid"; | ||||
import {Box, Grid, Tooltip, Typography} from "@mui/material"; | |||||
import { Box, Grid, Tooltip, Typography } from "@mui/material"; | |||||
import { ItemQc } from "@/app/api/settings/item"; | import { ItemQc } from "@/app/api/settings/item"; | ||||
import { QcChecksInputs } from "@/app/api/settings/qcCheck/actions"; | import { QcChecksInputs } from "@/app/api/settings/qcCheck/actions"; | ||||
import { GridApiCommunity } from "@mui/x-data-grid/internals"; | import { GridApiCommunity } from "@mui/x-data-grid/internals"; | ||||
import { RiceBowl } from "@mui/icons-material"; | import { RiceBowl } from "@mui/icons-material"; | ||||
import EditableSearchResults, {Column} from "@/components/SearchResults/EditableSearchResults"; | |||||
// import EditableSearchResults, { Column } from "@/components/SearchResults/EditableSearchResults"; | |||||
import { decimalFormatter } from "@/app/utils/formatUtil"; | import { decimalFormatter } from "@/app/utils/formatUtil"; | ||||
import { GridRenderCellParams } from "@mui/x-data-grid"; | import { GridRenderCellParams } from "@mui/x-data-grid"; | ||||
import { ProdScheduleLineResultByBom, ProdScheduleLineResultByBomByDate, ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
import ScheduleTable from "@/components/ScheduleTable"; | |||||
import { Column } from "@/components/ScheduleTable/ScheduleTable"; | |||||
type Props = { | type Props = { | ||||
apiRef: MutableRefObject<GridApiCommunity> | apiRef: MutableRefObject<GridApiCommunity> | ||||
isEdit: boolean | |||||
type: ScheduleType | |||||
dayPeriod: string[] | |||||
}; | }; | ||||
type EntryError = | |||||
| { | |||||
[field in keyof QcChecksInputs]?: string; | |||||
} | |||||
| undefined; | |||||
export type FGRecord = { | |||||
id: string | number | |||||
code: string; | |||||
name: string; | |||||
inStockQty: number; | |||||
purchaseQty: number; | |||||
} | |||||
// 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; | |||||
} | |||||
// 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<Props> = ({ apiRef, isEdit }) => { | |||||
const {t,i18n: { language },} = useTranslation("schedule"); | |||||
console.log("lang:", i18n.language, "t(code):", t("code")); | |||||
const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) => { | |||||
const { t, i18n: { language }, } = useTranslation("schedule"); | |||||
const { | const { | ||||
control, | |||||
getValues, | |||||
formState: { errors, defaultValues, touchedFields }, | formState: { errors, defaultValues, touchedFields }, | ||||
} = useFormContext<CreateItemInputs>(); | |||||
// const apiRef = useGridApiRef(); | |||||
} = useFormContext<ProdScheduleResult>(); | |||||
// 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<FGRecord[][]>( | |||||
() => [ | |||||
[ | |||||
{ 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.00 , 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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00 , 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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00 , 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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00 , 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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00 , 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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00 , 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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
[ | |||||
{ 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.00 , 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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
], | |||||
[] | |||||
); | |||||
const fakeOverallRecords = useMemo<FGOverallRecord[]>( | |||||
() => [ | |||||
{ 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.00 , | |||||
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.00 , purchaseQty: 0 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 0 }, | |||||
{ id: 11, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , 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.00 }, | |||||
], | |||||
[] | |||||
); | |||||
const { fields } = useFieldArray({ | |||||
control, | |||||
name: "prodScheduleLinesByBom" | |||||
}) | |||||
const [pagingController, setPagingController] = useState([ | const [pagingController, setPagingController] = useState([ | ||||
{ | { | ||||
@@ -295,10 +114,15 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
}, | }, | ||||
]) | ]) | ||||
const updatePagingController = (updatedObj) => { | |||||
const updatePagingController = (updatedObj: { | |||||
pageNum: number; | |||||
pageSize: number; | |||||
totalCount: number; | |||||
index?: number | undefined; | |||||
}) => { | |||||
setPagingController((prevState) => { | setPagingController((prevState) => { | ||||
return prevState.map((item, index) => { | return prevState.map((item, index) => { | ||||
if (index === updatedObj?.index){ | |||||
if (index === updatedObj?.index) { | |||||
return { | return { | ||||
...item, | ...item, | ||||
pageNum: item.pageNum, | pageNum: item.pageNum, | ||||
@@ -329,139 +153,142 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
field: "type", | field: "type", | ||||
label: t("type"), | label: t("type"), | ||||
type: 'read-only', | type: 'read-only', | ||||
renderCell: (params) => { | |||||
return t(params.type) | |||||
} | |||||
// editable: true, | // editable: true, | ||||
}, | }, | ||||
{ | { | ||||
field: "inStockQty", | |||||
field: "availableQty", | |||||
label: t("Available Qty"), | label: t("Available Qty"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.inStockQty) == "number") { | |||||
return decimalFormatter.format(row.inStockQty) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.availableQty) == "number") { | |||||
return decimalFormatter.format(row.availableQty) | |||||
} | } | ||||
return row.inStockQty | |||||
return row.availableQty | |||||
} | } | ||||
// editable: true, | // editable: true, | ||||
}, | }, | ||||
{ | { | ||||
field: "overallPurchaseQty", | |||||
field: "totalDemandQty", | |||||
label: t("Total Demand Qty"), | label: t("Total Demand Qty"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.overallPurchaseQty) == "number") { | |||||
return decimalFormatter.format(row.overallPurchaseQty) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.totalDemandQty) == "number") { | |||||
return decimalFormatter.format(row.totalDemandQty) | |||||
} | } | ||||
return row.overallPurchaseQty | |||||
return row.totalDemandQty | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "purchaseQty1", | |||||
field: "demandQty1", | |||||
label: t("Demand Qty (Day1)"), | label: t("Demand Qty (Day1)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.purchaseQty1) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty1) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty1) == "number") { | |||||
return decimalFormatter.format(row.demandQty1) | |||||
} | } | ||||
return row.purchaseQty1 | |||||
return row.demandQty1 | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "purchaseQty2", | |||||
field: "demandQty2", | |||||
label: t("Demand Qty (Day2)"), | label: t("Demand Qty (Day2)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.purchaseQty2) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty2) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty2) == "number") { | |||||
return decimalFormatter.format(row.demandQty2) | |||||
} | } | ||||
return row.purchaseQty2 | |||||
return row.demandQty2 | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "purchaseQty3", | |||||
field: "demandQty3", | |||||
label: t("Demand Qty (Day3)"), | label: t("Demand Qty (Day3)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.purchaseQty3) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty3) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty3) == "number") { | |||||
return decimalFormatter.format(row.demandQty3) | |||||
} | } | ||||
return row.purchaseQty3 | |||||
return row.demandQty3 | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "purchaseQty4", | |||||
field: "demandQty4", | |||||
label: t("Demand Qty (Day4)"), | label: t("Demand Qty (Day4)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.purchaseQty4) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty4) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty4) == "number") { | |||||
return decimalFormatter.format(row.demandQty4) | |||||
} | } | ||||
return row.purchaseQty4 | |||||
return row.demandQty4 | |||||
} | } | ||||
},{ | |||||
field: "purchaseQty5", | |||||
}, { | |||||
field: "demandQty5", | |||||
label: t("Demand Qty (Day5)"), | label: t("Demand Qty (Day5)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.purchaseQty5) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty5) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty5) == "number") { | |||||
return decimalFormatter.format(row.demandQty5) | |||||
} | } | ||||
return row.purchaseQty5 | |||||
return row.demandQty5 | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "purchaseQty6", | |||||
field: "demandQty6", | |||||
label: t("Demand Qty (Day6)"), | label: t("Demand Qty (Day6)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.purchaseQty6) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty6) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty6) == "number") { | |||||
return decimalFormatter.format(row.demandQty6) | |||||
} | } | ||||
return row.purchaseQty6 | |||||
return row.demandQty6 | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "purchaseQty7", | |||||
field: "demandQty7", | |||||
label: t("Demand Qty (Day7)"), | label: t("Demand Qty (Day7)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGOverallRecord) => { | |||||
if (typeof(row.purchaseQty7) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty7) | |||||
renderCell: (row: ProdScheduleLineResultByBom) => { | |||||
if (typeof (row.demandQty7) == "number") { | |||||
return decimalFormatter.format(row.demandQty7) | |||||
} | } | ||||
return row.purchaseQty7 | |||||
return row.demandQty7 | |||||
} | } | ||||
}, | }, | ||||
], | ], | ||||
[t] | [t] | ||||
); | ); | ||||
const columns = useMemo<Column<any>[]>( | |||||
const columns = useMemo<Column<ProdScheduleLineResultByBomByDate>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
field: "code", | field: "code", | ||||
@@ -478,56 +305,62 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
field: "type", | field: "type", | ||||
label: t("type"), | label: t("type"), | ||||
type: 'read-only', | type: 'read-only', | ||||
renderCell: (params) => { | |||||
return t(params.type) | |||||
} | |||||
}, | }, | ||||
{ | { | ||||
field: "inStockQty", | |||||
field: "availableQty", | |||||
label: t("Available Qty"), | label: t("Available Qty"), | ||||
type: 'read-only', | type: 'read-only', | ||||
// editable: true, | // editable: true, | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.inStockQty) == "number") { | |||||
return decimalFormatter.format(row.inStockQty) | |||||
renderCell: (row: ProdScheduleLineResultByBomByDate) => { | |||||
if (typeof (row.availableQty) == "number") { | |||||
return decimalFormatter.format(row.availableQty) | |||||
} | } | ||||
return row.inStockQty | |||||
return row.availableQty | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "purchaseQty", | |||||
field: "demandQty", | |||||
label: t("Demand Qty"), | label: t("Demand Qty"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.purchaseQty) == "number") { | |||||
return decimalFormatter.format(row.purchaseQty) | |||||
renderCell: (row: ProdScheduleLineResultByBomByDate) => { | |||||
if (typeof (row.demandQty) == "number") { | |||||
return decimalFormatter.format(row.demandQty) | |||||
} | } | ||||
return row.purchaseQty | |||||
return row.demandQty | |||||
} | } | ||||
}, | }, | ||||
], | ], | ||||
[] | [] | ||||
); | ); | ||||
console.log(getValues("prodScheduleLinesByBom")) | |||||
return ( | return ( | ||||
<Grid container spacing={2}> | <Grid container spacing={2}> | ||||
<Grid item xs={12} key={"all"}> | <Grid item xs={12} key={"all"}> | ||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{t("Material Demand List (7 Days)")} | {t("Material Demand List (7 Days)")} | ||||
</Typography> | </Typography> | ||||
<EditableSearchResults<FGRecord> | |||||
index={7} | |||||
items={fakeOverallRecords} | |||||
isMockUp={true} | |||||
<ScheduleTable<ProdScheduleLineResultByBom> | |||||
// index={7} | |||||
type={type} | |||||
items={getValues("prodScheduleLinesByBom")} | |||||
columns={overallColumns} | columns={overallColumns} | ||||
setPagingController={updatePagingController} | setPagingController={updatePagingController} | ||||
pagingController={pagingController[7]} | pagingController={pagingController[7]} | ||||
isAutoPaging={true} | isAutoPaging={true} | ||||
isEditable={false} | isEditable={false} | ||||
isEdit={false} | isEdit={false} | ||||
hasCollapse={false} | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
{dayPeriod.map((date, index) => ( | {dayPeriod.map((date, index) => ( | ||||
@@ -535,15 +368,17 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{`${t("Material Demand Date")}: ${date}`} | {`${t("Material Demand Date")}: ${date}`} | ||||
</Typography> | </Typography> | ||||
<EditableSearchResults<FGRecord> | |||||
index={index} | |||||
items={fakeRecords[index]} // Use the corresponding records for the day | |||||
<ScheduleTable<ProdScheduleLineResultByBomByDate> | |||||
// index={index} | |||||
type={type} | |||||
items={getValues("prodScheduleLinesByBomByDate")[index + 1]} // Use the corresponding records for the day | |||||
columns={columns} | columns={columns} | ||||
setPagingController={updatePagingController} | setPagingController={updatePagingController} | ||||
pagingController={pagingController[index]} | pagingController={pagingController[index]} | ||||
isAutoPaging={true} | isAutoPaging={true} | ||||
isEditable={false} | isEditable={false} | ||||
isEdit={isEdit} | isEdit={isEdit} | ||||
hasCollapse={false} | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
))} | ))} | ||||
@@ -9,379 +9,56 @@ import { | |||||
GridRowSelectionModel, | GridRowSelectionModel, | ||||
useGridApiRef, | useGridApiRef, | ||||
} from "@mui/x-data-grid"; | } from "@mui/x-data-grid"; | ||||
import {MutableRefObject, useCallback, useMemo, useState} from "react"; | |||||
import { useFormContext } from "react-hook-form"; | |||||
import { MutableRefObject, useCallback, useMemo, useState } from "react"; | |||||
import { useFieldArray, useFormContext } from "react-hook-form"; | |||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import InputDataGrid, { TableRow } from "../InputDataGrid/InputDataGrid"; | import InputDataGrid, { TableRow } from "../InputDataGrid/InputDataGrid"; | ||||
import {Box, Grid, Tooltip, Typography} from "@mui/material"; | |||||
import { Box, Grid, Tooltip, Typography } from "@mui/material"; | |||||
import { ItemQc } from "@/app/api/settings/item"; | import { ItemQc } from "@/app/api/settings/item"; | ||||
import { QcChecksInputs } from "@/app/api/settings/qcCheck/actions"; | import { QcChecksInputs } from "@/app/api/settings/qcCheck/actions"; | ||||
import { GridApiCommunity } from "@mui/x-data-grid/internals"; | import { GridApiCommunity } from "@mui/x-data-grid/internals"; | ||||
import { RiceBowl } from "@mui/icons-material"; | import { RiceBowl } from "@mui/icons-material"; | ||||
import EditableSearchResults, {Column} from "@/components/SearchResults/EditableSearchResults"; | |||||
import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | |||||
import ScheduleTable from "@/components/ScheduleTable"; | |||||
import { Column } from "@/components/ScheduleTable/ScheduleTable"; | |||||
import { arrayToDayjs, dayjsToDateString, decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | |||||
import { ProdScheduleLineResultByFg, ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
type Props = { | type Props = { | ||||
apiRef: MutableRefObject<GridApiCommunity> | apiRef: MutableRefObject<GridApiCommunity> | ||||
isEdit: Boolean | |||||
isEdit: boolean | |||||
type: ScheduleType | |||||
dayPeriod: string[] | |||||
}; | }; | ||||
type EntryError = | |||||
| { | |||||
[field in keyof QcChecksInputs]?: string; | |||||
} | |||||
| undefined; | |||||
export type FGRecord = { | |||||
id: string | number | |||||
code: string; | |||||
name: string; | |||||
inStockQty: number; | |||||
productionQty?: number; | |||||
purchaseQty?: number | |||||
} | |||||
// export type FGRecord = { | |||||
// id: string | number | |||||
// code: string; | |||||
// name: string; | |||||
// inStockQty: number; | |||||
// productionQty?: number; | |||||
// purchaseQty?: number | |||||
// } | |||||
const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit, type, dayPeriod }) => { | |||||
const { | const { | ||||
t, | t, | ||||
i18n: { language }, | i18n: { language }, | ||||
} = useTranslation("schedule"); | } = useTranslation("schedule"); | ||||
const { | const { | ||||
control, | |||||
getValues, | |||||
formState: { errors, defaultValues, touchedFields }, | formState: { errors, defaultValues, touchedFields }, | ||||
} = useFormContext<CreateItemInputs>(); | |||||
// const apiRef = useGridApiRef(); | |||||
} = useFormContext<ProdScheduleResult>(); | |||||
const dayPeriod = [ | |||||
'2025-05-11', | |||||
'2025-05-12', | |||||
'2025-05-13', | |||||
'2025-05-14', | |||||
'2025-05-15', | |||||
'2025-05-16', | |||||
'2025-05-17', | |||||
]; | |||||
const fakeRecordLine = useMemo<FGRecord[][]>( | |||||
() => [ | |||||
[ | |||||
{ id: 1, code: "mt1", name: "material 1", inStockQty: 10, purchaseQty: 1 }, | |||||
{ id: 2, code: "mt2", name: "material 2", inStockQty: 20, purchaseQty: 199 }, | |||||
], | |||||
[ | |||||
{ id: 3, code: "mt3", name: "material 3", inStockQty: 30, purchaseQty: 3 }, | |||||
{ id: 4, code: "mt4", name: "material 4", inStockQty: 40, purchaseQty: 499 }, | |||||
], | |||||
[ | |||||
{ id: 5, code: "mt5", name: "material 5", inStockQty: 50, purchaseQty: 5 }, | |||||
{ id: 6, code: "mt6", name: "material 6", inStockQty: 60, purchaseQty: 699 }, | |||||
], | |||||
[ | |||||
{ id: 7, code: "mt7", name: "material 7", inStockQty: 70, purchaseQty: 7 }, | |||||
{ id: 8, code: "mt8", name: "material 8", inStockQty: 80, purchaseQty: 899 }, | |||||
], | |||||
[ | |||||
{ id: 9, code: "mt9", name: "material 9", inStockQty: 90, purchaseQty: 9 }, | |||||
{ id: 10, code: "mt10", name: "material 10", inStockQty: 100, purchaseQty: 999 }, | |||||
], | |||||
[ | |||||
{ id: 11, code: "mt11", name: "material 11", inStockQty: 110, purchaseQty: 11 }, | |||||
{ id: 12, code: "mt12", name: "material 12", inStockQty: 120, purchaseQty: 1299 }, | |||||
], | |||||
[ | |||||
{ id: 13, code: "mt13", name: "material 13", inStockQty: 130, purchaseQty: 13 }, | |||||
{ id: 14, code: "mt14", name: "material 14", inStockQty: 140, purchaseQty: 1499 }, | |||||
], | |||||
], | |||||
[] | |||||
); | |||||
const { fields } = useFieldArray({ | |||||
control, | |||||
name: "prodScheduleLinesByFg" | |||||
}) | |||||
// const apiRef = useGridApiRef(); | |||||
const fakeRecords = useMemo<FGRecord[][]>( | |||||
() => [ | |||||
[ | |||||
{ id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0 , purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0 , purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0 , purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0 , purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0 , purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0 , purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0 , purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0 , purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ id: 1, code: "PP1080", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0 , purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", name: "粗蒜茸", inStockQty: 0 , purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 200.00 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0 , purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0 , purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[ | |||||
{ id: 1, code: "PP1080", type: "FG", name: "咖哩汁", inStockQty: 2400, productionQty: 1200.0, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0 , purchaseQty: 108.88 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 635.04 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 18.00 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 12.08 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 12.08 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0 , purchaseQty: 12.08 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 483.96 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 72.00 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 154.84 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 120.00 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 200.0 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", inStockQty: 1322, productionQty: 661, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", type: "FG", name: "咖喱膽", inStockQty: 1016.2, productionQty: 508.1, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 3, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15 }, | |||||
{ id: 4, code: "MG1288", type: "Material", name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 0, purchaseQty: 6.05 }, | |||||
{ id: 6, code: "MG0066", type: "Material", name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", type: "FG", name: "白麵撈", inStockQty: 1040, productionQty: 520, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
], | |||||
[] | |||||
); | |||||
console.log("%c DayPeriod: ", 'background: #222; color: #bada55', dayPeriod) | |||||
const [pagingController, setPagingController] = useState([ | const [pagingController, setPagingController] = useState([ | ||||
{ | { | ||||
@@ -426,10 +103,15 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
}, | }, | ||||
]) | ]) | ||||
const updatePagingController = (updatedObj) => { | |||||
const updatePagingController = (updatedObj: { | |||||
pageNum: number; | |||||
pageSize: number; | |||||
totalCount: number; | |||||
index?: number | undefined; | |||||
}) => { | |||||
setPagingController((prevState) => { | setPagingController((prevState) => { | ||||
return prevState.map((item, index) => { | return prevState.map((item, index) => { | ||||
if (index === updatedObj?.index){ | |||||
if (index === updatedObj?.index) { | |||||
return { | return { | ||||
...item, | ...item, | ||||
pageNum: item.pageNum, | pageNum: item.pageNum, | ||||
@@ -443,7 +125,7 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
}); | }); | ||||
}; | }; | ||||
const columns = useMemo<Column<any>[]>( | |||||
const columns = useMemo<Column<ProdScheduleLineResultByFg>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
field: "code", | field: "code", | ||||
@@ -463,39 +145,39 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
// editable: true, | // editable: true, | ||||
}, | }, | ||||
{ | { | ||||
field: "inStockQty", | |||||
field: "availableQty", | |||||
label: t("Available Qty"), | label: t("Available Qty"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
// editable: true, | // editable: true, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.inStockQty) == "number") { | |||||
return decimalFormatter.format(row.inStockQty) | |||||
renderCell: (row) => { | |||||
if (typeof (row.availableQty) == "number") { | |||||
return decimalFormatter.format(row.availableQty) | |||||
} | } | ||||
return row.inStockQty | |||||
return row.availableQty | |||||
} | } | ||||
}, | }, | ||||
{ | { | ||||
field: "productionQty", | |||||
field: "prodQty", | |||||
label: t("Demand Qty"), | label: t("Demand Qty"), | ||||
type: 'input', | type: 'input', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.productionQty) == "number") { | |||||
return decimalFormatter.format(row.productionQty ?? 0) | |||||
renderCell: (row) => { | |||||
if (typeof (row.prodQty) == "number") { | |||||
return decimalFormatter.format(row.prodQty ?? 0) | |||||
} | } | ||||
return row.productionQty | |||||
return row.prodQty | |||||
} | } | ||||
}, | }, | ||||
], | ], | ||||
[] | [] | ||||
); | ); | ||||
const overallColumns = useMemo<Column<any>[]>( | |||||
const overallColumns = useMemo<Column<ProdScheduleLineResultByFg>[]>( | |||||
() => [ | () => [ | ||||
{ | { | ||||
field: "code", | field: "code", | ||||
@@ -512,114 +194,75 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
field: "type", | field: "type", | ||||
label: t("type"), | label: t("type"), | ||||
type: 'read-only', | type: 'read-only', | ||||
renderCell: (params) => { | |||||
return t(params.type) | |||||
} | |||||
// editable: true, | // editable: true, | ||||
}, | }, | ||||
{ | { | ||||
field: "lastMonthAvgStock", | |||||
field: "lastMonthAvgSales", | |||||
label: t("Last Month Average Stock"), | label: t("Last Month Average Stock"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.lastMonthAvgStock) == "number") { | |||||
return decimalFormatter.format(row.lastMonthAvgStock) | |||||
renderCell: (row) => { | |||||
if (typeof (row.lastMonthAvgSales) == "number") { | |||||
return decimalFormatter.format(row.lastMonthAvgSales) | |||||
} | } | ||||
return row.lastMonthAvgStock | |||||
return row.lastMonthAvgSales | |||||
} | } | ||||
// editable: true, | // editable: true, | ||||
}, | }, | ||||
{ | { | ||||
field: "safetyStock", | |||||
field: "estCloseBal", | |||||
label: t("Safety Stock"), | label: t("Safety Stock"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.safetyStock) == "number") { | |||||
return decimalFormatter.format(row.safetyStock) | |||||
renderCell: (row) => { | |||||
if (typeof (row.estCloseBal) == "number") { | |||||
return decimalFormatter.format(row.estCloseBal) | |||||
} | } | ||||
return row.safetyStock | |||||
return row.estCloseBal | |||||
} | } | ||||
// editable: true, | // editable: true, | ||||
}, | }, | ||||
{ | { | ||||
field: "inStockQty", | |||||
field: "availableQty", | |||||
label: t("Available Qty"), | label: t("Available Qty"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.inStockQty) == "number") { | |||||
return decimalFormatter.format(row.inStockQty) | |||||
renderCell: (row) => { | |||||
if (typeof (row.availableQty) == "number") { | |||||
return decimalFormatter.format(row.availableQty) | |||||
} | } | ||||
return row.inStockQty | |||||
return row.availableQty | |||||
} | } | ||||
// editable: true, | // editable: true, | ||||
}, | }, | ||||
{ | { | ||||
field: "productionQty", | |||||
field: "prodQty", | |||||
label: t("Demand Qty (7 Days)"), | label: t("Demand Qty (7 Days)"), | ||||
type: 'read-only', | type: 'read-only', | ||||
style: { | style: { | ||||
textAlign: "right", | textAlign: "right", | ||||
}, | }, | ||||
renderCell: (row: FGRecord) => { | |||||
if (typeof(row.productionQty) == "number") { | |||||
return decimalFormatter.format(row.productionQty) | |||||
renderCell: (row) => { | |||||
if (typeof (row.prodQty) == "number") { | |||||
return decimalFormatter.format(row.prodQty) | |||||
} | } | ||||
return row.productionQty | |||||
return row.prodQty | |||||
} | } | ||||
}, | }, | ||||
], | ], | ||||
[] | [] | ||||
); | ); | ||||
const fakeOverallRecords = useMemo<FGRecord[]>( | |||||
() => [ | |||||
{ id: 1, code: "PP1080", type: "FG", name: "咖哩汁", lastMonthAvgStock: 2400, safetyStock: 2400, inStockQty: 2400, productionQty: 8400.0*7, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 54.44 , purchaseQty: 544.4*7 }, | |||||
{ id: 2, code: "GI3236", type: "Material", name: "清水(煮過牛腩)", inStockQty: 317.52 , purchaseQty: 3175.2*7 }, | |||||
{ id: 3, code: "MG1700", type: "Material", name: "STERILTOM 意大利茄粒", inStockQty: 9.00 , purchaseQty: 90*7 }, | |||||
{ id: 4, code: "FA0533", type: "Material", name: "乾蔥茸", inStockQty: 6.04 , purchaseQty: 60.4*7 }, | |||||
{ id: 5, code: "FA0210", type: "Material", name: "薑茸", inStockQty: 6.04 , purchaseQty: 60.4*7 }, | |||||
{ id: 6, code: "FA0608", type: "Material", name: "粗蒜茸", inStockQty: 6.04 , purchaseQty: 60.4*7 }, | |||||
{ id: 7, code: "FA0056", type: "Material", name: "洋蔥肉", inStockQty: 241.98 , purchaseQty: 2419.8*7 }, | |||||
{ id: 8, code: "PP1188", type: "Material", name: "咖喱膽", inStockQty: 36.00 , purchaseQty: 360*7 }, | |||||
{ id: 9, code: "PP8001", type: "Material", name: "咖哩汁箱料粉", inStockQty: 77.42 , purchaseQty: 774.2*7 }, | |||||
{ id: 10, code: "PP1096", type: "Material", name: "白麵撈", inStockQty: 60.00 , purchaseQty: 600*7 }, | |||||
{ id: 10, code: "NA0476", type: "Material", name: "2磅份量三邊覆合袋 (0.1x225x260mm)個計", inStockQty: 600.00 , purchaseQty: 6000*7 }, | |||||
] | |||||
}, | |||||
{ id: 2, code: "PP1193", type: "FG", name: "蔥油(1磅) ", lastMonthAvgStock: 1320, safetyStock: 1322, inStockQty: 1322, productionQty: 4627, | |||||
lines: [ | |||||
{ id: 2, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 20*7 }, | |||||
{ id: 3, code: "FA0161", type: "Material", name: "洋蔥粒", inStockQty: 0, purchaseQty: 10*7 } | |||||
] | |||||
}, | |||||
{ id: 3, code: " PP1188", type: "FG", name: "咖喱膽", lastMonthAvgStock: 1017, safetyStock: 1017, inStockQty: 1016.2, productionQty: 3556.7, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material",name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 217.72*7 }, | |||||
{ id: 2, code: "FA0161", type: "Material",name: "洋蔥粒", inStockQty: 0, purchaseQty: 18.15*7 }, | |||||
{ id: 3, code: "FA0608", type: "Material",name: "粗蒜茸", inStockQty: 0, purchaseQty: 18.15*7 }, | |||||
{ id: 4, code: "MG1288", type: "Material",name: "炸紅蔥頭", inStockQty: 0, purchaseQty: 6.05*7 }, | |||||
{ id: 5, code: "FA0210", type: "Material",name: "薑茸", inStockQty: 0, purchaseQty: 6.05*7 }, | |||||
{ id: 6, code: "MG0066", type: "Material",name: "咖哩料(5斤x16包+2斤/包)", inStockQty: 0, purchaseQty: 241.98*7 }, | |||||
] | |||||
}, | |||||
{ id: 4, code: " PP1096", type: "FG", name: "白麵撈", lastMonthAvgStock: 1040, safetyStock: 1040, inStockQty: 1040, productionQty: 3640, | |||||
lines: [ | |||||
{ id: 1, code: "MH0040", type: "Material", name: "大豆油(1噸/桶)", inStockQty: 0, purchaseQty: 190.00*7 }, | |||||
{ id: 1, code: "MH0040", type: "Material", name: "星加坡綠富貴花牌幼白麵粉 (50磅/包)", inStockQty: 0, purchaseQty: 250.00*7 }, | |||||
{ id: 2, code: "FA0161", type: "Material", name: "蔥油", inStockQty: 1322, purchaseQty: 0 }, | |||||
] | |||||
}, | |||||
], | |||||
[] | |||||
); | |||||
console.log(getValues("prodScheduleLinesByFg")) | |||||
return ( | return ( | ||||
<Grid container spacing={2}> | <Grid container spacing={2}> | ||||
@@ -627,9 +270,10 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{t("FG Demand List (7 Days)")} | {t("FG Demand List (7 Days)")} | ||||
</Typography> | </Typography> | ||||
<EditableSearchResults<FGRecord> | |||||
index={7} | |||||
items={fakeOverallRecords} | |||||
<ScheduleTable<ProdScheduleLineResultByFg> | |||||
// index={7} | |||||
type={type} | |||||
items={getValues("prodScheduleLinesByFg")} | |||||
columns={overallColumns} | columns={overallColumns} | ||||
setPagingController={updatePagingController} | setPagingController={updatePagingController} | ||||
pagingController={pagingController[7]} | pagingController={pagingController[7]} | ||||
@@ -644,8 +288,9 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => { | |||||
<Typography variant="overline" display="block" marginBlockEnd={1}> | <Typography variant="overline" display="block" marginBlockEnd={1}> | ||||
{`${t("FG Demand Date")}: ${date}`} | {`${t("FG Demand Date")}: ${date}`} | ||||
</Typography> | </Typography> | ||||
<EditableSearchResults<FGRecord> | |||||
items={fakeRecords[index]} // Use the corresponding records for the day | |||||
<ScheduleTable<ProdScheduleLineResultByFg> | |||||
type={type} | |||||
items={getValues("prodScheduleLinesByFgByDate")[index + 1]} // Use the corresponding records for the day | |||||
columns={columns} | columns={columns} | ||||
setPagingController={updatePagingController} | setPagingController={updatePagingController} | ||||
pagingController={pagingController[index]} | pagingController={pagingController[index]} | ||||
@@ -0,0 +1,255 @@ | |||||
"use client"; | |||||
import { | |||||
FooterPropsOverrides, | |||||
GridActionsCellItem, | |||||
GridCellParams, | |||||
GridRowId, | |||||
GridRowIdGetter, | |||||
GridRowModel, | |||||
GridRowModes, | |||||
GridRowModesModel, | |||||
GridToolbarContainer, | |||||
useGridApiRef, | |||||
} from "@mui/x-data-grid"; | |||||
import { | |||||
Dispatch, | |||||
MutableRefObject, | |||||
SetStateAction, | |||||
useCallback, | |||||
useEffect, | |||||
useMemo, | |||||
useState, | |||||
} from "react"; | |||||
import StyledDataGrid from "../StyledDataGrid"; | |||||
import { GridColDef } from "@mui/x-data-grid"; | |||||
import { Box, Button, Grid, Icon, Typography } from "@mui/material"; | |||||
import { useTranslation } from "react-i18next"; | |||||
import { Add } from "@mui/icons-material"; | |||||
import SaveIcon from "@mui/icons-material/Save"; | |||||
import DeleteIcon from "@mui/icons-material/Delete"; | |||||
import CancelIcon from "@mui/icons-material/Cancel"; | |||||
import FactCheckIcon from "@mui/icons-material/FactCheck"; | |||||
import ShoppingCartIcon from "@mui/icons-material/ShoppingCart"; | |||||
// import PoQcModal from "./PoQcModal"; | |||||
import PlayArrowIcon from "@mui/icons-material/PlayArrow"; | |||||
import { useSearchParams } from "next/navigation"; | |||||
import { decimalFormatter } from "@/app/utils/formatUtil"; | |||||
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; | |||||
import HighlightOffIcon from '@mui/icons-material/HighlightOff'; | |||||
import { ProdScheduleLineBomMaterialResult, ScheduleType } from "@/app/api/scheduling"; | |||||
interface ResultWithId { | |||||
id: number; | |||||
} | |||||
interface Props { | |||||
bomMaterial: ProdScheduleLineBomMaterialResult[]; | |||||
type: ScheduleType | |||||
} | |||||
export type BomMaterialEntryError = { | |||||
[field in keyof any]?: string; | |||||
}; | |||||
export type BomMaterialRow = Partial< | |||||
any & { | |||||
isActive: boolean | undefined; | |||||
_isNew: boolean; | |||||
_error: BomMaterialEntryError; | |||||
} & ResultWithId | |||||
>; | |||||
class ProcessRowUpdateError extends Error { | |||||
public readonly row: BomMaterialRow; | |||||
public readonly errors: BomMaterialEntryError | undefined; | |||||
constructor(row: BomMaterialRow, message?: string, errors?: BomMaterialEntryError) { | |||||
super(message); | |||||
this.row = row; | |||||
this.errors = errors; | |||||
Object.setPrototypeOf(this, ProcessRowUpdateError.prototype); | |||||
} | |||||
} | |||||
function BomMaterialTable({ bomMaterial }: Props) { | |||||
const { t } = useTranslation("schedule"); | |||||
const apiRef = useGridApiRef(); | |||||
const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({}); | |||||
const getRowId = useCallback<GridRowIdGetter<BomMaterialRow>>( | |||||
(row) => row.id as number, | |||||
[] | |||||
); | |||||
const [entries, setEntries] = useState<BomMaterialRow[]>(bomMaterial || []); | |||||
const columns = useMemo<GridColDef[]>( | |||||
() => [ | |||||
{ | |||||
field: "code", | |||||
headerName: t("Code"), | |||||
flex: 1, | |||||
}, | |||||
{ | |||||
field: "name", | |||||
headerName: t("Name"), | |||||
flex: 1, | |||||
}, | |||||
{ | |||||
field: "type", | |||||
headerName: t("type"), | |||||
flex: 1, | |||||
renderCell: (row) => { | |||||
return t(row.value) | |||||
} | |||||
}, | |||||
{ | |||||
field: "availableQty", | |||||
headerName: t("Available Qty"), | |||||
flex: 0.5, | |||||
type: "number", | |||||
editable: true, | |||||
align: "right", | |||||
headerAlign: "right", | |||||
renderCell: (row) => { | |||||
return decimalFormatter.format(row.value) | |||||
} | |||||
// replace with tooltip + content | |||||
}, | |||||
{ | |||||
field: "demandQty", | |||||
headerName: t("Demand Qty"), | |||||
flex: 0.5, | |||||
editable: true, | |||||
align: "right", | |||||
headerAlign: "right", | |||||
renderCell: (row) => { | |||||
return decimalFormatter.format(row.value) | |||||
} | |||||
}, | |||||
{ | |||||
field: "status", | |||||
headerName: t("status"), | |||||
flex: 0.5, | |||||
editable: true, | |||||
align: "center", | |||||
headerAlign: "center", | |||||
renderCell: (params) => { | |||||
return params.row.availableQty - params.row.demandQty >= 0 ? | |||||
<CheckCircleOutlineIcon | |||||
color="success" | |||||
fontSize="small" | |||||
/> : | |||||
<HighlightOffIcon | |||||
color="error" | |||||
fontSize="small" | |||||
/> | |||||
} | |||||
}, | |||||
], | |||||
[] | |||||
); | |||||
const validation = useCallback( | |||||
( | |||||
newRow: GridRowModel<BomMaterialRow> | |||||
): BomMaterialEntryError | undefined => { | |||||
const error: BomMaterialEntryError = {}; | |||||
console.log(newRow); | |||||
return Object.keys(error).length > 0 ? error : undefined; | |||||
}, | |||||
[] | |||||
); | |||||
const processRowUpdate = useCallback( | |||||
(newRow: GridRowModel<BomMaterialRow>, originalRow: GridRowModel<BomMaterialRow>) => { | |||||
const errors = validation(newRow); // change to validation | |||||
if (errors) { | |||||
throw new ProcessRowUpdateError( | |||||
originalRow, | |||||
"validation error", | |||||
errors | |||||
); | |||||
} | |||||
const { _isNew, _error, ...updatedRow } = newRow; | |||||
const rowToSave = { | |||||
...updatedRow, | |||||
} satisfies BomMaterialRow; | |||||
const newEntries = entries.map((e) => | |||||
getRowId(e) === getRowId(originalRow) ? rowToSave : e | |||||
); | |||||
setEntries(newEntries); | |||||
//update remaining qty | |||||
const total = newEntries.reduce((acc, curr) => acc + (curr.acceptedQty || 0), 0); | |||||
return rowToSave; | |||||
}, | |||||
[getRowId, entries] | |||||
); | |||||
const onProcessRowUpdateError = useCallback( | |||||
(updateError: ProcessRowUpdateError) => { | |||||
const errors = updateError.errors; | |||||
const oldRow = updateError.row; | |||||
apiRef.current.updateRows([{ ...oldRow, _error: errors }]); | |||||
}, | |||||
[apiRef] | |||||
); | |||||
return ( | |||||
<> | |||||
<StyledDataGrid | |||||
getRowId={getRowId} | |||||
apiRef={apiRef} | |||||
autoHeight | |||||
sx={{ | |||||
"--DataGrid-overlayHeight": "100px", | |||||
".MuiDataGrid-row .MuiDataGrid-cell.hasError": { | |||||
border: "1px solid", | |||||
borderColor: "error.main", | |||||
}, | |||||
".MuiDataGrid-row .MuiDataGrid-cell.hasWarning": { | |||||
border: "1px solid", | |||||
borderColor: "warning.main", | |||||
}, | |||||
}} | |||||
disableColumnMenu | |||||
editMode="row" | |||||
rows={entries} | |||||
rowModesModel={rowModesModel} | |||||
onRowModesModelChange={setRowModesModel} | |||||
processRowUpdate={processRowUpdate} | |||||
onProcessRowUpdateError={onProcessRowUpdateError} | |||||
columns={columns} | |||||
getCellClassName={(params: GridCellParams<BomMaterialRow>) => { | |||||
let classname = ""; | |||||
if (params.row._error) { | |||||
classname = "hasError"; | |||||
} | |||||
return classname; | |||||
}} | |||||
// slots={{ | |||||
// footer: FooterToolbar, | |||||
// noRowsOverlay: NoRowsOverlay, | |||||
// }} | |||||
// slotProps={{ | |||||
// footer: { child: footer }, | |||||
// }} | |||||
/> | |||||
</> | |||||
); | |||||
} | |||||
const NoRowsOverlay: React.FC = () => { | |||||
const { t } = useTranslation("home"); | |||||
return ( | |||||
<Box | |||||
display="flex" | |||||
justifyContent="center" | |||||
alignItems="center" | |||||
height="100%" | |||||
> | |||||
<Typography variant="caption">{t("Add some entries!")}</Typography> | |||||
</Box> | |||||
); | |||||
}; | |||||
const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => { | |||||
return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>; | |||||
}; | |||||
export default BomMaterialTable; |
@@ -0,0 +1,334 @@ | |||||
"use client"; | |||||
import React, { CSSProperties, DetailedHTMLProps, HTMLAttributes, useEffect, useState } from "react"; | |||||
import Paper from "@mui/material/Paper"; | |||||
import Table from "@mui/material/Table"; | |||||
import TableBody from "@mui/material/TableBody"; | |||||
import TableCell from "@mui/material/TableCell"; | |||||
import TableContainer from "@mui/material/TableContainer"; | |||||
import TableHead from "@mui/material/TableHead"; | |||||
import TablePagination from "@mui/material/TablePagination"; | |||||
import TableRow from "@mui/material/TableRow"; | |||||
import IconButton from "@mui/material/IconButton"; | |||||
import EditIcon from "@mui/icons-material/Edit"; | |||||
import SaveIcon from "@mui/icons-material/Save"; | |||||
import CancelIcon from "@mui/icons-material/Close"; | |||||
import DeleteIcon from "@mui/icons-material/Delete"; | |||||
import TextField from "@mui/material/TextField"; | |||||
import MultiSelect from "@/components/SearchBox/MultiSelect"; | |||||
import { Collapse, Typography } from "@mui/material"; | |||||
import BomMaterialTable from "./BomMaterialTable"; | |||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; | |||||
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; | |||||
import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | |||||
import PlayCircleOutlineIcon from '@mui/icons-material/PlayCircleOutline'; | |||||
import { useTranslation } from "react-i18next"; | |||||
import { ProdScheduleLineBomMaterialResult, ProdScheduleLineResultByFg, ProdScheduleResult, ScheduleType } from "@/app/api/scheduling"; | |||||
export interface ResultWithId { | |||||
id: string | number; | |||||
// id: number; | |||||
} | |||||
interface BaseColumn<T extends ResultWithId> { | |||||
field: keyof T; | |||||
label: string; | |||||
type: string; | |||||
options?: T[]; | |||||
renderCell?: (params: T) => React.ReactNode; | |||||
style?: Partial<HTMLElement["style"]> & { [propName: string]: string } & CSSProperties; | |||||
} | |||||
interface ColumnWithAction<T extends ResultWithId> extends BaseColumn<T> { | |||||
onClick: (item: T) => void; | |||||
buttonIcon: React.ReactNode; | |||||
buttonColor?: "inherit" | "default" | "primary" | "secondary"; | |||||
} | |||||
export type Column<T extends ResultWithId> = | |||||
| BaseColumn<T> | |||||
| ColumnWithAction<T>; | |||||
interface Props<T extends ResultWithId> { | |||||
index?: number, | |||||
items: T[], | |||||
columns: Column<T>[], | |||||
noWrapper?: boolean, | |||||
setPagingController: (value: { pageNum: number; pageSize: number; totalCount: number, index?: number }) => void, | |||||
pagingController: { pageNum: number; pageSize: number; totalCount: number }, | |||||
isAutoPaging: boolean, | |||||
isEdit: boolean, | |||||
isEditable: boolean, | |||||
hasCollapse: boolean, | |||||
type: ScheduleType | |||||
} | |||||
function ScheduleTable<T extends ResultWithId>({ | |||||
type, | |||||
index = 7, | |||||
items, | |||||
columns, | |||||
noWrapper, | |||||
pagingController, | |||||
setPagingController, | |||||
isAutoPaging = true, | |||||
isEdit = false, | |||||
isEditable = true, | |||||
hasCollapse = false, | |||||
}: Props<T>) { | |||||
const [page, setPage] = useState(0); | |||||
const [rowsPerPage, setRowsPerPage] = useState(10); | |||||
const [editingRowId, setEditingRowId] = useState<number | null>(null); | |||||
const [editedItems, setEditedItems] = useState<T[]>(items); | |||||
const { t } = useTranslation("schedule"); | |||||
useEffect(() => { | |||||
setEditedItems(items) | |||||
}, [items]) | |||||
const handleChangePage = (_event: unknown, newPage: number) => { | |||||
setPage(newPage); | |||||
if (setPagingController) { | |||||
setPagingController({ ...pagingController, pageNum: newPage + 1, index: (index ?? -1)}); | |||||
} | |||||
}; | |||||
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => { | |||||
setRowsPerPage(+event.target.value); | |||||
setPage(0); | |||||
if (setPagingController) { | |||||
setPagingController({ ...pagingController, pageSize: +event.target.value, pageNum: 1, index: index }); | |||||
} | |||||
}; | |||||
const handleEditClick = (id: number) => { | |||||
setEditingRowId(id); | |||||
}; | |||||
const handleSaveClick = (item: T) => { | |||||
setEditingRowId(null); | |||||
// Call API or any save logic here | |||||
setEditedItems((prev) => | |||||
prev.map((row) => (row.id === item.id ? { ...row } : row)) | |||||
); | |||||
}; | |||||
const handleInputChange = (id: number, field: keyof T, value: string | number[]) => { | |||||
setEditedItems((prev) => | |||||
prev.map((item) => | |||||
item.id === id ? { ...item, [field]: value } : item | |||||
) | |||||
); | |||||
}; | |||||
const handleDeleteClick = (id: number) => { | |||||
// Implement delete logic here | |||||
setEditedItems((prev) => prev.filter(item => item.id !== id)); | |||||
}; | |||||
useEffect(() => { | |||||
console.log("[debug] isEdit in table", isEdit) | |||||
//TODO: switch all record to not in edit mode and save the changes | |||||
if (!isEdit) { | |||||
editedItems?.forEach(item => { | |||||
// Call save logic here | |||||
// console.log("Saving item:", item); | |||||
// Reset editing state if needed | |||||
}); | |||||
setEditingRowId(null); | |||||
} | |||||
}, [isEdit]) | |||||
function isRoughType( | |||||
type: ScheduleType | |||||
): type is "rough" { | |||||
return type === "rough"; | |||||
} | |||||
function isDetailType( | |||||
type: ScheduleType | |||||
): type is "detail" { | |||||
return type === "detail"; | |||||
} | |||||
function Row(props: { row: T }) { | |||||
const { row } = props; | |||||
const [open, setOpen] = useState(false); | |||||
// console.log(row) | |||||
return ( | |||||
<> | |||||
<TableRow hover tabIndex={-1} key={row.id}> | |||||
{isDetailType(type) && <TableCell> | |||||
<IconButton disabled={!isEdit}> | |||||
<PlayCircleOutlineIcon /> | |||||
</IconButton> | |||||
</TableCell>} | |||||
{ | |||||
(isEditable || hasCollapse) && <TableCell> | |||||
{(editingRowId === row.id) ? ( | |||||
<> | |||||
{ | |||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => handleSaveClick(row)}> | |||||
<SaveIcon /> | |||||
</IconButton> | |||||
} | |||||
{ | |||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} onClick={() => setEditingRowId(null)}> | |||||
<CancelIcon /> | |||||
</IconButton> | |||||
} | |||||
{ | |||||
hasCollapse && <IconButton | |||||
aria-label="expand row" | |||||
size="small" | |||||
onClick={() => setOpen(!open)} | |||||
> | |||||
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />} | |||||
<Typography>{t("View BoM")}</Typography> | |||||
</IconButton> | |||||
} | |||||
</> | |||||
) : ( | |||||
<> | |||||
{ | |||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} | |||||
onClick={() => handleEditClick(row.id as number)}> | |||||
<EditIcon /> | |||||
</IconButton> | |||||
} | |||||
{ | |||||
isDetailType(type) && isEditable && <IconButton disabled={!isEdit} | |||||
onClick={() => handleDeleteClick(row.id as number)}> | |||||
<DeleteIcon /> | |||||
</IconButton> | |||||
} | |||||
{ | |||||
hasCollapse && <IconButton | |||||
aria-label="expand row" | |||||
size="small" | |||||
onClick={() => setOpen(!open)} | |||||
> | |||||
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />} | |||||
<Typography>{t("View BoM")}</Typography> | |||||
</IconButton> | |||||
} | |||||
</> | |||||
)} | |||||
</TableCell> | |||||
} | |||||
{columns.map((column, idx) => { | |||||
const columnName = column.field; | |||||
return ( | |||||
<TableCell key={`${columnName.toString()}-${idx}`}> | |||||
{editingRowId === row.id ? ( | |||||
(() => { | |||||
switch (column.type) { | |||||
case 'input': | |||||
return ( | |||||
<TextField | |||||
hiddenLabel={true} | |||||
fullWidth | |||||
defaultValue={row[columnName] as string} | |||||
onChange={(e) => handleInputChange(row.id as number, columnName, e.target.value)} | |||||
/> | |||||
); | |||||
// case 'multi-select': | |||||
// //TODO: May need update if use | |||||
// return ( | |||||
// <MultiSelect | |||||
// //label={column.label} | |||||
// options={column.options ?? []} | |||||
// selectedValues={[]} | |||||
// onChange={(selectedValues) => handleInputChange(row.id as number, columnName, selectedValues)} | |||||
// /> | |||||
// ); | |||||
case 'read-only': | |||||
return ( | |||||
<span> | |||||
{row[columnName] as string} | |||||
</span> | |||||
); | |||||
default: | |||||
return null; // Handle any default case if needed | |||||
} | |||||
})() | |||||
) : ( | |||||
column.renderCell ? | |||||
<div style={column.style}> | |||||
{column.renderCell(row)} | |||||
</div> | |||||
: | |||||
<div style={column.style}> | |||||
<span onDoubleClick={() => isEdit && handleEditClick(row.id as number)}> | |||||
{row[columnName] as String} | |||||
</span> | |||||
</div> | |||||
)} | |||||
</TableCell> | |||||
); | |||||
})} | |||||
</TableRow> | |||||
<TableRow> | |||||
{ | |||||
hasCollapse && | |||||
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}> | |||||
<Collapse in={open} timeout="auto" unmountOnExit> | |||||
<Table> | |||||
<TableBody> | |||||
<TableRow> | |||||
<TableCell> | |||||
<BomMaterialTable | |||||
type={type} | |||||
bomMaterial={(row as unknown as ProdScheduleLineResultByFg).bomMaterials} | |||||
/> | |||||
</TableCell> | |||||
</TableRow> | |||||
</TableBody> | |||||
</Table> | |||||
</Collapse> | |||||
</TableCell> | |||||
} | |||||
</TableRow> | |||||
</> | |||||
) | |||||
} | |||||
const table = ( | |||||
<> | |||||
<TableContainer sx={{ maxHeight: 440 }}> | |||||
<Table stickyHeader> | |||||
<TableHead> | |||||
<TableRow> | |||||
{isDetailType(type) && <TableCell>{t("Release")}</TableCell>} | |||||
{(isEditable || hasCollapse) && <TableCell>{t("Actions")}</TableCell>} {/* Action Column Header */} | |||||
{columns.map((column, idx) => ( | |||||
<TableCell style={column.style} key={`${column.field.toString()}${idx}`}> | |||||
{column.label} | |||||
</TableCell> | |||||
))} | |||||
</TableRow> | |||||
</TableHead> | |||||
<TableBody> | |||||
{/* {(isAutoPaging ? editedItems.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) : editedItems).map((item) => ( */} | |||||
{(editedItems?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage))?.map((item) => ( | |||||
<Row key={item.id} row={item} /> | |||||
))} | |||||
</TableBody> | |||||
</Table> | |||||
</TableContainer> | |||||
<TablePagination | |||||
rowsPerPageOptions={[10, 25, 100]} | |||||
component="div" | |||||
// count={pagingController.totalCount === 0 ? editedItems.length : pagingController.totalCount} | |||||
count={editedItems?.length ?? 0} | |||||
rowsPerPage={rowsPerPage} | |||||
page={page} | |||||
onPageChange={handleChangePage} | |||||
onRowsPerPageChange={handleChangeRowsPerPage} | |||||
/> | |||||
</> | |||||
); | |||||
return noWrapper ? table : <Paper sx={{ overflow: "hidden" }}>{table}</Paper>; | |||||
} | |||||
export default ScheduleTable; |
@@ -0,0 +1 @@ | |||||
export { default } from "./ScheduleTable" |
@@ -24,20 +24,20 @@ | |||||
"Product Count": "產品數量", | "Product Count": "產品數量", | ||||
"Scheduled At": "排程時間", | "Scheduled At": "排程時間", | ||||
"Demand Forecast Period": "需求預測期間", | "Demand Forecast Period": "需求預測期間", | ||||
"FG & Material Demand Forecast Detail": "FG 及材料需求預測詳情", | |||||
"FG & Material Demand Forecast": "FG 及材料需求預測", | |||||
"FG & Material Demand Forecast Detail": "成品及物料需求預測詳情", | |||||
"FG & Material Demand Forecast": "成品及物料需求預測", | |||||
"Total Estimated Demand Qty": "總預估需求量", | "Total Estimated Demand Qty": "總預估需求量", | ||||
"View By FG": "依 FG 分類", | |||||
"View By Material": "依材料分類", | |||||
"View By FG": "依成品分類", | |||||
"View By Material": "依物料分類", | |||||
" (Selected)": " (已選擇)", | " (Selected)": " (已選擇)", | ||||
"Total FG Item": "總 FG 項目", | |||||
"Total FG Item": "總成品項目", | |||||
"Release": "發佈", | "Release": "發佈", | ||||
"Actions": "動作", | "Actions": "動作", | ||||
"FG Demand List (7 Days)": "FG 需求列表(7 天)", | |||||
"FG Demand Date": "FG 需求日期", | |||||
"FG Demand Qty": "FG 需求數量", | |||||
"Material Demand Date": "材料需求日期", | |||||
"Material Demand List": "材料需求列表", | |||||
"FG Demand List (7 Days)": "成品需求列表(7 天)", | |||||
"FG Demand Date": "成品需求日期", | |||||
"FG Demand Qty": "成品需求數量", | |||||
"Material Demand Date": "物料需求日期", | |||||
"Material Demand List": "物料需求列表", | |||||
"Available Qty": "可用數量", | "Available Qty": "可用數量", | ||||
"Demand Qty": "需求數量", | "Demand Qty": "需求數量", | ||||
"Confirm": "確認", | "Confirm": "確認", | ||||
@@ -50,7 +50,7 @@ | |||||
"Selected": "已選擇", | "Selected": "已選擇", | ||||
"Unselected": "未選擇", | "Unselected": "未選擇", | ||||
"status": "狀態", | "status": "狀態", | ||||
"Material Demand List (7 Days)": "材料需求列表(7 天)", | |||||
"Material Demand List (7 Days)": "物料需求列表(7 天)", | |||||
"Mon": "週一", | "Mon": "週一", | ||||
"Tue": "週二", | "Tue": "週二", | ||||
"Wed": "週三", | "Wed": "週三", | ||||
@@ -59,14 +59,15 @@ | |||||
"Sat": "週六", | "Sat": "週六", | ||||
"Sun": "週日", | "Sun": "週日", | ||||
"Last Month Average Stock": "上個月平均庫存", | "Last Month Average Stock": "上個月平均庫存", | ||||
"Last Month Average Sales": "上個月平均銷售", | |||||
"Safety Stock": "安全庫存", | "Safety Stock": "安全庫存", | ||||
"Demand Qty (7 Days)": "需求數量(7 天)", | "Demand Qty (7 Days)": "需求數量(7 天)", | ||||
"Estimated Production Time": "預估生產時間", | "Estimated Production Time": "預估生產時間", | ||||
"Production Priority": "生產優先順序", | "Production Priority": "生產優先順序", | ||||
"View BoM": "查看 BoM", | |||||
"View BoM": "查看物料清單", | |||||
"Date": "日期", | "Date": "日期", | ||||
"Detail Scheduling": "詳細排程", | "Detail Scheduling": "詳細排程", | ||||
"FG Production Schedule": "FG 生產排程", | |||||
"FG Production Schedule": "成品生產排程", | |||||
"Production Date": "生產日期", | "Production Date": "生產日期", | ||||
"Total Job Order": "總工單數量", | "Total Job Order": "總工單數量", | ||||
"Total Production Qty": "總生產數量", | "Total Production Qty": "總生產數量", | ||||
@@ -76,6 +77,6 @@ | |||||
"Job Status": "工單狀態", | "Job Status": "工單狀態", | ||||
"Job Priority": "工單優先順序", | "Job Priority": "工單優先順序", | ||||
"Job Date": "工單日期", | "Job Date": "工單日期", | ||||
"Job Qty": "工單數量" | |||||
"Job Qty": "工單數量", | |||||
"mat": "物料" | |||||
} | } |