diff --git a/src/app/(main)/inventory/page.tsx b/src/app/(main)/inventory/page.tsx index 5016aba..046d56a 100644 --- a/src/app/(main)/inventory/page.tsx +++ b/src/app/(main)/inventory/page.tsx @@ -1,6 +1,6 @@ import { preloadInventory } from "@/app/api/inventory"; import InventorySearch from "@/components/InventorySearch"; -import { getServerI18n } from "@/i18n"; +import { I18nProvider, getServerI18n } from "@/i18n"; import { Stack, Typography } from "@mui/material"; import { Metadata } from "next"; import { Suspense } from "react"; @@ -10,7 +10,7 @@ export const metadata: Metadata = { } const Inventory: React.FC = async () => { - const { t } = await getServerI18n("inventory") + const { t } = await getServerI18n("inventory", "common") preloadInventory() @@ -25,9 +25,11 @@ const Inventory: React.FC = async () => { {t("Inventory")} - }> - - + + }> + + + ; } diff --git a/src/app/api/inventory/index.ts b/src/app/api/inventory/index.ts index 5425b24..a7b0aca 100644 --- a/src/app/api/inventory/index.ts +++ b/src/app/api/inventory/index.ts @@ -11,9 +11,9 @@ export interface InventoryResult { qty: number; uomCode: string; uomUdfudesc: string; - germPerSmallestUnit: number; - qtyPerSmallestUnit: number; - smallestUnit: string; + // germPerSmallestUnit: number; + // qtyPerSmallestUnit: number; + // smallestUnit: string; price: number; currencyName: string; status: string; diff --git a/src/app/api/settings/m18ImportTesting/actions.ts b/src/app/api/settings/m18ImportTesting/actions.ts index 7d36be8..97de637 100644 --- a/src/app/api/settings/m18ImportTesting/actions.ts +++ b/src/app/api/settings/m18ImportTesting/actions.ts @@ -8,6 +8,11 @@ export interface M18ImportPoForm { modifiedDateTo: string, } +export interface M18ImportDoForm { + modifiedDateFrom: string, + modifiedDateTo: string, +} + export interface M18ImportPqForm { modifiedDateFrom: string, modifiedDateTo: string, @@ -20,6 +25,7 @@ export interface M18ImportMasterDataForm { export interface M18ImportTestingForm { po: M18ImportPoForm, + do: M18ImportDoForm, pq: M18ImportPqForm, masterData: M18ImportMasterDataForm, } @@ -32,6 +38,14 @@ export const testM18ImportPo = async (data: M18ImportPoForm) => { }) } +export const testM18ImportDo = async (data: M18ImportDoForm) => { + 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", diff --git a/src/components/InventorySearch/InventorySearch.tsx b/src/components/InventorySearch/InventorySearch.tsx index b50cf20..97eec7e 100644 --- a/src/components/InventorySearch/InventorySearch.tsx +++ b/src/components/InventorySearch/InventorySearch.tsx @@ -27,7 +27,7 @@ type SearchParamNames = keyof SearchQuery; const InventorySearch: React.FC = ({ inventories, }) => { - const { t } = useTranslation("inventories"); + const { t } = useTranslation(["inventory", "common"]); const [filteredInventories, setFilteredInventories] = useState(inventories) @@ -56,6 +56,9 @@ const InventorySearch: React.FC = ({ { name: "type", label: t("Type"), + renderCell: (params) => { + return t(params.type) + } }, { name: "qty", @@ -68,17 +71,17 @@ const InventorySearch: React.FC = ({ name: "uomUdfudesc", label: t("UoM"), }, - { - name: "qtyPerSmallestUnit", - label: t("Qty Per Smallest Unit"), - align: "right", - headerAlign: "right", - type: "decimal" - }, - { - name: "smallestUnit", - label: t("Smallest Unit"), - }, + // { + // name: "qtyPerSmallestUnit", + // label: t("Qty Per Smallest Unit"), + // align: "right", + // headerAlign: "right", + // type: "decimal" + // }, + // { + // name: "smallestUnit", + // label: t("Smallest Unit"), + // }, // { // name: "price", // label: t("Price"), diff --git a/src/components/M18ImportTesting/M18ImportDo.tsx b/src/components/M18ImportTesting/M18ImportDo.tsx new file mode 100644 index 0000000..d749c61 --- /dev/null +++ b/src/components/M18ImportTesting/M18ImportDo.tsx @@ -0,0 +1,126 @@ +"use client" +import { M18ImportTestingForm, M18ImportDoForm } from "@/app/api/settings/m18ImportTesting/actions"; +import { INPUT_DATE_FORMAT, OUTPUT_DATE_FORMAT, OUTPUT_TIME_FORMAT, dateTimeStringToDayjs } from "@/app/utils/formatUtil"; +import { Check } from "@mui/icons-material"; +import { Box, Button, Card, CardContent, FormControl, Grid, Stack, Typography } from "@mui/material"; +import { DatePicker, DateTimePicker, LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs, { Dayjs } from "dayjs"; +import React, { useCallback, useState } from "react"; +import { Controller, useFormContext } from "react-hook-form"; +import { useTranslation } from "react-i18next"; + +interface Props { +} + +const M18ImportDo: React.FC = ({ +}) => { + + const { t } = useTranslation() + const [isLoading, setIsLoading] = useState(false) + const { + control, + formState: { errors }, + watch + } = useFormContext() + + const handleDateTimePickerOnChange = useCallback((value: Dayjs | null, onChange: (value: any) => void) => { + const formattedValue = value ? value.format(`${INPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`) : null + onChange(formattedValue) + }, []) + + + + return ( + + + + + {t("Import Delivery Order")} + + + + + + // value && dateTimeStringToDayjs(value).isValid() ? true : "Invalid date-time" + // }, + // }} + render={({ field, fieldState: { error } }) => ( + (handleDateTimePickerOnChange(newValue, field.onChange))} + slotProps={{ + textField: { + error: !!error, + helperText: error ? error.message : null + } + }} + /> + )} + /> + + {"-"} + + + // value && dateTimeStringToDayjs(value).isValid() ? true : "Invalid date-time", + // isFuture: (value) => + // dateTimeStringToDayjs(value).isAfter(watch("do.dateFrom")) || "Date must be in the future", + // }, + // }} + render={({ field, fieldState: { error } }) => ( + (handleDateTimePickerOnChange(newValue, field.onChange))} + slotProps={{ + textField: { + error: !!error, + helperText: error ? error.message : null + } + }} + /> + )} + /> + + + + + + + + + + ) +} + +export default M18ImportDo; \ No newline at end of file diff --git a/src/components/M18ImportTesting/M18ImportTesting.tsx b/src/components/M18ImportTesting/M18ImportTesting.tsx index 7804f25..b7f060c 100644 --- a/src/components/M18ImportTesting/M18ImportTesting.tsx +++ b/src/components/M18ImportTesting/M18ImportTesting.tsx @@ -1,6 +1,6 @@ "use client" -import { M18ImportTestingForm, testM18ImportPo, M18ImportPoForm, testM18ImportPq, testM18ImportMasterData } from "@/app/api/settings/m18ImportTesting/actions"; +import { M18ImportTestingForm, testM18ImportPo, M18ImportPoForm, testM18ImportPq, testM18ImportMasterData, testM18ImportDo } from "@/app/api/settings/m18ImportTesting/actions"; import { Card, CardContent, Grid, Stack, Typography } from "@mui/material"; import React, { BaseSyntheticEvent, FormEvent, useCallback, useState } from "react"; import { FormProvider, SubmitErrorHandler, useForm } from "react-hook-form"; @@ -9,6 +9,7 @@ import M18ImportPo from "./M18ImportPo"; import M18ImportPq from "./M18ImportPq"; import { dateTimeStringToDayjs } from "@/app/utils/formatUtil"; import M18ImportMasterData from "./M18ImportMasterData"; +import M18ImportDo from "./M18ImportDo"; interface Props { @@ -20,6 +21,7 @@ const M18ImportTesting: React.FC = ({ const { t } = useTranslation() const [isLoading, setIsLoading] = useState(false) + const [loadingType, setLoadingType] = useState(null) const formProps = useForm() const onSubmit = useCallback(async (data: M18ImportTestingForm, event?: BaseSyntheticEvent) => { @@ -37,11 +39,11 @@ const M18ImportTesting: React.FC = ({ case "m18ImportMasterData": const mdDateFrom = data.masterData.modifiedDateFrom const mdDateTo = data.masterData.modifiedDateTo - if (!(!!mdDateFrom && dateTimeStringToDayjs(mdDateFrom).isValid())) { + if (!(!mdDateFrom || dateTimeStringToDayjs(mdDateFrom).isValid())) { formProps.setError("masterData.modifiedDateFrom", { message: "Invalid DateTime Format" }) } - if (!(!!mdDateTo && dateTimeStringToDayjs(mdDateTo).isValid())) { + if (!(!mdDateTo || dateTimeStringToDayjs(mdDateTo).isValid())) { formProps.setError("masterData.modifiedDateTo", { message: "Invalid DateTime Format" }) } @@ -50,6 +52,7 @@ const M18ImportTesting: React.FC = ({ } setIsLoading(() => true) + setLoadingType(() => "Master Data") const mdResponse = await testM18ImportMasterData(data.masterData) console.log(mdResponse) if (mdResponse) { @@ -72,20 +75,44 @@ const M18ImportTesting: React.FC = ({ } setIsLoading(() => true) - const poResponse = await testM18ImportMasterData(data.po) + setLoadingType(() => "Purchase Order") + const poResponse = await testM18ImportPo(data.po) console.log(poResponse) if (poResponse) { setIsLoading(() => false) } break; + case "m18ImportDo": + const doDateFrom = data.do.modifiedDateFrom + const doDateTo = data.do.modifiedDateTo + if (!(doDateFrom && dateTimeStringToDayjs(doDateFrom).isValid())) { + formProps.setError("do.modifiedDateFrom", { message: "Invalid DateTime Format" }) + } + + if (!(doDateTo && dateTimeStringToDayjs(doDateTo).isValid())) { + formProps.setError("do.modifiedDateTo", { message: "Invalid DateTime Format" }) + } + + if (formProps.formState.errors.do) { + return; + } + + setIsLoading(() => true) + setLoadingType(() => "Delivery Order") + const doResponse = await testM18ImportDo(data.po) + console.log(doResponse) + if (doResponse) { + setIsLoading(() => false) + } + break; case "m18ImportPq": const pqDateFrom = data.pq.modifiedDateFrom const pqDateTo = data.pq.modifiedDateTo - if (!(!!pqDateFrom && dateTimeStringToDayjs(pqDateFrom).isValid())) { + if (!(pqDateFrom || dateTimeStringToDayjs(pqDateFrom).isValid())) { formProps.setError("pq.modifiedDateFrom", { message: "Invalid DateTime Format" }) } - if (!(!!pqDateTo && dateTimeStringToDayjs(pqDateTo).isValid())) { + if (!(pqDateTo || dateTimeStringToDayjs(pqDateTo).isValid())) { formProps.setError("pq.modifiedDateTo", { message: "Invalid DateTime Format" }) } @@ -94,6 +121,7 @@ const M18ImportTesting: React.FC = ({ } setIsLoading(() => true) + setLoadingType(() => "Purchase Quotation") const pqResponse = await testM18ImportPq(data.pq) console.log(pqResponse) if (pqResponse) { @@ -115,7 +143,7 @@ const M18ImportTesting: React.FC = ({ return ( - {t("Status: ")}{isLoading ? t("Importing...") : t("Ready to import")} + {t("Status: ")}{isLoading ? t(`Importing ${loadingType}...`) : t("Ready to import")} = ({ + + + diff --git a/src/i18n/en/inventory.json b/src/i18n/en/inventory.json new file mode 100644 index 0000000..544b7b4 --- /dev/null +++ b/src/i18n/en/inventory.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/src/i18n/zh/common.json b/src/i18n/zh/common.json index 94bab53..724c87d 100644 --- a/src/i18n/zh/common.json +++ b/src/i18n/zh/common.json @@ -3,5 +3,8 @@ "All": "全部", "No options": "沒有選項", "Reset": "重置", - "Search": "搜尋" + "Search": "搜尋", + "Code": "編號", + "Name": "名稱", + "Type": "類型" } \ No newline at end of file diff --git a/src/i18n/zh/inventory.json b/src/i18n/zh/inventory.json new file mode 100644 index 0000000..1e5a6ce --- /dev/null +++ b/src/i18n/zh/inventory.json @@ -0,0 +1,11 @@ +{ + "Inventory": "存貨", + "Code": "編號", + "Name": "名稱", + "Type": "類型", + "Status": "狀態", + "Qty": "數量", + "UoM": "單位", + "mat": "物料", + "fg": "成品" +} \ No newline at end of file