Tekijä | SHA1 | Viesti | Päivämäärä |
---|---|---|---|
|
5c6e25f78f |
Merge branch 'master' of https://git.2fi-solutions.com/derek/FPSMS-frontend
# Conflicts: # src/components/DetailScheduleDetail/DetailInfoCard.tsx # src/components/DetailScheduleDetail/DetailScheudleDetailView.tsx |
1 kuukausi sitten |
|
3c5cb3f8b2 | eslint suggested spacing | 1 kuukausi sitten |
@@ -5,7 +5,7 @@ const withPWA = require("next-pwa")({ | |||
dest: "public", | |||
register: true, | |||
skipWaiting: true, | |||
disable: process.env.NODE_ENV === 'development' | |||
disable: process.env.NODE_ENV === "development", | |||
}); | |||
const nextConfig = { | |||
@@ -6,7 +6,8 @@ | |||
"dev": "next dev", | |||
"build": "next build", | |||
"start": "NODE_OPTIONS='--inspect' next start", | |||
"lint": "next lint" | |||
"lint": "next lint", | |||
"type-check": "tsc --noEmit" | |||
}, | |||
"dependencies": { | |||
"@emotion/cache": "^11.11.0", | |||
@@ -3,4 +3,4 @@ module.exports = { | |||
tailwindcss: {}, | |||
autoprefixer: {}, | |||
}, | |||
} | |||
}; |
@@ -1,38 +1,42 @@ | |||
"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 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 | |||
export const useAxios = () => { | |||
return useContext(AxiosContext); | |||
return useContext(AxiosContext); | |||
}; | |||
// Custom hook to manage access token | |||
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({ | |||
baseURL: process.env.API_URL, | |||
baseURL: process.env.API_URL, | |||
}); | |||
// Clear existing interceptors to prevent multiple registrations | |||
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) => { | |||
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 { SearchParams } from "@/app/utils/fetchUtil"; | |||
export const metadata: Metadata = { | |||
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"); | |||
return ( | |||
<I18nProvider namespaces={["dashboard", "common"]}> | |||
<Suspense fallback={<DashboardPage.Loading />}> | |||
<DashboardPage | |||
searchParams={searchParams} | |||
/> | |||
<DashboardPage searchParams={searchParams} /> | |||
</Suspense> | |||
</I18nProvider> | |||
) | |||
); | |||
}; | |||
export default Dashboard; |
@@ -1,36 +1,35 @@ | |||
// import DoSearch from "@/components/DoSearch"; | |||
// import { getServerI18n } from "@/i18n" | |||
import DoSearch from "../../../components/DoSearch"; | |||
import { getServerI18n } from "../../../i18n" | |||
import { getServerI18n } from "../../../i18n"; | |||
import { Stack, Typography } from "@mui/material"; | |||
import { I18nProvider } from "@/i18n"; | |||
import { Metadata } from "next"; | |||
import { Suspense } from "react"; | |||
export const metadata: Metadata = { | |||
title: "Delivery Order" | |||
} | |||
title: "Delivery Order", | |||
}; | |||
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"; | |||
export const metadata: Metadata = { | |||
title: "Inventory" | |||
} | |||
title: "Inventory", | |||
}; | |||
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 { AuthOptions, getServerSession } from "next-auth"; | |||
import { authOptions, SessionWithTokens } from "@/config/authConfig"; | |||
@@ -15,13 +14,14 @@ import SessionProviderWrapper from "@/components/SessionProviderWrapper/SessionP | |||
import QrCodeScannerProvider from "@/components/QrCodeScannerProvider/QrCodeScannerProvider"; | |||
import { I18nProvider } from "@/i18n"; | |||
export default async function MainLayout({ | |||
children, | |||
}: { | |||
children: React.ReactNode; | |||
}) { | |||
const session = await getServerSession<AuthOptions, SessionWithTokens>(authOptions); | |||
const session = await getServerSession<AuthOptions, SessionWithTokens>( | |||
authOptions, | |||
); | |||
if (!session?.user) { | |||
redirect("/login"); | |||
@@ -36,33 +36,33 @@ export default async function MainLayout({ | |||
return ( | |||
<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> | |||
</SessionProviderWrapper> | |||
); | |||
@@ -11,13 +11,11 @@ export const metadata: Metadata = { | |||
title: "Material Setting", | |||
}; | |||
type Props = { | |||
} & SearchParams | |||
type Props = {} & SearchParams; | |||
const material: React.FC<Props> = async ({ searchParams }) => { | |||
const { t } = await getServerI18n("material"); | |||
console.log(searchParams) | |||
console.log(searchParams); | |||
return ( | |||
<> | |||
<Stack | |||
@@ -37,7 +35,6 @@ const material: React.FC<Props> = async ({ searchParams }) => { | |||
> | |||
{t("Create Claim")} | |||
</Button> | |||
</Stack> | |||
{/* <Suspense fallback={<MaterialSearch.Loading />}> | |||
<MaterialSearch /> | |||
@@ -1,4 +1,4 @@ | |||
import { PreloadPickOrder } from "@/app/api/pickorder"; | |||
import { PreloadPickOrder } from "@/app/api/pickOrder"; | |||
import { SearchParams } from "@/app/utils/fetchUtil"; | |||
import PickOrderDetail from "@/components/PickOrderDetail"; | |||
import { getServerI18n, I18nProvider } from "@/i18n"; | |||
@@ -20,7 +20,7 @@ const PickOrder: React.FC<Props> = async ({ searchParams }) => { | |||
<> | |||
<I18nProvider namespaces={["pickOrder"]}> | |||
<Suspense fallback={<PickOrderDetail.Loading />}> | |||
<PickOrderDetail consoCode={`${searchParams["consoCode"]}`}/> | |||
<PickOrderDetail consoCode={`${searchParams["consoCode"]}`} /> | |||
</Suspense> | |||
</I18nProvider> | |||
</> | |||
@@ -1,4 +1,4 @@ | |||
import { PreloadPickOrder } from "@/app/api/pickorder"; | |||
import { PreloadPickOrder } from "@/app/api/pickOrder"; | |||
import PickOrderSearch from "@/components/PickOrderSearch"; | |||
import { getServerI18n } from "@/i18n"; | |||
import { I18nProvider } from "@/i18n"; | |||
@@ -7,33 +7,33 @@ import { Metadata } from "next"; | |||
import { Suspense } from "react"; | |||
export const metadata: Metadata = { | |||
title: "Pick Order" | |||
} | |||
title: "Pick Order", | |||
}; | |||
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 { I18nProvider, getServerI18n } from "@/i18n"; | |||
import { Typography } from "@mui/material"; | |||
import isString from "lodash/isString"; | |||
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 { getServerI18n, I18nProvider } from "../../../i18n"; | |||
import Add from "@mui/icons-material/Add"; | |||
@@ -30,11 +23,10 @@ const PurchaseOrder: React.FC = async () => { | |||
justifyContent="space-between" | |||
flexWrap="wrap" | |||
rowGap={2} | |||
> | |||
</Stack> | |||
<Suspense fallback={<PoSearch.Loading />}> | |||
<PoSearch /> | |||
</Suspense> | |||
></Stack> | |||
<Suspense fallback={<PoSearch.Loading />}> | |||
<PoSearch /> | |||
</Suspense> | |||
</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 { getServerI18n } from "../../../i18n"; | |||
@@ -22,7 +15,7 @@ export const metadata: Metadata = { | |||
const production: React.FC = async () => { | |||
const { t } = await getServerI18n("claims"); | |||
// preloadClaims(); | |||
// preloadClaims(); | |||
return ( | |||
<> | |||
@@ -44,9 +37,9 @@ const production: React.FC = async () => { | |||
{t("Create Claim")} | |||
</Button> | |||
</Stack> | |||
<Suspense fallback={<ClaimSearch.Loading />}> | |||
<ProductionProcess /> | |||
</Suspense> | |||
{/* <Suspense fallback={<ClaimSearch.Loading />}> */} | |||
<ProductionProcess /> | |||
{/* </Suspense> */} | |||
</> | |||
); | |||
}; | |||
@@ -8,7 +8,9 @@ export default async function NotFound() { | |||
return ( | |||
<Stack spacing={2}> | |||
<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"> | |||
{t("Return to all detail scheduling")} | |||
</Link> | |||
@@ -4,7 +4,10 @@ import { getServerI18n, I18nProvider } from "../../../../../i18n"; | |||
import Typography from "@mui/material/Typography"; | |||
// import { fetchQcItemDetails, preloadQcItem } from "@/app/api/settings/qcItem"; | |||
// import QcItemSave from "@/components/QcItemSave"; | |||
import { fetchQcItemDetails, preloadQcItem } from "../../../../../app/api/settings/qcItem"; | |||
import { | |||
fetchQcItemDetails, | |||
preloadQcItem, | |||
} from "../../../../../app/api/settings/qcItem"; | |||
import QcItemSave from "../../../../../components/QcItemSave"; | |||
import { isArray } from "lodash"; | |||
import { notFound } from "next/navigation"; | |||
@@ -14,39 +17,41 @@ import { ServerFetchError } from "../../../../../app/utils/fetchUtil"; | |||
import DetailScheduleDetail from "../../../../../components/DetailScheduleDetail"; | |||
export const metadata: Metadata = { | |||
title: "Qc Item", | |||
title: "Qc Item", | |||
}; | |||
interface Props { | |||
searchParams: { [key: string]: string | string[] | undefined }; | |||
searchParams: { [key: string]: string | string[] | undefined }; | |||
} | |||
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"; | |||
export const metadata: Metadata = { | |||
title: "Detail Scheduling", | |||
title: "Detail Scheduling", | |||
}; | |||
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; |
@@ -1,11 +1,11 @@ | |||
import { Metadata } from "next"; | |||
export const metadata: Metadata = { | |||
title: "Scheduling", | |||
title: "Scheduling", | |||
}; | |||
const Scheduling: React.FC = async () => { | |||
return null; | |||
return null; | |||
}; | |||
export default Scheduling; |
@@ -8,7 +8,9 @@ export default async function NotFound() { | |||
return ( | |||
<Stack spacing={2}> | |||
<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"> | |||
{t("Return to all scheduling")} | |||
</Link> | |||
@@ -15,42 +15,45 @@ import { notFound } from "next/navigation"; | |||
import { fetchProdScheduleDetail } from "@/app/api/scheduling"; | |||
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 { 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" | |||
startIcon={<Add />} | |||
LinkComponent={Link} | |||
@@ -58,14 +61,14 @@ const roughSchedulingDetail: React.FC<Props> = async ({ searchParams }) => { | |||
> | |||
{t("Create product")} | |||
</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; |
@@ -14,46 +14,46 @@ import Link from "next/link"; | |||
import { Suspense } from "react"; | |||
export const metadata: Metadata = { | |||
title: "Demand Forecast", | |||
title: "Demand Forecast", | |||
}; | |||
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" | |||
startIcon={<Add />} | |||
onClick={() => testingRoughSchedule} | |||
> | |||
{t("Test Rough Scheduling")} | |||
</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; |
@@ -41,8 +41,8 @@ const productSetting: React.FC = async () => { | |||
</Button> */} | |||
</Stack> | |||
<Suspense fallback={<EquipmentSearch.Loading />}> | |||
<I18nProvider namespaces={["common","project"]}> | |||
<EquipmentSearch /> | |||
<I18nProvider namespaces={["common", "project"]}> | |||
<EquipmentSearch /> | |||
</I18nProvider> | |||
</Suspense> | |||
</> | |||
@@ -41,8 +41,8 @@ const productSetting: React.FC = async () => { | |||
</Button> */} | |||
</Stack> | |||
<Suspense fallback={<EquipmentTypeSearch.Loading />}> | |||
<I18nProvider namespaces={["common","project"]}> | |||
<EquipmentTypeSearch /> | |||
<I18nProvider namespaces={["common", "project"]}> | |||
<EquipmentTypeSearch /> | |||
</I18nProvider> | |||
</Suspense> | |||
</> | |||
@@ -14,7 +14,7 @@ export const metadata: Metadata = { | |||
}; | |||
const productSetting: React.FC = async () => { | |||
const project = TypeEnum.PRODUCT | |||
const project = TypeEnum.PRODUCT; | |||
const { t } = await getServerI18n(project); | |||
// preloadClaims(); | |||
@@ -6,28 +6,27 @@ import React, { Suspense } from "react"; | |||
import { I18nProvider } from "@/i18n"; | |||
export const metadata: Metadata = { | |||
title: "Import Testing" | |||
} | |||
title: "Import Testing", | |||
}; | |||
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"; | |||
export const metadata: Metadata = { | |||
title: "Mail", | |||
title: "Mail", | |||
}; | |||
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"; | |||
export const metadata: Metadata = { | |||
title: "Qc Category", | |||
title: "Qc Category", | |||
}; | |||
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 ( | |||
<Stack spacing={2}> | |||
<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"> | |||
{t("Return to all qc items")} | |||
</Link> | |||
@@ -5,20 +5,22 @@ import { preloadQcItem } from "@/app/api/settings/qcItem"; | |||
import QcItemSave from "@/components/QcItemSave"; | |||
export const metadata: Metadata = { | |||
title: "Qc Item", | |||
title: "Qc Item", | |||
}; | |||
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 ( | |||
<Stack spacing={2}> | |||
<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"> | |||
{t("Return to all qc items")} | |||
</Link> | |||
@@ -8,42 +8,46 @@ import { notFound } from "next/navigation"; | |||
import { ServerFetchError } from "@/app/utils/fetchUtil"; | |||
export const metadata: Metadata = { | |||
title: "Qc Item", | |||
title: "Qc Item", | |||
}; | |||
interface Props { | |||
searchParams: { [key: string]: string | string[] | undefined }; | |||
searchParams: { [key: string]: string | string[] | undefined }; | |||
} | |||
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"; | |||
export const metadata: Metadata = { | |||
title: "Qc Item", | |||
title: "Qc Item", | |||
}; | |||
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 Link from "next/link"; | |||
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"; | |||
export const metadata: Metadata = { | |||
title: "Demand Forecast Setting", | |||
title: "Demand Forecast Setting", | |||
}; | |||
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" | |||
startIcon={<Add />} | |||
LinkComponent={Link} | |||
@@ -39,14 +38,14 @@ const roughScheduleSetting: React.FC = async () => { | |||
> | |||
{t("Create product")} | |||
</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; |
@@ -19,7 +19,7 @@ const CreateStaffPage: React.FC = async () => { | |||
<Typography variant="h4">{t("Create User")}</Typography> | |||
<I18nProvider namespaces={["user", "common"]}> | |||
<Suspense fallback={<CreateUser.Loading />}> | |||
<CreateUser/> | |||
<CreateUser /> | |||
</Suspense> | |||
</I18nProvider> | |||
</> | |||
@@ -12,7 +12,7 @@ export const metadata: Metadata = { | |||
title: "User Management", | |||
}; | |||
const User: React.FC = async() => { | |||
const User: React.FC = async () => { | |||
const { t } = await getServerI18n("user"); | |||
return ( | |||
<> | |||
@@ -15,21 +15,21 @@ export interface PostStockInLiineResponse<T> { | |||
id: number | null; | |||
name: string; | |||
code: string; | |||
type?: string | |||
type?: string; | |||
message: string | null; | |||
errorPosition: string | keyof T; | |||
entity: T | T[] | |||
entity: T | T[]; | |||
// entity: StockInLine | StockInLine[] | |||
} | |||
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 { | |||
@@ -37,37 +37,39 @@ export interface PurchaseQcResult { | |||
failQty: number; | |||
} | |||
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 { | |||
status: string | |||
acceptedQty: number | |||
status: string; | |||
acceptedQty: number; | |||
sampleRate: number; | |||
sampleWeight: number; | |||
totalWeight: number; | |||
qcResult: PurchaseQcResult[]; | |||
} | |||
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 | |||
} | |||
export interface PutawayInput { | |||
status: string | |||
acceptedQty: number | |||
warehouseId: number | |||
status: string; | |||
acceptedQty: number; | |||
warehouseId: number; | |||
// handler: string | |||
// 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) => { | |||
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) => { | |||
return serverFetchJson<StockInLine>(`${BASE_API_URL}/stockInLine/${stockInLineId}`, { | |||
return serverFetchJson<StockInLine>( | |||
`${BASE_API_URL}/stockInLine/${stockInLineId}`, | |||
{ | |||
next: { tags: ["stockInLine"] }, | |||
}); | |||
}, | |||
); | |||
}); | |||
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", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
// 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", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
// revalidateTag("po"); | |||
return stockInLine | |||
} | |||
return stockInLine; | |||
}; | |||
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"); | |||
return po | |||
} | |||
return po; | |||
}; | |||
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"); | |||
return po | |||
} | |||
return po; | |||
}; | |||
export const fetchPoInClient = cache(async (id: number) => { | |||
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) { | |||
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 { | |||
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"] }, | |||
}); | |||
} 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"] }, | |||
}); | |||
} | |||
}); | |||
}, | |||
); | |||
} | |||
}); |
@@ -8,74 +8,76 @@ import { Uom } from "../settings/uom"; | |||
import { RecordsRes } from "../utils"; | |||
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 { | |||
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 { | |||
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"] }, | |||
}); | |||
} 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"] }, | |||
}); | |||
}); | |||
} | |||
}); | |||
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"; | |||
export interface CreateConsoDoInput { | |||
ids: GridRowSelectionModel | |||
ids: GridRowSelectionModel; | |||
} |
@@ -5,20 +5,20 @@ import { BASE_API_URL } from "../../../config/api"; | |||
import { cache } from "react"; | |||
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 = () => { | |||
fetchDoList(); | |||
} | |||
fetchDoList(); | |||
}; | |||
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"; | |||
import { serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||
import { | |||
serverFetchJson, | |||
serverFetchWithNoContent, | |||
} from "@/app/utils/fetchUtil"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { revalidateTag } from "next/cache"; | |||
import { cache } from "react"; | |||
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 { | |||
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 { | |||
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"] }, | |||
}); | |||
}, | |||
); | |||
}); | |||
export const saveGroup = async (data: CreateGroupInputs) => { | |||
const newGroup = serverFetchJson(`${BASE_API_URL}/group/save`, { | |||
method: "POST", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
revalidateTag("group") | |||
return newGroup | |||
}; | |||
revalidateTag("group"); | |||
return newGroup; | |||
}; | |||
export const deleteGroup = async (id: number) => { | |||
const newGroup = serverFetchWithNoContent(`${BASE_API_URL}/group/${id}`, { | |||
method: "DELETE", | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
revalidateTag("group") | |||
return newGroup | |||
}; | |||
revalidateTag("group"); | |||
return newGroup; | |||
}; |
@@ -4,31 +4,30 @@ import { cache } from "react"; | |||
import "server-only"; | |||
export interface Records { | |||
records: UserGroupResult[] | |||
records: UserGroupResult[]; | |||
} | |||
export interface UserGroupResult { | |||
id: number; | |||
action: () => void; | |||
name: string; | |||
description: string; | |||
id: number; | |||
action: () => void; | |||
name: string; | |||
description: string; | |||
} | |||
export type IndivUserGroup = { | |||
authIds: number[]; | |||
data: any; | |||
userIds: number[]; | |||
} | |||
}; | |||
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) => { | |||
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"; | |||
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"; | |||
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 = () => { | |||
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 { Machine, Operator } from "."; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { revalidateTag } from "next/cache"; | |||
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> { | |||
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) => { | |||
const isExist = await serverFetchJson<IsOperatorExistResponse<Operator>>(`${BASE_API_URL}/jop/isOperatorExist`, { | |||
const isExist = await serverFetchJson<IsOperatorExistResponse<Operator>>( | |||
`${BASE_API_URL}/jop/isOperatorExist`, | |||
{ | |||
method: "POST", | |||
body: JSON.stringify({ username }), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
revalidateTag("po"); | |||
return isExist | |||
} | |||
}, | |||
); | |||
revalidateTag("po"); | |||
return isExist; | |||
}; | |||
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 { | |||
id: number; | |||
name: string; | |||
username: string; | |||
id: number; | |||
name: string; | |||
username: string; | |||
} | |||
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 { 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 { MailSetting, MailTemplate } from "."; | |||
export interface MailSave { | |||
settings: MailSetting[]; | |||
templates: MailTemplate[]; | |||
// template: MailTemplate; | |||
settings: MailSetting[]; | |||
templates: MailTemplate[]; | |||
// template: MailTemplate; | |||
} | |||
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 () => { | |||
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 () => { | |||
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 () => { | |||
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 () => { | |||
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"; | |||
export interface MailSMTP { | |||
host: string; | |||
port: number; | |||
username: string; | |||
password: string; | |||
host: string; | |||
port: number; | |||
username: string; | |||
password: string; | |||
} | |||
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 { | |||
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 { | |||
@@ -43,21 +43,21 @@ export interface MailTemplate { | |||
// } | |||
export const preloadMails = () => { | |||
fetchMailSetting(); | |||
fetchMailTemplates(); | |||
// fetchMailTimesheetTemplate(); | |||
fetchMailSetting(); | |||
fetchMailTemplates(); | |||
// fetchMailTimesheetTemplate(); | |||
}; | |||
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 () => { | |||
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 () => { | |||
@@ -5,22 +5,20 @@ | |||
import { serverFetchBlob } from "../../utils/fetchUtil"; | |||
import { BASE_API_URL } from "../../../config/api"; | |||
export interface FileResponse { | |||
filename: string; | |||
blobValue: Uint8Array; | |||
filename: string; | |||
blobValue: Uint8Array; | |||
} | |||
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 { QcItemResult } from "../settings/qcItem"; | |||
import { RecordsRes } from "../utils"; | |||
import { ConsoPickOrderResult, PickOrderLineWithSuggestedLot, PickOrderResult, PreReleasePickOrderSummary, StockOutLine } from "."; | |||
import { | |||
ConsoPickOrderResult, | |||
PickOrderLineWithSuggestedLot, | |||
PickOrderResult, | |||
PreReleasePickOrderSummary, | |||
StockOutLine, | |||
} from "."; | |||
import { PurchaseQcResult } from "../po/actions"; | |||
// import { BASE_API_URL } from "@/config/api"; | |||
export interface PostStockOutLiineResponse<T> { | |||
id: number | null; | |||
name: string; | |||
code: string; | |||
type?: string | |||
type?: string; | |||
message: string | null; | |||
errorPosition: string | keyof T; | |||
entity: T | T[] | |||
entity: T | T[]; | |||
} | |||
export interface ReleasePickOrderInputs { | |||
consoCode: string | |||
assignTo: number, | |||
consoCode: string; | |||
assignTo: number; | |||
} | |||
export interface CreateStockOutLine { | |||
consoCode: string, | |||
pickOrderLineId: number, | |||
inventoryLotLineId: number, | |||
qty: number, | |||
consoCode: string; | |||
pickOrderLineId: number; | |||
inventoryLotLineId: number; | |||
qty: number; | |||
} | |||
export interface UpdateStockOutLine { | |||
id: number, | |||
id: number; | |||
// 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? | |||
} | |||
export interface PickOrderQcInput { | |||
qty: number | |||
status: string | |||
qty: number; | |||
status: string; | |||
qcResult: PurchaseQcResult[]; | |||
} | |||
export interface PickOrderApprovalInput { | |||
allowQty: number | |||
rejectQty: number | |||
status: string | |||
allowQty: number; | |||
rejectQty: number; | |||
status: string; | |||
} | |||
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[]) => { | |||
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) { | |||
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 { | |||
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) { | |||
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 { | |||
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) { | |||
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 { | |||
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"] }, | |||
}); | |||
}); | |||
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", | |||
body: JSON.stringify(data), | |||
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", | |||
body: JSON.stringify(data), | |||
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", | |||
body: JSON.stringify(data), | |||
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", | |||
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"; | |||
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 { | |||
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 { | |||
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 { | |||
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 = { | |||
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 { | |||
consoCode: string | |||
pickOrders: Omit<PickOrderResult, "items">[] | |||
items: ByItemsSummary[] | |||
consoCode: string; | |||
pickOrders: Omit<PickOrderResult, "items">[]; | |||
items: ByItemsSummary[]; | |||
} | |||
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 = () => { | |||
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) => { | |||
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; | |||
name: string; | |||
code: string; | |||
type?: string | |||
type?: string; | |||
message: string | null; | |||
errorPosition: string | keyof T; | |||
entity: T | T[] | |||
entity: T | T[]; | |||
// entity: StockInLine | StockInLine[] | |||
} | |||
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 { | |||
@@ -37,37 +37,39 @@ export interface PurchaseQcResult { | |||
failQty: number; | |||
} | |||
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 { | |||
status: string | |||
acceptedQty: number | |||
status: string; | |||
acceptedQty: number; | |||
sampleRate: number; | |||
sampleWeight: number; | |||
totalWeight: number; | |||
qcResult: PurchaseQcResult[]; | |||
} | |||
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 | |||
} | |||
export interface PutawayInput { | |||
status: string | |||
acceptedQty: number | |||
warehouseId: number | |||
status: string; | |||
acceptedQty: number; | |||
warehouseId: number; | |||
// handler: string | |||
// 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) => { | |||
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) => { | |||
return serverFetchJson<StockInLine>(`${BASE_API_URL}/stockInLine/${stockInLineId}`, { | |||
return serverFetchJson<StockInLine>( | |||
`${BASE_API_URL}/stockInLine/${stockInLineId}`, | |||
{ | |||
next: { tags: ["stockInLine"] }, | |||
}); | |||
}, | |||
); | |||
}); | |||
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", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
// 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", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
// revalidateTag("po"); | |||
return stockInLine | |||
} | |||
return stockInLine; | |||
}; | |||
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"); | |||
return po | |||
} | |||
return po; | |||
}; | |||
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"); | |||
return po | |||
} | |||
return po; | |||
}; | |||
export const fetchPoInClient = cache(async (id: number) => { | |||
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) { | |||
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 { | |||
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"] }, | |||
}); | |||
} 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"] }, | |||
}); | |||
} | |||
}); | |||
}, | |||
); | |||
} | |||
}); |
@@ -8,74 +8,76 @@ import { Uom } from "../settings/uom"; | |||
import { RecordsRes } from "../utils"; | |||
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 { | |||
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 { | |||
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"] }, | |||
}); | |||
} 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"] }, | |||
}); | |||
}); | |||
} | |||
}); | |||
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 "."; | |||
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) => { | |||
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) => { | |||
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) => { | |||
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"; | |||
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) => { | |||
var url = `${BASE_API_URL}/qcCheck` | |||
if (itemId) url +=`/${itemId}` | |||
let url = `${BASE_API_URL}/qcCheck`; | |||
if (itemId) url += `/${itemId}`; | |||
return serverFetchJson<QcItemWithChecks[]>(url, { | |||
next: { tags: ["qc"] }, | |||
}); | |||
}); | |||
}); |
@@ -7,9 +7,9 @@ import { BASE_API_URL } from "../../../config/api"; | |||
export interface QrCodeInfo { | |||
// warehouse qrcode | |||
warehouseId?: number | |||
// item qrcode | |||
warehouseId?: number; | |||
// item qrcode | |||
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 { 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 "."; | |||
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 { | |||
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 { | |||
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) | |||
return serverFetchJson<ProdScheduleResultByPage>(`${BASE_API_URL}/productionSchedule/getRecordByPage?${params}`, { | |||
return serverFetchJson<ProdScheduleResultByPage>( | |||
`${BASE_API_URL}/productionSchedule/getRecordByPage?${params}`, | |||
{ | |||
method: "GET", | |||
headers: { "Content-Type": "application/json" }, | |||
next: { | |||
tags: ["prodSchedules"] | |||
} | |||
}) | |||
}) | |||
tags: ["prodSchedules"], | |||
}, | |||
}, | |||
); | |||
}, | |||
); | |||
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 () => { | |||
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 interface RoughProdScheduleResult { | |||
id: number; | |||
scheduleAt: number[]; | |||
schedulePeriod: number[]; | |||
schedulePeriodTo: number[]; | |||
totalEstProdCount: number; | |||
totalFGType: number; | |||
type: string; | |||
prodScheduleLinesByFg: RoughProdScheduleLineResultByFg[]; | |||
prodScheduleLinesByFgByDate: { [assignDate: number]: RoughProdScheduleLineResultByFg[] }; | |||
prodScheduleLinesByBom: RoughProdScheduleLineResultByBom[]; | |||
prodScheduleLinesByBomByDate: { [assignDate: number]: RoughProdScheduleLineResultByBomByDate[] }; | |||
id: number; | |||
scheduleAt: number[]; | |||
schedulePeriod: number[]; | |||
schedulePeriodTo: number[]; | |||
totalEstProdCount: number; | |||
totalFGType: number; | |||
type: string; | |||
prodScheduleLinesByFg: RoughProdScheduleLineResultByFg[]; | |||
prodScheduleLinesByFgByDate: { | |||
[assignDate: number]: RoughProdScheduleLineResultByFg[]; | |||
}; | |||
prodScheduleLinesByBom: RoughProdScheduleLineResultByBom[]; | |||
prodScheduleLinesByBomByDate: { | |||
[assignDate: number]: RoughProdScheduleLineResultByBomByDate[]; | |||
}; | |||
} | |||
export interface RoughProdScheduleLineResultByFg { | |||
id: number; | |||
code: string; | |||
name: string; | |||
type: string; | |||
availableQty: number; | |||
prodQty: number; | |||
lastMonthAvgSales: number; | |||
estCloseBal: number; | |||
priority: number; | |||
assignDate: number; | |||
bomMaterials: RoughProdScheduleLineBomMaterialResult[]; | |||
id: number; | |||
code: string; | |||
name: string; | |||
type: string; | |||
availableQty: number; | |||
prodQty: number; | |||
lastMonthAvgSales: number; | |||
estCloseBal: number; | |||
priority: number; | |||
assignDate: number; | |||
bomMaterials: RoughProdScheduleLineBomMaterialResult[]; | |||
} | |||
export interface RoughProdScheduleLineBomMaterialResult { | |||
id: number; | |||
code: string; | |||
name: string; | |||
type: string; | |||
availableQty: number; | |||
demandQty: number; | |||
uomName: string; | |||
id: number; | |||
code: string; | |||
name: string; | |||
type: string; | |||
availableQty: number; | |||
demandQty: number; | |||
uomName: string; | |||
} | |||
export interface RoughProdScheduleLineResultByBom { | |||
id: number, | |||
code: string, | |||
name: string, | |||
type: string, | |||
availableQty: number, | |||
totalDemandQty: number, | |||
demandQty1: number, | |||
demandQty2: number, | |||
demandQty3: number, | |||
demandQty4: number, | |||
demandQty5: number, | |||
demandQty6: number, | |||
demandQty7: number, | |||
uomName: string, | |||
id: number; | |||
code: string; | |||
name: string; | |||
type: string; | |||
availableQty: number; | |||
totalDemandQty: number; | |||
demandQty1: number; | |||
demandQty2: number; | |||
demandQty3: number; | |||
demandQty4: number; | |||
demandQty5: number; | |||
demandQty6: number; | |||
demandQty7: number; | |||
uomName: string; | |||
} | |||
export interface RoughProdScheduleLineResultByBomByDate { | |||
id: number, | |||
code: string, | |||
name: string, | |||
type: string, | |||
availableQty: number, | |||
demandQty: number, | |||
assignDate: number, | |||
uomName: string, | |||
id: number; | |||
code: string; | |||
name: string; | |||
type: string; | |||
availableQty: number; | |||
demandQty: number; | |||
assignDate: number; | |||
uomName: string; | |||
} | |||
export const fetchProdScheduleDetail = cache(async (id: number) => { | |||
return serverFetchJson<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"; | |||
import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||
import { | |||
ServerFetchError, | |||
serverFetchJson, | |||
serverFetchWithNoContent, | |||
} from "@/app/utils/fetchUtil"; | |||
import { revalidateTag } from "next/cache"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { CreateEquipmentTypeResponse } from "../../utils"; | |||
@@ -16,23 +20,23 @@ import { CreateEquipmentTypeResponse } from "../../utils"; | |||
// conversion: number | |||
// } | |||
export type CreateEquipmentInputs = { | |||
id?: string | number | |||
id?: string | number; | |||
code: string; | |||
name: string; | |||
description?: string | undefined; | |||
equipmentTypeId?: string | number | undefined; | |||
} | |||
}; | |||
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"; | |||
// import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | |||
export type EquipmentResult = { | |||
id: string | number | |||
id: string | number; | |||
code: string; | |||
name: string; | |||
description: string | undefined; | |||
equipmentTypeId: string | number | undefined; | |||
action?: any | |||
} | |||
action?: any; | |||
}; | |||
export type Result = { | |||
equipment: EquipmentResult | |||
} | |||
equipment: EquipmentResult; | |||
}; | |||
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) => { | |||
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"; | |||
import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||
import { | |||
ServerFetchError, | |||
serverFetchJson, | |||
serverFetchWithNoContent, | |||
} from "@/app/utils/fetchUtil"; | |||
import { revalidateTag } from "next/cache"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { CreateEquipmentTypeResponse } from "../../utils"; | |||
@@ -16,22 +20,22 @@ import { CreateEquipmentTypeResponse } from "../../utils"; | |||
// conversion: number | |||
// } | |||
export type CreateEquipmentTypeInputs = { | |||
id?: string | number | |||
id?: string | number; | |||
code: string; | |||
name: string; | |||
description?: string | undefined; | |||
} | |||
}; | |||
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"; | |||
// import { TypeInputs, UomInputs, WeightUnitInputs } from "./actions"; | |||
export type EquipmentTypeResult = { | |||
id: string | number | |||
id: string | number; | |||
code: string; | |||
name: string; | |||
description: string | undefined; | |||
action?: any | |||
} | |||
action?: any; | |||
}; | |||
export type Result = { | |||
equipmentType: EquipmentTypeResult | |||
} | |||
equipmentType: EquipmentTypeResult; | |||
}; | |||
export const fetchAllEquipmentTypes = cache(async () => { | |||
return serverFetchJson<EquipmentTypeResult[]>(`${BASE_API_URL}/EquipmentType`, { | |||
return serverFetchJson<EquipmentTypeResult[]>( | |||
`${BASE_API_URL}/EquipmentType`, | |||
{ | |||
next: { tags: ["equipmentTypes"] }, | |||
}); | |||
}); | |||
}, | |||
); | |||
}); | |||
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"; | |||
import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; | |||
import { | |||
ServerFetchError, | |||
serverFetchJson, | |||
serverFetchWithNoContent, | |||
} from "@/app/utils/fetchUtil"; | |||
import { revalidateTag } from "next/cache"; | |||
import { BASE_API_URL } from "@/config/api"; | |||
import { CreateItemResponse } from "../../utils"; | |||
@@ -18,28 +22,30 @@ import { QcChecksInputs } from "../qcCheck/actions"; | |||
// conversion: number | |||
// } | |||
export type CreateItemInputs = { | |||
id?: string | number | |||
id?: string | number; | |||
code: string; | |||
name: string; | |||
description?: string | undefined; | |||
remarks?: string | undefined; | |||
shelfLife?: Number | undefined; | |||
shelfLife?: number | undefined; | |||
countryOfOrigin?: string | undefined; | |||
maxQty: number; | |||
type: string; | |||
qcChecks: QcChecksInputs[] | |||
qcChecks_active: number[] | |||
} | |||
qcChecks: QcChecksInputs[]; | |||
qcChecks_active: number[]; | |||
}; | |||
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; | |||
upperLimit: number | undefined; | |||
isActive: boolean | undefined; | |||
} | |||
}; | |||
export type ItemsResultResponse = { | |||
records: ItemsResult[]; | |||
total: number; | |||
} | |||
}; | |||
export type ItemsResult = { | |||
id: string | number | |||
id: string | number; | |||
code: string; | |||
name: string; | |||
description: string | undefined; | |||
remarks: string | undefined; | |||
shelfLife: Number | undefined; | |||
shelfLife: number | undefined; | |||
countryOfOrigin: string | undefined; | |||
maxQty: number | undefined; | |||
type: string; | |||
qcChecks: ItemQc[] | |||
action?: any | |||
} | |||
qcChecks: ItemQc[]; | |||
action?: any; | |||
}; | |||
export type Result = { | |||
item: ItemsResult | |||
qcChecks: ItemQc[] | |||
} | |||
item: ItemsResult; | |||
qcChecks: ItemQc[]; | |||
}; | |||
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) => { | |||
return serverFetchJson<Result>(`${BASE_API_URL}/items/details/${id}`, { | |||
next: { tags: ["items"] }, | |||
}); | |||
}); | |||
}); |
@@ -6,60 +6,62 @@ import { serverFetchWithNoContent } from "../../../utils/fetchUtil"; | |||
import { BASE_API_URL } from "../../../../config/api"; | |||
export interface M18ImportPoForm { | |||
modifiedDateFrom: string, | |||
modifiedDateTo: string, | |||
modifiedDateFrom: string; | |||
modifiedDateTo: string; | |||
} | |||
export interface M18ImportDoForm { | |||
modifiedDateFrom: string, | |||
modifiedDateTo: string, | |||
modifiedDateFrom: string; | |||
modifiedDateTo: string; | |||
} | |||
export interface M18ImportPqForm { | |||
modifiedDateFrom: string, | |||
modifiedDateTo: string, | |||
modifiedDateFrom: string; | |||
modifiedDateTo: string; | |||
} | |||
export interface M18ImportMasterDataForm { | |||
modifiedDateFrom: string, | |||
modifiedDateTo: string, | |||
modifiedDateFrom: string; | |||
modifiedDateTo: string; | |||
} | |||
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) => { | |||
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) => { | |||
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) => { | |||
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 { BASE_API_URL } from "@/config/api"; | |||
export interface CreateQcCategoryInputs { | |||
code: string; | |||
name: string; | |||
code: string; | |||
name: string; | |||
} | |||
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"; | |||
export interface QcCategoryResult { | |||
id: number; | |||
code: string; | |||
name: string; | |||
id: number; | |||
code: string; | |||
name: string; | |||
} | |||
export const preloadQcCategory = () => { | |||
fetchQcCategories(); | |||
fetchQcCategories(); | |||
}; | |||
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 { ItemQc } from "../item"; | |||
export type QcChecksInputs = { | |||
} & Partial<ItemQc> | |||
export type QcChecksInputs = {} & Partial<ItemQc>; | |||
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 { BASE_API_URL } from "@/config/api"; | |||
@@ -7,43 +7,49 @@ import { BASE_API_URL } from "../../../../config/api"; | |||
import { revalidatePath, revalidateTag } from "next/cache"; | |||
//import { QcItemResult } from '@/app/api/settings/qcItem'; | |||
import { QcItemResult } from '../../../api/settings/qcItem'; | |||
import { QcItemResult } from "../../../api/settings/qcItem"; | |||
export interface SaveQcItemInputs { | |||
id?: number; | |||
code: string; | |||
name: string; | |||
description?: string; | |||
id?: number; | |||
code: string; | |||
name: string; | |||
description?: string; | |||
} | |||
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) => { | |||
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) => { | |||
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"; | |||
export interface QcItemResult { | |||
id: number; | |||
code: string; | |||
name: string; | |||
description: string; | |||
id: number; | |||
code: string; | |||
name: string; | |||
description: string; | |||
} | |||
export const preloadQcItem = () => { | |||
fetchQcItems(); | |||
fetchQcItems(); | |||
}; | |||
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) => { | |||
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"; | |||
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 { 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 { revalidateTag } from "next/cache"; | |||
import { UserDetail, UserResult } from "."; | |||
import { cache } from "react"; | |||
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 { | |||
password: string; | |||
newPassword: string; | |||
newPasswordCheck: string; | |||
password: string; | |||
newPassword: string; | |||
newPasswordCheck: string; | |||
} | |||
export interface NameList { | |||
id: number | |||
name: string | |||
id: number; | |||
name: string; | |||
} | |||
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 () => { | |||
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) => { | |||
const newUser = serverFetchWithNoContent(`${BASE_API_URL}/user/${id}`, { | |||
@@ -45,8 +48,8 @@ export const editUser = async (id: number, data: UserInputs) => { | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
revalidateTag("user") | |||
return newUser | |||
revalidateTag("user"); | |||
return newUser; | |||
}; | |||
export const createUser = async (data: UserInputs) => { | |||
@@ -55,8 +58,8 @@ export const createUser = async (data: UserInputs) => { | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
revalidateTag("user") | |||
return newUser | |||
revalidateTag("user"); | |||
return newUser; | |||
}; | |||
export const deleteUser = async (id: number) => { | |||
@@ -64,22 +67,25 @@ export const deleteUser = async (id: number) => { | |||
method: "DELETE", | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
revalidateTag("user") | |||
return newUser | |||
}; | |||
revalidateTag("user"); | |||
return newUser; | |||
}; | |||
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) => { | |||
return serverFetchWithNoContent(`${BASE_API_URL}/user/admin-change-password`, { | |||
return serverFetchWithNoContent( | |||
`${BASE_API_URL}/user/admin-change-password`, | |||
{ | |||
method: "PATCH", | |||
body: JSON.stringify(data), | |||
headers: { "Content-Type": "application/json" }, | |||
}); | |||
}; | |||
}, | |||
); | |||
}; |
@@ -4,11 +4,11 @@ import { cache } from "react"; | |||
import "server-only"; | |||
export interface UserResult { | |||
action: any; | |||
id: number; | |||
username: string; | |||
// name: string; | |||
} | |||
action: any; | |||
id: number; | |||
username: string; | |||
// name: string; | |||
} | |||
// export interface DetailedUser extends UserResult { | |||
// username: string; | |||
@@ -16,43 +16,43 @@ export interface UserResult { | |||
// } | |||
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; | |||
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"; | |||
export interface WarehouseResult { | |||
id: number | |||
code: string | |||
name: string | |||
description: string | |||
id: number; | |||
code: string; | |||
name: string; | |||
description: string; | |||
} | |||
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 { isEmpty } from "lodash"; | |||
@@ -8,19 +8,21 @@ export const downloadFile = (blobData: Uint8Array, filename: string) => { | |||
link.href = url; | |||
link.setAttribute("download", filename); | |||
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)) { | |||
return '' | |||
return ""; | |||
} | |||
const params = new URLSearchParams() | |||
const params = new URLSearchParams(); | |||
Object.entries(data).forEach(([key, 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"; | |||
export interface Pageable { | |||
pageSize?: number | |||
pageNum?: number | |||
pageSize?: number; | |||
pageNum?: number; | |||
} | |||
export type SearchParams = { | |||
searchParams: { [key: string]: string | string[] | undefined }; | |||
} | |||
}; | |||
export interface searchParamsProps { | |||
searchParams: { [key: string]: string | string[] | undefined }; | |||
@@ -66,19 +66,22 @@ type FetchParams = Parameters<typeof fetch>; | |||
export async function serverFetchJson<T>(...args: FetchParams) { | |||
const response = await serverFetch(...args); | |||
console.log(response.status) | |||
console.log(response.status); | |||
if (response.ok) { | |||
if (response.status === 204) { | |||
return response.status as T | |||
return response.status as T; | |||
} | |||
return response.json() as T; | |||
} else { | |||
switch (response.status) { | |||
case 401: | |||
signOutUser(); | |||
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 { 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", { | |||
minimumFractionDigits: 2, | |||
@@ -15,11 +23,9 @@ export const moneyFormatter = new Intl.NumberFormat("en-HK", { | |||
export const decimalFormatter = new Intl.NumberFormat("en-HK", { | |||
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"; | |||
@@ -28,71 +34,72 @@ export const OUTPUT_DATE_FORMAT = "YYYY/MM/DD"; | |||
export const OUTPUT_TIME_FORMAT = "HH:mm:ss"; | |||
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; | |||
if (isArray(arr) && every(arr, isValidNumber) && arr.length >= 3) { | |||
// [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)[]) => { | |||
return arrayToDayjs(arr).format(OUTPUT_DATE_FORMAT) | |||
} | |||
return arrayToDayjs(arr).format(OUTPUT_DATE_FORMAT); | |||
}; | |||
export const dateStringToDayjs = (date: string) => { | |||
// Format: YYYY/MM/DD | |||
return dayjs(date, OUTPUT_DATE_FORMAT) | |||
} | |||
return dayjs(date, OUTPUT_DATE_FORMAT); | |||
}; | |||
export const dateTimeStringToDayjs = (dateTime: string) => { | |||
// 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) => { | |||
return date.format(OUTPUT_DATE_FORMAT) | |||
} | |||
return date.format(OUTPUT_DATE_FORMAT); | |||
}; | |||
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 } = { | |||
"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 | |||
// after qc = completed | |||
"completed": 4, | |||
"rejected": 5, | |||
completed: 4, | |||
rejected: 5, | |||
}; | |||
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) => { | |||
return qty * (uom.unit2Qty || 1) * (uom.unit3Qty || 1) * (uom.unit4Qty || 1); | |||
} | |||
}; | |||
export const returnWeightUnit = (uom: Uom) => { | |||
return uom.unit4 || uom.unit3 || uom.unit2 || uom.unit1; | |||
} | |||
}; |
@@ -1,10 +1,10 @@ | |||
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", | |||
"MAINTAIN_USER", | |||
"VIEW_GROUP", | |||
"MAINTAIN_GROUP", | |||
] | |||
]; |
@@ -30,7 +30,7 @@ const pathToLabelMap: { [path: string]: string } = { | |||
const Breadcrumb = () => { | |||
const pathname = usePathname(); | |||
const segments = pathname.split("/"); | |||
const { t } = useTranslation("common") | |||
const { t } = useTranslation("common"); | |||
return ( | |||
<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, | |||
} from "react-hook-form"; | |||
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 { TypeEnum } from "@/app/utils/typeEnum"; | |||
import EquipmentDetails from "./EquipmentDetails"; | |||
@@ -33,31 +42,30 @@ const CreateItem: React.FC<Props> = ({ | |||
isEditMode, | |||
// type, | |||
defaultValues, | |||
}) => { | |||
// console.log(type) | |||
const apiRef = useGridApiRef(); | |||
const params = useSearchParams() | |||
console.log(params.get("id")) | |||
const params = useSearchParams(); | |||
console.log(params.get("id")); | |||
const [serverError, setServerError] = useState(""); | |||
const [tabIndex, setTabIndex] = useState(0); | |||
const { t } = useTranslation("common"); | |||
const router = useRouter(); | |||
const title = "Equipment" | |||
const title = "Equipment"; | |||
const [mode, redirPath] = useMemo(() => { | |||
// var typeId = TypeEnum.CONSUMABLE_ID | |||
var title = ""; | |||
var mode = ""; | |||
var redirPath = ""; | |||
let title = ""; | |||
let mode = ""; | |||
let redirPath = ""; | |||
// if (type === TypeEnum.MATERIAL) { | |||
// typeId = TypeEnum.MATERIAL_ID | |||
// title = "Material"; | |||
// redirPath = "/settings/material"; | |||
// } | |||
// if (type === TypeEnum.PRODUCT) { | |||
// typeId = TypeEnum.PRODUCT_ID | |||
title = "Equipment"; | |||
redirPath = "/settings/equipment"; | |||
// typeId = TypeEnum.PRODUCT_ID | |||
title = "Equipment"; | |||
redirPath = "/settings/equipment"; | |||
// } | |||
// if (type === TypeEnum.BYPRODUCT) { | |||
// typeId = TypeEnum.BYPRODUCT_ID | |||
@@ -73,8 +81,7 @@ const CreateItem: React.FC<Props> = ({ | |||
}, [isEditMode]); | |||
// console.log(typeId) | |||
const formProps = useForm<CreateEquipmentInputs>({ | |||
defaultValues: defaultValues ? defaultValues : { | |||
}, | |||
defaultValues: defaultValues ? defaultValues : {}, | |||
}); | |||
const errors = formProps.formState.errors; | |||
@@ -90,8 +97,8 @@ const CreateItem: React.FC<Props> = ({ | |||
}; | |||
const onSubmit = useCallback<SubmitHandler<CreateEquipmentInputs & {}>>( | |||
async (data, event) => { | |||
let hasErrors = false; | |||
console.log(errors) | |||
const hasErrors = false; | |||
console.log(errors); | |||
// console.log(apiRef.current.getCellValue(2, "lowerLimit")) | |||
// apiRef.current. | |||
try { | |||
@@ -102,24 +109,25 @@ const CreateItem: React.FC<Props> = ({ | |||
console.log("data posted"); | |||
console.log(data); | |||
// TODO: | |||
// TODO: | |||
// 1. check field ( directly modify col def / check here ) | |||
// 2. set error change tab index | |||
// return | |||
// 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) | |||
if (responseI) { | |||
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)) { | |||
router.replace(redirPath); | |||
} | |||
@@ -130,13 +138,13 @@ const CreateItem: React.FC<Props> = ({ | |||
console.log(e); | |||
} | |||
}, | |||
[apiRef, router, t] | |||
[apiRef, router, t], | |||
); | |||
// multiple tabs | |||
const onSubmitError = useCallback<SubmitErrorHandler<CreateEquipmentInputs>>( | |||
(errors) => {}, | |||
[] | |||
[], | |||
); | |||
return ( | |||
@@ -147,21 +155,25 @@ const CreateItem: React.FC<Props> = ({ | |||
component="form" | |||
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 && ( | |||
<Typography variant="body2" color="error" alignSelf="flex-end"> | |||
{serverError} | |||
</Typography> | |||
)} | |||
{tabIndex === 0 && <EquipmentDetails isEditMode={isEditMode} />} | |||
{tabIndex === 0 && <EquipmentDetails isEditMode={isEditMode} />} | |||
{/* {tabIndex === 1 && <QcDetails apiRef={apiRef} />} */} | |||
{/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */} | |||
{/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */} | |||
@@ -23,7 +23,8 @@ export const CreateItemLoading: React.FC = () => { | |||
</Stack> | |||
</CardContent> | |||
</Card> | |||
<Card>CreateMaterial | |||
<Card> | |||
CreateMaterial | |||
<CardContent> | |||
<Stack spacing={2}> | |||
<Skeleton variant="rounded" height={40} /> | |||
@@ -9,34 +9,32 @@ interface SubComponents { | |||
} | |||
type Props = { | |||
id?: number | |||
id?: number; | |||
// 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) | |||
var qcChecks | |||
let qcChecks; | |||
if (id) { | |||
result = await fetchEquipment(id); | |||
const equipment = result | |||
console.log(equipment) | |||
const equipment = result; | |||
console.log(equipment); | |||
defaultValues = { | |||
id: equipment?.id, | |||
code: equipment?.code, | |||
name: equipment?.name, | |||
description: equipment?.description, | |||
equipmentTypeId: equipment?.equipmentTypeId ?? equipment?.equipmentType?.id, | |||
equipmentTypeId: equipment?.equipmentTypeId, | |||
}; | |||
} | |||
return ( | |||
<CreateEquipment | |||
isEditMode={Boolean(id)} | |||
defaultValues={defaultValues} | |||
/> | |||
<CreateEquipment isEditMode={Boolean(id)} defaultValues={defaultValues} /> | |||
); | |||
}; | |||
CreateEquipmentWrapper.Loading = CreateEquipmentLoading; | |||
@@ -26,10 +26,10 @@ type Props = { | |||
// type: TypeEnum; | |||
isEditMode: boolean; | |||
// type: TypeEnum; | |||
defaultValues: Partial<CreateEquipmentInputs> | undefined; | |||
defaultValues?: Partial<CreateEquipmentInputs> | undefined; | |||
}; | |||
const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
const ProductDetails: React.FC<Props> = ({ isEditMode }) => { | |||
const { | |||
t, | |||
i18n: { language }, | |||
@@ -99,7 +99,8 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
// [] | |||
// ); | |||
const handleCancel = () => { | |||
router.replace(`/settings/equipment`); | |||
// router.replace(`/settings/equipment`); | |||
console.log("cancel"); | |||
}; | |||
return ( | |||
<Card sx={{ display: "block" }}> | |||
@@ -139,8 +140,7 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
helperText={errors.code?.message} | |||
/> | |||
</Grid> | |||
*/ | |||
} | |||
*/} | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("description")} | |||
@@ -150,32 +150,37 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
</Grid> | |||
<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}> | |||
<InputDataGrid<CreateItemInputs, EntryError> | |||
_formKey={"type"} | |||
@@ -1,5 +1,5 @@ | |||
import { InputBaseComponentProps } from "@mui/material"; | |||
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, | |||
} from "react-hook-form"; | |||
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 { TypeEnum } from "@/app/utils/typeEnum"; | |||
import EquipmentTypeDetails from "./EquipmentTypeDetails"; | |||
@@ -33,31 +42,30 @@ const CreateItem: React.FC<Props> = ({ | |||
isEditMode, | |||
// type, | |||
defaultValues, | |||
}) => { | |||
// console.log(type) | |||
const apiRef = useGridApiRef(); | |||
const params = useSearchParams() | |||
console.log(params.get("id")) | |||
const params = useSearchParams(); | |||
console.log(params.get("id")); | |||
const [serverError, setServerError] = useState(""); | |||
const [tabIndex, setTabIndex] = useState(0); | |||
const { t } = useTranslation("common"); | |||
const router = useRouter(); | |||
const title = "Equipment Type" | |||
const title = "Equipment Type"; | |||
const [mode, redirPath] = useMemo(() => { | |||
// var typeId = TypeEnum.CONSUMABLE_ID | |||
var title = ""; | |||
var mode = ""; | |||
var redirPath = ""; | |||
let title = ""; | |||
let mode = ""; | |||
let redirPath = ""; | |||
// if (type === TypeEnum.MATERIAL) { | |||
// typeId = TypeEnum.MATERIAL_ID | |||
// title = "Material"; | |||
// redirPath = "/settings/material"; | |||
// } | |||
// if (type === TypeEnum.PRODUCT) { | |||
// typeId = TypeEnum.PRODUCT_ID | |||
title = "Equipment Type"; | |||
redirPath = "/settings/equipmentType"; | |||
// typeId = TypeEnum.PRODUCT_ID | |||
title = "Equipment Type"; | |||
redirPath = "/settings/equipmentType"; | |||
// } | |||
// if (type === TypeEnum.BYPRODUCT) { | |||
// typeId = TypeEnum.BYPRODUCT_ID | |||
@@ -73,8 +81,7 @@ const CreateItem: React.FC<Props> = ({ | |||
}, [isEditMode]); | |||
// console.log(typeId) | |||
const formProps = useForm<CreateEquipmentTypeInputs>({ | |||
defaultValues: defaultValues ? defaultValues : { | |||
}, | |||
defaultValues: defaultValues ? defaultValues : {}, | |||
}); | |||
const errors = formProps.formState.errors; | |||
@@ -90,8 +97,8 @@ const CreateItem: React.FC<Props> = ({ | |||
}; | |||
const onSubmit = useCallback<SubmitHandler<CreateEquipmentTypeInputs & {}>>( | |||
async (data, event) => { | |||
let hasErrors = false; | |||
console.log(errors) | |||
const hasErrors = false; | |||
console.log(errors); | |||
// console.log(apiRef.current.getCellValue(2, "lowerLimit")) | |||
// apiRef.current. | |||
try { | |||
@@ -102,24 +109,25 @@ const CreateItem: React.FC<Props> = ({ | |||
console.log("data posted"); | |||
console.log(data); | |||
// TODO: | |||
// TODO: | |||
// 1. check field ( directly modify col def / check here ) | |||
// 2. set error change tab index | |||
// return | |||
// 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) | |||
if (responseI) { | |||
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)) { | |||
router.replace(redirPath); | |||
} | |||
@@ -130,14 +138,13 @@ const CreateItem: React.FC<Props> = ({ | |||
console.log(e); | |||
} | |||
}, | |||
[apiRef, router, t] | |||
[apiRef, router, t], | |||
); | |||
// multiple tabs | |||
const onSubmitError = useCallback<SubmitErrorHandler<CreateEquipmentTypeInputs>>( | |||
(errors) => {}, | |||
[] | |||
); | |||
const onSubmitError = useCallback< | |||
SubmitErrorHandler<CreateEquipmentTypeInputs> | |||
>((errors) => {}, []); | |||
return ( | |||
<> | |||
@@ -147,21 +154,25 @@ const CreateItem: React.FC<Props> = ({ | |||
component="form" | |||
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 && ( | |||
<Typography variant="body2" color="error" alignSelf="flex-end"> | |||
{serverError} | |||
</Typography> | |||
)} | |||
{tabIndex === 0 && <EquipmentTypeDetails isEditMode={isEditMode} />} | |||
{tabIndex === 0 && <EquipmentTypeDetails isEditMode={isEditMode} />} | |||
{/* {tabIndex === 1 && <QcDetails apiRef={apiRef} />} */} | |||
{/* {type === TypeEnum.MATERIAL && <MaterialDetails />} */} | |||
{/* {type === TypeEnum.BYPRODUCT && <ByProductDetails />} */} | |||
@@ -23,7 +23,8 @@ export const CreateItemLoading: React.FC = () => { | |||
</Stack> | |||
</CardContent> | |||
</Card> | |||
<Card>CreateMaterial | |||
<Card> | |||
CreateMaterial | |||
<CardContent> | |||
<Stack spacing={2}> | |||
<Skeleton variant="rounded" height={40} /> | |||
@@ -9,20 +9,21 @@ interface SubComponents { | |||
} | |||
type Props = { | |||
id?: number | |||
id?: number; | |||
// 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) | |||
var qcChecks | |||
let qcChecks; | |||
if (id) { | |||
result = await fetchEquipmentType(id); | |||
const equipmentType = result | |||
console.log(equipmentType) | |||
const equipmentType = result; | |||
console.log(equipmentType); | |||
defaultValues = { | |||
id: equipmentType?.id, | |||
code: equipmentType?.code, | |||
@@ -30,7 +31,7 @@ const CreateEquipmentTypeWrapper: React.FC<Props> & | |||
description: equipmentType?.description, | |||
}; | |||
} | |||
return ( | |||
<CreateEquipmentType | |||
isEditMode={Boolean(id)} | |||
@@ -26,10 +26,10 @@ type Props = { | |||
// type: TypeEnum; | |||
isEditMode: boolean; | |||
// type: TypeEnum; | |||
defaultValues: Partial<CreateEquipmentTypeInputs> | undefined; | |||
defaultValues?: Partial<CreateEquipmentTypeInputs> | undefined; | |||
}; | |||
const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
const ProductDetails: React.FC<Props> = ({ isEditMode }) => { | |||
const { | |||
t, | |||
i18n: { language }, | |||
@@ -99,7 +99,8 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
// [] | |||
// ); | |||
const handleCancel = () => { | |||
router.replace(`/settings/equipmentType`); | |||
// router.replace(`/settings/equipmentType`); | |||
console.log("cancel"); | |||
}; | |||
return ( | |||
<Card sx={{ display: "block" }}> | |||
@@ -132,8 +133,7 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
helperText={errors.code?.message} | |||
/> | |||
</Grid> | |||
*/ | |||
} | |||
*/} | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("description")} | |||
@@ -143,32 +143,37 @@ const ProductDetails: React.FC<Props> = ({isEditMode}) => { | |||
</Grid> | |||
<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}> | |||
<InputDataGrid<CreateItemInputs, EntryError> | |||
_formKey={"type"} | |||
@@ -1,5 +1,5 @@ | |||
import { InputBaseComponentProps } from "@mui/material"; | |||
export var NumberInputProps: InputBaseComponentProps = { | |||
step: 0.01, | |||
}; | |||
step: 0.01, | |||
}; |
@@ -1 +1 @@ | |||
export { default } from "./CreateEquipmentTypeWrapper"; | |||
export { default } from "./CreateEquipmentTypeWrapper"; |