@@ -5,7 +5,7 @@ const withPWA = require("next-pwa")({ | |||||
dest: "public", | dest: "public", | ||||
register: true, | register: true, | ||||
skipWaiting: true, | skipWaiting: true, | ||||
disable: process.env.NODE_ENV === 'development' | |||||
disable: process.env.NODE_ENV === "development", | |||||
}); | }); | ||||
const nextConfig = { | const nextConfig = { | ||||
@@ -6,7 +6,8 @@ | |||||
"dev": "next dev", | "dev": "next dev", | ||||
"build": "next build", | "build": "next build", | ||||
"start": "NODE_OPTIONS='--inspect' next start", | "start": "NODE_OPTIONS='--inspect' next start", | ||||
"lint": "next lint" | |||||
"lint": "next lint", | |||||
"type-check": "tsc --noEmit" | |||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||
"@emotion/cache": "^11.11.0", | "@emotion/cache": "^11.11.0", | ||||
@@ -3,4 +3,4 @@ module.exports = { | |||||
tailwindcss: {}, | tailwindcss: {}, | ||||
autoprefixer: {}, | autoprefixer: {}, | ||||
}, | }, | ||||
} | |||||
}; |
@@ -1,38 +1,42 @@ | |||||
"use client"; | "use client"; | ||||
import React, {createContext, useContext, useEffect, useState} from 'react'; | |||||
import axiosInstance, {SetupAxiosInterceptors} from './axiosInstance'; | |||||
import React, { createContext, useContext, useEffect, useState } from "react"; | |||||
import axiosInstance, { SetupAxiosInterceptors } from "./axiosInstance"; | |||||
const AxiosContext = createContext(axiosInstance); | const AxiosContext = createContext(axiosInstance); | ||||
const TokenContext = createContext({ | const TokenContext = createContext({ | ||||
setAccessToken: (token: string | null) => {}, | |||||
setAccessToken: (token: string | null) => {}, | |||||
}); | }); | ||||
export const AxiosProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { | |||||
const [accessToken, setAccessToken] = useState<string | null>(localStorage.getItem("accessToken")); | |||||
export const AxiosProvider: React.FC<{ children: React.ReactNode }> = ({ | |||||
children, | |||||
}) => { | |||||
const [accessToken, setAccessToken] = useState<string | null>( | |||||
localStorage.getItem("accessToken"), | |||||
); | |||||
useEffect(() => { | |||||
if (accessToken) { | |||||
axiosInstance.defaults.headers.Authorization = `Bearer ${accessToken}`; | |||||
SetupAxiosInterceptors(accessToken); | |||||
console.log("[debug] Updated accessToken:", accessToken); | |||||
} | |||||
}, [accessToken]); | |||||
useEffect(() => { | |||||
if (accessToken) { | |||||
axiosInstance.defaults.headers.Authorization = `Bearer ${accessToken}`; | |||||
SetupAxiosInterceptors(accessToken); | |||||
console.log("[debug] Updated accessToken:", accessToken); | |||||
} | |||||
}, [accessToken]); | |||||
return ( | |||||
<AxiosContext.Provider value={axiosInstance}> | |||||
<TokenContext.Provider value={{ setAccessToken }}> | |||||
{children} | |||||
</TokenContext.Provider> | |||||
</AxiosContext.Provider> | |||||
); | |||||
return ( | |||||
<AxiosContext.Provider value={axiosInstance}> | |||||
<TokenContext.Provider value={{ setAccessToken }}> | |||||
{children} | |||||
</TokenContext.Provider> | |||||
</AxiosContext.Provider> | |||||
); | |||||
}; | }; | ||||
// Custom hook to use Axios instance | // Custom hook to use Axios instance | ||||
export const useAxios = () => { | export const useAxios = () => { | ||||
return useContext(AxiosContext); | |||||
return useContext(AxiosContext); | |||||
}; | }; | ||||
// Custom hook to manage access token | // Custom hook to manage access token | ||||
export const useToken = () => { | export const useToken = () => { | ||||
return useContext(TokenContext); | |||||
}; | |||||
return useContext(TokenContext); | |||||
}; |
@@ -1,56 +1,56 @@ | |||||
import axios from 'axios'; | |||||
import axios from "axios"; | |||||
const axiosInstance = axios.create({ | const axiosInstance = axios.create({ | ||||
baseURL: process.env.API_URL, | |||||
baseURL: process.env.API_URL, | |||||
}); | }); | ||||
// Clear existing interceptors to prevent multiple registrations | // Clear existing interceptors to prevent multiple registrations | ||||
const clearInterceptors = () => { | const clearInterceptors = () => { | ||||
const requestInterceptor = axiosInstance.interceptors.request.use(); | |||||
const responseInterceptor = axiosInstance.interceptors.response.use(); | |||||
const requestInterceptor = axiosInstance.interceptors.request.use(); | |||||
const responseInterceptor = axiosInstance.interceptors.response.use(); | |||||
if (requestInterceptor) { | |||||
axiosInstance.interceptors.request.eject(requestInterceptor); | |||||
} | |||||
if (requestInterceptor) { | |||||
axiosInstance.interceptors.request.eject(requestInterceptor); | |||||
} | |||||
if (responseInterceptor) { | |||||
axiosInstance.interceptors.response.eject(responseInterceptor); | |||||
} | |||||
if (responseInterceptor) { | |||||
axiosInstance.interceptors.response.eject(responseInterceptor); | |||||
} | |||||
}; | }; | ||||
export const SetupAxiosInterceptors = (inputToken: string | null) => { | export const SetupAxiosInterceptors = (inputToken: string | null) => { | ||||
console.log("[debug] set up interceptors", inputToken); | |||||
// Clear existing interceptors | |||||
clearInterceptors(); | |||||
// Request interceptor | |||||
axiosInstance.interceptors.request.use( | |||||
(config) => { | |||||
// Use the token passed in or retrieve from localStorage | |||||
const token = inputToken ?? localStorage.getItem('accessToken'); | |||||
if (token) { | |||||
config.headers.Authorization = `Bearer ${token}`; | |||||
} | |||||
return config; | |||||
}, | |||||
(error) => { | |||||
return Promise.reject(error); | |||||
} | |||||
); | |||||
console.log("[debug] set up interceptors2", inputToken); | |||||
// Response interceptor | |||||
axiosInstance.interceptors.response.use( | |||||
(response) => { | |||||
return response; | |||||
}, | |||||
(error) => { | |||||
console.error('API Error:', error.response?.data || error); | |||||
return Promise.reject(error); | |||||
} | |||||
); | |||||
console.log("[debug] set up interceptors", inputToken); | |||||
// Clear existing interceptors | |||||
clearInterceptors(); | |||||
// Request interceptor | |||||
axiosInstance.interceptors.request.use( | |||||
(config) => { | |||||
// Use the token passed in or retrieve from localStorage | |||||
const token = inputToken ?? localStorage.getItem("accessToken"); | |||||
if (token) { | |||||
config.headers.Authorization = `Bearer ${token}`; | |||||
} | |||||
return config; | |||||
}, | |||||
(error) => { | |||||
return Promise.reject(error); | |||||
}, | |||||
); | |||||
console.log("[debug] set up interceptors2", inputToken); | |||||
// Response interceptor | |||||
axiosInstance.interceptors.response.use( | |||||
(response) => { | |||||
return response; | |||||
}, | |||||
(error) => { | |||||
console.error("API Error:", error.response?.data || error); | |||||
return Promise.reject(error); | |||||
}, | |||||
); | |||||
}; | }; | ||||
export default axiosInstance; | |||||
export default axiosInstance; |
@@ -5,29 +5,22 @@ import { getServerI18n } from "@/i18n"; | |||||
import DashboardPage from "@/components/DashboardPage"; | import DashboardPage from "@/components/DashboardPage"; | ||||
import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Dashboard", | title: "Dashboard", | ||||
}; | }; | ||||
type Props = { | |||||
} & SearchParams | |||||
type Props = {} & SearchParams; | |||||
const Dashboard: React.FC<Props> = async ({ | |||||
searchParams | |||||
}) => { | |||||
const Dashboard: React.FC<Props> = async ({ searchParams }) => { | |||||
const { t } = await getServerI18n("dashboard"); | const { t } = await getServerI18n("dashboard"); | ||||
return ( | return ( | ||||
<I18nProvider namespaces={["dashboard", "common"]}> | <I18nProvider namespaces={["dashboard", "common"]}> | ||||
<Suspense fallback={<DashboardPage.Loading />}> | <Suspense fallback={<DashboardPage.Loading />}> | ||||
<DashboardPage | |||||
searchParams={searchParams} | |||||
/> | |||||
<DashboardPage searchParams={searchParams} /> | |||||
</Suspense> | </Suspense> | ||||
</I18nProvider> | </I18nProvider> | ||||
) | |||||
); | |||||
}; | }; | ||||
export default Dashboard; | export default Dashboard; |
@@ -1,36 +1,35 @@ | |||||
// import DoSearch from "@/components/DoSearch"; | // import DoSearch from "@/components/DoSearch"; | ||||
// import { getServerI18n } from "@/i18n" | // import { getServerI18n } from "@/i18n" | ||||
import DoSearch from "../../../components/DoSearch"; | import DoSearch from "../../../components/DoSearch"; | ||||
import { getServerI18n } from "../../../i18n" | |||||
import { getServerI18n } from "../../../i18n"; | |||||
import { Stack, Typography } from "@mui/material"; | import { Stack, Typography } from "@mui/material"; | ||||
import { I18nProvider } from "@/i18n"; | import { I18nProvider } from "@/i18n"; | ||||
import { Metadata } from "next"; | import { Metadata } from "next"; | ||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Delivery Order" | |||||
} | |||||
title: "Delivery Order", | |||||
}; | |||||
const DeliveryOrder: React.FC = async () => { | const DeliveryOrder: React.FC = async () => { | ||||
const { t } = await getServerI18n("do"); | |||||
const { t } = await getServerI18n("do"); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent={"space-between"} | |||||
flexWrap={"wrap"} | |||||
rowGap={2} | |||||
> | |||||
</Stack> | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent={"space-between"} | |||||
flexWrap={"wrap"} | |||||
rowGap={2} | |||||
></Stack> | |||||
<I18nProvider namespaces={["do", "common"]}> | |||||
<Suspense fallback={<DoSearch.Loading />}> | |||||
<DoSearch /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
) | |||||
} | |||||
<I18nProvider namespaces={["do", "common"]}> | |||||
<Suspense fallback={<DoSearch.Loading />}> | |||||
<DoSearch /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | |||||
export default DeliveryOrder; | |||||
export default DeliveryOrder; |
@@ -10,31 +10,33 @@ import { Metadata } from "next"; | |||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Inventory" | |||||
} | |||||
title: "Inventory", | |||||
}; | |||||
const Inventory: React.FC = async () => { | const Inventory: React.FC = async () => { | ||||
const { t } = await getServerI18n("inventory", "common") | |||||
const { t } = await getServerI18n("inventory", "common"); | |||||
preloadInventory() | |||||
preloadInventory(); | |||||
return <> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent={"space-between"} | |||||
flexWrap={"wrap"} | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Inventory")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["common", "inventory"]}> | |||||
<Suspense fallback={<InventorySearch.Loading />}> | |||||
<InventorySearch /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</>; | |||||
} | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent={"space-between"} | |||||
flexWrap={"wrap"} | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Inventory")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["common", "inventory"]}> | |||||
<Suspense fallback={<InventorySearch.Loading />}> | |||||
<InventorySearch /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | |||||
export default Inventory; | |||||
export default Inventory; |
@@ -1,4 +1,3 @@ | |||||
import AppBar from "@/components/AppBar"; | import AppBar from "@/components/AppBar"; | ||||
import { AuthOptions, getServerSession } from "next-auth"; | import { AuthOptions, getServerSession } from "next-auth"; | ||||
import { authOptions, SessionWithTokens } from "@/config/authConfig"; | import { authOptions, SessionWithTokens } from "@/config/authConfig"; | ||||
@@ -15,13 +14,14 @@ import SessionProviderWrapper from "@/components/SessionProviderWrapper/SessionP | |||||
import QrCodeScannerProvider from "@/components/QrCodeScannerProvider/QrCodeScannerProvider"; | import QrCodeScannerProvider from "@/components/QrCodeScannerProvider/QrCodeScannerProvider"; | ||||
import { I18nProvider } from "@/i18n"; | import { I18nProvider } from "@/i18n"; | ||||
export default async function MainLayout({ | export default async function MainLayout({ | ||||
children, | children, | ||||
}: { | }: { | ||||
children: React.ReactNode; | children: React.ReactNode; | ||||
}) { | }) { | ||||
const session = await getServerSession<AuthOptions, SessionWithTokens>(authOptions); | |||||
const session = await getServerSession<AuthOptions, SessionWithTokens>( | |||||
authOptions, | |||||
); | |||||
if (!session?.user) { | if (!session?.user) { | ||||
redirect("/login"); | redirect("/login"); | ||||
@@ -36,33 +36,33 @@ export default async function MainLayout({ | |||||
return ( | return ( | ||||
<SessionProviderWrapper session={session}> | <SessionProviderWrapper session={session}> | ||||
<UploadProvider> | |||||
<CameraProvider> | |||||
<AxiosProvider> | |||||
<QrCodeScannerProvider> | |||||
<> | |||||
<AppBar | |||||
profileName={session.user.name!} | |||||
avatarImageSrc={session.user.image || undefined} | |||||
/> | |||||
<Box | |||||
component="main" | |||||
sx={{ | |||||
marginInlineStart: { xs: 0, xl: NAVIGATION_CONTENT_WIDTH }, | |||||
padding: { xs: "1rem", sm: "1.5rem", lg: "3rem" }, | |||||
}} | |||||
> | |||||
<Stack spacing={2}> | |||||
<I18nProvider namespaces={["common"]}> | |||||
<Breadcrumb /> | |||||
{children} | |||||
</I18nProvider> | |||||
</Stack> | |||||
</Box> | |||||
</> | |||||
</QrCodeScannerProvider> | |||||
</AxiosProvider> | |||||
</CameraProvider> | |||||
<UploadProvider> | |||||
<CameraProvider> | |||||
<AxiosProvider> | |||||
<QrCodeScannerProvider> | |||||
<> | |||||
<AppBar | |||||
profileName={session.user.name!} | |||||
avatarImageSrc={session.user.image || undefined} | |||||
/> | |||||
<Box | |||||
component="main" | |||||
sx={{ | |||||
marginInlineStart: { xs: 0, xl: NAVIGATION_CONTENT_WIDTH }, | |||||
padding: { xs: "1rem", sm: "1.5rem", lg: "3rem" }, | |||||
}} | |||||
> | |||||
<Stack spacing={2}> | |||||
<I18nProvider namespaces={["common"]}> | |||||
<Breadcrumb /> | |||||
{children} | |||||
</I18nProvider> | |||||
</Stack> | |||||
</Box> | |||||
</> | |||||
</QrCodeScannerProvider> | |||||
</AxiosProvider> | |||||
</CameraProvider> | |||||
</UploadProvider> | </UploadProvider> | ||||
</SessionProviderWrapper> | </SessionProviderWrapper> | ||||
); | ); | ||||
@@ -11,13 +11,11 @@ export const metadata: Metadata = { | |||||
title: "Material Setting", | title: "Material Setting", | ||||
}; | }; | ||||
type Props = { | |||||
} & SearchParams | |||||
type Props = {} & SearchParams; | |||||
const material: React.FC<Props> = async ({ searchParams }) => { | const material: React.FC<Props> = async ({ searchParams }) => { | ||||
const { t } = await getServerI18n("material"); | const { t } = await getServerI18n("material"); | ||||
console.log(searchParams) | |||||
console.log(searchParams); | |||||
return ( | return ( | ||||
<> | <> | ||||
<Stack | <Stack | ||||
@@ -37,7 +35,6 @@ const material: React.FC<Props> = async ({ searchParams }) => { | |||||
> | > | ||||
{t("Create Claim")} | {t("Create Claim")} | ||||
</Button> | </Button> | ||||
</Stack> | </Stack> | ||||
{/* <Suspense fallback={<MaterialSearch.Loading />}> | {/* <Suspense fallback={<MaterialSearch.Loading />}> | ||||
<MaterialSearch /> | <MaterialSearch /> | ||||
@@ -1,4 +1,4 @@ | |||||
import { PreloadPickOrder } from "@/app/api/pickorder"; | |||||
import { PreloadPickOrder } from "@/app/api/pickOrder"; | |||||
import { SearchParams } from "@/app/utils/fetchUtil"; | import { SearchParams } from "@/app/utils/fetchUtil"; | ||||
import PickOrderDetail from "@/components/PickOrderDetail"; | import PickOrderDetail from "@/components/PickOrderDetail"; | ||||
import { getServerI18n, I18nProvider } from "@/i18n"; | import { getServerI18n, I18nProvider } from "@/i18n"; | ||||
@@ -20,7 +20,7 @@ const PickOrder: React.FC<Props> = async ({ searchParams }) => { | |||||
<> | <> | ||||
<I18nProvider namespaces={["pickOrder"]}> | <I18nProvider namespaces={["pickOrder"]}> | ||||
<Suspense fallback={<PickOrderDetail.Loading />}> | <Suspense fallback={<PickOrderDetail.Loading />}> | ||||
<PickOrderDetail consoCode={`${searchParams["consoCode"]}`}/> | |||||
<PickOrderDetail consoCode={`${searchParams["consoCode"]}`} /> | |||||
</Suspense> | </Suspense> | ||||
</I18nProvider> | </I18nProvider> | ||||
</> | </> | ||||
@@ -1,4 +1,4 @@ | |||||
import { PreloadPickOrder } from "@/app/api/pickorder"; | |||||
import { PreloadPickOrder } from "@/app/api/pickOrder"; | |||||
import PickOrderSearch from "@/components/PickOrderSearch"; | import PickOrderSearch from "@/components/PickOrderSearch"; | ||||
import { getServerI18n } from "@/i18n"; | import { getServerI18n } from "@/i18n"; | ||||
import { I18nProvider } from "@/i18n"; | import { I18nProvider } from "@/i18n"; | ||||
@@ -7,33 +7,33 @@ import { Metadata } from "next"; | |||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Pick Order" | |||||
} | |||||
title: "Pick Order", | |||||
}; | |||||
const PickOrder: React.FC = async () => { | const PickOrder: React.FC = async () => { | ||||
const { t } = await getServerI18n("pickOrder") | |||||
const { t } = await getServerI18n("pickOrder"); | |||||
PreloadPickOrder() | |||||
PreloadPickOrder(); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction={"row"} | |||||
justifyContent={"space-between"} | |||||
flexWrap={"wrap"} | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Pick Order")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["pickOrder", "common"]}> | |||||
<Suspense fallback={<PickOrderSearch.Loading />}> | |||||
<PickOrderSearch /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
) | |||||
} | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction={"row"} | |||||
justifyContent={"space-between"} | |||||
flexWrap={"wrap"} | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Pick Order")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["pickOrder", "common"]}> | |||||
<Suspense fallback={<PickOrderSearch.Loading />}> | |||||
<PickOrderSearch /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | |||||
export default PickOrder; | |||||
export default PickOrder; |
@@ -4,8 +4,6 @@ import CreateProductMaterial from "@/components/CreateItem"; | |||||
import PoDetail from "@/components/PoDetail"; | import PoDetail from "@/components/PoDetail"; | ||||
import { I18nProvider, getServerI18n } from "@/i18n"; | import { I18nProvider, getServerI18n } from "@/i18n"; | ||||
import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||
import isString from "lodash/isString"; | import isString from "lodash/isString"; | ||||
import { notFound } from "next/navigation"; | import { notFound } from "next/navigation"; | ||||
@@ -1,10 +1,3 @@ | |||||
//import { preloadClaims } from "@/app/api/claims"; | |||||
// import ClaimSearch from "@/components/ClaimSearch"; | |||||
// import PoSearch from "@/components/PoSearch"; | |||||
// import { getServerI18n, I18nProvider } from "@/i18n"; | |||||
import { preloadClaims } from "../../../app/api/claims"; | |||||
import ClaimSearch from "../../../components/ClaimSearch"; | |||||
import PoSearch from "../../../components/PoSearch"; | import PoSearch from "../../../components/PoSearch"; | ||||
import { getServerI18n, I18nProvider } from "../../../i18n"; | import { getServerI18n, I18nProvider } from "../../../i18n"; | ||||
import Add from "@mui/icons-material/Add"; | import Add from "@mui/icons-material/Add"; | ||||
@@ -30,11 +23,10 @@ const PurchaseOrder: React.FC = async () => { | |||||
justifyContent="space-between" | justifyContent="space-between" | ||||
flexWrap="wrap" | flexWrap="wrap" | ||||
rowGap={2} | rowGap={2} | ||||
> | |||||
</Stack> | |||||
<Suspense fallback={<PoSearch.Loading />}> | |||||
<PoSearch /> | |||||
</Suspense> | |||||
></Stack> | |||||
<Suspense fallback={<PoSearch.Loading />}> | |||||
<PoSearch /> | |||||
</Suspense> | |||||
</I18nProvider> | </I18nProvider> | ||||
</> | </> | ||||
); | ); | ||||
@@ -1,10 +1,3 @@ | |||||
// import { preloadClaims } from "@/app/api/claims"; | |||||
// import ClaimSearch from "@/components/ClaimSearch"; | |||||
// import ProductionProcess from "@/components/ProductionProcess"; | |||||
//import { getServerI18n } from "@/i18n"; | |||||
import { preloadClaims } from "../../../app/api/claims"; | |||||
import ClaimSearch from "../../../components/ClaimSearch"; | |||||
import ProductionProcess from "../../../components/ProductionProcess"; | import ProductionProcess from "../../../components/ProductionProcess"; | ||||
import { getServerI18n } from "../../../i18n"; | import { getServerI18n } from "../../../i18n"; | ||||
@@ -22,7 +15,7 @@ export const metadata: Metadata = { | |||||
const production: React.FC = async () => { | const production: React.FC = async () => { | ||||
const { t } = await getServerI18n("claims"); | const { t } = await getServerI18n("claims"); | ||||
// preloadClaims(); | |||||
// preloadClaims(); | |||||
return ( | return ( | ||||
<> | <> | ||||
@@ -44,9 +37,9 @@ const production: React.FC = async () => { | |||||
{t("Create Claim")} | {t("Create Claim")} | ||||
</Button> | </Button> | ||||
</Stack> | </Stack> | ||||
<Suspense fallback={<ClaimSearch.Loading />}> | |||||
<ProductionProcess /> | |||||
</Suspense> | |||||
{/* <Suspense fallback={<ClaimSearch.Loading />}> */} | |||||
<ProductionProcess /> | |||||
{/* </Suspense> */} | |||||
</> | </> | ||||
); | ); | ||||
}; | }; | ||||
@@ -8,7 +8,9 @@ export default async function NotFound() { | |||||
return ( | return ( | ||||
<Stack spacing={2}> | <Stack spacing={2}> | ||||
<Typography variant="h4">{t("Not Found")}</Typography> | <Typography variant="h4">{t("Not Found")}</Typography> | ||||
<Typography variant="body1">{t("The edit detail scheduling page was not found!")}</Typography> | |||||
<Typography variant="body1"> | |||||
{t("The edit detail scheduling page was not found!")} | |||||
</Typography> | |||||
<Link href="/scheduling/detail" component={NextLink} variant="body2"> | <Link href="/scheduling/detail" component={NextLink} variant="body2"> | ||||
{t("Return to all detail scheduling")} | {t("Return to all detail scheduling")} | ||||
</Link> | </Link> | ||||
@@ -4,7 +4,10 @@ import { getServerI18n, I18nProvider } from "../../../../../i18n"; | |||||
import Typography from "@mui/material/Typography"; | import Typography from "@mui/material/Typography"; | ||||
// import { fetchQcItemDetails, preloadQcItem } from "@/app/api/settings/qcItem"; | // import { fetchQcItemDetails, preloadQcItem } from "@/app/api/settings/qcItem"; | ||||
// import QcItemSave from "@/components/QcItemSave"; | // import QcItemSave from "@/components/QcItemSave"; | ||||
import { fetchQcItemDetails, preloadQcItem } from "../../../../../app/api/settings/qcItem"; | |||||
import { | |||||
fetchQcItemDetails, | |||||
preloadQcItem, | |||||
} from "../../../../../app/api/settings/qcItem"; | |||||
import QcItemSave from "../../../../../components/QcItemSave"; | import QcItemSave from "../../../../../components/QcItemSave"; | ||||
import { isArray } from "lodash"; | import { isArray } from "lodash"; | ||||
import { notFound } from "next/navigation"; | import { notFound } from "next/navigation"; | ||||
@@ -14,39 +17,41 @@ import { ServerFetchError } from "../../../../../app/utils/fetchUtil"; | |||||
import DetailScheduleDetail from "../../../../../components/DetailScheduleDetail"; | import DetailScheduleDetail from "../../../../../components/DetailScheduleDetail"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Qc Item", | |||||
title: "Qc Item", | |||||
}; | }; | ||||
interface Props { | interface Props { | ||||
searchParams: { [key: string]: string | string[] | undefined }; | |||||
searchParams: { [key: string]: string | string[] | undefined }; | |||||
} | } | ||||
const DetailScheduling: React.FC<Props> = async ({ searchParams }) => { | const DetailScheduling: React.FC<Props> = async ({ searchParams }) => { | ||||
const { t } = await getServerI18n("schedule") | |||||
const id = searchParams["id"] | |||||
if (!id || isArray(id)) { | |||||
notFound() | |||||
} | |||||
// try { | |||||
// await fetchQcItemDetails(id) | |||||
// } catch (e) { | |||||
// if (e instanceof ServerFetchError && (e.response?.status === 404 || e.response?.status === 400)) { | |||||
// console.log(e) | |||||
// notFound(); | |||||
// } | |||||
// } | |||||
return <> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("FG Production Schedule")} | |||||
</Typography> | |||||
<I18nProvider namespaces={["schedule", "common", "project"]}> | |||||
<DetailScheduleDetail id={id}/> | |||||
</I18nProvider> | |||||
</>; | |||||
const { t } = await getServerI18n("schedule"); | |||||
const id = searchParams["id"]; | |||||
if (!id || isArray(id)) { | |||||
notFound(); | |||||
} | |||||
// try { | |||||
// await fetchQcItemDetails(id) | |||||
// } catch (e) { | |||||
// if (e instanceof ServerFetchError && (e.response?.status === 404 || e.response?.status === 400)) { | |||||
// console.log(e) | |||||
// notFound(); | |||||
// } | |||||
// } | |||||
return ( | |||||
<> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("FG Production Schedule")} | |||||
</Typography> | |||||
<I18nProvider namespaces={["schedule", "common", "project"]}> | |||||
<DetailScheduleDetail id={id} /> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default DetailScheduling; | |||||
export default DetailScheduling; |
@@ -11,33 +11,33 @@ import { Metadata } from "next"; | |||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Detail Scheduling", | |||||
title: "Detail Scheduling", | |||||
}; | }; | ||||
const DetailScheduling: React.FC = async () => { | const DetailScheduling: React.FC = async () => { | ||||
const { t } = await getServerI18n("schedule"); | |||||
const type = "detailed" | |||||
// preloadClaims(); | |||||
const { t } = await getServerI18n("schedule"); | |||||
const type = "detailed"; | |||||
// preloadClaims(); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Detail Scheduling")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["schedule", "common"]}> | |||||
<Suspense fallback={<DetailSchedule.Loading />}> | |||||
<DetailSchedule type={type}/> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Detail Scheduling")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["schedule", "common"]}> | |||||
<Suspense fallback={<DetailSchedule.Loading />}> | |||||
<DetailSchedule type={type} /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default DetailScheduling; | export default DetailScheduling; |
@@ -1,11 +1,11 @@ | |||||
import { Metadata } from "next"; | import { Metadata } from "next"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Scheduling", | |||||
title: "Scheduling", | |||||
}; | }; | ||||
const Scheduling: React.FC = async () => { | const Scheduling: React.FC = async () => { | ||||
return null; | |||||
return null; | |||||
}; | }; | ||||
export default Scheduling; | export default Scheduling; |
@@ -8,7 +8,9 @@ export default async function NotFound() { | |||||
return ( | return ( | ||||
<Stack spacing={2}> | <Stack spacing={2}> | ||||
<Typography variant="h4">{t("Not Found")}</Typography> | <Typography variant="h4">{t("Not Found")}</Typography> | ||||
<Typography variant="body1">{t("The production schedule detail page was not found!")}</Typography> | |||||
<Typography variant="body1"> | |||||
{t("The production schedule detail page was not found!")} | |||||
</Typography> | |||||
<Link href="/settings/scheduling" component={NextLink} variant="body2"> | <Link href="/settings/scheduling" component={NextLink} variant="body2"> | ||||
{t("Return to all scheduling")} | {t("Return to all scheduling")} | ||||
</Link> | </Link> | ||||
@@ -15,42 +15,45 @@ import { notFound } from "next/navigation"; | |||||
import { fetchProdScheduleDetail } from "@/app/api/scheduling"; | import { fetchProdScheduleDetail } from "@/app/api/scheduling"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Demand Forecast Detail", | |||||
title: "Demand Forecast Detail", | |||||
}; | }; | ||||
type Props = SearchParams | |||||
type Props = SearchParams; | |||||
const roughSchedulingDetail: React.FC<Props> = async ({ searchParams }) => { | const roughSchedulingDetail: React.FC<Props> = async ({ searchParams }) => { | ||||
const { t } = await getServerI18n("schedule"); | |||||
const id = searchParams["id"] | |||||
const type = "rough" | |||||
const { t } = await getServerI18n("schedule"); | |||||
const id = searchParams["id"]; | |||||
const type = "rough"; | |||||
if (!id || isArray(id) || !isFinite(parseInt(id))) { | |||||
notFound() | |||||
} | |||||
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(); | |||||
} | |||||
try { | |||||
await fetchProdScheduleDetail(parseInt(id)); | |||||
} catch (e) { | |||||
if ( | |||||
e instanceof ServerFetchError && | |||||
(e.response?.status === 404 || e.response?.status === 400) | |||||
) { | |||||
console.log(e); | |||||
notFound(); | |||||
} | } | ||||
// preloadClaims(); | |||||
} | |||||
// preloadClaims(); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("FG & Material Demand Forecast Detail")} | |||||
</Typography> | |||||
{/* <Button | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("FG & Material Demand Forecast Detail")} | |||||
</Typography> | |||||
{/* <Button | |||||
variant="contained" | variant="contained" | ||||
startIcon={<Add />} | startIcon={<Add />} | ||||
LinkComponent={Link} | LinkComponent={Link} | ||||
@@ -58,14 +61,14 @@ const roughSchedulingDetail: React.FC<Props> = async ({ searchParams }) => { | |||||
> | > | ||||
{t("Create product")} | {t("Create product")} | ||||
</Button> */} | </Button> */} | ||||
</Stack> | |||||
<I18nProvider namespaces={["schedule","common"]}> | |||||
<Suspense fallback={<RoughScheduleDetailView.Loading />}> | |||||
<RoughScheduleDetailView type={type} id={parseInt(id)}/> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
</Stack> | |||||
<I18nProvider namespaces={["schedule", "common"]}> | |||||
<Suspense fallback={<RoughScheduleDetailView.Loading />}> | |||||
<RoughScheduleDetailView type={type} id={parseInt(id)} /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default roughSchedulingDetail; | export default roughSchedulingDetail; |
@@ -14,46 +14,46 @@ import Link from "next/link"; | |||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Demand Forecast", | |||||
title: "Demand Forecast", | |||||
}; | }; | ||||
const roughScheduling: React.FC = async () => { | const roughScheduling: React.FC = async () => { | ||||
// const project = TypeEnum.PRODUCT | |||||
const { t } = await getServerI18n("schedule"); | |||||
const type = "rough" | |||||
// preloadClaims(); | |||||
// const project = TypeEnum.PRODUCT | |||||
const { t } = await getServerI18n("schedule"); | |||||
const type = "rough"; | |||||
// preloadClaims(); | |||||
// async function testingRoughSchedule() { | |||||
// await testRoughSchedule(); | |||||
// } | |||||
// async function testingRoughSchedule() { | |||||
// await testRoughSchedule(); | |||||
// } | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Demand Forecast")} | |||||
</Typography> | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Demand Forecast")} | |||||
</Typography> | |||||
{/* <Button | |||||
{/* <Button | |||||
variant="contained" | variant="contained" | ||||
startIcon={<Add />} | startIcon={<Add />} | ||||
onClick={() => testingRoughSchedule} | onClick={() => testingRoughSchedule} | ||||
> | > | ||||
{t("Test Rough Scheduling")} | {t("Test Rough Scheduling")} | ||||
</Button> */} | </Button> */} | ||||
</Stack> | |||||
<I18nProvider namespaces={["schedule", "common"]}> | |||||
<Suspense fallback={<RoughSchedule.Loading />}> | |||||
<RoughSchedule type={type} /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
</Stack> | |||||
<I18nProvider namespaces={["schedule", "common"]}> | |||||
<Suspense fallback={<RoughSchedule.Loading />}> | |||||
<RoughSchedule type={type} /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default roughScheduling; | export default roughScheduling; |
@@ -41,8 +41,8 @@ const productSetting: React.FC = async () => { | |||||
</Button> */} | </Button> */} | ||||
</Stack> | </Stack> | ||||
<Suspense fallback={<EquipmentSearch.Loading />}> | <Suspense fallback={<EquipmentSearch.Loading />}> | ||||
<I18nProvider namespaces={["common","project"]}> | |||||
<EquipmentSearch /> | |||||
<I18nProvider namespaces={["common", "project"]}> | |||||
<EquipmentSearch /> | |||||
</I18nProvider> | </I18nProvider> | ||||
</Suspense> | </Suspense> | ||||
</> | </> | ||||
@@ -41,8 +41,8 @@ const productSetting: React.FC = async () => { | |||||
</Button> */} | </Button> */} | ||||
</Stack> | </Stack> | ||||
<Suspense fallback={<EquipmentTypeSearch.Loading />}> | <Suspense fallback={<EquipmentTypeSearch.Loading />}> | ||||
<I18nProvider namespaces={["common","project"]}> | |||||
<EquipmentTypeSearch /> | |||||
<I18nProvider namespaces={["common", "project"]}> | |||||
<EquipmentTypeSearch /> | |||||
</I18nProvider> | </I18nProvider> | ||||
</Suspense> | </Suspense> | ||||
</> | </> | ||||
@@ -14,7 +14,7 @@ export const metadata: Metadata = { | |||||
}; | }; | ||||
const productSetting: React.FC = async () => { | const productSetting: React.FC = async () => { | ||||
const project = TypeEnum.PRODUCT | |||||
const project = TypeEnum.PRODUCT; | |||||
const { t } = await getServerI18n(project); | const { t } = await getServerI18n(project); | ||||
// preloadClaims(); | // preloadClaims(); | ||||
@@ -6,28 +6,27 @@ import React, { Suspense } from "react"; | |||||
import { I18nProvider } from "@/i18n"; | import { I18nProvider } from "@/i18n"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Import Testing" | |||||
} | |||||
title: "Import Testing", | |||||
}; | |||||
const M18ImportTestingPage: React.FC = async () => { | const M18ImportTestingPage: React.FC = async () => { | ||||
const { t } = await getServerI18n("m18ImportTesting"); | |||||
const { t } = await getServerI18n("m18ImportTesting"); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
</Stack> | |||||
<Suspense fallback={<M18ImportTesting.Loading />}> | |||||
<I18nProvider namespaces={["common", "m18ImportTesting"]}> | |||||
<M18ImportTesting /> | |||||
</I18nProvider> | |||||
</Suspense> | |||||
</> | |||||
) | |||||
} | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
></Stack> | |||||
<Suspense fallback={<M18ImportTesting.Loading />}> | |||||
<I18nProvider namespaces={["common", "m18ImportTesting"]}> | |||||
<M18ImportTesting /> | |||||
</I18nProvider> | |||||
</Suspense> | |||||
</> | |||||
); | |||||
}; | |||||
export default M18ImportTestingPage; | |||||
export default M18ImportTestingPage; |
@@ -9,33 +9,33 @@ import { preloadMails } from "@/app/api/mail"; | |||||
import MailSetting from "@/components/MailSetting"; | import MailSetting from "@/components/MailSetting"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Mail", | |||||
title: "Mail", | |||||
}; | }; | ||||
const Customer: React.FC = async () => { | const Customer: React.FC = async () => { | ||||
const { t } = await getServerI18n("mail"); | |||||
preloadMails(); | |||||
// const abilities = await fetchUserAbilities() | |||||
const { t } = await getServerI18n("mail"); | |||||
preloadMails(); | |||||
// const abilities = await fetchUserAbilities() | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Mail")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["mail", "common"]}> | |||||
<Suspense fallback={<MailSetting.Loading />}> | |||||
<MailSetting /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Mail")} | |||||
</Typography> | |||||
</Stack> | |||||
<I18nProvider namespaces={["mail", "common"]}> | |||||
<Suspense fallback={<MailSetting.Loading />}> | |||||
<MailSetting /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default Customer; | |||||
export default Customer; |
@@ -8,37 +8,39 @@ import QcCategorySearch from "@/components/QcCategorySearch"; | |||||
import { preloadQcCategory } from "@/app/api/settings/qcCategory"; | import { preloadQcCategory } from "@/app/api/settings/qcCategory"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Qc Category", | |||||
title: "Qc Category", | |||||
}; | }; | ||||
const qcCategory: React.FC = async () => { | const qcCategory: React.FC = async () => { | ||||
const { t } = await getServerI18n("qcCategory") | |||||
const { t } = await getServerI18n("qcCategory"); | |||||
preloadQcCategory() | |||||
preloadQcCategory(); | |||||
return <> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Qc Category")} | |||||
</Typography> | |||||
<Button | |||||
variant="contained" | |||||
startIcon={<Add />} | |||||
LinkComponent={Link} | |||||
href="qcCategory/create" | |||||
> | > | ||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Qc Category")} | |||||
</Typography> | |||||
<Button | |||||
variant="contained" | |||||
startIcon={<Add />} | |||||
LinkComponent={Link} | |||||
href="qcCategory/create" | |||||
> | |||||
{t("Create Qc Category")} | |||||
</Button> | |||||
</Stack> | |||||
<Suspense fallback={<QcCategorySearch.Loading />}> | |||||
<QcCategorySearch /> | |||||
</Suspense> | |||||
</>; | |||||
{t("Create Qc Category")} | |||||
</Button> | |||||
</Stack> | |||||
<Suspense fallback={<QcCategorySearch.Loading />}> | |||||
<QcCategorySearch /> | |||||
</Suspense> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default qcCategory; | |||||
export default qcCategory; |
@@ -8,7 +8,9 @@ export default async function NotFound() { | |||||
return ( | return ( | ||||
<Stack spacing={2}> | <Stack spacing={2}> | ||||
<Typography variant="h4">{t("Not Found")}</Typography> | <Typography variant="h4">{t("Not Found")}</Typography> | ||||
<Typography variant="body1">{t("The create qc item page was not found!")}</Typography> | |||||
<Typography variant="body1"> | |||||
{t("The create qc item page was not found!")} | |||||
</Typography> | |||||
<Link href="/qcItems" component={NextLink} variant="body2"> | <Link href="/qcItems" component={NextLink} variant="body2"> | ||||
{t("Return to all qc items")} | {t("Return to all qc items")} | ||||
</Link> | </Link> | ||||
@@ -5,20 +5,22 @@ import { preloadQcItem } from "@/app/api/settings/qcItem"; | |||||
import QcItemSave from "@/components/QcItemSave"; | import QcItemSave from "@/components/QcItemSave"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Qc Item", | |||||
title: "Qc Item", | |||||
}; | }; | ||||
const qcItem: React.FC = async () => { | const qcItem: React.FC = async () => { | ||||
const { t } = await getServerI18n("qcItem") | |||||
const { t } = await getServerI18n("qcItem"); | |||||
return <> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Create Qc Item")} | |||||
</Typography> | |||||
<I18nProvider namespaces={["qcItem"]}> | |||||
<QcItemSave /> | |||||
</I18nProvider> | |||||
</>; | |||||
return ( | |||||
<> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Create Qc Item")} | |||||
</Typography> | |||||
<I18nProvider namespaces={["qcItem"]}> | |||||
<QcItemSave /> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default qcItem; | |||||
export default qcItem; |
@@ -8,7 +8,9 @@ export default async function NotFound() { | |||||
return ( | return ( | ||||
<Stack spacing={2}> | <Stack spacing={2}> | ||||
<Typography variant="h4">{t("Not Found")}</Typography> | <Typography variant="h4">{t("Not Found")}</Typography> | ||||
<Typography variant="body1">{t("The edit qc item page was not found!")}</Typography> | |||||
<Typography variant="body1"> | |||||
{t("The edit qc item page was not found!")} | |||||
</Typography> | |||||
<Link href="/settings/qcItems" component={NextLink} variant="body2"> | <Link href="/settings/qcItems" component={NextLink} variant="body2"> | ||||
{t("Return to all qc items")} | {t("Return to all qc items")} | ||||
</Link> | </Link> | ||||
@@ -8,42 +8,46 @@ import { notFound } from "next/navigation"; | |||||
import { ServerFetchError } from "@/app/utils/fetchUtil"; | import { ServerFetchError } from "@/app/utils/fetchUtil"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Qc Item", | |||||
title: "Qc Item", | |||||
}; | }; | ||||
interface Props { | interface Props { | ||||
searchParams: { [key: string]: string | string[] | undefined }; | |||||
searchParams: { [key: string]: string | string[] | undefined }; | |||||
} | } | ||||
const qcItem: React.FC<Props> = async ({ searchParams }) => { | const qcItem: React.FC<Props> = async ({ searchParams }) => { | ||||
const { t } = await getServerI18n("qcItem") | |||||
const id = searchParams["id"] | |||||
if (!id || isArray(id)) { | |||||
notFound() | |||||
} | |||||
try { | |||||
console.log("first") | |||||
await fetchQcItemDetails(id) | |||||
console.log("firsts") | |||||
} catch (e) { | |||||
if (e instanceof ServerFetchError && (e.response?.status === 404 || e.response?.status === 400)) { | |||||
console.log(e) | |||||
notFound(); | |||||
} | |||||
const { t } = await getServerI18n("qcItem"); | |||||
const id = searchParams["id"]; | |||||
if (!id || isArray(id)) { | |||||
notFound(); | |||||
} | |||||
try { | |||||
console.log("first"); | |||||
await fetchQcItemDetails(id); | |||||
console.log("firsts"); | |||||
} catch (e) { | |||||
if ( | |||||
e instanceof ServerFetchError && | |||||
(e.response?.status === 404 || e.response?.status === 400) | |||||
) { | |||||
console.log(e); | |||||
notFound(); | |||||
} | } | ||||
return <> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Edit Qc Item")} | |||||
</Typography> | |||||
<I18nProvider namespaces={["qcItem"]}> | |||||
<QcItemSave id={id}/> | |||||
</I18nProvider> | |||||
</>; | |||||
} | |||||
return ( | |||||
<> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Edit Qc Item")} | |||||
</Typography> | |||||
<I18nProvider namespaces={["qcItem"]}> | |||||
<QcItemSave id={id} /> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default qcItem; | |||||
export default qcItem; |
@@ -8,37 +8,39 @@ import { preloadQcItem } from "@/app/api/settings/qcItem"; | |||||
import QcItemSearch from "@/components/QcItemSearch"; | import QcItemSearch from "@/components/QcItemSearch"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Qc Item", | |||||
title: "Qc Item", | |||||
}; | }; | ||||
const qcItem: React.FC = async () => { | const qcItem: React.FC = async () => { | ||||
const { t } = await getServerI18n("qcItem") | |||||
const { t } = await getServerI18n("qcItem"); | |||||
preloadQcItem() | |||||
preloadQcItem(); | |||||
return <> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Qc Item")} | |||||
</Typography> | |||||
<Button | |||||
variant="contained" | |||||
startIcon={<Add />} | |||||
LinkComponent={Link} | |||||
href="qcItem/create" | |||||
> | > | ||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Qc Item")} | |||||
</Typography> | |||||
<Button | |||||
variant="contained" | |||||
startIcon={<Add />} | |||||
LinkComponent={Link} | |||||
href="qcItem/create" | |||||
> | |||||
{t("Create Qc Item")} | |||||
</Button> | |||||
</Stack> | |||||
<Suspense fallback={<QcItemSearch.Loading />}> | |||||
<QcItemSearch /> | |||||
</Suspense> | |||||
</>; | |||||
{t("Create Qc Item")} | |||||
</Button> | |||||
</Stack> | |||||
<Suspense fallback={<QcItemSearch.Loading />}> | |||||
<QcItemSearch /> | |||||
</Suspense> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default qcItem; | |||||
export default qcItem; |
@@ -8,30 +8,29 @@ import Typography from "@mui/material/Typography"; | |||||
import { Metadata } from "next"; | import { Metadata } from "next"; | ||||
import Link from "next/link"; | import Link from "next/link"; | ||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
import RoughScheduleLoading from "@/components/RoughScheduleSetting/RoughScheduleLoading"; | |||||
import RoughScheduleSetting from "@/components/RoughScheduleSetting/RoughScheduleSetting"; | |||||
import RoughScheduleSetting from "@/components/RoughScheduleSetting"; | |||||
import { I18nProvider } from "@/i18n"; | import { I18nProvider } from "@/i18n"; | ||||
export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
title: "Demand Forecast Setting", | |||||
title: "Demand Forecast Setting", | |||||
}; | }; | ||||
const roughScheduleSetting: React.FC = async () => { | const roughScheduleSetting: React.FC = async () => { | ||||
const project = TypeEnum.PRODUCT | |||||
const { t } = await getServerI18n(project); | |||||
// preloadClaims(); | |||||
const project = TypeEnum.PRODUCT; | |||||
const { t } = await getServerI18n(project); | |||||
// preloadClaims(); | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Demand Forecast Setting")} | |||||
</Typography> | |||||
{/* <Button | |||||
return ( | |||||
<> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="space-between" | |||||
flexWrap="wrap" | |||||
rowGap={2} | |||||
> | |||||
<Typography variant="h4" marginInlineEnd={2}> | |||||
{t("Demand Forecast Setting")} | |||||
</Typography> | |||||
{/* <Button | |||||
variant="contained" | variant="contained" | ||||
startIcon={<Add />} | startIcon={<Add />} | ||||
LinkComponent={Link} | LinkComponent={Link} | ||||
@@ -39,14 +38,14 @@ const roughScheduleSetting: React.FC = async () => { | |||||
> | > | ||||
{t("Create product")} | {t("Create product")} | ||||
</Button> */} | </Button> */} | ||||
</Stack> | |||||
<I18nProvider namespaces={[ "common", "project"]}> | |||||
<Suspense fallback={<RoughScheduleLoading.Loading />}> | |||||
<RoughScheduleSetting /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
</Stack> | |||||
<I18nProvider namespaces={["common", "project"]}> | |||||
<Suspense fallback={<RoughScheduleSetting.Loading />}> | |||||
<RoughScheduleSetting /> | |||||
</Suspense> | |||||
</I18nProvider> | |||||
</> | |||||
); | |||||
}; | }; | ||||
export default roughScheduleSetting; | export default roughScheduleSetting; |
@@ -19,7 +19,7 @@ const CreateStaffPage: React.FC = async () => { | |||||
<Typography variant="h4">{t("Create User")}</Typography> | <Typography variant="h4">{t("Create User")}</Typography> | ||||
<I18nProvider namespaces={["user", "common"]}> | <I18nProvider namespaces={["user", "common"]}> | ||||
<Suspense fallback={<CreateUser.Loading />}> | <Suspense fallback={<CreateUser.Loading />}> | ||||
<CreateUser/> | |||||
<CreateUser /> | |||||
</Suspense> | </Suspense> | ||||
</I18nProvider> | </I18nProvider> | ||||
</> | </> | ||||
@@ -12,7 +12,7 @@ export const metadata: Metadata = { | |||||
title: "User Management", | title: "User Management", | ||||
}; | }; | ||||
const User: React.FC = async() => { | |||||
const User: React.FC = async () => { | |||||
const { t } = await getServerI18n("user"); | const { t } = await getServerI18n("user"); | ||||
return ( | return ( | ||||
<> | <> | ||||
@@ -15,21 +15,21 @@ export interface PostStockInLiineResponse<T> { | |||||
id: number | null; | id: number | null; | ||||
name: string; | name: string; | ||||
code: string; | code: string; | ||||
type?: string | |||||
type?: string; | |||||
message: string | null; | message: string | null; | ||||
errorPosition: string | keyof T; | errorPosition: string | keyof T; | ||||
entity: T | T[] | |||||
entity: T | T[]; | |||||
// entity: StockInLine | StockInLine[] | // entity: StockInLine | StockInLine[] | ||||
} | } | ||||
export interface StockInLineEntry { | export interface StockInLineEntry { | ||||
id?: number | |||||
itemId: number | |||||
purchaseOrderId: number | |||||
purchaseOrderLineId: number | |||||
acceptedQty: number | |||||
status?: string | |||||
expiryDate?: string | |||||
id?: number; | |||||
itemId: number; | |||||
purchaseOrderId: number; | |||||
purchaseOrderLineId: number; | |||||
acceptedQty: number; | |||||
status?: string; | |||||
expiryDate?: string; | |||||
} | } | ||||
export interface PurchaseQcResult { | export interface PurchaseQcResult { | ||||
@@ -37,37 +37,39 @@ export interface PurchaseQcResult { | |||||
failQty: number; | failQty: number; | ||||
} | } | ||||
export interface StockInInput { | export interface StockInInput { | ||||
status: string | |||||
productLotNo?: string, | |||||
receiptDate: string | |||||
acceptedQty: number | |||||
acceptedWeight?: number | |||||
productionDate?: string | |||||
expiryDate: string | |||||
status: string; | |||||
productLotNo?: string; | |||||
receiptDate: string; | |||||
acceptedQty: number; | |||||
acceptedWeight?: number; | |||||
productionDate?: string; | |||||
expiryDate: string; | |||||
} | } | ||||
export interface PurchaseQCInput { | export interface PurchaseQCInput { | ||||
status: string | |||||
acceptedQty: number | |||||
status: string; | |||||
acceptedQty: number; | |||||
sampleRate: number; | sampleRate: number; | ||||
sampleWeight: number; | sampleWeight: number; | ||||
totalWeight: number; | totalWeight: number; | ||||
qcResult: PurchaseQcResult[]; | qcResult: PurchaseQcResult[]; | ||||
} | } | ||||
export interface EscalationInput { | export interface EscalationInput { | ||||
status: string | |||||
handler: string | |||||
acceptedQty: number // this is the qty to be escalated | |||||
status: string; | |||||
handler: string; | |||||
acceptedQty: number; // this is the qty to be escalated | |||||
// escalationQty: number | // escalationQty: number | ||||
} | } | ||||
export interface PutawayInput { | export interface PutawayInput { | ||||
status: string | |||||
acceptedQty: number | |||||
warehouseId: number | |||||
status: string; | |||||
acceptedQty: number; | |||||
warehouseId: number; | |||||
// handler: string | // handler: string | ||||
// stockInLine: StockInLineEntry[] | // stockInLine: StockInLineEntry[] | ||||
} | } | ||||
export type ModalFormInput = Partial<PurchaseQCInput & StockInInput & EscalationInput & PutawayInput> | |||||
export type ModalFormInput = Partial< | |||||
PurchaseQCInput & StockInInput & EscalationInput & PutawayInput | |||||
>; | |||||
export const testFetch = cache(async (id: number) => { | export const testFetch = cache(async (id: number) => { | ||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | ||||
@@ -76,50 +78,65 @@ export const testFetch = cache(async (id: number) => { | |||||
}); | }); | ||||
export const fetchStockInLineInfo = cache(async (stockInLineId: number) => { | export const fetchStockInLineInfo = cache(async (stockInLineId: number) => { | ||||
return serverFetchJson<StockInLine>(`${BASE_API_URL}/stockInLine/${stockInLineId}`, { | |||||
return serverFetchJson<StockInLine>( | |||||
`${BASE_API_URL}/stockInLine/${stockInLineId}`, | |||||
{ | |||||
next: { tags: ["stockInLine"] }, | next: { tags: ["stockInLine"] }, | ||||
}); | |||||
}, | |||||
); | |||||
}); | }); | ||||
export const createStockInLine = async (data: StockInLineEntry) => { | export const createStockInLine = async (data: StockInLineEntry) => { | ||||
const stockInLine = await serverFetchJson<PostStockInLiineResponse<StockInLineEntry>>(`${BASE_API_URL}/stockInLine/create`, { | |||||
const stockInLine = await serverFetchJson< | |||||
PostStockInLiineResponse<StockInLineEntry> | |||||
>(`${BASE_API_URL}/stockInLine/create`, { | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
// revalidateTag("po"); | // revalidateTag("po"); | ||||
return stockInLine | |||||
} | |||||
return stockInLine; | |||||
}; | |||||
export const updateStockInLine = async (data: StockInLineEntry & ModalFormInput) => { | |||||
const stockInLine = await serverFetchJson<PostStockInLiineResponse<StockInLineEntry & ModalFormInput>>(`${BASE_API_URL}/stockInLine/update`, { | |||||
export const updateStockInLine = async ( | |||||
data: StockInLineEntry & ModalFormInput, | |||||
) => { | |||||
const stockInLine = await serverFetchJson< | |||||
PostStockInLiineResponse<StockInLineEntry & ModalFormInput> | |||||
>(`${BASE_API_URL}/stockInLine/update`, { | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
// revalidateTag("po"); | // revalidateTag("po"); | ||||
return stockInLine | |||||
} | |||||
return stockInLine; | |||||
}; | |||||
export const startPo = async (poId: number) => { | export const startPo = async (poId: number) => { | ||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>(`${BASE_API_URL}/po/start/${poId}`, { | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>( | |||||
`${BASE_API_URL}/po/start/${poId}`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("po"); | revalidateTag("po"); | ||||
return po | |||||
} | |||||
return po; | |||||
}; | |||||
export const checkPolAndCompletePo = async (poId: number) => { | export const checkPolAndCompletePo = async (poId: number) => { | ||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>(`${BASE_API_URL}/po/check/${poId}`, { | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>( | |||||
`${BASE_API_URL}/po/check/${poId}`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("po"); | revalidateTag("po"); | ||||
return po | |||||
} | |||||
return po; | |||||
}; | |||||
export const fetchPoInClient = cache(async (id: number) => { | export const fetchPoInClient = cache(async (id: number) => { | ||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | ||||
@@ -127,33 +144,46 @@ export const fetchPoInClient = cache(async (id: number) => { | |||||
}); | }); | ||||
}); | }); | ||||
export const fetchPoListClient = cache(async (queryParams?: Record<string, any>) => { | |||||
export const fetchPoListClient = cache( | |||||
async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | if (queryParams) { | ||||
const queryString = new URLSearchParams(queryParams).toString(); | const queryString = new URLSearchParams(queryParams).toString(); | ||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list?${queryString}`, { | |||||
method: 'GET', | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/list?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | |||||
}, | |||||
); | |||||
} else { | } else { | ||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list`, { | |||||
method: 'GET', | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/list`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | |||||
}, | |||||
); | |||||
} | } | ||||
}); | |||||
}, | |||||
); | |||||
export const testing = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/testing?${queryString}`, { | |||||
method: 'GET', | |||||
export const testing = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/testing?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/testing`, { | |||||
method: 'GET', | |||||
}, | |||||
); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/testing`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | |||||
} | |||||
}); | |||||
}, | |||||
); | |||||
} | |||||
}); |
@@ -8,74 +8,76 @@ import { Uom } from "../settings/uom"; | |||||
import { RecordsRes } from "../utils"; | import { RecordsRes } from "../utils"; | ||||
export interface PoResult { | export interface PoResult { | ||||
id: number | |||||
code: string | |||||
orderDate: string | |||||
supplier: string | |||||
estimatedArrivalDate: string | |||||
completedDate: string | |||||
escalated: boolean | |||||
status: string | |||||
pol?: PurchaseOrderLine[] | |||||
} | |||||
id: number; | |||||
code: string; | |||||
orderDate: string; | |||||
supplier: string; | |||||
estimatedArrivalDate: string; | |||||
completedDate: string; | |||||
escalated: boolean; | |||||
status: string; | |||||
pol?: PurchaseOrderLine[]; | |||||
} | |||||
export interface PurchaseOrderLine { | export interface PurchaseOrderLine { | ||||
id: number | |||||
purchaseOrderId: number | |||||
itemId: number | |||||
itemNo: string | |||||
itemName: string | |||||
qty: number | |||||
processed: number | |||||
uom: Uom | |||||
price: number | |||||
status: string | |||||
stockInLine: StockInLine[] | |||||
id: number; | |||||
purchaseOrderId: number; | |||||
itemId: number; | |||||
itemNo: string; | |||||
itemName: string; | |||||
qty: number; | |||||
processed: number; | |||||
uom: Uom; | |||||
price: number; | |||||
status: string; | |||||
stockInLine: StockInLine[]; | |||||
} | } | ||||
export interface StockInLine { | export interface StockInLine { | ||||
id: number | |||||
stockInId: number | |||||
purchaseOrderId?: number | |||||
purchaseOrderLineId: number | |||||
itemId: number | |||||
itemNo: string | |||||
itemName: string | |||||
itemType: string | |||||
demandQty: number | |||||
acceptedQty: number | |||||
price: number | |||||
priceUnit: string | |||||
shelfLife?: number, | |||||
receiptDate?: string | |||||
productionDate?: string | |||||
expiryDate?: string | |||||
status: string | |||||
supplier: string | |||||
lotNo: string | |||||
poCode: string | |||||
uom: Uom | |||||
defaultWarehouseId: number // id for now | |||||
id: number; | |||||
stockInId: number; | |||||
purchaseOrderId?: number; | |||||
purchaseOrderLineId: number; | |||||
itemId: number; | |||||
itemNo: string; | |||||
itemName: string; | |||||
itemType: string; | |||||
demandQty: number; | |||||
acceptedQty: number; | |||||
price: number; | |||||
priceUnit: string; | |||||
shelfLife?: number; | |||||
receiptDate?: string; | |||||
productionDate?: string; | |||||
expiryDate?: string; | |||||
status: string; | |||||
supplier: string; | |||||
lotNo: string; | |||||
poCode: string; | |||||
uom: Uom; | |||||
defaultWarehouseId: number; // id for now | |||||
} | } | ||||
export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list?${queryString}`, { | |||||
method: 'GET', | |||||
export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/list?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list`, { | |||||
method: 'GET', | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
} | |||||
}); | |||||
export const fetchPoWithStockInLines = cache(async (id: number) => { | |||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | |||||
}, | |||||
); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list`, { | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | }); | ||||
}); | |||||
} | |||||
}); | |||||
export const fetchPoWithStockInLines = cache(async (id: number) => { | |||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
}); |
@@ -10,5 +10,5 @@ import { DoResult } from "."; | |||||
import { GridRowId, GridRowSelectionModel } from "@mui/x-data-grid"; | import { GridRowId, GridRowSelectionModel } from "@mui/x-data-grid"; | ||||
export interface CreateConsoDoInput { | export interface CreateConsoDoInput { | ||||
ids: GridRowSelectionModel | |||||
ids: GridRowSelectionModel; | |||||
} | } |
@@ -5,20 +5,20 @@ import { BASE_API_URL } from "../../../config/api"; | |||||
import { cache } from "react"; | import { cache } from "react"; | ||||
export interface DoResult { | export interface DoResult { | ||||
id: number, | |||||
code: string, | |||||
orderDate: string, | |||||
estimatedArrivalDate: string, | |||||
status: string, | |||||
shopName: string, | |||||
id: number; | |||||
code: string; | |||||
orderDate: string; | |||||
estimatedArrivalDate: string; | |||||
status: string; | |||||
shopName: string; | |||||
} | } | ||||
export const preloadDo = () => { | export const preloadDo = () => { | ||||
fetchDoList(); | |||||
} | |||||
fetchDoList(); | |||||
}; | |||||
export const fetchDoList = cache(async () => { | export const fetchDoList = cache(async () => { | ||||
return serverFetchJson<DoResult[]>(`${BASE_API_URL}/do/list`, { | |||||
next: { tags: ["doList"] } | |||||
}) | |||||
}) | |||||
return serverFetchJson<DoResult[]>(`${BASE_API_URL}/do/list`, { | |||||
next: { tags: ["doList"] }, | |||||
}); | |||||
}); |
@@ -1,55 +1,60 @@ | |||||
"use server"; | "use server"; | ||||
import { serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||||
import { | |||||
serverFetchJson, | |||||
serverFetchWithNoContent, | |||||
} from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
import { revalidateTag } from "next/cache"; | import { revalidateTag } from "next/cache"; | ||||
import { cache } from "react"; | import { cache } from "react"; | ||||
export interface CreateGroupInputs { | export interface CreateGroupInputs { | ||||
id?: number; | |||||
name: string; | |||||
description: string; | |||||
addUserIds?: number[]; | |||||
removeUserIds?: number[]; | |||||
addAuthIds?: number[]; | |||||
removeAuthIds?: number[]; | |||||
} | |||||
id?: number; | |||||
name: string; | |||||
description: string; | |||||
addUserIds?: number[]; | |||||
removeUserIds?: number[]; | |||||
addAuthIds?: number[]; | |||||
removeAuthIds?: number[]; | |||||
} | |||||
export interface auth { | export interface auth { | ||||
id: number; | |||||
module?: any | null; | |||||
authority: string; | |||||
name: string; | |||||
description: string | null; | |||||
v: number; | |||||
} | |||||
id: number; | |||||
module?: any | null; | |||||
authority: string; | |||||
name: string; | |||||
description: string | null; | |||||
v: number; | |||||
} | |||||
export interface record { | export interface record { | ||||
records: auth[]; | |||||
} | |||||
records: auth[]; | |||||
} | |||||
export const fetchAuth = cache(async (target: string, id?: number ) => { | |||||
return serverFetchJson<record>(`${BASE_API_URL}/group/auth/${target}/${id ?? 0}`, { | |||||
export const fetchAuth = cache(async (target: string, id?: number) => { | |||||
return serverFetchJson<record>( | |||||
`${BASE_API_URL}/group/auth/${target}/${id ?? 0}`, | |||||
{ | |||||
next: { tags: ["auth"] }, | next: { tags: ["auth"] }, | ||||
}); | |||||
}, | |||||
); | |||||
}); | }); | ||||
export const saveGroup = async (data: CreateGroupInputs) => { | export const saveGroup = async (data: CreateGroupInputs) => { | ||||
const newGroup = serverFetchJson(`${BASE_API_URL}/group/save`, { | const newGroup = serverFetchJson(`${BASE_API_URL}/group/save`, { | ||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
revalidateTag("group") | |||||
return newGroup | |||||
}; | |||||
revalidateTag("group"); | |||||
return newGroup; | |||||
}; | |||||
export const deleteGroup = async (id: number) => { | export const deleteGroup = async (id: number) => { | ||||
const newGroup = serverFetchWithNoContent(`${BASE_API_URL}/group/${id}`, { | const newGroup = serverFetchWithNoContent(`${BASE_API_URL}/group/${id}`, { | ||||
method: "DELETE", | method: "DELETE", | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
revalidateTag("group") | |||||
return newGroup | |||||
}; | |||||
revalidateTag("group"); | |||||
return newGroup; | |||||
}; |
@@ -4,31 +4,30 @@ import { cache } from "react"; | |||||
import "server-only"; | import "server-only"; | ||||
export interface Records { | export interface Records { | ||||
records: UserGroupResult[] | |||||
records: UserGroupResult[]; | |||||
} | } | ||||
export interface UserGroupResult { | export interface UserGroupResult { | ||||
id: number; | |||||
action: () => void; | |||||
name: string; | |||||
description: string; | |||||
id: number; | |||||
action: () => void; | |||||
name: string; | |||||
description: string; | |||||
} | } | ||||
export type IndivUserGroup = { | export type IndivUserGroup = { | ||||
authIds: number[]; | authIds: number[]; | ||||
data: any; | data: any; | ||||
userIds: number[]; | userIds: number[]; | ||||
} | |||||
}; | |||||
export const fetchGroup = cache(async () => { | export const fetchGroup = cache(async () => { | ||||
return serverFetchJson<Records>(`${BASE_API_URL}/group`, { | |||||
next: { tags: ["group"] }, | |||||
}); | |||||
return serverFetchJson<Records>(`${BASE_API_URL}/group`, { | |||||
next: { tags: ["group"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchIndivGroup = cache(async (id: number) => { | export const fetchIndivGroup = cache(async (id: number) => { | ||||
return serverFetchJson<IndivUserGroup>(`${BASE_API_URL}/group/${id}`, { | |||||
next: { tags: ["group"] }, | |||||
}); | |||||
return serverFetchJson<IndivUserGroup>(`${BASE_API_URL}/group/${id}`, { | |||||
next: { tags: ["group"] }, | |||||
}); | }); | ||||
}); |
@@ -9,18 +9,21 @@ import { RecordsRes } from "../utils"; | |||||
// import { BASE_API_URL } from "@/config/api"; | // import { BASE_API_URL } from "@/config/api"; | ||||
export interface LotLineInfo { | export interface LotLineInfo { | ||||
inventoryLotLineId: number, | |||||
itemId: number, | |||||
itemNo: string, | |||||
itemName: string, | |||||
lotNo: string, | |||||
remainingQty: number, | |||||
uom: string | |||||
inventoryLotLineId: number; | |||||
itemId: number; | |||||
itemNo: string; | |||||
itemName: string; | |||||
lotNo: string; | |||||
remainingQty: number; | |||||
uom: string; | |||||
} | } | ||||
export const fetchLotDetail = cache(async (stockInLineId: number) => { | |||||
return serverFetchJson<LotLineInfo>(`${BASE_API_URL}/inventoryLotLine/lot-detail/${stockInLineId}`, { | |||||
method: 'GET', | |||||
next: { tags: ["inventory"] }, | |||||
}); | |||||
}); | |||||
export const fetchLotDetail = cache(async (stockInLineId: number) => { | |||||
return serverFetchJson<LotLineInfo>( | |||||
`${BASE_API_URL}/inventoryLotLine/lot-detail/${stockInLineId}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["inventory"] }, | |||||
}, | |||||
); | |||||
}); |
@@ -4,27 +4,27 @@ import { cache } from "react"; | |||||
import "server-only"; | import "server-only"; | ||||
export interface InventoryResult { | export interface InventoryResult { | ||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
qty: number; | |||||
uomCode: string; | |||||
uomUdfudesc: string; | |||||
// germPerSmallestUnit: number; | |||||
// qtyPerSmallestUnit: number; | |||||
// smallestUnit: string; | |||||
price: number; | |||||
currencyName: string; | |||||
status: string; | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
qty: number; | |||||
uomCode: string; | |||||
uomUdfudesc: string; | |||||
// germPerSmallestUnit: number; | |||||
// qtyPerSmallestUnit: number; | |||||
// smallestUnit: string; | |||||
price: number; | |||||
currencyName: string; | |||||
status: string; | |||||
} | } | ||||
export const preloadInventory = () => { | export const preloadInventory = () => { | ||||
fetchInventories(); | |||||
} | |||||
fetchInventories(); | |||||
}; | |||||
export const fetchInventories = cache(async() => { | |||||
return serverFetchJson<InventoryResult[]>(`${BASE_API_URL}/inventory/list`, { | |||||
next: { tags: ["inventories"]} | |||||
}) | |||||
}) | |||||
export const fetchInventories = cache(async () => { | |||||
return serverFetchJson<InventoryResult[]>(`${BASE_API_URL}/inventory/list`, { | |||||
next: { tags: ["inventories"] }, | |||||
}); | |||||
}); |
@@ -1,46 +1,51 @@ | |||||
'use server' | |||||
"use server"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | import { serverFetchJson } from "@/app/utils/fetchUtil"; | ||||
import { Machine, Operator } from "."; | import { Machine, Operator } from "."; | ||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
import { revalidateTag } from "next/cache"; | import { revalidateTag } from "next/cache"; | ||||
export interface IsOperatorExistResponse<T> { | export interface IsOperatorExistResponse<T> { | ||||
id: number | null; | |||||
name: string; | |||||
code: string; | |||||
type?: string | |||||
message: string | null; | |||||
errorPosition: string | keyof T; | |||||
entity: T | |||||
id: number | null; | |||||
name: string; | |||||
code: string; | |||||
type?: string; | |||||
message: string | null; | |||||
errorPosition: string | keyof T; | |||||
entity: T; | |||||
} | } | ||||
export interface isCorrectMachineUsedResponse<T> { | export interface isCorrectMachineUsedResponse<T> { | ||||
id: number | null; | |||||
name: string; | |||||
code: string; | |||||
type?: string | |||||
message: string | null; | |||||
errorPosition: string | keyof T; | |||||
entity: T | |||||
id: number | null; | |||||
name: string; | |||||
code: string; | |||||
type?: string; | |||||
message: string | null; | |||||
errorPosition: string | keyof T; | |||||
entity: T; | |||||
} | } | ||||
export const isOperatorExist = async (username: string) => { | export const isOperatorExist = async (username: string) => { | ||||
const isExist = await serverFetchJson<IsOperatorExistResponse<Operator>>(`${BASE_API_URL}/jop/isOperatorExist`, { | |||||
const isExist = await serverFetchJson<IsOperatorExistResponse<Operator>>( | |||||
`${BASE_API_URL}/jop/isOperatorExist`, | |||||
{ | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify({ username }), | body: JSON.stringify({ username }), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | |||||
revalidateTag("po"); | |||||
return isExist | |||||
} | |||||
}, | |||||
); | |||||
revalidateTag("po"); | |||||
return isExist; | |||||
}; | |||||
export const isCorrectMachineUsed = async (machineCode: string) => { | export const isCorrectMachineUsed = async (machineCode: string) => { | ||||
const isExist = await serverFetchJson<isCorrectMachineUsedResponse<Machine>>(`${BASE_API_URL}/jop/isCorrectMachineUsed`, { | |||||
method: "POST", | |||||
body: JSON.stringify({ machineCode }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
revalidateTag("po"); | |||||
return isExist | |||||
} | |||||
const isExist = await serverFetchJson<isCorrectMachineUsedResponse<Machine>>( | |||||
`${BASE_API_URL}/jop/isCorrectMachineUsed`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify({ machineCode }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("po"); | |||||
return isExist; | |||||
}; |
@@ -1,14 +1,14 @@ | |||||
'server=only' | |||||
"server=only"; | |||||
export interface Operator { | export interface Operator { | ||||
id: number; | |||||
name: string; | |||||
username: string; | |||||
id: number; | |||||
name: string; | |||||
username: string; | |||||
} | } | ||||
export interface Machine { | export interface Machine { | ||||
id: number; | |||||
name: string; | |||||
code: string; | |||||
qrCode: string; | |||||
} | |||||
id: number; | |||||
name: string; | |||||
code: string; | |||||
qrCode: string; | |||||
} |
@@ -2,53 +2,56 @@ | |||||
// import { serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | // import { serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | ||||
// import { BASE_API_URL } from "@/config/api"; | // import { BASE_API_URL } from "@/config/api"; | ||||
import { serverFetchJson, serverFetchWithNoContent } from "../../utils/fetchUtil"; | |||||
import { | |||||
serverFetchJson, | |||||
serverFetchWithNoContent, | |||||
} from "../../utils/fetchUtil"; | |||||
import { BASE_API_URL } from "../../../config/api"; | import { BASE_API_URL } from "../../../config/api"; | ||||
import { MailSetting, MailTemplate } from "."; | import { MailSetting, MailTemplate } from "."; | ||||
export interface MailSave { | export interface MailSave { | ||||
settings: MailSetting[]; | |||||
templates: MailTemplate[]; | |||||
// template: MailTemplate; | |||||
settings: MailSetting[]; | |||||
templates: MailTemplate[]; | |||||
// template: MailTemplate; | |||||
} | } | ||||
export const saveMail = async (data: MailSave) => { | export const saveMail = async (data: MailSave) => { | ||||
return serverFetchJson<MailSetting[]>(`${BASE_API_URL}/mails/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
return serverFetchJson<MailSetting[]>(`${BASE_API_URL}/mails/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | }; | ||||
export const testSendMail = async () => { | export const testSendMail = async () => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/test-send`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/test-send`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | }; | ||||
export const testEveryone = async () => { | export const testEveryone = async () => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/testEveryone`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/testEveryone`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | }; | ||||
export const test7th = async () => { | export const test7th = async () => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/test7th`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/test7th`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | }; | ||||
export const test15th = async () => { | export const test15th = async () => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/test15th`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/mails/test15th`, { | |||||
method: "GET", | |||||
// body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; |
@@ -7,32 +7,32 @@ import { cache } from "react"; | |||||
import "server-only"; | import "server-only"; | ||||
export interface MailSMTP { | export interface MailSMTP { | ||||
host: string; | |||||
port: number; | |||||
username: string; | |||||
password: string; | |||||
host: string; | |||||
port: number; | |||||
username: string; | |||||
password: string; | |||||
} | } | ||||
export interface MailSetting { | export interface MailSetting { | ||||
id: number; | |||||
name: string; | |||||
value: string; | |||||
category: string; | |||||
type: string; | |||||
id: number; | |||||
name: string; | |||||
value: string; | |||||
category: string; | |||||
type: string; | |||||
} | } | ||||
export interface MailTemplate { | export interface MailTemplate { | ||||
id: number; | |||||
to: string; | |||||
cc: string; | |||||
code: string; | |||||
description: string; | |||||
type: string; | |||||
params: string; | |||||
subjectCht: string; | |||||
subjectEng: string; | |||||
contentCht: string; | |||||
contentEng: string; | |||||
id: number; | |||||
to: string; | |||||
cc: string; | |||||
code: string; | |||||
description: string; | |||||
type: string; | |||||
params: string; | |||||
subjectCht: string; | |||||
subjectEng: string; | |||||
contentCht: string; | |||||
contentEng: string; | |||||
} | } | ||||
// export interface MailTemplate { | // export interface MailTemplate { | ||||
@@ -43,21 +43,21 @@ export interface MailTemplate { | |||||
// } | // } | ||||
export const preloadMails = () => { | export const preloadMails = () => { | ||||
fetchMailSetting(); | |||||
fetchMailTemplates(); | |||||
// fetchMailTimesheetTemplate(); | |||||
fetchMailSetting(); | |||||
fetchMailTemplates(); | |||||
// fetchMailTimesheetTemplate(); | |||||
}; | }; | ||||
export const fetchMailSetting = cache(async () => { | export const fetchMailSetting = cache(async () => { | ||||
return serverFetchJson<MailSetting[]>(`${BASE_API_URL}/mails/setting`, { | |||||
next: { tags: ["mailSetting"] }, | |||||
}); | |||||
return serverFetchJson<MailSetting[]>(`${BASE_API_URL}/mails/setting`, { | |||||
next: { tags: ["mailSetting"] }, | |||||
}); | |||||
}); | }); | ||||
export const fetchMailTemplates = cache(async () => { | export const fetchMailTemplates = cache(async () => { | ||||
return serverFetchJson<MailTemplate[]>(`${BASE_API_URL}/mailTemplates`, { | |||||
next: { tags: ["mailTemplates"] }, | |||||
}); | |||||
return serverFetchJson<MailTemplate[]>(`${BASE_API_URL}/mailTemplates`, { | |||||
next: { tags: ["mailTemplates"] }, | |||||
}); | |||||
}); | }); | ||||
// export const fetchMailTimesheetTemplate = cache(async () => { | // export const fetchMailTimesheetTemplate = cache(async () => { | ||||
@@ -5,22 +5,20 @@ | |||||
import { serverFetchBlob } from "../../utils/fetchUtil"; | import { serverFetchBlob } from "../../utils/fetchUtil"; | ||||
import { BASE_API_URL } from "../../../config/api"; | import { BASE_API_URL } from "../../../config/api"; | ||||
export interface FileResponse { | export interface FileResponse { | ||||
filename: string; | |||||
blobValue: Uint8Array; | |||||
filename: string; | |||||
blobValue: Uint8Array; | |||||
} | } | ||||
export const fetchPoQrcode = async (data: any) => { | export const fetchPoQrcode = async (data: any) => { | ||||
const reportBlob = await serverFetchBlob<FileResponse>( | |||||
`${BASE_API_URL}/stockInLine/print-label`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
const reportBlob = await serverFetchBlob<FileResponse>( | |||||
`${BASE_API_URL}/stockInLine/print-label`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
return reportBlob | |||||
}; | |||||
return reportBlob; | |||||
}; |
@@ -6,177 +6,229 @@ import { cache } from "react"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | import { serverFetchJson } from "@/app/utils/fetchUtil"; | ||||
import { QcItemResult } from "../settings/qcItem"; | import { QcItemResult } from "../settings/qcItem"; | ||||
import { RecordsRes } from "../utils"; | import { RecordsRes } from "../utils"; | ||||
import { ConsoPickOrderResult, PickOrderLineWithSuggestedLot, PickOrderResult, PreReleasePickOrderSummary, StockOutLine } from "."; | |||||
import { | |||||
ConsoPickOrderResult, | |||||
PickOrderLineWithSuggestedLot, | |||||
PickOrderResult, | |||||
PreReleasePickOrderSummary, | |||||
StockOutLine, | |||||
} from "."; | |||||
import { PurchaseQcResult } from "../po/actions"; | import { PurchaseQcResult } from "../po/actions"; | ||||
// import { BASE_API_URL } from "@/config/api"; | // import { BASE_API_URL } from "@/config/api"; | ||||
export interface PostStockOutLiineResponse<T> { | export interface PostStockOutLiineResponse<T> { | ||||
id: number | null; | id: number | null; | ||||
name: string; | name: string; | ||||
code: string; | code: string; | ||||
type?: string | |||||
type?: string; | |||||
message: string | null; | message: string | null; | ||||
errorPosition: string | keyof T; | errorPosition: string | keyof T; | ||||
entity: T | T[] | |||||
entity: T | T[]; | |||||
} | } | ||||
export interface ReleasePickOrderInputs { | export interface ReleasePickOrderInputs { | ||||
consoCode: string | |||||
assignTo: number, | |||||
consoCode: string; | |||||
assignTo: number; | |||||
} | } | ||||
export interface CreateStockOutLine { | export interface CreateStockOutLine { | ||||
consoCode: string, | |||||
pickOrderLineId: number, | |||||
inventoryLotLineId: number, | |||||
qty: number, | |||||
consoCode: string; | |||||
pickOrderLineId: number; | |||||
inventoryLotLineId: number; | |||||
qty: number; | |||||
} | } | ||||
export interface UpdateStockOutLine { | export interface UpdateStockOutLine { | ||||
id: number, | |||||
id: number; | |||||
// consoCode: String, | // consoCode: String, | ||||
itemId: number, | |||||
qty: number, | |||||
pickOrderLineId: number, | |||||
inventoryLotLineId?: number, | |||||
status: string, | |||||
pickTime?: string, | |||||
itemId: number; | |||||
qty: number; | |||||
pickOrderLineId: number; | |||||
inventoryLotLineId?: number; | |||||
status: string; | |||||
pickTime?: string; | |||||
// pickerId: number? | // pickerId: number? | ||||
} | } | ||||
export interface PickOrderQcInput { | export interface PickOrderQcInput { | ||||
qty: number | |||||
status: string | |||||
qty: number; | |||||
status: string; | |||||
qcResult: PurchaseQcResult[]; | qcResult: PurchaseQcResult[]; | ||||
} | } | ||||
export interface PickOrderApprovalInput { | export interface PickOrderApprovalInput { | ||||
allowQty: number | |||||
rejectQty: number | |||||
status: string | |||||
allowQty: number; | |||||
rejectQty: number; | |||||
status: string; | |||||
} | } | ||||
export const consolidatePickOrder = async (ids: number[]) => { | export const consolidatePickOrder = async (ids: number[]) => { | ||||
const pickOrder = await serverFetchJson<any>(`${BASE_API_URL}/pickOrder/conso`, { | |||||
method: "POST", | |||||
body: JSON.stringify({ ids: ids }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
// revalidateTag("po"); | |||||
return pickOrder | |||||
} | |||||
const pickOrder = await serverFetchJson<any>( | |||||
`${BASE_API_URL}/pickOrder/conso`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify({ ids: ids }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
// revalidateTag("po"); | |||||
return pickOrder; | |||||
}; | |||||
export const consolidatePickOrder_revert = async (ids: number[]) => { | export const consolidatePickOrder_revert = async (ids: number[]) => { | ||||
const pickOrder = await serverFetchJson<any>(`${BASE_API_URL}/pickOrder/deconso`, { | |||||
method: "POST", | |||||
body: JSON.stringify({ ids: ids }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
// revalidateTag("po"); | |||||
return pickOrder | |||||
} | |||||
export const fetchPickOrderClient = cache(async (queryParams?: Record<string, any>) => { | |||||
const pickOrder = await serverFetchJson<any>( | |||||
`${BASE_API_URL}/pickOrder/deconso`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify({ ids: ids }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
// revalidateTag("po"); | |||||
return pickOrder; | |||||
}; | |||||
export const fetchPickOrderClient = cache( | |||||
async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | if (queryParams) { | ||||
const queryString = new URLSearchParams(queryParams).toString(); | const queryString = new URLSearchParams(queryParams).toString(); | ||||
return serverFetchJson<RecordsRes<PickOrderResult[]>>(`${BASE_API_URL}/pickOrder/getRecordByPage?${queryString}`, { | |||||
method: 'GET', | |||||
next: { tags: ["pickorder"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PickOrderResult[]>>( | |||||
`${BASE_API_URL}/pickOrder/getRecordByPage?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | |||||
}, | |||||
); | |||||
} else { | } else { | ||||
return serverFetchJson<RecordsRes<PickOrderResult[]>>(`${BASE_API_URL}/pickOrder/getRecordByPage`, { | |||||
method: 'GET', | |||||
next: { tags: ["pickorder"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PickOrderResult[]>>( | |||||
`${BASE_API_URL}/pickOrder/getRecordByPage`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | |||||
}, | |||||
); | |||||
} | } | ||||
}); | |||||
}, | |||||
); | |||||
export const fetchConsoPickOrderClient = cache(async (queryParams?: Record<string, any>) => { | |||||
export const fetchConsoPickOrderClient = cache( | |||||
async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | if (queryParams) { | ||||
const queryString = new URLSearchParams(queryParams).toString(); | const queryString = new URLSearchParams(queryParams).toString(); | ||||
return serverFetchJson<RecordsRes<ConsoPickOrderResult[]>>(`${BASE_API_URL}/pickOrder/getRecordByPage-conso?${queryString}`, { | |||||
method: 'GET', | |||||
next: { tags: ["pickorder"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<ConsoPickOrderResult[]>>( | |||||
`${BASE_API_URL}/pickOrder/getRecordByPage-conso?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | |||||
}, | |||||
); | |||||
} else { | } else { | ||||
return serverFetchJson<RecordsRes<ConsoPickOrderResult[]>>(`${BASE_API_URL}/pickOrder/getRecordByPage-conso`, { | |||||
method: 'GET', | |||||
next: { tags: ["pickorder"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<ConsoPickOrderResult[]>>( | |||||
`${BASE_API_URL}/pickOrder/getRecordByPage-conso`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | |||||
}, | |||||
); | |||||
} | } | ||||
}); | |||||
}, | |||||
); | |||||
export const fetchPickOrderLineClient = cache(async (queryParams?: Record<string, any>) => { | |||||
export const fetchPickOrderLineClient = cache( | |||||
async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | if (queryParams) { | ||||
const queryString = new URLSearchParams(queryParams).toString(); | const queryString = new URLSearchParams(queryParams).toString(); | ||||
return serverFetchJson<RecordsRes<PickOrderLineWithSuggestedLot[]>>(`${BASE_API_URL}/pickOrder/get-pickorder-line-byPage?${queryString}`, { | |||||
method: 'GET', | |||||
next: { tags: ["pickorder"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PickOrderLineWithSuggestedLot[]>>( | |||||
`${BASE_API_URL}/pickOrder/get-pickorder-line-byPage?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | |||||
}, | |||||
); | |||||
} else { | } else { | ||||
return serverFetchJson<RecordsRes<PickOrderLineWithSuggestedLot[]>>(`${BASE_API_URL}/pickOrder/get-pickorder-line-byPage`, { | |||||
method: 'GET', | |||||
next: { tags: ["pickorder"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PickOrderLineWithSuggestedLot[]>>( | |||||
`${BASE_API_URL}/pickOrder/get-pickorder-line-byPage`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | |||||
}, | |||||
); | |||||
} | } | ||||
}); | |||||
export const fetchStockOutLineClient = cache(async (pickOrderLineId: number) => { | |||||
return serverFetchJson<StockOutLine[]>(`${BASE_API_URL}/stockOutLine/getByPickOrderLineId/${pickOrderLineId}`, { | |||||
method: 'GET', | |||||
next: { tags: ["pickorder"] }, | |||||
}); | |||||
}); | |||||
export const fetchConsoDetail = cache(async (consoCode: string) => { | |||||
return serverFetchJson<PreReleasePickOrderSummary>(`${BASE_API_URL}/pickOrder/pre-release-info/${consoCode}`, { | |||||
method: 'GET', | |||||
}, | |||||
); | |||||
export const fetchStockOutLineClient = cache( | |||||
async (pickOrderLineId: number) => { | |||||
return serverFetchJson<StockOutLine[]>( | |||||
`${BASE_API_URL}/stockOutLine/getByPickOrderLineId/${pickOrderLineId}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | next: { tags: ["pickorder"] }, | ||||
}); | |||||
}); | |||||
export const releasePickOrder = async (data: ReleasePickOrderInputs) => { | |||||
console.log(data) | |||||
console.log(JSON.stringify(data)) | |||||
const po = await serverFetchJson<{body: any, status: number}>(`${BASE_API_URL}/pickOrder/releaseConso`, { | |||||
}, | |||||
); | |||||
}, | |||||
); | |||||
export const fetchConsoDetail = cache(async (consoCode: string) => { | |||||
return serverFetchJson<PreReleasePickOrderSummary>( | |||||
`${BASE_API_URL}/pickOrder/pre-release-info/${consoCode}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["pickorder"] }, | |||||
}, | |||||
); | |||||
}); | |||||
export const releasePickOrder = async (data: ReleasePickOrderInputs) => { | |||||
console.log(data); | |||||
console.log(JSON.stringify(data)); | |||||
const po = await serverFetchJson<{ body: any; status: number }>( | |||||
`${BASE_API_URL}/pickOrder/releaseConso`, | |||||
{ | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | |||||
revalidateTag("pickorder"); | |||||
return po | |||||
} | |||||
export const createStockOutLine = async (data: CreateStockOutLine) => { | |||||
console.log("triggering") | |||||
const po = await serverFetchJson<PostStockOutLiineResponse<StockOutLine>>(`${BASE_API_URL}/stockOutLine/create`, { | |||||
}, | |||||
); | |||||
revalidateTag("pickorder"); | |||||
return po; | |||||
}; | |||||
export const createStockOutLine = async (data: CreateStockOutLine) => { | |||||
console.log("triggering"); | |||||
const po = await serverFetchJson<PostStockOutLiineResponse<StockOutLine>>( | |||||
`${BASE_API_URL}/stockOutLine/create`, | |||||
{ | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | |||||
revalidateTag("pickorder"); | |||||
return po | |||||
} | |||||
export const updateStockOutLine = async (data: UpdateStockOutLine) => { | |||||
console.log(data) | |||||
const po = await serverFetchJson<PostStockOutLiineResponse<StockOutLine>> | |||||
(`${BASE_API_URL}/stockOutLine/update`, { | |||||
}, | |||||
); | |||||
revalidateTag("pickorder"); | |||||
return po; | |||||
}; | |||||
export const updateStockOutLine = async (data: UpdateStockOutLine) => { | |||||
console.log(data); | |||||
const po = await serverFetchJson<PostStockOutLiineResponse<StockOutLine>>( | |||||
`${BASE_API_URL}/stockOutLine/update`, | |||||
{ | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | |||||
revalidateTag("pickorder"); | |||||
return po | |||||
} | |||||
export const completeConsoPickOrder = async (consoCode: string) => { | |||||
const po = await serverFetchJson<PostStockOutLiineResponse<StockOutLine>> | |||||
(`${BASE_API_URL}/pickOrder/consoPickOrder/complete/${consoCode}`, { | |||||
}, | |||||
); | |||||
revalidateTag("pickorder"); | |||||
return po; | |||||
}; | |||||
export const completeConsoPickOrder = async (consoCode: string) => { | |||||
const po = await serverFetchJson<PostStockOutLiineResponse<StockOutLine>>( | |||||
`${BASE_API_URL}/pickOrder/consoPickOrder/complete/${consoCode}`, | |||||
{ | |||||
method: "POST", | method: "POST", | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | |||||
revalidateTag("pickorder"); | |||||
return po | |||||
} | |||||
}, | |||||
); | |||||
revalidateTag("pickorder"); | |||||
return po; | |||||
}; |
@@ -5,106 +5,111 @@ import { cache } from "react"; | |||||
import { String } from "lodash"; | import { String } from "lodash"; | ||||
interface PickOrderItemInfo { | interface PickOrderItemInfo { | ||||
name: string, | |||||
type: string, | |||||
name: string; | |||||
type: string; | |||||
} | } | ||||
export interface PickOrderResult{ | |||||
id: number, | |||||
code: string, | |||||
consoCode?: string, | |||||
targetDate: number[], | |||||
completeDate?: number[], | |||||
type: string, | |||||
status: string, | |||||
releasedBy: string, | |||||
items?: PickOrderItemInfo[] | null, | |||||
pickOrderLine?: PickOrderLine[] | |||||
export interface PickOrderResult { | |||||
id: number; | |||||
code: string; | |||||
consoCode?: string; | |||||
targetDate: number[]; | |||||
completeDate?: number[]; | |||||
type: string; | |||||
status: string; | |||||
releasedBy: string; | |||||
items?: PickOrderItemInfo[] | null; | |||||
pickOrderLine?: PickOrderLine[]; | |||||
} | } | ||||
export interface PickOrderLine { | export interface PickOrderLine { | ||||
id: number, | |||||
itemId: number, | |||||
itemCode: string, | |||||
itemName: string, | |||||
availableQty: number, | |||||
requiredQty: number, | |||||
uomCode: string, | |||||
uomDesc: string | |||||
id: number; | |||||
itemId: number; | |||||
itemCode: string; | |||||
itemName: string; | |||||
availableQty: number; | |||||
requiredQty: number; | |||||
uomCode: string; | |||||
uomDesc: string; | |||||
} | } | ||||
export interface StockOutLine { | export interface StockOutLine { | ||||
id: number | |||||
itemId: number | |||||
itemName: string | |||||
itemNo: string | |||||
qty: number | |||||
stockOutId?: number | |||||
pickOrderLineId: number | |||||
lotNo?: string | |||||
inventoryLotLineId?: number | |||||
status: string | |||||
pickTime?: string | |||||
id: number; | |||||
itemId: number; | |||||
itemName: string; | |||||
itemNo: string; | |||||
qty: number; | |||||
stockOutId?: number; | |||||
pickOrderLineId: number; | |||||
lotNo?: string; | |||||
inventoryLotLineId?: number; | |||||
status: string; | |||||
pickTime?: string; | |||||
} | } | ||||
export interface ConsoPickOrderResult{ | |||||
id: number, | |||||
code: string, | |||||
consoCode?: string, | |||||
targetDate: number[], | |||||
completeDate?: number[], | |||||
type: string, | |||||
status: string, | |||||
releasedBy: string, | |||||
items?: PickOrderItemInfo[] | null, | |||||
export interface ConsoPickOrderResult { | |||||
id: number; | |||||
code: string; | |||||
consoCode?: string; | |||||
targetDate: number[]; | |||||
completeDate?: number[]; | |||||
type: string; | |||||
status: string; | |||||
releasedBy: string; | |||||
items?: PickOrderItemInfo[] | null; | |||||
} | } | ||||
export interface FetchPickOrders extends Pageable { | export interface FetchPickOrders extends Pageable { | ||||
code: string | undefined | |||||
targetDateFrom: string | undefined | |||||
targetDateTo: string | undefined | |||||
type: string | undefined | |||||
status: string | undefined | |||||
itemName: string | undefined | |||||
code: string | undefined; | |||||
targetDateFrom: string | undefined; | |||||
targetDateTo: string | undefined; | |||||
type: string | undefined; | |||||
status: string | undefined; | |||||
itemName: string | undefined; | |||||
} | } | ||||
export type ByItemsSummary = { | export type ByItemsSummary = { | ||||
id: number, | |||||
code: string, | |||||
name: string, | |||||
uomDesc: string, | |||||
availableQty: number, | |||||
requiredQty: number, | |||||
} | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
uomDesc: string; | |||||
availableQty: number; | |||||
requiredQty: number; | |||||
}; | |||||
export interface PreReleasePickOrderSummary { | export interface PreReleasePickOrderSummary { | ||||
consoCode: string | |||||
pickOrders: Omit<PickOrderResult, "items">[] | |||||
items: ByItemsSummary[] | |||||
consoCode: string; | |||||
pickOrders: Omit<PickOrderResult, "items">[]; | |||||
items: ByItemsSummary[]; | |||||
} | } | ||||
export interface PickOrderLineWithSuggestedLot { | export interface PickOrderLineWithSuggestedLot { | ||||
id: number, | |||||
itemName: string, | |||||
qty: number, | |||||
uom: string | |||||
status: string | |||||
warehouse: string | |||||
suggestedLotNo: string | |||||
id: number; | |||||
itemName: string; | |||||
qty: number; | |||||
uom: string; | |||||
status: string; | |||||
warehouse: string; | |||||
suggestedLotNo: string; | |||||
} | } | ||||
export const PreloadPickOrder = () => { | export const PreloadPickOrder = () => { | ||||
fetchPickOrders({ | |||||
code: undefined, | |||||
targetDateFrom: undefined, | |||||
targetDateTo: undefined, | |||||
type: undefined, | |||||
status: undefined, | |||||
itemName: undefined, | |||||
}) | |||||
} | |||||
fetchPickOrders({ | |||||
code: undefined, | |||||
targetDateFrom: undefined, | |||||
targetDateTo: undefined, | |||||
type: undefined, | |||||
status: undefined, | |||||
itemName: undefined, | |||||
}); | |||||
}; | |||||
export const fetchPickOrders = cache(async (queryParams: FetchPickOrders) => { | export const fetchPickOrders = cache(async (queryParams: FetchPickOrders) => { | ||||
const queryString = new URLSearchParams(queryParams as Record<string, any>).toString(); | |||||
return serverFetchJson<PickOrderResult[]>(`${BASE_API_URL}/pickOrder/list?${queryString}`, { | |||||
next: { | |||||
tags: ["pickOrders"] | |||||
} | |||||
}) | |||||
}) | |||||
const queryString = new URLSearchParams( | |||||
queryParams as Record<string, any>, | |||||
).toString(); | |||||
return serverFetchJson<PickOrderResult[]>( | |||||
`${BASE_API_URL}/pickOrder/list?${queryString}`, | |||||
{ | |||||
next: { | |||||
tags: ["pickOrders"], | |||||
}, | |||||
}, | |||||
); | |||||
}); |
@@ -15,21 +15,21 @@ export interface PostStockInLiineResponse<T> { | |||||
id: number | null; | id: number | null; | ||||
name: string; | name: string; | ||||
code: string; | code: string; | ||||
type?: string | |||||
type?: string; | |||||
message: string | null; | message: string | null; | ||||
errorPosition: string | keyof T; | errorPosition: string | keyof T; | ||||
entity: T | T[] | |||||
entity: T | T[]; | |||||
// entity: StockInLine | StockInLine[] | // entity: StockInLine | StockInLine[] | ||||
} | } | ||||
export interface StockInLineEntry { | export interface StockInLineEntry { | ||||
id?: number | |||||
itemId: number | |||||
purchaseOrderId: number | |||||
purchaseOrderLineId: number | |||||
acceptedQty: number | |||||
status?: string | |||||
expiryDate?: string | |||||
id?: number; | |||||
itemId: number; | |||||
purchaseOrderId: number; | |||||
purchaseOrderLineId: number; | |||||
acceptedQty: number; | |||||
status?: string; | |||||
expiryDate?: string; | |||||
} | } | ||||
export interface PurchaseQcResult { | export interface PurchaseQcResult { | ||||
@@ -37,37 +37,39 @@ export interface PurchaseQcResult { | |||||
failQty: number; | failQty: number; | ||||
} | } | ||||
export interface StockInInput { | export interface StockInInput { | ||||
status: string | |||||
productLotNo?: string, | |||||
receiptDate: string | |||||
acceptedQty: number | |||||
acceptedWeight?: number | |||||
productionDate?: string | |||||
expiryDate: string | |||||
status: string; | |||||
productLotNo?: string; | |||||
receiptDate: string; | |||||
acceptedQty: number; | |||||
acceptedWeight?: number; | |||||
productionDate?: string; | |||||
expiryDate: string; | |||||
} | } | ||||
export interface PurchaseQCInput { | export interface PurchaseQCInput { | ||||
status: string | |||||
acceptedQty: number | |||||
status: string; | |||||
acceptedQty: number; | |||||
sampleRate: number; | sampleRate: number; | ||||
sampleWeight: number; | sampleWeight: number; | ||||
totalWeight: number; | totalWeight: number; | ||||
qcResult: PurchaseQcResult[]; | qcResult: PurchaseQcResult[]; | ||||
} | } | ||||
export interface EscalationInput { | export interface EscalationInput { | ||||
status: string | |||||
handler: string | |||||
acceptedQty: number // this is the qty to be escalated | |||||
status: string; | |||||
handler: string; | |||||
acceptedQty: number; // this is the qty to be escalated | |||||
// escalationQty: number | // escalationQty: number | ||||
} | } | ||||
export interface PutawayInput { | export interface PutawayInput { | ||||
status: string | |||||
acceptedQty: number | |||||
warehouseId: number | |||||
status: string; | |||||
acceptedQty: number; | |||||
warehouseId: number; | |||||
// handler: string | // handler: string | ||||
// stockInLine: StockInLineEntry[] | // stockInLine: StockInLineEntry[] | ||||
} | } | ||||
export type ModalFormInput = Partial<PurchaseQCInput & StockInInput & EscalationInput & PutawayInput> | |||||
export type ModalFormInput = Partial< | |||||
PurchaseQCInput & StockInInput & EscalationInput & PutawayInput | |||||
>; | |||||
export const testFetch = cache(async (id: number) => { | export const testFetch = cache(async (id: number) => { | ||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | ||||
@@ -76,50 +78,65 @@ export const testFetch = cache(async (id: number) => { | |||||
}); | }); | ||||
export const fetchStockInLineInfo = cache(async (stockInLineId: number) => { | export const fetchStockInLineInfo = cache(async (stockInLineId: number) => { | ||||
return serverFetchJson<StockInLine>(`${BASE_API_URL}/stockInLine/${stockInLineId}`, { | |||||
return serverFetchJson<StockInLine>( | |||||
`${BASE_API_URL}/stockInLine/${stockInLineId}`, | |||||
{ | |||||
next: { tags: ["stockInLine"] }, | next: { tags: ["stockInLine"] }, | ||||
}); | |||||
}, | |||||
); | |||||
}); | }); | ||||
export const createStockInLine = async (data: StockInLineEntry) => { | export const createStockInLine = async (data: StockInLineEntry) => { | ||||
const stockInLine = await serverFetchJson<PostStockInLiineResponse<StockInLineEntry>>(`${BASE_API_URL}/stockInLine/create`, { | |||||
const stockInLine = await serverFetchJson< | |||||
PostStockInLiineResponse<StockInLineEntry> | |||||
>(`${BASE_API_URL}/stockInLine/create`, { | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
// revalidateTag("po"); | // revalidateTag("po"); | ||||
return stockInLine | |||||
} | |||||
return stockInLine; | |||||
}; | |||||
export const updateStockInLine = async (data: StockInLineEntry & ModalFormInput) => { | |||||
const stockInLine = await serverFetchJson<PostStockInLiineResponse<StockInLineEntry & ModalFormInput>>(`${BASE_API_URL}/stockInLine/update`, { | |||||
export const updateStockInLine = async ( | |||||
data: StockInLineEntry & ModalFormInput, | |||||
) => { | |||||
const stockInLine = await serverFetchJson< | |||||
PostStockInLiineResponse<StockInLineEntry & ModalFormInput> | |||||
>(`${BASE_API_URL}/stockInLine/update`, { | |||||
method: "POST", | method: "POST", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
// revalidateTag("po"); | // revalidateTag("po"); | ||||
return stockInLine | |||||
} | |||||
return stockInLine; | |||||
}; | |||||
export const startPo = async (poId: number) => { | export const startPo = async (poId: number) => { | ||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>(`${BASE_API_URL}/po/start/${poId}`, { | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>( | |||||
`${BASE_API_URL}/po/start/${poId}`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("po"); | revalidateTag("po"); | ||||
return po | |||||
} | |||||
return po; | |||||
}; | |||||
export const checkPolAndCompletePo = async (poId: number) => { | export const checkPolAndCompletePo = async (poId: number) => { | ||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>(`${BASE_API_URL}/po/check/${poId}`, { | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
const po = await serverFetchJson<PostStockInLiineResponse<PoResult>>( | |||||
`${BASE_API_URL}/po/check/${poId}`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify({ poId }), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("po"); | revalidateTag("po"); | ||||
return po | |||||
} | |||||
return po; | |||||
}; | |||||
export const fetchPoInClient = cache(async (id: number) => { | export const fetchPoInClient = cache(async (id: number) => { | ||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | ||||
@@ -127,33 +144,46 @@ export const fetchPoInClient = cache(async (id: number) => { | |||||
}); | }); | ||||
}); | }); | ||||
export const fetchPoListClient = cache(async (queryParams?: Record<string, any>) => { | |||||
export const fetchPoListClient = cache( | |||||
async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | if (queryParams) { | ||||
const queryString = new URLSearchParams(queryParams).toString(); | const queryString = new URLSearchParams(queryParams).toString(); | ||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list?${queryString}`, { | |||||
method: 'GET', | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/list?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | |||||
}, | |||||
); | |||||
} else { | } else { | ||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list`, { | |||||
method: 'GET', | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/list`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | |||||
}, | |||||
); | |||||
} | } | ||||
}); | |||||
}, | |||||
); | |||||
export const testing = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/testing?${queryString}`, { | |||||
method: 'GET', | |||||
export const testing = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/testing?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/testing`, { | |||||
method: 'GET', | |||||
}, | |||||
); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/testing`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | |||||
} | |||||
}); | |||||
}, | |||||
); | |||||
} | |||||
}); |
@@ -8,74 +8,76 @@ import { Uom } from "../settings/uom"; | |||||
import { RecordsRes } from "../utils"; | import { RecordsRes } from "../utils"; | ||||
export interface PoResult { | export interface PoResult { | ||||
id: number | |||||
code: string | |||||
orderDate: string | |||||
supplier: string | |||||
estimatedArrivalDate: string | |||||
completedDate: string | |||||
escalated: boolean | |||||
status: string | |||||
pol?: PurchaseOrderLine[] | |||||
} | |||||
id: number; | |||||
code: string; | |||||
orderDate: string; | |||||
supplier: string; | |||||
estimatedArrivalDate: string; | |||||
completedDate: string; | |||||
escalated: boolean; | |||||
status: string; | |||||
pol?: PurchaseOrderLine[]; | |||||
} | |||||
export interface PurchaseOrderLine { | export interface PurchaseOrderLine { | ||||
id: number | |||||
purchaseOrderId: number | |||||
itemId: number | |||||
itemNo: string | |||||
itemName: string | |||||
qty: number | |||||
processed: number | |||||
uom: Uom | |||||
price: number | |||||
status: string | |||||
stockInLine: StockInLine[] | |||||
id: number; | |||||
purchaseOrderId: number; | |||||
itemId: number; | |||||
itemNo: string; | |||||
itemName: string; | |||||
qty: number; | |||||
processed: number; | |||||
uom: Uom; | |||||
price: number; | |||||
status: string; | |||||
stockInLine: StockInLine[]; | |||||
} | } | ||||
export interface StockInLine { | export interface StockInLine { | ||||
id: number | |||||
stockInId: number | |||||
purchaseOrderId?: number | |||||
purchaseOrderLineId: number | |||||
itemId: number | |||||
itemNo: string | |||||
itemName: string | |||||
itemType: string | |||||
demandQty: number | |||||
acceptedQty: number | |||||
price: number | |||||
priceUnit: string | |||||
shelfLife?: number, | |||||
receiptDate?: string | |||||
productionDate?: string | |||||
expiryDate?: string | |||||
status: string | |||||
supplier: string | |||||
lotNo: string | |||||
poCode: string | |||||
uom: Uom | |||||
defaultWarehouseId: number // id for now | |||||
id: number; | |||||
stockInId: number; | |||||
purchaseOrderId?: number; | |||||
purchaseOrderLineId: number; | |||||
itemId: number; | |||||
itemNo: string; | |||||
itemName: string; | |||||
itemType: string; | |||||
demandQty: number; | |||||
acceptedQty: number; | |||||
price: number; | |||||
priceUnit: string; | |||||
shelfLife?: number; | |||||
receiptDate?: string; | |||||
productionDate?: string; | |||||
expiryDate?: string; | |||||
status: string; | |||||
supplier: string; | |||||
lotNo: string; | |||||
poCode: string; | |||||
uom: Uom; | |||||
defaultWarehouseId: number; // id for now | |||||
} | } | ||||
export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list?${queryString}`, { | |||||
method: 'GET', | |||||
export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | |||||
if (queryParams) { | |||||
const queryString = new URLSearchParams(queryParams).toString(); | |||||
return serverFetchJson<RecordsRes<PoResult[]>>( | |||||
`${BASE_API_URL}/po/list?${queryString}`, | |||||
{ | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list`, { | |||||
method: 'GET', | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
} | |||||
}); | |||||
export const fetchPoWithStockInLines = cache(async (id: number) => { | |||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | |||||
}, | |||||
); | |||||
} else { | |||||
return serverFetchJson<RecordsRes<PoResult[]>>(`${BASE_API_URL}/po/list`, { | |||||
method: "GET", | |||||
next: { tags: ["po"] }, | next: { tags: ["po"] }, | ||||
}); | }); | ||||
}); | |||||
} | |||||
}); | |||||
export const fetchPoWithStockInLines = cache(async (id: number) => { | |||||
return serverFetchJson<PoResult>(`${BASE_API_URL}/po/detail/${id}`, { | |||||
next: { tags: ["po"] }, | |||||
}); | |||||
}); |
@@ -8,32 +8,34 @@ import { serverFetchJson } from "../../utils/fetchUtil"; | |||||
import { QcItemWithChecks } from "."; | import { QcItemWithChecks } from "."; | ||||
export interface QcResult { | export interface QcResult { | ||||
id: number | |||||
qcItemId: number | |||||
name: string | |||||
code: string | |||||
stockInLineId?: number | |||||
stockOutLineId?: number | |||||
failQty: number | |||||
id: number; | |||||
qcItemId: number; | |||||
name: string; | |||||
code: string; | |||||
stockInLineId?: number; | |||||
stockOutLineId?: number; | |||||
failQty: number; | |||||
} | } | ||||
export const fetchQcItemCheck = cache(async (itemId?: number) => { | export const fetchQcItemCheck = cache(async (itemId?: number) => { | ||||
var url = `${BASE_API_URL}/qcCheck` | |||||
if (itemId) url +=`/${itemId}` | |||||
return serverFetchJson<QcItemWithChecks[]>(url, { | |||||
next: { tags: ["qc"] }, | |||||
}); | |||||
let url = `${BASE_API_URL}/qcCheck`; | |||||
if (itemId) url += `/${itemId}`; | |||||
return serverFetchJson<QcItemWithChecks[]>(url, { | |||||
next: { tags: ["qc"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchQcResult = cache(async (id: number) => { | export const fetchQcResult = cache(async (id: number) => { | ||||
return serverFetchJson<QcResult[]>(`${BASE_API_URL}/qcResult/${id}`, { | |||||
next: { tags: ["qc"] }, | |||||
}); | |||||
return serverFetchJson<QcResult[]>(`${BASE_API_URL}/qcResult/${id}`, { | |||||
next: { tags: ["qc"] }, | |||||
}); | |||||
}); | }); | ||||
export const fetchPickOrderQcResult = cache(async (id: number) => { | export const fetchPickOrderQcResult = cache(async (id: number) => { | ||||
return serverFetchJson<QcResult[]>(`${BASE_API_URL}/qcResult/pick-order/${id}`, { | |||||
next: { tags: ["qc"] }, | |||||
}); | |||||
}); | |||||
return serverFetchJson<QcResult[]>( | |||||
`${BASE_API_URL}/qcResult/pick-order/${id}`, | |||||
{ | |||||
next: { tags: ["qc"] }, | |||||
}, | |||||
); | |||||
}); |
@@ -6,27 +6,25 @@ import { serverFetchJson } from "../../utils/fetchUtil"; | |||||
import { BASE_API_URL } from "../../../config/api"; | import { BASE_API_URL } from "../../../config/api"; | ||||
export interface QcItemWithChecks { | export interface QcItemWithChecks { | ||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
itemId: number; | |||||
lowerLimit: number | undefined; | |||||
upperLimit: number | undefined; | |||||
description: string | undefined; | |||||
} | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
itemId: number; | |||||
lowerLimit: number | undefined; | |||||
upperLimit: number | undefined; | |||||
description: string | undefined; | |||||
} | |||||
export const fetchQcItemCheckList = cache(async () => { | |||||
return serverFetchJson<QcItemWithChecks[]>(`${BASE_API_URL}/qc/list`, { | |||||
next: { tags: ["qc"] }, | |||||
}); | |||||
export const fetchQcItemCheckList = cache(async () => { | |||||
return serverFetchJson<QcItemWithChecks[]>(`${BASE_API_URL}/qc/list`, { | |||||
next: { tags: ["qc"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchQcItemCheck = cache(async (itemId?: number) => { | export const fetchQcItemCheck = cache(async (itemId?: number) => { | ||||
var url = `${BASE_API_URL}/qcCheck` | |||||
if (itemId) url +=`/${itemId}` | |||||
let url = `${BASE_API_URL}/qcCheck`; | |||||
if (itemId) url += `/${itemId}`; | |||||
return serverFetchJson<QcItemWithChecks[]>(url, { | return serverFetchJson<QcItemWithChecks[]>(url, { | ||||
next: { tags: ["qc"] }, | next: { tags: ["qc"] }, | ||||
}); | }); | ||||
}); | |||||
}); |
@@ -7,9 +7,9 @@ import { BASE_API_URL } from "../../../config/api"; | |||||
export interface QrCodeInfo { | export interface QrCodeInfo { | ||||
// warehouse qrcode | // warehouse qrcode | ||||
warehouseId?: number | |||||
// item qrcode | |||||
warehouseId?: number; | |||||
// item qrcode | |||||
stockInLineId?: number; | stockInLineId?: number; | ||||
itemId: number | |||||
lotNo?: string | |||||
} | |||||
itemId: number; | |||||
lotNo?: string; | |||||
} |
@@ -1,64 +1,75 @@ | |||||
"use server" | |||||
"use server"; | |||||
import { convertObjToURLSearchParams } from "@/app/utils/commonUtil"; | import { convertObjToURLSearchParams } from "@/app/utils/commonUtil"; | ||||
import { serverFetchJson } from "@/app/utils/fetchUtil" | |||||
import { BASE_API_URL } from "@/config/api" | |||||
import { cache } from "react" | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | |||||
import { cache } from "react"; | |||||
import { ScheduleType } from "."; | import { ScheduleType } from "."; | ||||
export interface SearchProdSchedule { | export interface SearchProdSchedule { | ||||
scheduleAt?: string; | |||||
schedulePeriod?: string; | |||||
schedulePeriodTo?: string; | |||||
totalEstProdCount?: number; | |||||
types?: ScheduleType[]; | |||||
pageSize?: number; | |||||
pageNum?: number; | |||||
scheduleAt?: string; | |||||
schedulePeriod?: string; | |||||
schedulePeriodTo?: string; | |||||
totalEstProdCount?: number; | |||||
types?: ScheduleType[]; | |||||
pageSize?: number; | |||||
pageNum?: number; | |||||
} | } | ||||
export interface ProdScheduleResult { | export interface ProdScheduleResult { | ||||
id: number; | |||||
scheduleAt: number[]; | |||||
schedulePeriod: number[]; | |||||
schedulePeriodTo: number[]; | |||||
totalEstProdCount: number; | |||||
totalFGType: number; | |||||
type: string; | |||||
id: number; | |||||
scheduleAt: number[]; | |||||
schedulePeriod: number[]; | |||||
schedulePeriodTo: number[]; | |||||
totalEstProdCount: number; | |||||
totalFGType: number; | |||||
type: string; | |||||
} | } | ||||
export interface ProdScheduleResultByPage { | export interface ProdScheduleResultByPage { | ||||
total: number; | |||||
records: ProdScheduleResult[]; | |||||
total: number; | |||||
records: ProdScheduleResult[]; | |||||
} | } | ||||
export const fetchProdSchedules = cache(async (data: SearchProdSchedule | null) => { | |||||
const params = convertObjToURLSearchParams<SearchProdSchedule>(data) | |||||
export const fetchProdSchedules = cache( | |||||
async (data: SearchProdSchedule | null) => { | |||||
const params = convertObjToURLSearchParams<SearchProdSchedule>(data); | |||||
// console.log(params) | // console.log(params) | ||||
return serverFetchJson<ProdScheduleResultByPage>(`${BASE_API_URL}/productionSchedule/getRecordByPage?${params}`, { | |||||
return serverFetchJson<ProdScheduleResultByPage>( | |||||
`${BASE_API_URL}/productionSchedule/getRecordByPage?${params}`, | |||||
{ | |||||
method: "GET", | method: "GET", | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
next: { | next: { | ||||
tags: ["prodSchedules"] | |||||
} | |||||
}) | |||||
}) | |||||
tags: ["prodSchedules"], | |||||
}, | |||||
}, | |||||
); | |||||
}, | |||||
); | |||||
export const testRoughSchedule = cache(async () => { | export const testRoughSchedule = cache(async () => { | ||||
return serverFetchJson(`${BASE_API_URL}/productionSchedule/testRoughSchedule`, { | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedules"] | |||||
} | |||||
}) | |||||
}) | |||||
return serverFetchJson( | |||||
`${BASE_API_URL}/productionSchedule/testRoughSchedule`, | |||||
{ | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedules"], | |||||
}, | |||||
}, | |||||
); | |||||
}); | |||||
export const testDetailSchedule = cache(async () => { | export const testDetailSchedule = cache(async () => { | ||||
return serverFetchJson(`${BASE_API_URL}/productionSchedule/testDetailSchedule`, { | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedules"] | |||||
} | |||||
}) | |||||
}) | |||||
return serverFetchJson( | |||||
`${BASE_API_URL}/productionSchedule/testDetailSchedule`, | |||||
{ | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedules"], | |||||
}, | |||||
}, | |||||
); | |||||
}); |
@@ -1,82 +1,89 @@ | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil" | |||||
import { BASE_API_URL } from "@/config/api" | |||||
import { cache } from "react" | |||||
import "server-only" | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | |||||
import { cache } from "react"; | |||||
import "server-only"; | |||||
export type ScheduleType = "all" | "rough" | "detailed" | "manual"; | export type ScheduleType = "all" | "rough" | "detailed" | "manual"; | ||||
export interface RoughProdScheduleResult { | export interface RoughProdScheduleResult { | ||||
id: number; | |||||
scheduleAt: number[]; | |||||
schedulePeriod: number[]; | |||||
schedulePeriodTo: number[]; | |||||
totalEstProdCount: number; | |||||
totalFGType: number; | |||||
type: string; | |||||
prodScheduleLinesByFg: RoughProdScheduleLineResultByFg[]; | |||||
prodScheduleLinesByFgByDate: { [assignDate: number]: RoughProdScheduleLineResultByFg[] }; | |||||
prodScheduleLinesByBom: RoughProdScheduleLineResultByBom[]; | |||||
prodScheduleLinesByBomByDate: { [assignDate: number]: RoughProdScheduleLineResultByBomByDate[] }; | |||||
id: number; | |||||
scheduleAt: number[]; | |||||
schedulePeriod: number[]; | |||||
schedulePeriodTo: number[]; | |||||
totalEstProdCount: number; | |||||
totalFGType: number; | |||||
type: string; | |||||
prodScheduleLinesByFg: RoughProdScheduleLineResultByFg[]; | |||||
prodScheduleLinesByFgByDate: { | |||||
[assignDate: number]: RoughProdScheduleLineResultByFg[]; | |||||
}; | |||||
prodScheduleLinesByBom: RoughProdScheduleLineResultByBom[]; | |||||
prodScheduleLinesByBomByDate: { | |||||
[assignDate: number]: RoughProdScheduleLineResultByBomByDate[]; | |||||
}; | |||||
} | } | ||||
export interface RoughProdScheduleLineResultByFg { | export interface RoughProdScheduleLineResultByFg { | ||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
prodQty: number; | |||||
lastMonthAvgSales: number; | |||||
estCloseBal: number; | |||||
priority: number; | |||||
assignDate: number; | |||||
bomMaterials: RoughProdScheduleLineBomMaterialResult[]; | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
prodQty: number; | |||||
lastMonthAvgSales: number; | |||||
estCloseBal: number; | |||||
priority: number; | |||||
assignDate: number; | |||||
bomMaterials: RoughProdScheduleLineBomMaterialResult[]; | |||||
} | } | ||||
export interface RoughProdScheduleLineBomMaterialResult { | export interface RoughProdScheduleLineBomMaterialResult { | ||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
demandQty: number; | |||||
uomName: string; | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
demandQty: number; | |||||
uomName: string; | |||||
} | } | ||||
export interface RoughProdScheduleLineResultByBom { | export interface RoughProdScheduleLineResultByBom { | ||||
id: number, | |||||
code: string, | |||||
name: string, | |||||
type: string, | |||||
availableQty: number, | |||||
totalDemandQty: number, | |||||
demandQty1: number, | |||||
demandQty2: number, | |||||
demandQty3: number, | |||||
demandQty4: number, | |||||
demandQty5: number, | |||||
demandQty6: number, | |||||
demandQty7: number, | |||||
uomName: string, | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
totalDemandQty: number; | |||||
demandQty1: number; | |||||
demandQty2: number; | |||||
demandQty3: number; | |||||
demandQty4: number; | |||||
demandQty5: number; | |||||
demandQty6: number; | |||||
demandQty7: number; | |||||
uomName: string; | |||||
} | } | ||||
export interface RoughProdScheduleLineResultByBomByDate { | export interface RoughProdScheduleLineResultByBomByDate { | ||||
id: number, | |||||
code: string, | |||||
name: string, | |||||
type: string, | |||||
availableQty: number, | |||||
demandQty: number, | |||||
assignDate: number, | |||||
uomName: string, | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
type: string; | |||||
availableQty: number; | |||||
demandQty: number; | |||||
assignDate: number; | |||||
uomName: string; | |||||
} | } | ||||
export const fetchProdScheduleDetail = cache(async (id: number) => { | export const fetchProdScheduleDetail = cache(async (id: number) => { | ||||
return serverFetchJson<RoughProdScheduleResult>(`${BASE_API_URL}/productionSchedule/detail/${id}`, { | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedule"] | |||||
} | |||||
}) | |||||
}) | |||||
return serverFetchJson<RoughProdScheduleResult>( | |||||
`${BASE_API_URL}/productionSchedule/detail/${id}`, | |||||
{ | |||||
method: "GET", | |||||
headers: { "Content-Type": "application/json" }, | |||||
next: { | |||||
tags: ["prodSchedule"], | |||||
}, | |||||
}, | |||||
); | |||||
}); |
@@ -1,5 +1,9 @@ | |||||
"use server"; | "use server"; | ||||
import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||||
import { | |||||
ServerFetchError, | |||||
serverFetchJson, | |||||
serverFetchWithNoContent, | |||||
} from "@/app/utils/fetchUtil"; | |||||
import { revalidateTag } from "next/cache"; | import { revalidateTag } from "next/cache"; | ||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
import { CreateEquipmentTypeResponse } from "../../utils"; | import { CreateEquipmentTypeResponse } from "../../utils"; | ||||
@@ -16,23 +20,23 @@ import { CreateEquipmentTypeResponse } from "../../utils"; | |||||
// conversion: number | // conversion: number | ||||
// } | // } | ||||
export type CreateEquipmentInputs = { | export type CreateEquipmentInputs = { | ||||
id?: string | number | |||||
id?: string | number; | |||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
description?: string | undefined; | description?: string | undefined; | ||||
equipmentTypeId?: string | number | undefined; | equipmentTypeId?: string | number | undefined; | ||||
} | |||||
}; | |||||
export const saveEquipment = async (data: CreateEquipmentInputs) => { | export const saveEquipment = async (data: CreateEquipmentInputs) => { | ||||
// try { | |||||
const equipment = await serverFetchJson<CreateEquipmentTypeResponse<CreateEquipmentInputs>>(`${BASE_API_URL}/Equipment/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
revalidateTag("EquipmentType"); | |||||
return equipment | |||||
}; | |||||
// try { | |||||
const equipment = await serverFetchJson< | |||||
CreateEquipmentTypeResponse<CreateEquipmentInputs> | |||||
>(`${BASE_API_URL}/Equipment/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
revalidateTag("EquipmentType"); | |||||
return equipment; | |||||
}; |
@@ -7,28 +7,29 @@ import { BASE_API_URL } from "../../../../config/api"; | |||||
export { default } from "../../../../components/CreateEquipment/CreateEquipment"; | export { default } from "../../../../components/CreateEquipment/CreateEquipment"; | ||||
// import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | // import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | ||||
export type EquipmentResult = { | export type EquipmentResult = { | ||||
id: string | number | |||||
id: string | number; | |||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
description: string | undefined; | description: string | undefined; | ||||
equipmentTypeId: string | number | undefined; | equipmentTypeId: string | number | undefined; | ||||
action?: any | |||||
} | |||||
action?: any; | |||||
}; | |||||
export type Result = { | export type Result = { | ||||
equipment: EquipmentResult | |||||
} | |||||
equipment: EquipmentResult; | |||||
}; | |||||
export const fetchAllEquipments = cache(async () => { | export const fetchAllEquipments = cache(async () => { | ||||
return serverFetchJson<EquipmentResult[]>(`${BASE_API_URL}/Equipment`, { | |||||
next: { tags: ["equipments"] }, | |||||
}); | |||||
return serverFetchJson<EquipmentResult[]>(`${BASE_API_URL}/Equipment`, { | |||||
next: { tags: ["equipments"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchEquipment = cache(async (id: number) => { | export const fetchEquipment = cache(async (id: number) => { | ||||
return serverFetchJson<EquipmentResult>(`${BASE_API_URL}/Equipment/details/${id}`, { | |||||
next: { tags: ["equipments"] }, | |||||
}); | |||||
}); | |||||
return serverFetchJson<EquipmentResult>( | |||||
`${BASE_API_URL}/Equipment/details/${id}`, | |||||
{ | |||||
next: { tags: ["equipments"] }, | |||||
}, | |||||
); | |||||
}); |
@@ -1,5 +1,9 @@ | |||||
"use server"; | "use server"; | ||||
import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||||
import { | |||||
ServerFetchError, | |||||
serverFetchJson, | |||||
serverFetchWithNoContent, | |||||
} from "@/app/utils/fetchUtil"; | |||||
import { revalidateTag } from "next/cache"; | import { revalidateTag } from "next/cache"; | ||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
import { CreateEquipmentTypeResponse } from "../../utils"; | import { CreateEquipmentTypeResponse } from "../../utils"; | ||||
@@ -16,22 +20,22 @@ import { CreateEquipmentTypeResponse } from "../../utils"; | |||||
// conversion: number | // conversion: number | ||||
// } | // } | ||||
export type CreateEquipmentTypeInputs = { | export type CreateEquipmentTypeInputs = { | ||||
id?: string | number | |||||
id?: string | number; | |||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
description?: string | undefined; | description?: string | undefined; | ||||
} | |||||
}; | |||||
export const saveEquipmentType = async (data: CreateEquipmentTypeInputs) => { | export const saveEquipmentType = async (data: CreateEquipmentTypeInputs) => { | ||||
// try { | |||||
const equipmentType = await serverFetchJson<CreateEquipmentTypeResponse<CreateEquipmentTypeInputs>>(`${BASE_API_URL}/EquipmentType/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
revalidateTag("EquipmentType"); | |||||
return equipmentType | |||||
}; | |||||
// try { | |||||
const equipmentType = await serverFetchJson< | |||||
CreateEquipmentTypeResponse<CreateEquipmentTypeInputs> | |||||
>(`${BASE_API_URL}/EquipmentType/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
revalidateTag("EquipmentType"); | |||||
return equipmentType; | |||||
}; |
@@ -7,27 +7,31 @@ import { BASE_API_URL } from "../../../../config/api"; | |||||
export { default } from "../../../../components/CreateEquipmentType/CreateEquipmentType"; | export { default } from "../../../../components/CreateEquipmentType/CreateEquipmentType"; | ||||
// import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | // import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | ||||
export type EquipmentTypeResult = { | export type EquipmentTypeResult = { | ||||
id: string | number | |||||
id: string | number; | |||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
description: string | undefined; | description: string | undefined; | ||||
action?: any | |||||
} | |||||
action?: any; | |||||
}; | |||||
export type Result = { | export type Result = { | ||||
equipmentType: EquipmentTypeResult | |||||
} | |||||
equipmentType: EquipmentTypeResult; | |||||
}; | |||||
export const fetchAllEquipmentTypes = cache(async () => { | export const fetchAllEquipmentTypes = cache(async () => { | ||||
return serverFetchJson<EquipmentTypeResult[]>(`${BASE_API_URL}/EquipmentType`, { | |||||
return serverFetchJson<EquipmentTypeResult[]>( | |||||
`${BASE_API_URL}/EquipmentType`, | |||||
{ | |||||
next: { tags: ["equipmentTypes"] }, | next: { tags: ["equipmentTypes"] }, | ||||
}); | |||||
}); | |||||
}, | |||||
); | |||||
}); | |||||
export const fetchEquipmentType = cache(async (id: number) => { | export const fetchEquipmentType = cache(async (id: number) => { | ||||
return serverFetchJson<EquipmentTypeResult>(`${BASE_API_URL}/EquipmentType/details/${id}`, { | |||||
next: { tags: ["equipmentTypes"] }, | |||||
}); | |||||
}); | |||||
return serverFetchJson<EquipmentTypeResult>( | |||||
`${BASE_API_URL}/EquipmentType/details/${id}`, | |||||
{ | |||||
next: { tags: ["equipmentTypes"] }, | |||||
}, | |||||
); | |||||
}); |
@@ -1,5 +1,9 @@ | |||||
"use server"; | "use server"; | ||||
import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||||
import { | |||||
ServerFetchError, | |||||
serverFetchJson, | |||||
serverFetchWithNoContent, | |||||
} from "@/app/utils/fetchUtil"; | |||||
import { revalidateTag } from "next/cache"; | import { revalidateTag } from "next/cache"; | ||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
import { CreateItemResponse } from "../../utils"; | import { CreateItemResponse } from "../../utils"; | ||||
@@ -18,28 +22,30 @@ import { QcChecksInputs } from "../qcCheck/actions"; | |||||
// conversion: number | // conversion: number | ||||
// } | // } | ||||
export type CreateItemInputs = { | export type CreateItemInputs = { | ||||
id?: string | number | |||||
id?: string | number; | |||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
description?: string | undefined; | description?: string | undefined; | ||||
remarks?: string | undefined; | remarks?: string | undefined; | ||||
shelfLife?: Number | undefined; | |||||
shelfLife?: number | undefined; | |||||
countryOfOrigin?: string | undefined; | countryOfOrigin?: string | undefined; | ||||
maxQty: number; | maxQty: number; | ||||
type: string; | type: string; | ||||
qcChecks: QcChecksInputs[] | |||||
qcChecks_active: number[] | |||||
} | |||||
qcChecks: QcChecksInputs[]; | |||||
qcChecks_active: number[]; | |||||
}; | |||||
export const saveItem = async (data: CreateItemInputs) => { | export const saveItem = async (data: CreateItemInputs) => { | ||||
// try { | |||||
const item = await serverFetchJson<CreateItemResponse<CreateItemInputs>>(`${BASE_API_URL}/items/new`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
revalidateTag("items"); | |||||
return item | |||||
}; | |||||
// try { | |||||
const item = await serverFetchJson<CreateItemResponse<CreateItemInputs>>( | |||||
`${BASE_API_URL}/items/new`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("items"); | |||||
return item; | |||||
}; |
@@ -16,40 +16,39 @@ export type ItemQc = { | |||||
lowerLimit: number | undefined; | lowerLimit: number | undefined; | ||||
upperLimit: number | undefined; | upperLimit: number | undefined; | ||||
isActive: boolean | undefined; | isActive: boolean | undefined; | ||||
} | |||||
}; | |||||
export type ItemsResultResponse = { | export type ItemsResultResponse = { | ||||
records: ItemsResult[]; | records: ItemsResult[]; | ||||
total: number; | total: number; | ||||
} | |||||
}; | |||||
export type ItemsResult = { | export type ItemsResult = { | ||||
id: string | number | |||||
id: string | number; | |||||
code: string; | code: string; | ||||
name: string; | name: string; | ||||
description: string | undefined; | description: string | undefined; | ||||
remarks: string | undefined; | remarks: string | undefined; | ||||
shelfLife: Number | undefined; | |||||
shelfLife: number | undefined; | |||||
countryOfOrigin: string | undefined; | countryOfOrigin: string | undefined; | ||||
maxQty: number | undefined; | maxQty: number | undefined; | ||||
type: string; | type: string; | ||||
qcChecks: ItemQc[] | |||||
action?: any | |||||
} | |||||
qcChecks: ItemQc[]; | |||||
action?: any; | |||||
}; | |||||
export type Result = { | export type Result = { | ||||
item: ItemsResult | |||||
qcChecks: ItemQc[] | |||||
} | |||||
item: ItemsResult; | |||||
qcChecks: ItemQc[]; | |||||
}; | |||||
export const fetchAllItems = cache(async () => { | export const fetchAllItems = cache(async () => { | ||||
return serverFetchJson<ItemsResult[]>(`${BASE_API_URL}/items`, { | |||||
next: { tags: ["items"] }, | |||||
}); | |||||
return serverFetchJson<ItemsResult[]>(`${BASE_API_URL}/items`, { | |||||
next: { tags: ["items"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchItem = cache(async (id: number) => { | export const fetchItem = cache(async (id: number) => { | ||||
return serverFetchJson<Result>(`${BASE_API_URL}/items/details/${id}`, { | return serverFetchJson<Result>(`${BASE_API_URL}/items/details/${id}`, { | ||||
next: { tags: ["items"] }, | next: { tags: ["items"] }, | ||||
}); | }); | ||||
}); | |||||
}); |
@@ -6,60 +6,62 @@ import { serverFetchWithNoContent } from "../../../utils/fetchUtil"; | |||||
import { BASE_API_URL } from "../../../../config/api"; | import { BASE_API_URL } from "../../../../config/api"; | ||||
export interface M18ImportPoForm { | export interface M18ImportPoForm { | ||||
modifiedDateFrom: string, | |||||
modifiedDateTo: string, | |||||
modifiedDateFrom: string; | |||||
modifiedDateTo: string; | |||||
} | } | ||||
export interface M18ImportDoForm { | export interface M18ImportDoForm { | ||||
modifiedDateFrom: string, | |||||
modifiedDateTo: string, | |||||
modifiedDateFrom: string; | |||||
modifiedDateTo: string; | |||||
} | } | ||||
export interface M18ImportPqForm { | export interface M18ImportPqForm { | ||||
modifiedDateFrom: string, | |||||
modifiedDateTo: string, | |||||
modifiedDateFrom: string; | |||||
modifiedDateTo: string; | |||||
} | } | ||||
export interface M18ImportMasterDataForm { | export interface M18ImportMasterDataForm { | ||||
modifiedDateFrom: string, | |||||
modifiedDateTo: string, | |||||
modifiedDateFrom: string; | |||||
modifiedDateTo: string; | |||||
} | } | ||||
export interface M18ImportTestingForm { | export interface M18ImportTestingForm { | ||||
po: M18ImportPoForm, | |||||
do: M18ImportDoForm, | |||||
pq: M18ImportPqForm, | |||||
masterData: M18ImportMasterDataForm, | |||||
po: M18ImportPoForm; | |||||
do: M18ImportDoForm; | |||||
pq: M18ImportPqForm; | |||||
masterData: M18ImportMasterDataForm; | |||||
} | } | ||||
export const testM18ImportPo = async (data: M18ImportPoForm) => { | export const testM18ImportPo = async (data: M18ImportPoForm) => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/po`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}) | |||||
} | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/po`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | |||||
export const testM18ImportDo = async (data: M18ImportDoForm) => { | export const testM18ImportDo = async (data: M18ImportDoForm) => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/do`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}) | |||||
} | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/do`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | |||||
export const testM18ImportPq = async (data: M18ImportPqForm) => { | export const testM18ImportPq = async (data: M18ImportPqForm) => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/pq`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}) | |||||
} | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/pq`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | |||||
export const testM18ImportMasterData = async (data: M18ImportMasterDataForm) => { | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/master-data`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}) | |||||
} | |||||
export const testM18ImportMasterData = async ( | |||||
data: M18ImportMasterDataForm, | |||||
) => { | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/m18/master-data`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; |
@@ -1 +1 @@ | |||||
// "server only" | |||||
// "server only" |
@@ -1,17 +1,17 @@ | |||||
"use server" | |||||
"use server"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | import { serverFetchJson } from "@/app/utils/fetchUtil"; | ||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
export interface CreateQcCategoryInputs { | export interface CreateQcCategoryInputs { | ||||
code: string; | |||||
name: string; | |||||
code: string; | |||||
name: string; | |||||
} | } | ||||
export const saveQcCategory = async (data: CreateQcCategoryInputs) => { | export const saveQcCategory = async (data: CreateQcCategoryInputs) => { | ||||
return serverFetchJson(`${BASE_API_URL}/qcCategories/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}) | |||||
} | |||||
return serverFetchJson(`${BASE_API_URL}/qcCategories/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; |
@@ -4,17 +4,17 @@ import { cache } from "react"; | |||||
import "server-only"; | import "server-only"; | ||||
export interface QcCategoryResult { | export interface QcCategoryResult { | ||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
} | } | ||||
export const preloadQcCategory = () => { | export const preloadQcCategory = () => { | ||||
fetchQcCategories(); | |||||
fetchQcCategories(); | |||||
}; | }; | ||||
export const fetchQcCategories = cache(async () => { | export const fetchQcCategories = cache(async () => { | ||||
return serverFetchJson<QcCategoryResult[]>(`${BASE_API_URL}/qcCategories`, { | |||||
next: { tags: ["qcCategories"]} | |||||
}); | |||||
}); | |||||
return serverFetchJson<QcCategoryResult[]>(`${BASE_API_URL}/qcCategories`, { | |||||
next: { tags: ["qcCategories"] }, | |||||
}); | |||||
}); |
@@ -7,18 +7,18 @@ import { BASE_API_URL } from "../../../../config/api"; | |||||
import { CreateItemResponse } from "../../utils"; | import { CreateItemResponse } from "../../utils"; | ||||
import { ItemQc } from "../item"; | import { ItemQc } from "../item"; | ||||
export type QcChecksInputs = { | |||||
} & Partial<ItemQc> | |||||
export type QcChecksInputs = {} & Partial<ItemQc>; | |||||
export const saveItemQcChecks = async (data: QcChecksInputs[]) => { | export const saveItemQcChecks = async (data: QcChecksInputs[]) => { | ||||
// try { | |||||
const res = await serverFetchJson<CreateItemResponse<QcChecksInputs>>(`${BASE_API_URL}/qcCheck/new`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
revalidateTag("items"); | |||||
return res | |||||
}; | |||||
// try { | |||||
const res = await serverFetchJson<CreateItemResponse<QcChecksInputs>>( | |||||
`${BASE_API_URL}/qcCheck/new`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("items"); | |||||
return res; | |||||
}; |
@@ -1,4 +1,4 @@ | |||||
"use server" | |||||
"use server"; | |||||
// import { serverFetchJson } from "@/app/utils/fetchUtil"; | // import { serverFetchJson } from "@/app/utils/fetchUtil"; | ||||
// import { BASE_API_URL } from "@/config/api"; | // import { BASE_API_URL } from "@/config/api"; | ||||
@@ -7,43 +7,49 @@ import { BASE_API_URL } from "../../../../config/api"; | |||||
import { revalidatePath, revalidateTag } from "next/cache"; | import { revalidatePath, revalidateTag } from "next/cache"; | ||||
//import { QcItemResult } from '@/app/api/settings/qcItem'; | //import { QcItemResult } from '@/app/api/settings/qcItem'; | ||||
import { QcItemResult } from '../../../api/settings/qcItem'; | |||||
import { QcItemResult } from "../../../api/settings/qcItem"; | |||||
export interface SaveQcItemInputs { | export interface SaveQcItemInputs { | ||||
id?: number; | |||||
code: string; | |||||
name: string; | |||||
description?: string; | |||||
id?: number; | |||||
code: string; | |||||
name: string; | |||||
description?: string; | |||||
} | } | ||||
export interface SaveQcItemResponse { | export interface SaveQcItemResponse { | ||||
id?: number; | |||||
code: string; | |||||
name: string; | |||||
description?: string; | |||||
errors: Record<keyof SaveQcItemInputs, string> | |||||
id?: number; | |||||
code: string; | |||||
name: string; | |||||
description?: string; | |||||
errors: Record<keyof SaveQcItemInputs, string>; | |||||
} | } | ||||
export const saveQcItem = async (data: SaveQcItemInputs) => { | export const saveQcItem = async (data: SaveQcItemInputs) => { | ||||
const response = await serverFetchJson<SaveQcItemResponse>(`${BASE_API_URL}/qcItems/save`, { | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}) | |||||
const response = await serverFetchJson<SaveQcItemResponse>( | |||||
`${BASE_API_URL}/qcItems/save`, | |||||
{ | |||||
method: "POST", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("qcItems") | |||||
revalidateTag("qcItems"); | |||||
return response | |||||
} | |||||
return response; | |||||
}; | |||||
export const deleteQcItem = async (id: number) => { | export const deleteQcItem = async (id: number) => { | ||||
const response = await serverFetchJson<QcItemResult[]>(`${BASE_API_URL}/qcItems/${id}`, { | |||||
method: "DELETE", | |||||
headers: { "Content-Type": "application/json" }, | |||||
}) | |||||
revalidateTag("qcItems") | |||||
revalidatePath("/(main)/settings/qcItem") | |||||
return response | |||||
} | |||||
const response = await serverFetchJson<QcItemResult[]>( | |||||
`${BASE_API_URL}/qcItems/${id}`, | |||||
{ | |||||
method: "DELETE", | |||||
headers: { "Content-Type": "application/json" }, | |||||
}, | |||||
); | |||||
revalidateTag("qcItems"); | |||||
revalidatePath("/(main)/settings/qcItem"); | |||||
return response; | |||||
}; |
@@ -9,27 +9,27 @@ import { SaveQcItemInputs } from "./actions"; | |||||
import next from "next"; | import next from "next"; | ||||
export interface QcItemResult { | export interface QcItemResult { | ||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
description: string; | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
description: string; | |||||
} | } | ||||
export const preloadQcItem = () => { | export const preloadQcItem = () => { | ||||
fetchQcItems(); | |||||
fetchQcItems(); | |||||
}; | }; | ||||
export const fetchQcItems = cache(async () => { | export const fetchQcItems = cache(async () => { | ||||
return serverFetchJson<QcItemResult[]>(`${BASE_API_URL}/qcItems`, { | |||||
next: { tags: ["qcItems"] } | |||||
}); | |||||
return serverFetchJson<QcItemResult[]>(`${BASE_API_URL}/qcItems`, { | |||||
next: { tags: ["qcItems"] }, | |||||
}); | |||||
}); | }); | ||||
export const fetchQcItemDetails = cache(async (qcItemId: string) => { | export const fetchQcItemDetails = cache(async (qcItemId: string) => { | ||||
return serverFetchJson<SaveQcItemInputs>( | |||||
`${BASE_API_URL}/qcItems/qcItemDetails/${qcItemId}`, | |||||
{ | |||||
next: { tags: [`qcItemDetails_${qcItemId}`] } | |||||
} | |||||
) | |||||
}) | |||||
return serverFetchJson<SaveQcItemInputs>( | |||||
`${BASE_API_URL}/qcItems/qcItemDetails/${qcItemId}`, | |||||
{ | |||||
next: { tags: [`qcItemDetails_${qcItemId}`] }, | |||||
}, | |||||
); | |||||
}); |
@@ -6,17 +6,17 @@ import { serverFetchJson } from "../../../utils/fetchUtil"; | |||||
import { BASE_API_URL } from "../../../../config/api"; | import { BASE_API_URL } from "../../../../config/api"; | ||||
export interface Uom { | export interface Uom { | ||||
id: number | |||||
code: string | |||||
name: string | |||||
unit1: string | |||||
unit1Qty: number | |||||
unit2?: string | |||||
unit2Qty: number | |||||
unit3?: string | |||||
unit3Qty: number | |||||
unit4?: string | |||||
unit4Qty: number | |||||
sizeInGram: number | |||||
gramPerSmallestUnit: number | |||||
} | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
unit1: string; | |||||
unit1Qty: number; | |||||
unit2?: string; | |||||
unit2Qty: number; | |||||
unit3?: string; | |||||
unit3Qty: number; | |||||
unit4?: string; | |||||
unit4Qty: number; | |||||
sizeInGram: number; | |||||
gramPerSmallestUnit: number; | |||||
} |
@@ -2,42 +2,45 @@ | |||||
// import { serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | // import { serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | ||||
// import { BASE_API_URL } from "@/config/api"; | // import { BASE_API_URL } from "@/config/api"; | ||||
import { serverFetchJson, serverFetchWithNoContent } from "../../utils/fetchUtil"; | |||||
import { | |||||
serverFetchJson, | |||||
serverFetchWithNoContent, | |||||
} from "../../utils/fetchUtil"; | |||||
import { BASE_API_URL } from "../../../config/api"; | import { BASE_API_URL } from "../../../config/api"; | ||||
import { revalidateTag } from "next/cache"; | import { revalidateTag } from "next/cache"; | ||||
import { UserDetail, UserResult } from "."; | import { UserDetail, UserResult } from "."; | ||||
import { cache } from "react"; | import { cache } from "react"; | ||||
export interface UserInputs { | export interface UserInputs { | ||||
username: string; | |||||
// name: string; | |||||
addAuthIds?: number[]; | |||||
removeAuthIds?: number[]; | |||||
password?: string; | |||||
username: string; | |||||
// name: string; | |||||
addAuthIds?: number[]; | |||||
removeAuthIds?: number[]; | |||||
password?: string; | |||||
} | } | ||||
export interface PasswordInputs { | export interface PasswordInputs { | ||||
password: string; | |||||
newPassword: string; | |||||
newPasswordCheck: string; | |||||
password: string; | |||||
newPassword: string; | |||||
newPasswordCheck: string; | |||||
} | } | ||||
export interface NameList { | export interface NameList { | ||||
id: number | |||||
name: string | |||||
id: number; | |||||
name: string; | |||||
} | } | ||||
export const fetchUserDetails = cache(async (id: number) => { | export const fetchUserDetails = cache(async (id: number) => { | ||||
return serverFetchJson<UserDetail>(`${BASE_API_URL}/user/${id}`, { | |||||
next: { tags: ["user"] }, | |||||
}); | |||||
return serverFetchJson<UserDetail>(`${BASE_API_URL}/user/${id}`, { | |||||
next: { tags: ["user"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchNameList = cache(async () => { | export const fetchNameList = cache(async () => { | ||||
return serverFetchJson<NameList[]>(`${BASE_API_URL}/user/name-list`, { | |||||
next: { tags: ["user"] }, | |||||
}); | |||||
return serverFetchJson<NameList[]>(`${BASE_API_URL}/user/name-list`, { | |||||
next: { tags: ["user"] }, | |||||
}); | }); | ||||
}); | |||||
export const editUser = async (id: number, data: UserInputs) => { | export const editUser = async (id: number, data: UserInputs) => { | ||||
const newUser = serverFetchWithNoContent(`${BASE_API_URL}/user/${id}`, { | const newUser = serverFetchWithNoContent(`${BASE_API_URL}/user/${id}`, { | ||||
@@ -45,8 +48,8 @@ export const editUser = async (id: number, data: UserInputs) => { | |||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
revalidateTag("user") | |||||
return newUser | |||||
revalidateTag("user"); | |||||
return newUser; | |||||
}; | }; | ||||
export const createUser = async (data: UserInputs) => { | export const createUser = async (data: UserInputs) => { | ||||
@@ -55,8 +58,8 @@ export const createUser = async (data: UserInputs) => { | |||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
revalidateTag("user") | |||||
return newUser | |||||
revalidateTag("user"); | |||||
return newUser; | |||||
}; | }; | ||||
export const deleteUser = async (id: number) => { | export const deleteUser = async (id: number) => { | ||||
@@ -64,22 +67,25 @@ export const deleteUser = async (id: number) => { | |||||
method: "DELETE", | method: "DELETE", | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | }); | ||||
revalidateTag("user") | |||||
return newUser | |||||
}; | |||||
revalidateTag("user"); | |||||
return newUser; | |||||
}; | |||||
export const changePassword = async (data: any) => { | export const changePassword = async (data: any) => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/user/change-password`, { | |||||
method: "PATCH", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | |||||
return serverFetchWithNoContent(`${BASE_API_URL}/user/change-password`, { | |||||
method: "PATCH", | |||||
body: JSON.stringify(data), | |||||
headers: { "Content-Type": "application/json" }, | |||||
}); | |||||
}; | |||||
export const adminChangePassword = async (data: any) => { | export const adminChangePassword = async (data: any) => { | ||||
return serverFetchWithNoContent(`${BASE_API_URL}/user/admin-change-password`, { | |||||
return serverFetchWithNoContent( | |||||
`${BASE_API_URL}/user/admin-change-password`, | |||||
{ | |||||
method: "PATCH", | method: "PATCH", | ||||
body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
}); | |||||
}; | |||||
}, | |||||
); | |||||
}; |
@@ -4,11 +4,11 @@ import { cache } from "react"; | |||||
import "server-only"; | import "server-only"; | ||||
export interface UserResult { | export interface UserResult { | ||||
action: any; | |||||
id: number; | |||||
username: string; | |||||
// name: string; | |||||
} | |||||
action: any; | |||||
id: number; | |||||
username: string; | |||||
// name: string; | |||||
} | |||||
// export interface DetailedUser extends UserResult { | // export interface DetailedUser extends UserResult { | ||||
// username: string; | // username: string; | ||||
@@ -16,43 +16,43 @@ export interface UserResult { | |||||
// } | // } | ||||
export interface UserDetail { | export interface UserDetail { | ||||
data: UserResult; | |||||
authIds: number[]; | |||||
groupIds: number[]; | |||||
auths: any[] | |||||
} | |||||
export type passwordRule = { | |||||
min: number; | |||||
max: number; | |||||
number: boolean; | |||||
upperEng: boolean; | |||||
lowerEng: boolean; | |||||
specialChar: boolean; | |||||
} | |||||
export const preloadUser = () => { | |||||
fetchUser(); | |||||
}; | |||||
export const preloadUserDetail = (id: number) => { | |||||
fetchUserDetail(id); | |||||
}; | |||||
export const fetchUser = cache(async () => { | |||||
return serverFetchJson<UserResult[]>(`${BASE_API_URL}/user`, { | |||||
next: { tags: ["user"] }, | |||||
}); | |||||
data: UserResult; | |||||
authIds: number[]; | |||||
groupIds: number[]; | |||||
auths: any[]; | |||||
} | |||||
export type passwordRule = { | |||||
min: number; | |||||
max: number; | |||||
number: boolean; | |||||
upperEng: boolean; | |||||
lowerEng: boolean; | |||||
specialChar: boolean; | |||||
}; | |||||
export const preloadUser = () => { | |||||
fetchUser(); | |||||
}; | |||||
export const preloadUserDetail = (id: number) => { | |||||
fetchUserDetail(id); | |||||
}; | |||||
export const fetchUser = cache(async () => { | |||||
return serverFetchJson<UserResult[]>(`${BASE_API_URL}/user`, { | |||||
next: { tags: ["user"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchUserDetail = cache(async (id: number) => { | |||||
return serverFetchJson<UserResult[]>(`${BASE_API_URL}/user/${id}`, { | |||||
next: { tags: ["user"] }, | |||||
}); | |||||
export const fetchUserDetail = cache(async (id: number) => { | |||||
return serverFetchJson<UserResult[]>(`${BASE_API_URL}/user/${id}`, { | |||||
next: { tags: ["user"] }, | |||||
}); | }); | ||||
}); | |||||
export const fetchPwRules = cache(async () => { | |||||
return serverFetchJson<passwordRule>(`${BASE_API_URL}/user/password-rule`, { | |||||
next: { tags: ["pwRule"] }, | |||||
}); | |||||
}); | |||||
export const fetchPwRules = cache(async () => { | |||||
return serverFetchJson<passwordRule>(`${BASE_API_URL}/user/password-rule`, { | |||||
next: { tags: ["pwRule"] }, | |||||
}); | |||||
}); |
@@ -19,7 +19,7 @@ export interface CreateEquipmentResponse<T> { | |||||
message: string | null; | message: string | null; | ||||
errorPosition: string | keyof T; | errorPosition: string | keyof T; | ||||
} | } | ||||
export interface RecordsRes<T>{ | |||||
records: T | |||||
total: number | |||||
} | |||||
export interface RecordsRes<T> { | |||||
records: T; | |||||
total: number; | |||||
} |
@@ -4,14 +4,14 @@ import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
export interface WarehouseResult { | export interface WarehouseResult { | ||||
id: number | |||||
code: string | |||||
name: string | |||||
description: string | |||||
id: number; | |||||
code: string; | |||||
name: string; | |||||
description: string; | |||||
} | } | ||||
export const fetchWarehouseList = cache(async () => { | export const fetchWarehouseList = cache(async () => { | ||||
return serverFetchJson<WarehouseResult[]>(`${BASE_API_URL}/warehouse`, { | |||||
next: { tags: ["warehouse"] }, | |||||
}); | |||||
}); | |||||
return serverFetchJson<WarehouseResult[]>(`${BASE_API_URL}/warehouse`, { | |||||
next: { tags: ["warehouse"] }, | |||||
}); | |||||
}); |
@@ -1,4 +1,4 @@ | |||||
import { defaultPagingController } from './../../components/SearchResults/SearchResults'; | |||||
import { defaultPagingController } from "./../../components/SearchResults/SearchResults"; | |||||
import { isNullOrUndefined } from "html5-qrcode/esm/core"; | import { isNullOrUndefined } from "html5-qrcode/esm/core"; | ||||
import { isEmpty } from "lodash"; | import { isEmpty } from "lodash"; | ||||
@@ -8,19 +8,21 @@ export const downloadFile = (blobData: Uint8Array, filename: string) => { | |||||
link.href = url; | link.href = url; | ||||
link.setAttribute("download", filename); | link.setAttribute("download", filename); | ||||
link.click(); | link.click(); | ||||
} | |||||
}; | |||||
export const convertObjToURLSearchParams = <T extends Object>(data: T | null): string => { | |||||
export const convertObjToURLSearchParams = <T extends Object>( | |||||
data: T | null, | |||||
): string => { | |||||
if (isEmpty(data)) { | if (isEmpty(data)) { | ||||
return '' | |||||
return ""; | |||||
} | } | ||||
const params = new URLSearchParams() | |||||
const params = new URLSearchParams(); | |||||
Object.entries(data).forEach(([key, value]) => { | Object.entries(data).forEach(([key, value]) => { | ||||
if (!isNullOrUndefined(value)) { | if (!isNullOrUndefined(value)) { | ||||
params.append(key, String(value)) | |||||
params.append(key, String(value)); | |||||
} | } | ||||
}) | |||||
}); | |||||
return params.toString() | |||||
} | |||||
return params.toString(); | |||||
}; |
@@ -4,13 +4,13 @@ import { headers } from "next/headers"; | |||||
import { redirect } from "next/navigation"; | import { redirect } from "next/navigation"; | ||||
export interface Pageable { | export interface Pageable { | ||||
pageSize?: number | |||||
pageNum?: number | |||||
pageSize?: number; | |||||
pageNum?: number; | |||||
} | } | ||||
export type SearchParams = { | export type SearchParams = { | ||||
searchParams: { [key: string]: string | string[] | undefined }; | searchParams: { [key: string]: string | string[] | undefined }; | ||||
} | |||||
}; | |||||
export interface searchParamsProps { | export interface searchParamsProps { | ||||
searchParams: { [key: string]: string | string[] | undefined }; | searchParams: { [key: string]: string | string[] | undefined }; | ||||
@@ -66,19 +66,22 @@ type FetchParams = Parameters<typeof fetch>; | |||||
export async function serverFetchJson<T>(...args: FetchParams) { | export async function serverFetchJson<T>(...args: FetchParams) { | ||||
const response = await serverFetch(...args); | const response = await serverFetch(...args); | ||||
console.log(response.status) | |||||
console.log(response.status); | |||||
if (response.ok) { | if (response.ok) { | ||||
if (response.status === 204) { | if (response.status === 204) { | ||||
return response.status as T | |||||
return response.status as T; | |||||
} | } | ||||
return response.json() as T; | return response.json() as T; | ||||
} else { | } else { | ||||
switch (response.status) { | switch (response.status) { | ||||
case 401: | case 401: | ||||
signOutUser(); | signOutUser(); | ||||
default: | default: | ||||
throw new ServerFetchError("Something went wrong fetching data in server.", response); | |||||
throw new ServerFetchError( | |||||
"Something went wrong fetching data in server.", | |||||
response, | |||||
); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -1,7 +1,15 @@ | |||||
import dayjs, { ConfigType, Dayjs } from "dayjs"; | import dayjs, { ConfigType, Dayjs } from "dayjs"; | ||||
import { Uom } from "../api/settings/uom"; | import { Uom } from "../api/settings/uom"; | ||||
import { ListIterateeCustom, every, isArray, isNaN, isNull, isUndefined, take } from "lodash"; | |||||
import { Box, BoxProps, } from "@mui/material"; | |||||
import { | |||||
ListIterateeCustom, | |||||
every, | |||||
isArray, | |||||
isNaN, | |||||
isNull, | |||||
isUndefined, | |||||
take, | |||||
} from "lodash"; | |||||
import { Box, BoxProps } from "@mui/material"; | |||||
export const manhourFormatter = new Intl.NumberFormat("en-HK", { | export const manhourFormatter = new Intl.NumberFormat("en-HK", { | ||||
minimumFractionDigits: 2, | minimumFractionDigits: 2, | ||||
@@ -15,11 +23,9 @@ export const moneyFormatter = new Intl.NumberFormat("en-HK", { | |||||
export const decimalFormatter = new Intl.NumberFormat("en-HK", { | export const decimalFormatter = new Intl.NumberFormat("en-HK", { | ||||
minimumFractionDigits: 2, | minimumFractionDigits: 2, | ||||
}) | |||||
export const integerFormatter = new Intl.NumberFormat("en-HK", { | |||||
}); | |||||
}) | |||||
export const integerFormatter = new Intl.NumberFormat("en-HK", {}); | |||||
export const INPUT_DATE_FORMAT = "YYYY-MM-DD"; | export const INPUT_DATE_FORMAT = "YYYY-MM-DD"; | ||||
@@ -28,71 +34,72 @@ export const OUTPUT_DATE_FORMAT = "YYYY/MM/DD"; | |||||
export const OUTPUT_TIME_FORMAT = "HH:mm:ss"; | export const OUTPUT_TIME_FORMAT = "HH:mm:ss"; | ||||
export const arrayToDayjs = (arr: ConfigType | (number | undefined)[]) => { | export const arrayToDayjs = (arr: ConfigType | (number | undefined)[]) => { | ||||
const isValidNumber = (item: ListIterateeCustom<number | undefined, boolean>): boolean => | |||||
typeof item === "number" && !isNaN(item) && isFinite(item) | |||||
const isValidNumber = ( | |||||
item: ListIterateeCustom<number | undefined, boolean>, | |||||
): boolean => typeof item === "number" && !isNaN(item) && isFinite(item); | |||||
let tempArr = arr; | let tempArr = arr; | ||||
if (isArray(arr) && every(arr, isValidNumber) && arr.length >= 3) { | if (isArray(arr) && every(arr, isValidNumber) && arr.length >= 3) { | ||||
// [year, month, day] | // [year, month, day] | ||||
tempArr = take(arr, 3) | |||||
tempArr = take(arr, 3); | |||||
} | } | ||||
return dayjs(tempArr as ConfigType) | |||||
} | |||||
return dayjs(tempArr as ConfigType); | |||||
}; | |||||
export const arrayToDateString = (arr: ConfigType | (number | undefined)[]) => { | export const arrayToDateString = (arr: ConfigType | (number | undefined)[]) => { | ||||
return arrayToDayjs(arr).format(OUTPUT_DATE_FORMAT) | |||||
} | |||||
return arrayToDayjs(arr).format(OUTPUT_DATE_FORMAT); | |||||
}; | |||||
export const dateStringToDayjs = (date: string) => { | export const dateStringToDayjs = (date: string) => { | ||||
// Format: YYYY/MM/DD | // Format: YYYY/MM/DD | ||||
return dayjs(date, OUTPUT_DATE_FORMAT) | |||||
} | |||||
return dayjs(date, OUTPUT_DATE_FORMAT); | |||||
}; | |||||
export const dateTimeStringToDayjs = (dateTime: string) => { | export const dateTimeStringToDayjs = (dateTime: string) => { | ||||
// Format: YYYY/MM/DD HH:mm:ss | // Format: YYYY/MM/DD HH:mm:ss | ||||
return dayjs(dateTime, `${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`) | |||||
} | |||||
return dayjs(dateTime, `${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`); | |||||
}; | |||||
export const dayjsToDateString = (date: Dayjs) => { | export const dayjsToDateString = (date: Dayjs) => { | ||||
return date.format(OUTPUT_DATE_FORMAT) | |||||
} | |||||
return date.format(OUTPUT_DATE_FORMAT); | |||||
}; | |||||
export const stockInLineStatusMap: { [status: string]: number } = { | export const stockInLineStatusMap: { [status: string]: number } = { | ||||
"draft": 0, | |||||
"pending": 1, | |||||
"qc": 2, | |||||
"determine1": 3, | |||||
"determine2": 4, | |||||
"determine3": 5, | |||||
"receiving": 6, | |||||
"received": 7, | |||||
"completed": 8, | |||||
"rejected": 9, | |||||
draft: 0, | |||||
pending: 1, | |||||
qc: 2, | |||||
determine1: 3, | |||||
determine2: 4, | |||||
determine3: 5, | |||||
receiving: 6, | |||||
received: 7, | |||||
completed: 8, | |||||
rejected: 9, | |||||
}; | }; | ||||
export const stockOutLineStatusMap: { [status: string]: number } = { | export const stockOutLineStatusMap: { [status: string]: number } = { | ||||
"draft": 0, | |||||
"pending": 1, // waiting for qc | |||||
"determine1": 2, // waiting for qc | |||||
draft: 0, | |||||
pending: 1, // waiting for qc | |||||
determine1: 2, // waiting for qc | |||||
"lot-change": 3, // waiting for qc | "lot-change": 3, // waiting for qc | ||||
// after qc = completed | // after qc = completed | ||||
"completed": 4, | |||||
"rejected": 5, | |||||
completed: 4, | |||||
rejected: 5, | |||||
}; | }; | ||||
export const pickOrderStatusMap: { [status: string]: number } = { | export const pickOrderStatusMap: { [status: string]: number } = { | ||||
"pending": 1, | |||||
"consolidated": 2, | |||||
"released": 3, | |||||
"completed": 4, | |||||
pending: 1, | |||||
consolidated: 2, | |||||
released: 3, | |||||
completed: 4, | |||||
}; | }; | ||||
export const calculateWeight = (qty: number, uom: Uom) => { | export const calculateWeight = (qty: number, uom: Uom) => { | ||||
return qty * (uom.unit2Qty || 1) * (uom.unit3Qty || 1) * (uom.unit4Qty || 1); | return qty * (uom.unit2Qty || 1) * (uom.unit3Qty || 1) * (uom.unit4Qty || 1); | ||||
} | |||||
}; | |||||
export const returnWeightUnit = (uom: Uom) => { | export const returnWeightUnit = (uom: Uom) => { | ||||
return uom.unit4 || uom.unit3 || uom.unit2 || uom.unit1; | return uom.unit4 || uom.unit3 || uom.unit2 || uom.unit1; | ||||
} | |||||
}; |
@@ -1,10 +1,10 @@ | |||||
export enum TypeEnum { | export enum TypeEnum { | ||||
MATERIAL = "material", | |||||
MATERIAL_ID = 1, | |||||
PRODUCT = "product", | |||||
PRODUCT_ID = 2, | |||||
BYPRODUCT = "byProduct", | |||||
BYPRODUCT_ID = 3, | |||||
CONSUMABLE = "consumables", | |||||
CONSUMABLE_ID = 4, | |||||
} | |||||
MATERIAL = "material", | |||||
MATERIAL_ID = 1, | |||||
PRODUCT = "product", | |||||
PRODUCT_ID = 2, | |||||
BYPRODUCT = "byProduct", | |||||
BYPRODUCT_ID = 3, | |||||
CONSUMABLE = "consumables", | |||||
CONSUMABLE_ID = 4, | |||||
} |
@@ -1,12 +1,6 @@ | |||||
export const [ | |||||
VIEW_USER, | |||||
MAINTAIN_USER, | |||||
VIEW_GROUP, | |||||
MAINTAIN_GROUP, | |||||
] = [ | |||||
export const [VIEW_USER, MAINTAIN_USER, VIEW_GROUP, MAINTAIN_GROUP] = [ | |||||
"VIEW_USER", | "VIEW_USER", | ||||
"MAINTAIN_USER", | "MAINTAIN_USER", | ||||
"VIEW_GROUP", | "VIEW_GROUP", | ||||
"MAINTAIN_GROUP", | "MAINTAIN_GROUP", | ||||
] | |||||
]; |
@@ -30,7 +30,7 @@ const pathToLabelMap: { [path: string]: string } = { | |||||
const Breadcrumb = () => { | const Breadcrumb = () => { | ||||
const pathname = usePathname(); | const pathname = usePathname(); | ||||
const segments = pathname.split("/"); | const segments = pathname.split("/"); | ||||
const { t } = useTranslation("common") | |||||
const { t } = useTranslation("common"); | |||||
return ( | return ( | ||||
<Breadcrumbs> | <Breadcrumbs> | ||||
@@ -1,93 +0,0 @@ | |||||
"use client"; | |||||
import { ClaimResult } from "@/app/api/claims"; | |||||
import React, { useCallback, useMemo, useState } from "react"; | |||||
import SearchBox, { Criterion } from "../SearchBox/index"; | |||||
import { useTranslation } from "react-i18next"; | |||||
import SearchResults, { Column } from "../SearchResults/index"; | |||||
import EditNote from "@mui/icons-material/EditNote"; | |||||
interface Props { | |||||
claims: ClaimResult[]; | |||||
} | |||||
type SearchQuery = Partial<Omit<ClaimResult, "id">>; | |||||
type SearchParamNames = keyof SearchQuery; | |||||
const ClaimSearch: React.FC<Props> = ({ claims }) => { | |||||
const { t } = useTranslation("claims"); | |||||
// If claim searching is done on the server-side, then no need for this. | |||||
const [filteredClaims, setFilteredClaims] = useState(claims); | |||||
const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | |||||
() => [ | |||||
{ label: t("Creation Date"), paramName: "created", type: "dateRange" }, | |||||
{ label: t("Related Project Name"), paramName: "name", type: "text" }, | |||||
{ | |||||
label: t("Cost (HKD)"), | |||||
paramName: "cost", | |||||
type: "text", | |||||
}, | |||||
{ | |||||
label: t("Expense Type"), | |||||
paramName: "type", | |||||
type: "select", | |||||
options: ["Expense", "Petty Cash"], | |||||
}, | |||||
{ | |||||
label: t("Status"), | |||||
paramName: "status", | |||||
type: "select", | |||||
options: [ | |||||
"Not Submitted", | |||||
"Waiting for Approval", | |||||
"Approved", | |||||
"Rejected", | |||||
], | |||||
}, | |||||
{ | |||||
label: t("Remarks"), | |||||
paramName: "remarks", | |||||
type: "text", | |||||
}, | |||||
], | |||||
[t], | |||||
); | |||||
const onClaimClick = useCallback((claim: ClaimResult) => { | |||||
console.log(claim); | |||||
}, []); | |||||
const columns = useMemo<Column<ClaimResult>[]>( | |||||
() => [ | |||||
// { | |||||
// name: "action", | |||||
// label: t("Actions"), | |||||
// onClick: onClaimClick, | |||||
// buttonIcon: <EditNote />, | |||||
// }, | |||||
{ name: "created", label: t("Creation Date") }, | |||||
{ name: "name", label: t("Related Project Name") }, | |||||
{ name: "cost", label: t("Cost (HKD)") }, | |||||
{ name: "type", label: t("Expense Type") }, | |||||
{ name: "status", label: t("Status") }, | |||||
{ name: "remarks", label: t("Remarks") }, | |||||
], | |||||
[t, onClaimClick], | |||||
); | |||||
return ( | |||||
<> | |||||
<SearchBox | |||||
criteria={searchCriteria} | |||||
onSearch={(query) => { | |||||
console.log(query); | |||||
}} | |||||
/> | |||||
<SearchResults<ClaimResult> items={filteredClaims} columns={columns} /> | |||||
</> | |||||
); | |||||
}; | |||||
export default ClaimSearch; |
@@ -1,40 +0,0 @@ | |||||
import Card from "@mui/material/Card"; | |||||
import CardContent from "@mui/material/CardContent"; | |||||
import Skeleton from "@mui/material/Skeleton"; | |||||
import Stack from "@mui/material/Stack"; | |||||
import React from "react"; | |||||
// Can make this nicer | |||||
export const ClaimSearchLoading: React.FC = () => { | |||||
return ( | |||||
<> | |||||
<Card> | |||||
<CardContent> | |||||
<Stack spacing={2}> | |||||
<Skeleton variant="rounded" height={60} /> | |||||
<Skeleton variant="rounded" height={60} /> | |||||
<Skeleton variant="rounded" height={60} /> | |||||
<Skeleton | |||||
variant="rounded" | |||||
height={50} | |||||
width={100} | |||||
sx={{ alignSelf: "flex-end" }} | |||||
/> | |||||
</Stack> | |||||
</CardContent> | |||||
</Card> | |||||
<Card> | |||||
<CardContent> | |||||
<Stack spacing={2}> | |||||
<Skeleton variant="rounded" height={40} /> | |||||
<Skeleton variant="rounded" height={40} /> | |||||
<Skeleton variant="rounded" height={40} /> | |||||
<Skeleton variant="rounded" height={40} /> | |||||
</Stack> | |||||
</CardContent> | |||||
</Card> | |||||
</> | |||||
); | |||||
}; | |||||
export default ClaimSearchLoading; |
@@ -1,18 +0,0 @@ | |||||
import { fetchClaims } from "@/app/api/claims"; | |||||
import React from "react"; | |||||
import ClaimSearch from "./ClaimSearch"; | |||||
import ClaimSearchLoading from "./ClaimSearchLoading"; | |||||
interface SubComponents { | |||||
Loading: typeof ClaimSearchLoading; | |||||
} | |||||
const ClaimSearchWrapper: React.FC & SubComponents = async () => { | |||||
const claims = await fetchClaims(); | |||||
return <ClaimSearch claims={claims} />; | |||||
}; | |||||
ClaimSearchWrapper.Loading = ClaimSearchLoading; | |||||
export default ClaimSearchWrapper; |
@@ -1 +0,0 @@ | |||||
export { default } from "./ClaimSearchWrapper"; |
@@ -1 +1 @@ | |||||
export { default } from "./ControlledAutoComplete"; | |||||
export { default } from "./ControlledAutoComplete"; |
@@ -14,7 +14,16 @@ import { | |||||
useForm, | useForm, | ||||
} from "react-hook-form"; | } from "react-hook-form"; | ||||
import { deleteDialog } from "../Swal/CustomAlerts"; | import { deleteDialog } from "../Swal/CustomAlerts"; | ||||
import { Box, Button, Grid, Stack, Tab, Tabs, TabsProps, Typography } from "@mui/material"; | |||||
import { | |||||
Box, | |||||
Button, | |||||
Grid, | |||||
Stack, | |||||
Tab, | |||||
Tabs, | |||||
TabsProps, | |||||
Typography, | |||||
} from "@mui/material"; | |||||
import { Check, Close, EditNote } from "@mui/icons-material"; | import { Check, Close, EditNote } from "@mui/icons-material"; | ||||
import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
import EquipmentDetails from "./EquipmentDetails"; | import EquipmentDetails from "./EquipmentDetails"; | ||||
@@ -33,31 +42,30 @@ const CreateItem: React.FC<Props> = ({ | |||||
isEditMode, | isEditMode, | ||||
// type, | // type, | ||||
defaultValues, | defaultValues, | ||||
}) => { | }) => { | ||||
// console.log(type) | // console.log(type) | ||||
const apiRef = useGridApiRef(); | const apiRef = useGridApiRef(); | ||||
const params = useSearchParams() | |||||
console.log(params.get("id")) | |||||
const params = useSearchParams(); | |||||
console.log(params.get("id")); | |||||
const [serverError, setServerError] = useState(""); | const [serverError, setServerError] = useState(""); | ||||
const [tabIndex, setTabIndex] = useState(0); | const [tabIndex, setTabIndex] = useState(0); | ||||
const { t } = useTranslation("common"); | const { t } = useTranslation("common"); | ||||
const router = useRouter(); | const router = useRouter(); | ||||
const title = "Equipment" | |||||
const title = "Equipment"; | |||||
const [mode, redirPath] = useMemo(() => { | const [mode, redirPath] = useMemo(() => { | ||||
// var typeId = TypeEnum.CONSUMABLE_ID | // var typeId = TypeEnum.CONSUMABLE_ID | ||||
var title = ""; | |||||
var mode = ""; | |||||
var redirPath = ""; | |||||
let title = ""; | |||||
let mode = ""; | |||||
let redirPath = ""; | |||||
// if (type === TypeEnum.MATERIAL) { | // if (type === TypeEnum.MATERIAL) { | ||||
// typeId = TypeEnum.MATERIAL_ID | // typeId = TypeEnum.MATERIAL_ID | ||||
// title = "Material"; | // title = "Material"; | ||||
// redirPath = "/settings/material"; | // redirPath = "/settings/material"; | ||||
// } | // } | ||||
// if (type === TypeEnum.PRODUCT) { | // if (type === TypeEnum.PRODUCT) { | ||||
// typeId = TypeEnum.PRODUCT_ID | |||||
title = "Equipment"; | |||||
redirPath = "/settings/equipment"; | |||||
// typeId = TypeEnum.PRODUCT_ID | |||||
title = "Equipment"; | |||||
redirPath = "/settings/equipment"; | |||||
// } | // } | ||||
// if (type === TypeEnum.BYPRODUCT) { | // if (type === TypeEnum.BYPRODUCT) { | ||||
// typeId = TypeEnum.BYPRODUCT_ID | // typeId = TypeEnum.BYPRODUCT_ID | ||||
@@ -73,8 +81,7 @@ const CreateItem: React.FC<Props> = ({ | |||||
}, [isEditMode]); | }, [isEditMode]); | ||||
// console.log(typeId) | // console.log(typeId) | ||||
const formProps = useForm<CreateEquipmentInputs>({ | const formProps = useForm<CreateEquipmentInputs>({ | ||||
defaultValues: defaultValues ? defaultValues : { | |||||
}, | |||||
defaultValues: defaultValues ? defaultValues : {}, | |||||
}); | }); | ||||
const errors = formProps.formState.errors; | const errors = formProps.formState.errors; | ||||
@@ -90,8 +97,8 @@ const CreateItem: React.FC<Props> = ({ | |||||
}; | }; | ||||
const onSubmit = useCallback<SubmitHandler<CreateEquipmentInputs & {}>>( | const onSubmit = useCallback<SubmitHandler<CreateEquipmentInputs & {}>>( | ||||
async (data, event) => { | async (data, event) => { | ||||
let hasErrors = false; | |||||
console.log(errors) | |||||
const hasErrors = false; | |||||
console.log(errors); | |||||
// console.log(apiRef.current.getCellValue(2, "lowerLimit")) | // console.log(apiRef.current.getCellValue(2, "lowerLimit")) | ||||
// apiRef.current. | // apiRef.current. | ||||
try { | try { | ||||
@@ -102,24 +109,25 @@ const CreateItem: React.FC<Props> = ({ | |||||
console.log("data posted"); | console.log("data posted"); | ||||
console.log(data); | console.log(data); | ||||
// TODO: | |||||
// TODO: | |||||
// 1. check field ( directly modify col def / check here ) | // 1. check field ( directly modify col def / check here ) | ||||
// 2. set error change tab index | // 2. set error change tab index | ||||
// return | // return | ||||
// do api | // do api | ||||
console.log("asdad") | |||||
var responseI = await saveEquipment(data); | |||||
console.log("asdad") | |||||
console.log("asdad"); | |||||
const responseI = await saveEquipment(data); | |||||
console.log("asdad"); | |||||
// var responseQ = await saveItemQcChecks(qcCheck) | // var responseQ = await saveItemQcChecks(qcCheck) | ||||
if (responseI) { | if (responseI) { | ||||
if (!Boolean(responseI.id)) { | if (!Boolean(responseI.id)) { | ||||
formProps.setError(responseI.errorPosition!! as keyof CreateEquipmentInputs, { | |||||
message: responseI.message!!, | |||||
type: "required", | |||||
}) | |||||
formProps.setError( | |||||
responseI.errorPosition! as keyof CreateEquipmentInputs, | |||||
{ | |||||
message: responseI.message!, | |||||
type: "required", | |||||
}, | |||||
); | |||||
} else if (Boolean(responseI.id)) { | } else if (Boolean(responseI.id)) { | ||||
router.replace(redirPath); | router.replace(redirPath); | ||||
} | } | ||||
@@ -130,13 +138,13 @@ const CreateItem: React.FC<Props> = ({ | |||||
console.log(e); | console.log(e); | ||||
} | } | ||||
}, | }, | ||||
[apiRef, router, t] | |||||
[apiRef, router, t], | |||||
); | ); | ||||
// multiple tabs | // multiple tabs | ||||
const onSubmitError = useCallback<SubmitErrorHandler<CreateEquipmentInputs>>( | const onSubmitError = useCallback<SubmitErrorHandler<CreateEquipmentInputs>>( | ||||
(errors) => {}, | (errors) => {}, | ||||
[] | |||||
[], | |||||
); | ); | ||||
return ( | return ( | ||||
@@ -147,21 +155,25 @@ const CreateItem: React.FC<Props> = ({ | |||||
component="form" | component="form" | ||||
onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} | onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} | ||||
> | > | ||||
<Grid> | |||||
<Typography mb={2} variant="h4"> | |||||
{t(`${mode} ${title}`)} | |||||
</Typography> | |||||
</Grid> | |||||
<Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | |||||
<Tab label={t("Equipment Details")} iconPosition="end"/> | |||||
{/* <Tab label={t("Qc items")} iconPosition="end" /> */} | |||||
</Tabs> | |||||
<Grid> | |||||
<Typography mb={2} variant="h4"> | |||||
{t(`${mode} ${title}`)} | |||||
</Typography> | |||||
</Grid> | |||||
<Tabs | |||||
value={tabIndex} | |||||
onChange={handleTabChange} | |||||
variant="scrollable" | |||||
> | |||||
<Tab label={t("Equipment Details")} iconPosition="end" /> | |||||
{/* <Tab label={t("Qc items")} iconPosition="end" /> */} | |||||
</Tabs> | |||||
{serverError && ( | {serverError && ( | ||||
<Typography variant="body2" color="error" alignSelf="flex-end"> | <Typography variant="body2" color="error" alignSelf="flex-end"> | ||||
{serverError} | {serverError} | ||||
</Typography> | </Typography> | ||||
)} | )} | ||||
{tabIndex === 0 && <EquipmentDetails isEditMode={isEditMode} />} | |||||
{tabIndex === 0 && <EquipmentDetails isEditMode={isEditMode} />} | |||||
{/* {tabIndex === 1 && <QcDetails apiRef={apiRef} />} */} | {/* {tabIndex === 1 && <QcDetails apiRef={apiRef} />} */} | ||||
{/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */} | {/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */} | ||||
{/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */} | {/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */} | ||||
@@ -23,7 +23,8 @@ export const CreateItemLoading: React.FC = () => { | |||||
</Stack> | </Stack> | ||||
</CardContent> | </CardContent> | ||||
</Card> | </Card> | ||||
<Card>CreateMaterial | |||||
<Card> | |||||
CreateMaterial | |||||
<CardContent> | <CardContent> | ||||
<Stack spacing={2}> | <Stack spacing={2}> | ||||
<Skeleton variant="rounded" height={40} /> | <Skeleton variant="rounded" height={40} /> | ||||
@@ -9,34 +9,32 @@ interface SubComponents { | |||||
} | } | ||||
type Props = { | type Props = { | ||||
id?: number | |||||
id?: number; | |||||
// type: TypeEnum; | // type: TypeEnum; | ||||
}; | }; | ||||
const CreateEquipmentWrapper: React.FC<Props> & | |||||
SubComponents = async ({ id }) => { | |||||
var result | |||||
var defaultValues: Partial<CreateEquipmentInputs> | undefined | |||||
const CreateEquipmentWrapper: React.FC<Props> & SubComponents = async ({ | |||||
id, | |||||
}) => { | |||||
let result; | |||||
let defaultValues: Partial<CreateEquipmentInputs> | undefined; | |||||
// console.log(type) | // console.log(type) | ||||
var qcChecks | |||||
let qcChecks; | |||||
if (id) { | if (id) { | ||||
result = await fetchEquipment(id); | result = await fetchEquipment(id); | ||||
const equipment = result | |||||
console.log(equipment) | |||||
const equipment = result; | |||||
console.log(equipment); | |||||
defaultValues = { | defaultValues = { | ||||
id: equipment?.id, | id: equipment?.id, | ||||
code: equipment?.code, | code: equipment?.code, | ||||
name: equipment?.name, | name: equipment?.name, | ||||
description: equipment?.description, | description: equipment?.description, | ||||
equipmentTypeId: equipment?.equipmentTypeId ?? equipment?.equipmentType?.id, | |||||
equipmentTypeId: equipment?.equipmentTypeId, | |||||
}; | }; | ||||
} | } | ||||
return ( | return ( | ||||
<CreateEquipment | |||||
isEditMode={Boolean(id)} | |||||
defaultValues={defaultValues} | |||||
/> | |||||
<CreateEquipment isEditMode={Boolean(id)} defaultValues={defaultValues} /> | |||||
); | ); | ||||
}; | }; | ||||
CreateEquipmentWrapper.Loading = CreateEquipmentLoading; | CreateEquipmentWrapper.Loading = CreateEquipmentLoading; | ||||
@@ -26,10 +26,10 @@ type Props = { | |||||
// type: TypeEnum; | // type: TypeEnum; | ||||
isEditMode: boolean; | isEditMode: boolean; | ||||
// type: TypeEnum; | // type: TypeEnum; | ||||
defaultValues: Partial<CreateEquipmentInputs> | undefined; | |||||
defaultValues?: Partial<CreateEquipmentInputs> | undefined; | |||||
}; | }; | ||||
const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
const ProductDetails: React.FC<Props> = ({ isEditMode }) => { | |||||
const { | const { | ||||
t, | t, | ||||
i18n: { language }, | i18n: { language }, | ||||
@@ -99,7 +99,8 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
// [] | // [] | ||||
// ); | // ); | ||||
const handleCancel = () => { | const handleCancel = () => { | ||||
router.replace(`/settings/equipment`); | |||||
// router.replace(`/settings/equipment`); | |||||
console.log("cancel"); | |||||
}; | }; | ||||
return ( | return ( | ||||
<Card sx={{ display: "block" }}> | <Card sx={{ display: "block" }}> | ||||
@@ -139,8 +140,7 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
helperText={errors.code?.message} | helperText={errors.code?.message} | ||||
/> | /> | ||||
</Grid> | </Grid> | ||||
*/ | |||||
} | |||||
*/} | |||||
<Grid item xs={6}> | <Grid item xs={6}> | ||||
<TextField | <TextField | ||||
label={t("description")} | label={t("description")} | ||||
@@ -150,32 +150,37 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
</Grid> | </Grid> | ||||
<Grid item xs={12}> | <Grid item xs={12}> | ||||
<Stack direction="row" justifyContent="flex-start" spacing={2} sx={{ mt: 2 }}> | |||||
<Button | |||||
name="submit" | |||||
variant="contained" | |||||
startIcon={<Check />} | |||||
type="submit" | |||||
// disabled={submitDisabled} | |||||
> | |||||
{isEditMode ? t("Save") : t("Confirm")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<Close />} | |||||
onClick={handleCancel} | |||||
> | |||||
{t("Cancel")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<RestartAlt />} | |||||
onClick={() => reset()} | |||||
> | |||||
{t("Reset")} | |||||
</Button> | |||||
</Stack> | |||||
</Grid> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="flex-start" | |||||
spacing={2} | |||||
sx={{ mt: 2 }} | |||||
> | |||||
<Button | |||||
name="submit" | |||||
variant="contained" | |||||
startIcon={<Check />} | |||||
type="submit" | |||||
// disabled={submitDisabled} | |||||
> | |||||
{isEditMode ? t("Save") : t("Confirm")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<Close />} | |||||
onClick={handleCancel} | |||||
> | |||||
{t("Cancel")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<RestartAlt />} | |||||
onClick={() => reset()} | |||||
> | |||||
{t("Reset")} | |||||
</Button> | |||||
</Stack> | |||||
</Grid> | |||||
{/* <Grid item xs={6}> | {/* <Grid item xs={6}> | ||||
<InputDataGrid<CreateItemInputs, EntryError> | <InputDataGrid<CreateItemInputs, EntryError> | ||||
_formKey={"type"} | _formKey={"type"} | ||||
@@ -1,5 +1,5 @@ | |||||
import { InputBaseComponentProps } from "@mui/material"; | import { InputBaseComponentProps } from "@mui/material"; | ||||
export var NumberInputProps: InputBaseComponentProps = { | export var NumberInputProps: InputBaseComponentProps = { | ||||
step: 0.01, | |||||
}; | |||||
step: 0.01, | |||||
}; |
@@ -1 +1 @@ | |||||
export { default } from "./CreateEquipmentWrapper"; | |||||
export { default } from "./CreateEquipmentWrapper"; |
@@ -14,7 +14,16 @@ import { | |||||
useForm, | useForm, | ||||
} from "react-hook-form"; | } from "react-hook-form"; | ||||
import { deleteDialog } from "../Swal/CustomAlerts"; | import { deleteDialog } from "../Swal/CustomAlerts"; | ||||
import { Box, Button, Grid, Stack, Tab, Tabs, TabsProps, Typography } from "@mui/material"; | |||||
import { | |||||
Box, | |||||
Button, | |||||
Grid, | |||||
Stack, | |||||
Tab, | |||||
Tabs, | |||||
TabsProps, | |||||
Typography, | |||||
} from "@mui/material"; | |||||
import { Check, Close, EditNote } from "@mui/icons-material"; | import { Check, Close, EditNote } from "@mui/icons-material"; | ||||
import { TypeEnum } from "@/app/utils/typeEnum"; | import { TypeEnum } from "@/app/utils/typeEnum"; | ||||
import EquipmentTypeDetails from "./EquipmentTypeDetails"; | import EquipmentTypeDetails from "./EquipmentTypeDetails"; | ||||
@@ -33,31 +42,30 @@ const CreateItem: React.FC<Props> = ({ | |||||
isEditMode, | isEditMode, | ||||
// type, | // type, | ||||
defaultValues, | defaultValues, | ||||
}) => { | }) => { | ||||
// console.log(type) | // console.log(type) | ||||
const apiRef = useGridApiRef(); | const apiRef = useGridApiRef(); | ||||
const params = useSearchParams() | |||||
console.log(params.get("id")) | |||||
const params = useSearchParams(); | |||||
console.log(params.get("id")); | |||||
const [serverError, setServerError] = useState(""); | const [serverError, setServerError] = useState(""); | ||||
const [tabIndex, setTabIndex] = useState(0); | const [tabIndex, setTabIndex] = useState(0); | ||||
const { t } = useTranslation("common"); | const { t } = useTranslation("common"); | ||||
const router = useRouter(); | const router = useRouter(); | ||||
const title = "Equipment Type" | |||||
const title = "Equipment Type"; | |||||
const [mode, redirPath] = useMemo(() => { | const [mode, redirPath] = useMemo(() => { | ||||
// var typeId = TypeEnum.CONSUMABLE_ID | // var typeId = TypeEnum.CONSUMABLE_ID | ||||
var title = ""; | |||||
var mode = ""; | |||||
var redirPath = ""; | |||||
let title = ""; | |||||
let mode = ""; | |||||
let redirPath = ""; | |||||
// if (type === TypeEnum.MATERIAL) { | // if (type === TypeEnum.MATERIAL) { | ||||
// typeId = TypeEnum.MATERIAL_ID | // typeId = TypeEnum.MATERIAL_ID | ||||
// title = "Material"; | // title = "Material"; | ||||
// redirPath = "/settings/material"; | // redirPath = "/settings/material"; | ||||
// } | // } | ||||
// if (type === TypeEnum.PRODUCT) { | // if (type === TypeEnum.PRODUCT) { | ||||
// typeId = TypeEnum.PRODUCT_ID | |||||
title = "Equipment Type"; | |||||
redirPath = "/settings/equipmentType"; | |||||
// typeId = TypeEnum.PRODUCT_ID | |||||
title = "Equipment Type"; | |||||
redirPath = "/settings/equipmentType"; | |||||
// } | // } | ||||
// if (type === TypeEnum.BYPRODUCT) { | // if (type === TypeEnum.BYPRODUCT) { | ||||
// typeId = TypeEnum.BYPRODUCT_ID | // typeId = TypeEnum.BYPRODUCT_ID | ||||
@@ -73,8 +81,7 @@ const CreateItem: React.FC<Props> = ({ | |||||
}, [isEditMode]); | }, [isEditMode]); | ||||
// console.log(typeId) | // console.log(typeId) | ||||
const formProps = useForm<CreateEquipmentTypeInputs>({ | const formProps = useForm<CreateEquipmentTypeInputs>({ | ||||
defaultValues: defaultValues ? defaultValues : { | |||||
}, | |||||
defaultValues: defaultValues ? defaultValues : {}, | |||||
}); | }); | ||||
const errors = formProps.formState.errors; | const errors = formProps.formState.errors; | ||||
@@ -90,8 +97,8 @@ const CreateItem: React.FC<Props> = ({ | |||||
}; | }; | ||||
const onSubmit = useCallback<SubmitHandler<CreateEquipmentTypeInputs & {}>>( | const onSubmit = useCallback<SubmitHandler<CreateEquipmentTypeInputs & {}>>( | ||||
async (data, event) => { | async (data, event) => { | ||||
let hasErrors = false; | |||||
console.log(errors) | |||||
const hasErrors = false; | |||||
console.log(errors); | |||||
// console.log(apiRef.current.getCellValue(2, "lowerLimit")) | // console.log(apiRef.current.getCellValue(2, "lowerLimit")) | ||||
// apiRef.current. | // apiRef.current. | ||||
try { | try { | ||||
@@ -102,24 +109,25 @@ const CreateItem: React.FC<Props> = ({ | |||||
console.log("data posted"); | console.log("data posted"); | ||||
console.log(data); | console.log(data); | ||||
// TODO: | |||||
// TODO: | |||||
// 1. check field ( directly modify col def / check here ) | // 1. check field ( directly modify col def / check here ) | ||||
// 2. set error change tab index | // 2. set error change tab index | ||||
// return | // return | ||||
// do api | // do api | ||||
console.log("asdad") | |||||
var responseI = await saveEquipmentType(data); | |||||
console.log("asdad") | |||||
console.log("asdad"); | |||||
const responseI = await saveEquipmentType(data); | |||||
console.log("asdad"); | |||||
// var responseQ = await saveItemQcChecks(qcCheck) | // var responseQ = await saveItemQcChecks(qcCheck) | ||||
if (responseI) { | if (responseI) { | ||||
if (!Boolean(responseI.id)) { | if (!Boolean(responseI.id)) { | ||||
formProps.setError(responseI.errorPosition!! as keyof CreateEquipmentTypeInputs, { | |||||
message: responseI.message!!, | |||||
type: "required", | |||||
}) | |||||
formProps.setError( | |||||
responseI.errorPosition! as keyof CreateEquipmentTypeInputs, | |||||
{ | |||||
message: responseI.message!, | |||||
type: "required", | |||||
}, | |||||
); | |||||
} else if (Boolean(responseI.id)) { | } else if (Boolean(responseI.id)) { | ||||
router.replace(redirPath); | router.replace(redirPath); | ||||
} | } | ||||
@@ -130,14 +138,13 @@ const CreateItem: React.FC<Props> = ({ | |||||
console.log(e); | console.log(e); | ||||
} | } | ||||
}, | }, | ||||
[apiRef, router, t] | |||||
[apiRef, router, t], | |||||
); | ); | ||||
// multiple tabs | // multiple tabs | ||||
const onSubmitError = useCallback<SubmitErrorHandler<CreateEquipmentTypeInputs>>( | |||||
(errors) => {}, | |||||
[] | |||||
); | |||||
const onSubmitError = useCallback< | |||||
SubmitErrorHandler<CreateEquipmentTypeInputs> | |||||
>((errors) => {}, []); | |||||
return ( | return ( | ||||
<> | <> | ||||
@@ -147,21 +154,25 @@ const CreateItem: React.FC<Props> = ({ | |||||
component="form" | component="form" | ||||
onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} | onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} | ||||
> | > | ||||
<Grid> | |||||
<Typography mb={2} variant="h4"> | |||||
{t(`${mode} ${title}`)} | |||||
</Typography> | |||||
</Grid> | |||||
<Tabs value={tabIndex} onChange={handleTabChange} variant="scrollable"> | |||||
<Tab label={t("Equipment Type Details")} iconPosition="end"/> | |||||
{/* <Tab label={t("Qc items")} iconPosition="end" /> */} | |||||
</Tabs> | |||||
<Grid> | |||||
<Typography mb={2} variant="h4"> | |||||
{t(`${mode} ${title}`)} | |||||
</Typography> | |||||
</Grid> | |||||
<Tabs | |||||
value={tabIndex} | |||||
onChange={handleTabChange} | |||||
variant="scrollable" | |||||
> | |||||
<Tab label={t("Equipment Type Details")} iconPosition="end" /> | |||||
{/* <Tab label={t("Qc items")} iconPosition="end" /> */} | |||||
</Tabs> | |||||
{serverError && ( | {serverError && ( | ||||
<Typography variant="body2" color="error" alignSelf="flex-end"> | <Typography variant="body2" color="error" alignSelf="flex-end"> | ||||
{serverError} | {serverError} | ||||
</Typography> | </Typography> | ||||
)} | )} | ||||
{tabIndex === 0 && <EquipmentTypeDetails isEditMode={isEditMode} />} | |||||
{tabIndex === 0 && <EquipmentTypeDetails isEditMode={isEditMode} />} | |||||
{/* {tabIndex === 1 && <QcDetails apiRef={apiRef} />} */} | {/* {tabIndex === 1 && <QcDetails apiRef={apiRef} />} */} | ||||
{/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */} | {/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */} | ||||
{/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */} | {/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */} | ||||
@@ -23,7 +23,8 @@ export const CreateItemLoading: React.FC = () => { | |||||
</Stack> | </Stack> | ||||
</CardContent> | </CardContent> | ||||
</Card> | </Card> | ||||
<Card>CreateMaterial | |||||
<Card> | |||||
CreateMaterial | |||||
<CardContent> | <CardContent> | ||||
<Stack spacing={2}> | <Stack spacing={2}> | ||||
<Skeleton variant="rounded" height={40} /> | <Skeleton variant="rounded" height={40} /> | ||||
@@ -9,20 +9,21 @@ interface SubComponents { | |||||
} | } | ||||
type Props = { | type Props = { | ||||
id?: number | |||||
id?: number; | |||||
// type: TypeEnum; | // type: TypeEnum; | ||||
}; | }; | ||||
const CreateEquipmentTypeWrapper: React.FC<Props> & | |||||
SubComponents = async ({ id }) => { | |||||
var result | |||||
var defaultValues: Partial<CreateEquipmentTypeInputs> | undefined | |||||
const CreateEquipmentTypeWrapper: React.FC<Props> & SubComponents = async ({ | |||||
id, | |||||
}) => { | |||||
let result; | |||||
let defaultValues: Partial<CreateEquipmentTypeInputs> | undefined; | |||||
// console.log(type) | // console.log(type) | ||||
var qcChecks | |||||
let qcChecks; | |||||
if (id) { | if (id) { | ||||
result = await fetchEquipmentType(id); | result = await fetchEquipmentType(id); | ||||
const equipmentType = result | |||||
console.log(equipmentType) | |||||
const equipmentType = result; | |||||
console.log(equipmentType); | |||||
defaultValues = { | defaultValues = { | ||||
id: equipmentType?.id, | id: equipmentType?.id, | ||||
code: equipmentType?.code, | code: equipmentType?.code, | ||||
@@ -30,7 +31,7 @@ const CreateEquipmentTypeWrapper: React.FC<Props> & | |||||
description: equipmentType?.description, | description: equipmentType?.description, | ||||
}; | }; | ||||
} | } | ||||
return ( | return ( | ||||
<CreateEquipmentType | <CreateEquipmentType | ||||
isEditMode={Boolean(id)} | isEditMode={Boolean(id)} | ||||
@@ -26,10 +26,10 @@ type Props = { | |||||
// type: TypeEnum; | // type: TypeEnum; | ||||
isEditMode: boolean; | isEditMode: boolean; | ||||
// type: TypeEnum; | // type: TypeEnum; | ||||
defaultValues: Partial<CreateEquipmentTypeInputs> | undefined; | |||||
defaultValues?: Partial<CreateEquipmentTypeInputs> | undefined; | |||||
}; | }; | ||||
const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
const ProductDetails: React.FC<Props> = ({ isEditMode }) => { | |||||
const { | const { | ||||
t, | t, | ||||
i18n: { language }, | i18n: { language }, | ||||
@@ -99,7 +99,8 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
// [] | // [] | ||||
// ); | // ); | ||||
const handleCancel = () => { | const handleCancel = () => { | ||||
router.replace(`/settings/equipmentType`); | |||||
// router.replace(`/settings/equipmentType`); | |||||
console.log("cancel"); | |||||
}; | }; | ||||
return ( | return ( | ||||
<Card sx={{ display: "block" }}> | <Card sx={{ display: "block" }}> | ||||
@@ -132,8 +133,7 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
helperText={errors.code?.message} | helperText={errors.code?.message} | ||||
/> | /> | ||||
</Grid> | </Grid> | ||||
*/ | |||||
} | |||||
*/} | |||||
<Grid item xs={6}> | <Grid item xs={6}> | ||||
<TextField | <TextField | ||||
label={t("description")} | label={t("description")} | ||||
@@ -143,32 +143,37 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||||
</Grid> | </Grid> | ||||
<Grid item xs={12}> | <Grid item xs={12}> | ||||
<Stack direction="row" justifyContent="flex-start" spacing={2} sx={{ mt: 2 }}> | |||||
<Button | |||||
name="submit" | |||||
variant="contained" | |||||
startIcon={<Check />} | |||||
type="submit" | |||||
// disabled={submitDisabled} | |||||
> | |||||
{isEditMode ? t("Save") : t("Confirm")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<Close />} | |||||
onClick={handleCancel} | |||||
> | |||||
{t("Cancel")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<RestartAlt />} | |||||
onClick={() => reset()} | |||||
> | |||||
{t("Reset")} | |||||
</Button> | |||||
</Stack> | |||||
</Grid> | |||||
<Stack | |||||
direction="row" | |||||
justifyContent="flex-start" | |||||
spacing={2} | |||||
sx={{ mt: 2 }} | |||||
> | |||||
<Button | |||||
name="submit" | |||||
variant="contained" | |||||
startIcon={<Check />} | |||||
type="submit" | |||||
// disabled={submitDisabled} | |||||
> | |||||
{isEditMode ? t("Save") : t("Confirm")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<Close />} | |||||
onClick={handleCancel} | |||||
> | |||||
{t("Cancel")} | |||||
</Button> | |||||
<Button | |||||
variant="outlined" | |||||
startIcon={<RestartAlt />} | |||||
onClick={() => reset()} | |||||
> | |||||
{t("Reset")} | |||||
</Button> | |||||
</Stack> | |||||
</Grid> | |||||
{/* <Grid item xs={6}> | {/* <Grid item xs={6}> | ||||
<InputDataGrid<CreateItemInputs, EntryError> | <InputDataGrid<CreateItemInputs, EntryError> | ||||
_formKey={"type"} | _formKey={"type"} | ||||
@@ -1,5 +1,5 @@ | |||||
import { InputBaseComponentProps } from "@mui/material"; | import { InputBaseComponentProps } from "@mui/material"; | ||||
export var NumberInputProps: InputBaseComponentProps = { | export var NumberInputProps: InputBaseComponentProps = { | ||||
step: 0.01, | |||||
}; | |||||
step: 0.01, | |||||
}; |
@@ -1 +1 @@ | |||||
export { default } from "./CreateEquipmentTypeWrapper"; | |||||
export { default } from "./CreateEquipmentTypeWrapper"; |