Parcourir la source

[Prod Schedule] Update Rough Schedule (e.g. search & view detail)

master
cyril.tsui il y a 1 mois
Parent
révision
7cb91cda01
17 fichiers modifiés avec 1857 ajouts et 998 suppressions
  1. +17
    -0
      src/app/(main)/scheduling/rough/edit/not-found.tsx
  2. +26
    -6
      src/app/(main)/scheduling/rough/edit/page.tsx
  3. +2
    -1
      src/app/(main)/scheduling/rough/page.tsx
  4. +43
    -0
      src/app/api/scheduling/actions.ts
  5. +82
    -0
      src/app/api/scheduling/index.ts
  6. +156
    -108
      src/components/RoughSchedule/RoughSchedileSearchView.tsx
  7. +18
    -4
      src/components/RoughSchedule/RoughScheduleWrapper.tsx
  8. +42
    -37
      src/components/RoughScheduleDetail/DetailInfoCard.tsx
  9. +8
    -29
      src/components/RoughScheduleDetail/RoughScheduleDetailWrapper.tsx
  10. +62
    -75
      src/components/RoughScheduleDetail/RoughScheudleDetailView.tsx
  11. +592
    -0
      src/components/RoughScheduleDetail/TempRecords.tsx
  12. +125
    -290
      src/components/RoughScheduleDetail/ViewByBomDetails.tsx
  13. +78
    -433
      src/components/RoughScheduleDetail/ViewByFGDetails.tsx
  14. +255
    -0
      src/components/ScheduleTable/BomMaterialTable.tsx
  15. +334
    -0
      src/components/ScheduleTable/ScheduleTable.tsx
  16. +1
    -0
      src/components/ScheduleTable/index.ts
  17. +16
    -15
      src/i18n/zh/schedule.json

+ 17
- 0
src/app/(main)/scheduling/rough/edit/not-found.tsx Voir le fichier

@@ -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>
);
}

+ 26
- 6
src/app/(main)/scheduling/rough/edit/page.tsx Voir le fichier

@@ -8,15 +8,35 @@ import Typography from "@mui/material/Typography";
import { Metadata } from "next";
import Link from "next/link";
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 = {
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();

return (
@@ -39,9 +59,9 @@ const roughSchedulingDetail: React.FC = async () => {
{t("Create product")}
</Button> */}
</Stack>
<I18nProvider namespaces={["schedule","project","common"]}>
<I18nProvider namespaces={["schedule","common"]}>
<Suspense fallback={<RoughScheduleDetailView.Loading />}>
<RoughScheduleDetailView />
<RoughScheduleDetailView type={type} id={parseInt(id)}/>
</Suspense>
</I18nProvider>
</>


+ 2
- 1
src/app/(main)/scheduling/rough/page.tsx Voir le fichier

@@ -19,6 +19,7 @@ export const metadata: Metadata = {
const roughScheduling: React.FC = async () => {
// const project = TypeEnum.PRODUCT
const { t } = await getServerI18n("schedule");
const type = "rough"
// preloadClaims();

return (
@@ -44,7 +45,7 @@ const roughScheduling: React.FC = async () => {
</Stack>
<I18nProvider namespaces={["schedule", "common","items","project"]}>
<Suspense fallback={<RoughSchedule.Loading />}>
<RoughSchedule />
<RoughSchedule type={type}/>
</Suspense>
</I18nProvider>
</>


+ 43
- 0
src/app/api/scheduling/actions.ts Voir le fichier

@@ -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"]
}
})
})

+ 82
- 0
src/app/api/scheduling/index.ts Voir le fichier

@@ -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"]
}
})
})

+ 156
- 108
src/components/RoughSchedule/RoughSchedileSearchView.tsx Voir le fichier

@@ -1,65 +1,60 @@
"use client";

import React, {useCallback, useEffect, useMemo, useState} from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
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 { EditNote } from "@mui/icons-material";
import { useRouter, useSearchParams } from "next/navigation";
import { GridDeleteIcon } from "@mui/x-data-grid";
import { TypeEnum } from "@/app/utils/typeEnum";
import axios from "axios";
import {BASE_API_URL, NEXT_PUBLIC_API_URL} from "@/config/api";
import { BASE_API_URL, NEXT_PUBLIC_API_URL } from "@/config/api";
import { useTranslation } from "react-i18next";
import axiosInstance from "@/app/(main)/axios/axiosInstance";
import Qs from 'qs';
import EditableSearchResults from "@/components/SearchResults/EditableSearchResults"; // Make sure to import Qs

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 = {
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;

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 [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(
() => {
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("Product Count"), paramName: "productCount", type: "input" },
{ label: t("Product Count"), paramName: "totalEstProdCount", type: "text" },
]
return searchCriteria
},
[t, records]
[t]
);

// const onDetailClick = useCallback(
@@ -70,7 +65,7 @@ const RSOverview: React.FC<Props> = ({ records }) => {
// );

const onDeleteClick = useCallback(
(item: ItemsResult) => {},
(item: ItemsResult) => { },
[router]
);

@@ -79,25 +74,36 @@ const RSOverview: React.FC<Props> = ({ records }) => {
router.push(`/scheduling/rough/edit?id=${record.id}`);
}

const columns = useMemo<Column<ItemsResult>[]>(
const columns = useMemo<Column<ProdScheduleResult>[]>(
() => [
{
name: "id",
label: t("Details"),
onClick: (record)=>onDetailClick(record),
onClick: (record) => onDetailClick(record),
buttonIcon: <EditNote />,
},
{
name: "scheduledPeriod",
name: "schedulePeriod",
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)"),
headerAlign: "right",
align: "right",
renderCell: (params) => {
return decimalFormatter.format(params.totalEstProdCount)
}
},
// {
// name: "action",
@@ -106,92 +112,134 @@ const RSOverview: React.FC<Props> = ({ records }) => {
// 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(() => {
//setFilteredItems(items ?? []);
setFilterObj({});
setTempSelectedValue({});
refetchData();
}, [records]);
// setFilteredSchedules(items ?? []);
// setFilterObj({});
// setTempSelectedValue({});
refetchData(inputs, "reset");
}, []);

return (
<>
<SearchBox
criteria={searchCriteria}
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}
/>
<SearchResults<ItemsResult>
items={filteredItems}
<SearchResults<ProdScheduleResult>
items={filteredSchedules}
columns={columns}
setPagingController={setPagingController}
pagingController={pagingController}
isAutoPaging={false}
hasCollapse={false}
totalCount={totalCount}
// isAutoPaging={false}
/>
</>
);


+ 18
- 4
src/components/RoughSchedule/RoughScheduleWrapper.tsx Voir le fichier

@@ -1,21 +1,35 @@
import { fetchAllItems } from "@/app/api/settings/item";
import { RoughScheduleLoading } from "./RoughScheduleLoading";
import RSOverview from "./RoughSchedileSearchView";
import { SearchProdSchedule, fetchProdSchedules } from "@/app/api/scheduling/actions";

interface SubComponents {
Loading: typeof RoughScheduleLoading;
}

type Props = {};
type Props = {
type: SearchProdSchedule["type"]
};

const RoughScheduleWrapper: React.FC<Props> & SubComponents = async (
{
// type,
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;


+ 42
- 37
src/components/RoughScheduleDetail/DetailInfoCard.tsx Voir le fichier

@@ -3,48 +3,53 @@ import {
Box,
Card,
CardContent,
FormControl,
Grid,
Stack,
TextField,
Typography,
} from "@mui/material";
import { useFormContext } from "react-hook-form";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
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 { InputDataGridProps, TableRow } from "../InputDataGrid/InputDataGrid";
import { TypeEnum } from "@/app/utils/typeEnum";
import { CreateItemInputs } from "@/app/api/settings/item/actions";
import {NumberInputProps} from "@/components/CreateItem/NumberInputProps";
import { integerFormatter } from "@/app/utils/formatUtil";
import { 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 = {
// isEditMode: boolean;
// type: TypeEnum;
isEditing: boolean;
};

const DetailInfoCard: React.FC<Props> = ({ recordDetails, isEditing}) => {
const DetailInfoCard: React.FC<Props> = ({ isEditing }) => {
const {
t,
i18n: { language },
} = useTranslation();

const {
control,
register,
getValues,
watch,
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)
},[isEditing])
}, [isEditing])

return (
<Card sx={{ display: "block" }}>
@@ -58,39 +63,39 @@ const DetailInfoCard: React.FC<Props> = ({ recordDetails, isEditing}) => {
<TextField
label={t("Date")}
fullWidth
{...register("scheduledPeriod", {
required: "name required!",
})}
defaultValue={details?.scheduledPeriod}
// {...register("scheduledPeriod", {
// required: "name required!",
// })}
defaultValue={`${arrayToDateString(getValues("schedulePeriod"))} - ${arrayToDateString(getValues("schedulePeriodTo"))}`}
disabled={!isEditing}
error={Boolean(errors.name)}
helperText={errors.name?.message}
// error={Boolean(errors.name)}
// helperText={errors.name?.message}
/>
</Grid>
<Grid item xs={6}>
<TextField
label={t("Total FG Item")}
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}
error={Boolean(errors.code)}
helperText={errors.code?.message}
// error={Boolean(errors.code)}
// helperText={errors.code?.message}
/>
</Grid>
<Grid item xs={6}>
<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>


+ 8
- 29
src/components/RoughScheduleDetail/RoughScheduleDetailWrapper.tsx Voir le fichier

@@ -2,46 +2,25 @@ import { CreateItemInputs } from "@/app/api/settings/item/actions";
import { fetchItem } from "@/app/api/settings/item";
import GeneralLoading from "@/components/General/GeneralLoading";
import RoughScheduleDetailView from "@/components/RoughScheduleDetail/RoughScheudleDetailView";
import React from "react";
import { ScheduleType, fetchProdScheduleDetail } from "@/app/api/scheduling";
interface SubComponents {
Loading: typeof GeneralLoading;
}

type Props = {
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 (
<RoughScheduleDetailView
isEditMode={Boolean(id)}
defaultValues={defaultValues}
qcChecks={qcChecks || []}
type={type}
defaultValues={prodSchedule}
/>
);
};


+ 62
- 75
src/components/RoughScheduleDetail/RoughScheudleDetailView.tsx Voir le fichier

@@ -14,28 +14,30 @@ import {
useForm,
} from "react-hook-form";
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 ProductDetails from "@/components/CreateItem/ProductDetails";
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 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 = {
isEditMode: boolean;
// type: TypeEnum;
defaultValues: Partial<CreateItemInputs> | undefined;
qcChecks: ItemQc[]
type: ScheduleType;
defaultValues: Partial<ProdScheduleResult> | undefined;
// qcChecks: ItemQc[]
};

const RoughScheduleDetailView: React.FC<Props> = ({
isEditMode,
// type,
type,
defaultValues,
qcChecks
}) => {
// console.log(type)
const apiRef = useGridApiRef();
@@ -47,35 +49,9 @@ const RoughScheduleDetailView: React.FC<Props> = ({
const router = useRouter();
const [isEdit, setIsEdit] = useState(false);
//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)
const formProps = useForm<CreateItemInputs>({
const formProps = useForm<ProdScheduleResult>({
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({
pageNum: 1,
@@ -101,7 +88,7 @@ const RoughScheduleDetailView: React.FC<Props> = ({
router.replace(`/scheduling/rough`);
};

const onSubmit = useCallback<SubmitHandler<CreateItemInputs & {}>>(
const onSubmit = useCallback<SubmitHandler<ProdScheduleResult>>(
async (data, event) => {
let hasErrors = false;
console.log(errors)
@@ -122,12 +109,12 @@ const RoughScheduleDetailView: React.FC<Props> = ({
);

// multiple tabs
const onSubmitError = useCallback<SubmitErrorHandler<CreateItemInputs>>(
(errors) => {},
const onSubmitError = useCallback<SubmitErrorHandler<ProdScheduleResult>>(
(errors) => { },
[]
);

const onClickEdit = () =>{
const onClickEdit = () => {
setIsEdit(!isEdit)
}

@@ -139,57 +126,57 @@ const RoughScheduleDetailView: React.FC<Props> = ({
component="form"
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}
/>
<Stack
/>
{/* <Stack
direction="row"
justifyContent="space-between"
flexWrap="wrap"
rowGap={2}
>
<Button
>
<Button
variant="contained"
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 && (
<Typography variant="body2" color="error" alignSelf="flex-end">
{serverError}
</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
name="submit"
variant="contained"
startIcon={<Check />}
type="submit"
// disabled={submitDisabled}
// disabled={submitDisabled}
>
{isEditMode ? t("Save") : t("Confirm")}
</Button>
@@ -200,7 +187,7 @@ const RoughScheduleDetailView: React.FC<Props> = ({
>
{t("Cancel")}
</Button>
</Stack>
</Stack> */}
</Stack>
</FormProvider>
</>


+ 592
- 0
src/components/RoughScheduleDetail/TempRecords.tsx Voir le fichier

@@ -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 },
],
]

+ 125
- 290
src/components/RoughScheduleDetail/ViewByBomDetails.tsx Voir le fichier

@@ -9,248 +9,67 @@ import {
GridRowSelectionModel,
useGridApiRef,
} 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 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 { QcChecksInputs } from "@/app/api/settings/qcCheck/actions";
import { GridApiCommunity } from "@mui/x-data-grid/internals";
import { RiceBowl } from "@mui/icons-material";
import EditableSearchResults, {Column} from "@/components/SearchResults/EditableSearchResults";
// import EditableSearchResults, { Column } from "@/components/SearchResults/EditableSearchResults";
import { decimalFormatter } from "@/app/utils/formatUtil";
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 = {
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 {
control,
getValues,
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([
{
@@ -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) => {
return prevState.map((item, index) => {
if (index === updatedObj?.index){
if (index === updatedObj?.index) {
return {
...item,
pageNum: item.pageNum,
@@ -329,139 +153,142 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
field: "type",
label: t("type"),
type: 'read-only',
renderCell: (params) => {
return t(params.type)
}
// editable: true,
},
{
field: "inStockQty",
field: "availableQty",
label: t("Available Qty"),
type: 'read-only',
style: {
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,
},
{
field: "overallPurchaseQty",
field: "totalDemandQty",
label: t("Total Demand Qty"),
type: 'read-only',
style: {
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)"),
type: 'read-only',
style: {
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)"),
type: 'read-only',
style: {
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)"),
type: 'read-only',
style: {
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)"),
type: 'read-only',
style: {
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)"),
type: 'read-only',
style: {
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)"),
type: 'read-only',
style: {
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)"),
type: 'read-only',
style: {
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]
);

const columns = useMemo<Column<any>[]>(
const columns = useMemo<Column<ProdScheduleLineResultByBomByDate>[]>(
() => [
{
field: "code",
@@ -478,56 +305,62 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
field: "type",
label: t("type"),
type: 'read-only',
renderCell: (params) => {
return t(params.type)
}
},
{
field: "inStockQty",
field: "availableQty",
label: t("Available Qty"),
type: 'read-only',
// editable: true,
style: {
textAlign: "right",
},
renderCell: (row: FGRecord) => {
if (typeof(row.inStockQty) == "number") {
return decimalFormatter.format(row.inStockQty)
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"),
type: 'read-only',
style: {
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 (
<Grid container spacing={2}>
<Grid item xs={12} key={"all"}>
<Typography variant="overline" display="block" marginBlockEnd={1}>
{t("Material Demand List (7 Days)")}
</Typography>
<EditableSearchResults<FGRecord>
index={7}
items={fakeOverallRecords}
isMockUp={true}
<ScheduleTable<ProdScheduleLineResultByBom>
// index={7}
type={type}
items={getValues("prodScheduleLinesByBom")}
columns={overallColumns}
setPagingController={updatePagingController}
pagingController={pagingController[7]}
isAutoPaging={true}
isEditable={false}
isEdit={false}
hasCollapse={false}
/>
</Grid>
{dayPeriod.map((date, index) => (
@@ -535,15 +368,17 @@ const ViewByBomDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
<Typography variant="overline" display="block" marginBlockEnd={1}>
{`${t("Material Demand Date")}: ${date}`}
</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}
setPagingController={updatePagingController}
pagingController={pagingController[index]}
isAutoPaging={true}
isEditable={false}
isEdit={isEdit}
hasCollapse={false}
/>
</Grid>
))}


+ 78
- 433
src/components/RoughScheduleDetail/ViewByFGDetails.tsx Voir le fichier

@@ -9,379 +9,56 @@ import {
GridRowSelectionModel,
useGridApiRef,
} 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 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 { QcChecksInputs } from "@/app/api/settings/qcCheck/actions";
import { GridApiCommunity } from "@mui/x-data-grid/internals";
import { RiceBowl } from "@mui/icons-material";
import EditableSearchResults, {Column} from "@/components/SearchResults/EditableSearchResults";
import { decimalFormatter, 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 = {
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 {
t,
i18n: { language },
} = useTranslation("schedule");

const {
control,
getValues,
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([
{
@@ -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) => {
return prevState.map((item, index) => {
if (index === updatedObj?.index){
if (index === updatedObj?.index) {
return {
...item,
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",
@@ -463,39 +145,39 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
// editable: true,
},
{
field: "inStockQty",
field: "availableQty",
label: t("Available Qty"),
type: 'read-only',
style: {
textAlign: "right",
},
// 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"),
type: 'input',
style: {
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",
@@ -512,114 +194,75 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
field: "type",
label: t("type"),
type: 'read-only',
renderCell: (params) => {
return t(params.type)
}
// editable: true,
},
{
field: "lastMonthAvgStock",
field: "lastMonthAvgSales",
label: t("Last Month Average Stock"),
type: 'read-only',
style: {
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,
},
{
field: "safetyStock",
field: "estCloseBal",
label: t("Safety Stock"),
type: 'read-only',
style: {
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,
},
{
field: "inStockQty",
field: "availableQty",
label: t("Available Qty"),
type: 'read-only',
style: {
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,
},
{
field: "productionQty",
field: "prodQty",
label: t("Demand Qty (7 Days)"),
type: 'read-only',
style: {
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 (
<Grid container spacing={2}>
@@ -627,9 +270,10 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
<Typography variant="overline" display="block" marginBlockEnd={1}>
{t("FG Demand List (7 Days)")}
</Typography>
<EditableSearchResults<FGRecord>
index={7}
items={fakeOverallRecords}
<ScheduleTable<ProdScheduleLineResultByFg>
// index={7}
type={type}
items={getValues("prodScheduleLinesByFg")}
columns={overallColumns}
setPagingController={updatePagingController}
pagingController={pagingController[7]}
@@ -644,8 +288,9 @@ const ViewByFGDetails: React.FC<Props> = ({ apiRef, isEdit }) => {
<Typography variant="overline" display="block" marginBlockEnd={1}>
{`${t("FG Demand Date")}: ${date}`}
</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}
setPagingController={updatePagingController}
pagingController={pagingController[index]}


+ 255
- 0
src/components/ScheduleTable/BomMaterialTable.tsx Voir le fichier

@@ -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;

+ 334
- 0
src/components/ScheduleTable/ScheduleTable.tsx Voir le fichier

@@ -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;

+ 1
- 0
src/components/ScheduleTable/index.ts Voir le fichier

@@ -0,0 +1 @@
export { default } from "./ScheduleTable"

+ 16
- 15
src/i18n/zh/schedule.json Voir le fichier

@@ -24,20 +24,20 @@
"Product Count": "產品數量",
"Scheduled At": "排程時間",
"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": "總預估需求量",
"View By FG": "依 FG 分類",
"View By Material": "依料分類",
"View By FG": "依成品分類",
"View By Material": "依料分類",
" (Selected)": " (已選擇)",
"Total FG Item": "總 FG 項目",
"Total FG Item": "總成品項目",
"Release": "發佈",
"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": "可用數量",
"Demand Qty": "需求數量",
"Confirm": "確認",
@@ -50,7 +50,7 @@
"Selected": "已選擇",
"Unselected": "未選擇",
"status": "狀態",
"Material Demand List (7 Days)": "料需求列表(7 天)",
"Material Demand List (7 Days)": "料需求列表(7 天)",
"Mon": "週一",
"Tue": "週二",
"Wed": "週三",
@@ -59,14 +59,15 @@
"Sat": "週六",
"Sun": "週日",
"Last Month Average Stock": "上個月平均庫存",
"Last Month Average Sales": "上個月平均銷售",
"Safety Stock": "安全庫存",
"Demand Qty (7 Days)": "需求數量(7 天)",
"Estimated Production Time": "預估生產時間",
"Production Priority": "生產優先順序",
"View BoM": "查看 BoM",
"View BoM": "查看物料清單",
"Date": "日期",
"Detail Scheduling": "詳細排程",
"FG Production Schedule": "FG 生產排程",
"FG Production Schedule": "成品生產排程",
"Production Date": "生產日期",
"Total Job Order": "總工單數量",
"Total Production Qty": "總生產數量",
@@ -76,6 +77,6 @@
"Job Status": "工單狀態",
"Job Priority": "工單優先順序",
"Job Date": "工單日期",
"Job Qty": "工單數量"
"Job Qty": "工單數量",
"mat": "物料"
}

Chargement…
Annuler
Enregistrer