Bläddra i källkod

update

master
MSI\derek 1 månad sedan
förälder
incheckning
3ffcb07882
14 ändrade filer med 727 tillägg och 54 borttagningar
  1. +3
    -3
      .env.production
  2. +0
    -10
      src/app/(main)/pickOrder/page.tsx
  3. +35
    -1
      src/app/api/pickOrder/actions.ts
  4. +1
    -1
      src/app/api/pickOrder/index.ts
  5. +15
    -1
      src/app/api/settings/item/actions.ts
  6. +1
    -1
      src/app/utils/commonUtil.ts
  7. +1
    -1
      src/app/utils/formatUtil.ts
  8. +318
    -0
      src/components/PickOrderSearch/CreateForm.tsx
  9. +98
    -0
      src/components/PickOrderSearch/CreatePickOrderModal.tsx
  10. +79
    -0
      src/components/PickOrderSearch/ItemSelect.tsx
  11. +73
    -12
      src/components/PickOrderSearch/PickOrderSearch.tsx
  12. +25
    -18
      src/components/PickOrderSearch/PickOrders.tsx
  13. +73
    -0
      src/components/PickOrderSearch/UomSelect.tsx
  14. +5
    -6
      src/components/PoSearch/PoSearch.tsx

+ 3
- 3
.env.production Visa fil

@@ -1,4 +1,4 @@
API_URL=http://localhost:8090/api
API_URL=http://10.100.0.81:8090/api
NEXTAUTH_SECRET=secret
NEXTAUTH_URL=https://fpsms-uat.2fi-solutions.com
NEXT_PUBLIC_API_URL=http://localhost:8090/api
NEXTAUTH_URL=http://10.100.0.81:3000
NEXT_PUBLIC_API_URL=http://10.100.0.81:8090/api

+ 0
- 10
src/app/(main)/pickOrder/page.tsx Visa fil

@@ -17,16 +17,6 @@ const PickOrder: React.FC = async () => {

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 />


+ 35
- 1
src/app/api/pickOrder/actions.ts Visa fil

@@ -15,6 +15,27 @@ import {
} from ".";
import { PurchaseQcResult } from "../po/actions";
// import { BASE_API_URL } from "@/config/api";

export interface SavePickOrderLineRequest {
itemId: number
qty: number
uomId: number
}

export interface SavePickOrderRequest {
type: string
targetDate: string
pickOrderLine: SavePickOrderLineRequest[]
}
export interface PostPickOrderResponse<T = null> {
id: number | null;
name: string;
code: string;
type?: string;
message: string | null;
errorPosition: string
entity?: T | T[];
}
export interface PostStockOutLiineResponse<T> {
id: number | null;
name: string;
@@ -22,7 +43,7 @@ export interface PostStockOutLiineResponse<T> {
type?: string;
message: string | null;
errorPosition: string | keyof T;
entity: T | T[];
entity: T | T[] | null;
}

export interface ReleasePickOrderInputs {
@@ -60,6 +81,19 @@ export interface PickOrderApprovalInput {
rejectQty: number;
status: string;
}
export const createPickOrder = async (data: SavePickOrderRequest) => {
console.log(data);
const po = await serverFetchJson<PostPickOrderResponse>(
`${BASE_API_URL}/pickOrder/create`,
{
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
},
);
revalidateTag("pickorder");
return po;
}

export const consolidatePickOrder = async (ids: number[]) => {
const pickOrder = await serverFetchJson<any>(


+ 1
- 1
src/app/api/pickOrder/index.ts Visa fil

@@ -13,7 +13,7 @@ export interface PickOrderResult {
id: number;
code: string;
consoCode?: string;
targetDate: number[];
targetDate: string;
completeDate?: number[];
type: string;
status: string;


+ 15
- 1
src/app/api/settings/item/actions.ts Visa fil

@@ -7,8 +7,9 @@ import {
import { revalidateTag } from "next/cache";
import { BASE_API_URL } from "@/config/api";
import { CreateItemResponse } from "../../utils";
import { ItemQc } from ".";
import { ItemQc, ItemsResult } from ".";
import { QcChecksInputs } from "../qcCheck/actions";
import { cache } from "react";

// export type TypeInputs = {
// id: number;
@@ -48,3 +49,16 @@ export const saveItem = async (data: CreateItemInputs) => {
revalidateTag("items");
return item;
};

export interface ItemCombo {
id: number,
label: string,
uomId: number,
uom: string,
}

export const fetchAllItemsInClient = cache(async () => {
return serverFetchJson<ItemCombo[]>(`${BASE_API_URL}/items/consumables`, {
next: { tags: ["items"] },
});
});

+ 1
- 1
src/app/utils/commonUtil.ts Visa fil

@@ -10,7 +10,7 @@ export const downloadFile = (blobData: Uint8Array, filename: string) => {
link.click();
};

export const convertObjToURLSearchParams = <T extends Object>(
export const convertObjToURLSearchParams = <T extends object>(
data?: T | null,
): string => {
if (isEmpty(data)) {


+ 1
- 1
src/app/utils/formatUtil.ts Visa fil

@@ -92,7 +92,7 @@ export const minutesToHoursMinutes = (minutes: number): string => {
finalMinStr = `1 ${defaultMinStr}`
}

let colon = finalHrStr.length > 0 && finalMinStr.length > 0 ? ":" : ""
const colon = finalHrStr.length > 0 && finalMinStr.length > 0 ? ":" : ""

return `${finalHrStr} ${colon} ${finalMinStr}`.trim()
}


+ 318
- 0
src/components/PickOrderSearch/CreateForm.tsx Visa fil

@@ -0,0 +1,318 @@
"use client";

import { PurchaseQcResult, PurchaseQCInput } from "@/app/api/po/actions";
import {
Autocomplete,
Box,
Card,
CardContent,
FormControl,
Grid,
Stack,
TextField,
Tooltip,
Typography,
} from "@mui/material";
import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import StyledDataGrid from "../StyledDataGrid";
import { useCallback, useEffect, useMemo, useState } from "react";
import {
GridColDef,
GridRowIdGetter,
GridRowModel,
useGridApiContext,
GridRenderCellParams,
GridRenderEditCellParams,
useGridApiRef,
} from "@mui/x-data-grid";
import InputDataGrid from "../InputDataGrid";
import { TableRow } from "../InputDataGrid/InputDataGrid";
import { GridEditInputCell } from "@mui/x-data-grid";
import { StockInLine } from "@/app/api/po";
import { INPUT_DATE_FORMAT, stockInLineStatusMap } from "@/app/utils/formatUtil";
import { fetchQcItemCheck, fetchQcResult } from "@/app/api/qc/actions";
import { QcItemWithChecks } from "@/app/api/qc";
import axios from "@/app/(main)/axios/axiosInstance";
import { NEXT_PUBLIC_API_URL } from "@/config/api";
import axiosInstance from "@/app/(main)/axios/axiosInstance";
import { SavePickOrderLineRequest, SavePickOrderRequest } from "@/app/api/pickOrder/actions";
import TwoLineCell from "../PoDetail/TwoLineCell";
import ItemSelect from "./ItemSelect";
import { ItemCombo } from "@/app/api/settings/item/actions";
import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import dayjs from "dayjs";

interface Props {
items: ItemCombo[];
// disabled: boolean;
}
type EntryError =
| {
[field in keyof SavePickOrderLineRequest]?: string;
}
| undefined;

type PolRow = TableRow<Partial<SavePickOrderLineRequest>, EntryError>;
// fetchQcItemCheck
const CreateForm: React.FC<Props> = ({ items }) => {
const {
t,
i18n: { language },
} = useTranslation("purchaseOrder");
const apiRef = useGridApiRef();
const {
formState: { errors, defaultValues, touchedFields },
watch,
control,
setValue,
} = useFormContext<SavePickOrderRequest>();
console.log(defaultValues);
const targetDate = watch("targetDate");
//// validate form
// const accQty = watch("acceptedQty");
// const validateForm = useCallback(() => {
// console.log(accQty);
// if (accQty > itemDetail.acceptedQty) {
// setError("acceptedQty", {
// message: `${t("acceptedQty must not greater than")} ${
// itemDetail.acceptedQty
// }`,
// type: "required",
// });
// }
// if (accQty < 1) {
// setError("acceptedQty", {
// message: t("minimal value is 1"),
// type: "required",
// });
// }
// if (isNaN(accQty)) {
// setError("acceptedQty", {
// message: t("value must be a number"),
// type: "required",
// });
// }
// }, [accQty]);

// useEffect(() => {
// clearErrors();
// validateForm();
// }, [clearErrors, validateForm]);

const columns = useMemo<GridColDef[]>(
() => [
{
field: "itemId",
headerName: t("Item"),
flex: 1,
editable: true,
valueFormatter(params) {
const row = params.id ? params.api.getRow<PolRow>(params.id) : null;
if (!row) {
return null;
}
const Item = items.find((q) => q.id === row.itemId);
return Item ? Item.label : t("Please select item");
},
renderCell(params: GridRenderCellParams<PolRow, number>) {
console.log(params.value);
return <TwoLineCell>{params.formattedValue}</TwoLineCell>;
},
renderEditCell(params: GridRenderEditCellParams<PolRow, number>) {
const errorMessage =
params.row._error?.[params.field as keyof SavePickOrderLineRequest];
console.log(errorMessage);
const content = (
// <></>
<ItemSelect
allItems={items}
value={params.row.itemId}
onItemSelect={async (itemId, uom, uomId) => {
console.log(uom)
await params.api.setEditCellValue({
id: params.id,
field: "itemId",
value: itemId,
});
await params.api.setEditCellValue({
id: params.id,
field: "uom",
value: uom
})
await params.api.setEditCellValue({
id: params.id,
field: "uomId",
value: uomId
})
}}
/>
);
return errorMessage ? (
<Tooltip title={errorMessage}>
<Box width="100%">{content}</Box>
</Tooltip>
) : (
content
);
},
},
{
field: "qty",
headerName: t("qty"),
flex: 1,
type: "number",
editable: true,
renderEditCell(params: GridRenderEditCellParams<PolRow>) {
const errorMessage =
params.row._error?.[params.field as keyof SavePickOrderLineRequest];
const content = <GridEditInputCell {...params} />;
return errorMessage ? (
<Tooltip title={t(errorMessage)}>
<Box width="100%">{content}</Box>
</Tooltip>
) : (
content
);
},
},
{
field: "uom",
headerName: t("uom"),
flex: 1,
editable: true,
// renderEditCell(params: GridRenderEditCellParams<PolRow>) {
// console.log(params.row)
// const errorMessage =
// params.row._error?.[params.field as keyof SavePickOrderLineRequest];
// const content = <GridEditInputCell {...params} />;
// return errorMessage ? (
// <Tooltip title={t(errorMessage)}>
// <Box width="100%">{content}</Box>
// </Tooltip>
// ) : (
// content
// );
// }
}
],
[items, t],
);
/// validate datagrid
const validation = useCallback(
(newRow: GridRowModel<PolRow>): EntryError => {
const error: EntryError = {};
const { itemId, qty } = newRow;
if (!itemId || itemId <= 0) {
error["itemId"] = t("select qc");
}
if (!qty || qty <= 0) {
error["qty"] = t("enter a qty");
}
return Object.keys(error).length > 0 ? error : undefined;
},
[],
);

const typeList = [
{
type: "Consumable"
}
]

const onChange = useCallback(
(event: React.SyntheticEvent, newValue: {type: string}) => {
console.log(newValue);
setValue("type", newValue.type);
},
[setValue],
);

return (
<Grid container justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={12}>
<Typography variant="h6" display="block" marginBlockEnd={1}>
{t("Pick Order Detail")}
</Typography>
</Grid>
<Grid
container
justifyContent="flex-start"
alignItems="flex-start"
spacing={2}
sx={{ mt: 0.5 }}
>
<Grid item xs={6} lg={6}>
<FormControl fullWidth>
<Autocomplete
disableClearable
fullWidth
getOptionLabel={(option) => option.type}
options={typeList}
onChange={onChange}
renderInput={(params) => <TextField {...params} label={t("type")}/>}
/>
</FormControl>
</Grid>
<Grid item xs={6}>
<Controller
control={control}
name="targetDate"
// rules={{ required: !Boolean(productionDate) }}
render={({ field }) => {
return (
<LocalizationProvider
dateAdapter={AdapterDayjs}
adapterLocale={`${language}-hk`}
>
<DatePicker
{...field}
sx={{ width: "100%" }}
label={t("targetDate")}
value={targetDate ? dayjs(targetDate) : undefined}
onChange={(date) => {
console.log(date);
if (!date) return;
console.log(date.format(INPUT_DATE_FORMAT));
setValue("targetDate", date.format(INPUT_DATE_FORMAT));
// field.onChange(date);
}}
inputRef={field.ref}
slotProps={{
textField: {
// required: true,
error: Boolean(errors.targetDate?.message),
helperText: errors.targetDate?.message,
},
}}
/>
</LocalizationProvider>
);
}}
/>
</Grid>
</Grid>
<Grid
container
justifyContent="flex-start"
alignItems="flex-start"
spacing={2}
sx={{ mt: 0.5 }}
>
<Grid item xs={12}>
<InputDataGrid<SavePickOrderRequest, SavePickOrderLineRequest, EntryError>
apiRef={apiRef}
checkboxSelection={false}
_formKey={"pickOrderLine"}
columns={columns}
validateRow={validation}
needAdd={true}
/>
</Grid>
</Grid>
</Grid>
);
};
export default CreateForm;

+ 98
- 0
src/components/PickOrderSearch/CreatePickOrderModal.tsx Visa fil

@@ -0,0 +1,98 @@
import { createPickOrder, SavePickOrderRequest } from "@/app/api/pickOrder/actions";
import { Box, Button, Modal, ModalProps, Stack } from "@mui/material";
import dayjs from "dayjs";
import arraySupport from "dayjs/plugin/arraySupport";
import { useCallback } from "react";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import CreateForm from "./CreateForm";
import { ItemCombo } from "@/app/api/settings/item/actions";
import { Check } from "@mui/icons-material";
dayjs.extend(arraySupport);

const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
overflow: "scroll",
bgcolor: "background.paper",
pt: 5,
px: 5,
pb: 10,
display: "block",
width: { xs: "60%", sm: "60%", md: "60%" },
};

interface Props extends Omit<ModalProps, "children"> {
items: ItemCombo[]
}

const CreatePickOrderModal: React.FC<Props> = ({
open,
onClose,
items
}) => {
const { t } = useTranslation("pickOrder");
const formProps = useForm<SavePickOrderRequest>();
const errors = formProps.formState.errors;
const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
(...args) => {
onClose?.(...args);
// reset();
},
[onClose]
);
const onSubmit = useCallback<SubmitHandler<SavePickOrderRequest>>(
async (data, event) => {
console.log(data)
try {
const res = await createPickOrder(data)
if (res.id) {
closeHandler({}, "backdropClick");
}
} catch (error) {
console.log(error)
throw error
}
// formProps.reset()
},
[closeHandler]
);
return (
<>
<FormProvider {...formProps}>
<Modal open={open} onClose={closeHandler} sx={{ overflowY: "scroll" }}>
<Box
sx={style}
component="form"
onSubmit={formProps.handleSubmit(onSubmit)}
>
<CreateForm
items={items}
/>
<Stack direction="row" justifyContent="flex-end" gap={1}>
<Button
name="submit"
variant="contained"
startIcon={<Check />}
type="submit"
>
{t("submit")}
</Button>
<Button
name="reset"
variant="contained"
startIcon={<Check />}
onClick={() => formProps.reset()}
>
{t("reset")}
</Button>
</Stack>
</Box>
</Modal>
</FormProvider>
</>
);
};
export default CreatePickOrderModal;

+ 79
- 0
src/components/PickOrderSearch/ItemSelect.tsx Visa fil

@@ -0,0 +1,79 @@

import { ItemCombo } from "@/app/api/settings/item/actions";
import { Autocomplete, TextField } from "@mui/material";
import { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";

interface CommonProps {
allItems: ItemCombo[];
error?: boolean;
}

interface SingleAutocompleteProps extends CommonProps {
value: number | string | undefined;
onItemSelect: (itemId: number, uom: string, uomId: number) => void | Promise<void>;
// multiple: false;
}

type Props = SingleAutocompleteProps;

const ItemSelect: React.FC<Props> = ({
allItems,
value,
error,
onItemSelect
}) => {
const { t } = useTranslation("item");
const filteredItems = useMemo(() => {
return allItems
}, [allItems])

const options = useMemo(() => {
return [
{
value: -1, // think think sin
label: t("None"),
uom: "",
uomId: -1,
group: "default",
},
...filteredItems.map((i) => ({
value: i.id as number,
label: i.label,
uom: i.uom,
uomId: i.uomId,
group: "existing",
})),
];
}, [t, filteredItems]);

const currentValue = options.find((o) => o.value === value) || options[0];

const onChange = useCallback(
(
event: React.SyntheticEvent,
newValue: { value: number; uom: string; uomId: number; group: string } | { uom: string; uomId: number; value: number }[],
) => {
const singleNewVal = newValue as {
value: number;
uom: string;
uomId: number;
group: string;
};
onItemSelect(singleNewVal.value, singleNewVal.uom, singleNewVal.uomId)
}
, [onItemSelect])
return (
<Autocomplete
noOptionsText={t("No Item")}
disableClearable
fullWidth
value={currentValue}
onChange={onChange}
getOptionLabel={(option) => option.label}
options={options}
renderInput={(params) => <TextField {...params} error={error} />}
/>
);
}
export default ItemSelect

+ 73
- 12
src/components/PickOrderSearch/PickOrderSearch.tsx Visa fil

@@ -1,33 +1,27 @@
"use client";
import { PickOrderResult } from "@/app/api/pickOrder";
import { SearchParams } from "@/app/utils/fetchUtil";
import { useCallback, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import SearchBox, { Criterion } from "../SearchBox";
import SearchResults, { Column } from "../SearchResults";
import {
flatten,
groupBy,
intersectionWith,
isEmpty,
map,
sortBy,
sortedUniq,
uniqBy,
upperCase,
upperFirst,
} from "lodash";
import {
arrayToDateString,
arrayToDayjs,
dateStringToDayjs,
} from "@/app/utils/formatUtil";
import dayjs from "dayjs";
import { Button, Grid, Stack, Tab, Tabs, TabsProps } from "@mui/material";
import { Button, Grid, Stack, Tab, Tabs, TabsProps, Typography } from "@mui/material";
import PickOrders from "./PickOrders";
import ConsolidatedPickOrders from "./ConsolidatedPickOrders";
import CreatePickOrderModal from "./CreatePickOrderModal";
import { fetchAllItemsInClient, ItemCombo } from "@/app/api/settings/item/actions";
import { fetchPickOrderClient } from "@/app/api/pickOrder/actions";

import { getServerI18n } from "@/i18n";
interface Props {
pickOrders: PickOrderResult[];
}
@@ -41,15 +35,30 @@ type SearchParamNames = keyof SearchQuery;
const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => {
const { t } = useTranslation("pickOrder");

const [isOpenCreateModal, setIsOpenCreateModal] = useState(false)
const [items, setItems] = useState<ItemCombo[]>([])
const [filteredPickOrders, setFilteredPickOrders] = useState(pickOrders);
const [filterArgs, setFilterArgs] = useState<Record<string, any>>({});
const [tabIndex, setTabIndex] = useState(0);
const [totalCount, setTotalCount] = useState<number>();

const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
(_e, newValue) => {
setTabIndex(newValue);
},
[],
);
const openCreateModal = useCallback(async () => {
console.log("testing")
const res = await fetchAllItemsInClient()
console.log(res)
setItems(res)
setIsOpenCreateModal(true)
}, [])

const closeCreateModal = useCallback(() => {
setIsOpenCreateModal(false)
}, [])

const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
() => [
@@ -113,15 +122,67 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => {
),
},
],
[t],
[pickOrders, t],
);

const fetchNewPagePickOrder = useCallback(
async (
pagingController: Record<string, number>,
filterArgs: Record<string, number>,
) => {
const params = {
...pagingController,
...filterArgs,
};
const res = await fetchPickOrderClient(params);
if (res) {
console.log(res);
setFilteredPickOrders(res.records);
setTotalCount(res.total);
}
},
[],
);

const onReset = useCallback(() => {
setFilteredPickOrders(pickOrders);
}, [pickOrders]);

useEffect(() => {
if (!isOpenCreateModal) {
setTabIndex(1)
setTimeout(async () => {
setTabIndex(0)
}, 200)
}
}, [isOpenCreateModal])
return (
<>
<Stack
rowGap={2}
>
<Grid container>
<Grid item xs={8}>
<Typography variant="h4" marginInlineEnd={2}>
{t("Pick Order")}
</Typography>
</Grid>
<Grid item xs={4} display="flex" justifyContent="end" alignItems="end">
<Button
onClick={openCreateModal}
>
{t("create")}
</Button>
{isOpenCreateModal &&
<CreatePickOrderModal
open={isOpenCreateModal}
onClose={closeCreateModal}
items={items}
/>}
</Grid>
</Grid>
</Stack>
<SearchBox
criteria={searchCriteria}
onSearch={(query) => {


+ 25
- 18
src/components/PickOrderSearch/PickOrders.tsx Visa fil

@@ -4,13 +4,15 @@ import { PickOrderResult } from "@/app/api/pickOrder";
import { useTranslation } from "react-i18next";
import { useCallback, useEffect, useMemo, useState } from "react";
import { isEmpty, upperCase, upperFirst } from "lodash";
import { arrayToDateString } from "@/app/utils/formatUtil";
import { arrayToDateString, OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import {
consolidatePickOrder,
fetchPickOrderClient,
} from "@/app/api/pickOrder/actions";
import useUploadContext from "../UploadProvider/useUploadContext";

import dayjs from "dayjs";
import arraySupport from "dayjs/plugin/arraySupport";
dayjs.extend(arraySupport);
interface Props {
filteredPickOrders: PickOrderResult[];
filterArgs: Record<string, any>;
@@ -30,21 +32,6 @@ const PickOrders: React.FC<Props> = ({ filteredPickOrders, filterArgs }) => {
});
const [totalCount, setTotalCount] = useState<number>();

const handleConsolidatedRows = useCallback(async () => {
console.log(selectedRows);
setIsUploading(true);
try {
const res = await consolidatePickOrder(selectedRows as number[]);
if (res) {
console.log(res);
}
} catch {
setIsUploading(false);
}
fetchNewPagePickOrder(pagingController, filterArgs);
setIsUploading(false);
}, [selectedRows, pagingController]);

const fetchNewPagePickOrder = useCallback(
async (
pagingController: Record<string, number>,
@@ -66,6 +53,22 @@ const PickOrders: React.FC<Props> = ({ filteredPickOrders, filterArgs }) => {
[],
);

const handleConsolidatedRows = useCallback(async () => {
console.log(selectedRows);
setIsUploading(true);
try {
const res = await consolidatePickOrder(selectedRows as number[]);
if (res) {
console.log(res);
}
} catch {
setIsUploading(false);
}
fetchNewPagePickOrder(pagingController, filterArgs);
setIsUploading(false);
}, [selectedRows, setIsUploading, fetchNewPagePickOrder, pagingController, filterArgs]);


useEffect(() => {
fetchNewPagePickOrder(pagingController, filterArgs);
}, [fetchNewPagePickOrder, pagingController, filterArgs]);
@@ -109,7 +112,11 @@ const PickOrders: React.FC<Props> = ({ filteredPickOrders, filterArgs }) => {
name: "targetDate",
label: t("Target Date"),
renderCell: (params) => {
return arrayToDateString(params.targetDate);
return (
dayjs(params.targetDate)
.add(-1, "month")
.format(OUTPUT_DATE_FORMAT)
);
},
},
{


+ 73
- 0
src/components/PickOrderSearch/UomSelect.tsx Visa fil

@@ -0,0 +1,73 @@

import { ItemCombo } from "@/app/api/settings/item/actions";
import { Autocomplete, TextField } from "@mui/material";
import { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";

interface CommonProps {
allUom: ItemCombo[];
error?: boolean;
}

interface SingleAutocompleteProps extends CommonProps {
value: number | string | undefined;
onUomSelect: (itemId: number) => void | Promise<void>;
// multiple: false;
}

type Props = SingleAutocompleteProps;

const UomSelect: React.FC<Props> = ({
allUom,
value,
error,
onUomSelect
}) => {
const { t } = useTranslation("item");
const filteredUom = useMemo(() => {
return allUom
}, [allUom])

const options = useMemo(() => {
return [
{
value: -1, // think think sin
label: t("None"),
group: "default",
},
...filteredUom.map((i) => ({
value: i.id as number,
label: i.label,
group: "existing",
})),
];
}, [t, filteredUom]);

const currentValue = options.find((o) => o.value === value) || options[0];

const onChange = useCallback(
(
event: React.SyntheticEvent,
newValue: { value: number; group: string } | { value: number }[],
) => {
const singleNewVal = newValue as {
value: number;
group: string;
};
onUomSelect(singleNewVal.value)
}
, [onUomSelect])
return (
<Autocomplete
noOptionsText={t("No Uom")}
disableClearable
fullWidth
value={currentValue}
onChange={onChange}
getOptionLabel={(option) => option.label}
options={options}
renderInput={(params) => <TextField {...params} error={error} />}
/>
);
}
export default UomSelect

+ 5
- 6
src/components/PoSearch/PoSearch.tsx Visa fil

@@ -15,7 +15,7 @@ import { useSession } from "next-auth/react";
import { defaultPagingController } from "../SearchResults/SearchResults";
import { fetchPoListClient, testing } from "@/app/api/po/actions";
import dayjs from "dayjs";
import { arrayToDateString } from "@/app/utils/formatUtil";
import { arrayToDateString, OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import arraySupport from "dayjs/plugin/arraySupport";
dayjs.extend(arraySupport);

@@ -72,7 +72,7 @@ const PoSearch: React.FC<Props> = ({
[router],
);

const onDeleteClick = useCallback((po: PoResult) => {}, [router]);
const onDeleteClick = useCallback((po: PoResult) => {}, []);

const columns = useMemo<Column<PoResult>[]>(
() => [
@@ -91,10 +91,9 @@ const PoSearch: React.FC<Props> = ({
label: t("OrderDate"),
renderCell: (params) => {
return (
// dayjs(params.orderDate)
arrayToDateString(params.orderDate)
// .add(-1, "month")
// .format(OUTPUT_DATE_FORMAT)
dayjs(params.orderDate)
.add(-1, "month")
.format(OUTPUT_DATE_FORMAT)
);
},
},


Laddar…
Avbryt
Spara