diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx
index 61c8ec1..f4b1a47 100644
--- a/src/app/(main)/layout.tsx
+++ b/src/app/(main)/layout.tsx
@@ -55,8 +55,8 @@ export default async function MainLayout({
+ {children}
- {children}
>
diff --git a/src/app/(main)/pickOrder/detail/page.tsx b/src/app/(main)/pickOrder/detail/page.tsx
new file mode 100644
index 0000000..fa4b09e
--- /dev/null
+++ b/src/app/(main)/pickOrder/detail/page.tsx
@@ -0,0 +1,30 @@
+import { PreloadPickOrder } from "@/app/api/pickorder";
+import { SearchParams } from "@/app/utils/fetchUtil";
+import PickOrderDetail from "@/components/PickOrderDetail";
+import { getServerI18n, I18nProvider } from "@/i18n";
+import { Stack, Typography } from "@mui/material";
+import { Metadata } from "next";
+import { Suspense } from "react";
+
+export const metadata: Metadata = {
+ title: "Consolidated Pick Order Flow",
+};
+type Props = {} & SearchParams;
+
+const PickOrder: React.FC = async ({ searchParams }) => {
+ const { t } = await getServerI18n("pickOrder");
+
+ PreloadPickOrder();
+
+ return (
+ <>
+
+ }>
+
+
+
+ >
+ );
+};
+
+export default PickOrder;
diff --git a/src/app/(main)/pickOrder/page.tsx b/src/app/(main)/pickOrder/page.tsx
index 20f3f10..60e2a0c 100644
--- a/src/app/(main)/pickOrder/page.tsx
+++ b/src/app/(main)/pickOrder/page.tsx
@@ -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";
diff --git a/src/app/api/inventory/actions.ts b/src/app/api/inventory/actions.ts
index e69de29..860c4bb 100644
--- a/src/app/api/inventory/actions.ts
+++ b/src/app/api/inventory/actions.ts
@@ -0,0 +1,23 @@
+"use server";
+import { BASE_API_URL } from "@/config/api";
+// import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
+import { revalidateTag } from "next/cache";
+import { cache } from "react";
+import { serverFetchJson } from "@/app/utils/fetchUtil";
+import { QcItemResult } from "../settings/qcItem";
+import { RecordsRes } from "../utils";
+// import { BASE_API_URL } from "@/config/api";
+
+export interface LotLineInfo {
+ inventoryLotLineId: number,
+ lotNo: string,
+ remainingQty: number,
+ uom: string
+}
+
+ export const fetchLotDetail = cache(async (stockInLineId: number) => {
+ return serverFetchJson(`${BASE_API_URL}/inventoryLotLine/lot-detail/${stockInLineId}`, {
+ method: 'GET',
+ next: { tags: ["inventory"] },
+ });
+ });
diff --git a/src/app/api/pickOrder/actions.ts b/src/app/api/pickOrder/actions.ts
index e69de29..592df57 100644
--- a/src/app/api/pickOrder/actions.ts
+++ b/src/app/api/pickOrder/actions.ts
@@ -0,0 +1,101 @@
+"use server";
+import { BASE_API_URL } from "@/config/api";
+// import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
+import { revalidateTag } from "next/cache";
+import { cache } from "react";
+import { serverFetchJson } from "@/app/utils/fetchUtil";
+import { QcItemResult } from "../settings/qcItem";
+import { RecordsRes } from "../utils";
+import { ConsoPickOrderResult, PickOrderLineWithSuggestedLot, PickOrderResult, PreReleasePickOrderSummary } from ".";
+// import { BASE_API_URL } from "@/config/api";
+
+export interface ReleasePickOrderInputs {
+ consoCode: string
+ assignTo: number,
+}
+
+export const consolidatePickOrder = async (ids: number[]) => {
+ const pickOrder = await serverFetchJson(`${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(`${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) => {
+ if (queryParams) {
+ const queryString = new URLSearchParams(queryParams).toString();
+ return serverFetchJson>(`${BASE_API_URL}/pickOrder/getRecordByPage?${queryString}`, {
+ method: 'GET',
+ next: { tags: ["pickorder"] },
+ });
+ } else {
+ return serverFetchJson>(`${BASE_API_URL}/pickOrder/getRecordByPage`, {
+ method: 'GET',
+ next: { tags: ["pickorder"] },
+ });
+ }
+ });
+
+ export const fetchConsoPickOrderClient = cache(async (queryParams?: Record) => {
+ if (queryParams) {
+ const queryString = new URLSearchParams(queryParams).toString();
+ return serverFetchJson>(`${BASE_API_URL}/pickOrder/getRecordByPage-conso?${queryString}`, {
+ method: 'GET',
+ next: { tags: ["pickorder"] },
+ });
+ } else {
+ return serverFetchJson>(`${BASE_API_URL}/pickOrder/getRecordByPage-conso`, {
+ method: 'GET',
+ next: { tags: ["pickorder"] },
+ });
+ }
+ });
+
+ export const fetchPickOrderLineClient = cache(async (queryParams?: Record) => {
+ if (queryParams) {
+ const queryString = new URLSearchParams(queryParams).toString();
+ return serverFetchJson>(`${BASE_API_URL}/pickOrder/get-pickorder-line-byPage?${queryString}`, {
+ method: 'GET',
+ next: { tags: ["pickorder"] },
+ });
+ } else {
+ return serverFetchJson>(`${BASE_API_URL}/pickOrder/get-pickorder-line-byPage`, {
+ method: 'GET',
+ next: { tags: ["pickorder"] },
+ });
+ }
+ });
+
+ export const fetchConsoDetail = cache(async (consoCode: string) => {
+ return serverFetchJson(`${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(`${BASE_API_URL}/pickOrder/releaseConso`, {
+ method: "POST",
+ body: JSON.stringify(data),
+ headers: { "Content-Type": "application/json" },
+ });
+ revalidateTag("pickorder");
+ return po
+ }
\ No newline at end of file
diff --git a/src/app/api/pickOrder/index.ts b/src/app/api/pickOrder/index.ts
index a128fc5..285b606 100644
--- a/src/app/api/pickOrder/index.ts
+++ b/src/app/api/pickOrder/index.ts
@@ -1,8 +1,6 @@
import "server-only";
-// import { serverFetchJson } from "@/app/utils/fetchUtil";
-// import { BASE_API_URL } from "@/config/api";
-import { serverFetchJson } from "../../utils/fetchUtil";
-import { BASE_API_URL } from "../../../config/api";
+import { Pageable, serverFetchJson } from "@/app/utils/fetchUtil";
+import { BASE_API_URL } from "@/config/api";
import { cache } from "react";
interface PickOrderItemInfo {
@@ -20,14 +18,77 @@ export interface PickOrderResult{
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
+}
+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
+}
+export type ByItemsSummary = {
+ id: number,
+ code: string,
+ name: string,
+ uomDesc: string,
+ availableQty: number,
+ requiredQty: number,
+}
+export interface PreReleasePickOrderSummary {
+ consoCode: string
+ pickOrders: Omit[]
+ items: ByItemsSummary[]
+}
+
+export interface PickOrderLineWithSuggestedLot {
+ id: number,
+ itemName: string,
+ qty: number,
+ uom: string
+ status: string
+ warehouse: string
+ suggestedLotNo: string
}
export const PreloadPickOrder = () => {
- fetchPickOrders()
+ fetchPickOrders({
+ code: undefined,
+ targetDateFrom: undefined,
+ targetDateTo: undefined,
+ type: undefined,
+ status: undefined,
+ itemName: undefined,
+ })
}
-export const fetchPickOrders = cache(async () => {
- return serverFetchJson(`${BASE_API_URL}/pickOrder/list`, {
+export const fetchPickOrders = cache(async (queryParams: FetchPickOrders) => {
+ const queryString = new URLSearchParams(queryParams as Record).toString();
+ return serverFetchJson(`${BASE_API_URL}/pickOrder/list?${queryString}`, {
next: {
tags: ["pickOrders"]
}
diff --git a/src/app/api/qrcode/index.ts b/src/app/api/qrcode/index.ts
index 5079cf9..61339dc 100644
--- a/src/app/api/qrcode/index.ts
+++ b/src/app/api/qrcode/index.ts
@@ -6,8 +6,10 @@ import { serverFetchJson } from "../../utils/fetchUtil";
import { BASE_API_URL } from "../../../config/api";
export interface QrCodeInfo {
- stockInLineId?: number;
- itemId: number
- warehouseId?: number
- lotNo?: string
- }
\ No newline at end of file
+ // warehouse qrcode
+ warehouseId?: number
+ // item qrcode
+ stockInLineId?: number;
+ itemId: number
+ lotNo?: string
+}
\ No newline at end of file
diff --git a/src/app/api/user/actions.ts b/src/app/api/user/actions.ts
index 9562e53..f0a42fc 100644
--- a/src/app/api/user/actions.ts
+++ b/src/app/api/user/actions.ts
@@ -22,12 +22,23 @@ export interface PasswordInputs {
newPasswordCheck: string;
}
+export interface NameList {
+ id: number
+ name: string
+}
+
export const fetchUserDetails = cache(async (id: number) => {
return serverFetchJson(`${BASE_API_URL}/user/${id}`, {
next: { tags: ["user"] },
});
});
+export const fetchNameList = cache(async () => {
+ return serverFetchJson(`${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}`, {
method: "PUT",
diff --git a/src/app/utils/fetchUtil.ts b/src/app/utils/fetchUtil.ts
index 053957a..a925dd0 100644
--- a/src/app/utils/fetchUtil.ts
+++ b/src/app/utils/fetchUtil.ts
@@ -3,6 +3,11 @@ import { getServerSession } from "next-auth";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
+export interface Pageable {
+ pageSize?: number
+ pageNum?: number
+}
+
export type SearchParams = {
searchParams: { [key: string]: string | string[] | undefined };
}
diff --git a/src/app/utils/formatUtil.ts b/src/app/utils/formatUtil.ts
index 206f0e3..7d2fb40 100644
--- a/src/app/utils/formatUtil.ts
+++ b/src/app/utils/formatUtil.ts
@@ -67,6 +67,13 @@ export const stockInLineStatusMap: { [status: string]: number } = {
"rejected": 9,
};
+export const pickOrderStatusMap: { [status: string]: number } = {
+ "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);
}
diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx
index cedc17f..b52993f 100644
--- a/src/components/Breadcrumb/Breadcrumb.tsx
+++ b/src/components/Breadcrumb/Breadcrumb.tsx
@@ -24,6 +24,7 @@ const pathToLabelMap: { [path: string]: string } = {
"/do": "Delivery Order",
"/pickOrder": "Pick Order",
"/po": "Purchase Order",
+ "/dashboard": "dashboard",
};
const Breadcrumb = () => {
diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx
index 7c2476a..b5cc4e2 100644
--- a/src/components/NavigationContent/NavigationContent.tsx
+++ b/src/components/NavigationContent/NavigationContent.tsx
@@ -52,7 +52,7 @@ const NavigationContent: React.FC = () => {
{
icon: ,
label: "Pick Order",
- path: "/pickOrder",
+ path: "/pickorder",
},
// {
// icon: ,
diff --git a/src/components/PickOrderDetail/PickOrderDetail.tsx b/src/components/PickOrderDetail/PickOrderDetail.tsx
new file mode 100644
index 0000000..fa077b5
--- /dev/null
+++ b/src/components/PickOrderDetail/PickOrderDetail.tsx
@@ -0,0 +1,314 @@
+"use client";
+
+import {
+ Button,
+ ButtonProps,
+ Card,
+ CardContent,
+ CardHeader,
+ CircularProgress,
+ Grid,
+ Stack,
+ Typography,
+} from "@mui/material";
+import { useTranslation } from "react-i18next";
+import StyledDataGrid from "../StyledDataGrid";
+import { useCallback, useEffect, useMemo, useState } from "react";
+import { GridColDef } from "@mui/x-data-grid";
+import { PlayArrow } from "@mui/icons-material";
+import DoneIcon from "@mui/icons-material/Done";
+import { GridRowSelectionModel } from "@mui/x-data-grid";
+import { useQcCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider";
+import { fetchPickOrderLineClient } from "@/app/api/pickorder/actions";
+import { PickOrderLineWithSuggestedLot } from "@/app/api/pickorder";
+import { Pageable } from "@/app/utils/fetchUtil";
+import { QrCodeInfo } from "@/app/api/qrcode";
+import { QrCode } from "../QrCode";
+import { fetchLotDetail, LotLineInfo } from "@/app/api/inventory/actions";
+import { GridRowModesModel } from "@mui/x-data-grid";
+
+interface Props {
+ consoCode: string;
+}
+interface IsLoadingModel {
+ pickOrderLineTable: boolean;
+ stockOutLineTable: boolean;
+}
+
+const PickOrderDetail: React.FC = ({ consoCode }) => {
+ const { t } = useTranslation("pickOrder");
+ const [selectedRow, setSelectRow] = useState();
+ const [isLoadingModel, setIsLoadingModel] = useState({
+ pickOrderLineTable: false,
+ stockOutLineTable: false,
+ });
+ const [polCriteriaArgs, setPolCriteriaArgs] = useState({
+ pageNum: 1,
+ pageSize: 10,
+ });
+ const [solCriteriaArgs, setSolCriteriaArgs] = useState({
+ pageNum: 1,
+ pageSize: 10,
+ });
+ const [polTotalCount, setPolTotalCount] = useState(0);
+ const [solTotalCount, setSolTotalCount] = useState(0);
+ const [rowModesModel, setRowModesModel] = useState({});
+
+ const [pickOrderLine, setPickOrderLine] = useState<
+ PickOrderLineWithSuggestedLot[]
+ >([]);
+
+ const pickOrderLineColumns = useMemo(
+ () => [
+ {
+ field: "id",
+ headerName: "pickOrderLineId",
+ flex: 1,
+ },
+ {
+ field: "itemName",
+ headerName: "itemId",
+ flex: 1,
+ },
+ {
+ field: "qty",
+ headerName: "qty",
+ flex: 1,
+ },
+ {
+ field: "uom",
+ headerName: "uom",
+ flex: 1,
+ },
+ {
+ field: "warehouse",
+ headerName: "location",
+ flex: 1,
+ },
+ {
+ field: "suggestedLotNo",
+ headerName: "suggestedLotNo",
+ flex: 1.2,
+ },
+ ],
+ []
+ );
+ const [stockOutLine, setStockOutLine] = useState([]);
+ const stockOutLineColumns = useMemo(
+ () => [
+ {
+ field: "code",
+ headerName: "actual lot (out line",
+ flex: 1,
+ },
+ ],
+ []
+ );
+
+ const handleStartPickOrder = useCallback(async () => {}, []);
+
+ const handleCompletePickOrder = useCallback(async () => {}, []);
+
+ useEffect(() => {
+ console.log(selectedRow);
+ }, [selectedRow]);
+
+ const buttonData = useMemo(
+ () => ({
+ buttonName: "complete",
+ title: t("Do you want to complete?"),
+ confirmButtonText: t("Complete"),
+ successTitle: t("Complete Success"),
+ errorTitle: t("Complete Fail"),
+ buttonText: t("Complete PO"),
+ buttonIcon: ,
+ buttonColor: "info",
+ disabled: true,
+ }),
+ []
+ );
+
+ const [isOpenScanner, setOpenScanner] = useState(false);
+ const onOpenScanner = useCallback(() => {
+ setOpenScanner((prev) => !prev);
+ }, []);
+
+ const fetchPickOrderLine = useCallback(
+ async (params: Record) => {
+ setIsLoadingModel((prev) => ({
+ ...prev,
+ pickOrderLineTable: true,
+ }));
+ const res = await fetchPickOrderLineClient({
+ ...params,
+ consoCode: consoCode,
+ });
+ if (res) {
+ console.log(res);
+ setPickOrderLine(res.records);
+ setPolTotalCount(res.total);
+ } else {
+ console.log("error");
+ console.log(res);
+ }
+ setIsLoadingModel((prev) => ({
+ ...prev,
+ pickOrderLineTable: false,
+ }));
+ },
+ [fetchPickOrderLineClient, consoCode]
+ );
+ const fetchStockOutLine = useCallback(
+ async (params: Record) => {},
+ []
+ );
+
+ useEffect(() => {
+ fetchPickOrderLine(polCriteriaArgs);
+ }, [polCriteriaArgs]);
+
+ useEffect(() => {
+ fetchStockOutLine(solCriteriaArgs);
+ }, [solCriteriaArgs]);
+
+ const getLotDetail = useCallback(
+ async (stockInLineId: number): Promise => {
+ const res = await fetchLotDetail(stockInLineId);
+ return res;
+ },
+ [fetchLotDetail]
+ );
+
+ const scanner = useQcCodeScanner();
+ useEffect(() => {
+ if (isOpenScanner && !scanner.isScanning) {
+ scanner.startScan();
+ } else if (!isOpenScanner && scanner.isScanning) {
+ scanner.stopScan();
+ }
+ }, [isOpenScanner]);
+
+ useEffect(() => {
+ if (scanner.values.length > 0) {
+ console.log(scanner.values[0]);
+ const data: QrCodeInfo = JSON.parse(scanner.values[0]);
+ console.log(data);
+ if (data.stockInLineId) {
+ console.log("still got in");
+ console.log(data.stockInLineId);
+ // fetch
+ getLotDetail(data.stockInLineId).then((value) => {});
+ }
+ scanner.resetScan();
+ }
+ }, [scanner.values]);
+
+ const homemade_Qrcode = {
+ stockInLineId: 156,
+ };
+
+ return (
+ <>
+
+
+
+
+ {consoCode}
+
+
+
+
+
+
+
+
+ {/* homemade qrcode for testing purpose */}
+ {/*
+
+ */}
+
+
+ {/*
+
+ */}
+
+ {isLoadingModel.pickOrderLineTable ? (
+
+ ) : (
+ {
+ setSelectRow(newRowSelectionModel);
+ }}
+ initialState={{
+ pagination: {
+ paginationModel: { pageSize: 10, page: 0 },
+ },
+ }}
+ pageSizeOptions={[10, 25, 50, 100]}
+ onPaginationModelChange={async (model, details) => {
+ setPolCriteriaArgs({
+ pageNum: model.page + 1,
+ pageSize: model.pageSize,
+ });
+ }}
+ rowCount={polTotalCount}
+ />
+ )}
+
+
+ {
+ setSolCriteriaArgs({
+ pageNum: model.page + 1,
+ pageSize: model.pageSize,
+ });
+ }}
+ rowCount={solTotalCount}
+ />
+
+
+
+ >
+ );
+};
+export default PickOrderDetail;
diff --git a/src/components/PickOrderDetail/PickOrderDetailLoading.tsx b/src/components/PickOrderDetail/PickOrderDetailLoading.tsx
new file mode 100644
index 0000000..7fc248b
--- /dev/null
+++ b/src/components/PickOrderDetail/PickOrderDetailLoading.tsx
@@ -0,0 +1,40 @@
+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 PickOrderDetailLoading: React.FC = () => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default PickOrderDetailLoading;
diff --git a/src/components/PickOrderDetail/PickOrderDetailWrapper.tsx b/src/components/PickOrderDetail/PickOrderDetailWrapper.tsx
new file mode 100644
index 0000000..f201af7
--- /dev/null
+++ b/src/components/PickOrderDetail/PickOrderDetailWrapper.tsx
@@ -0,0 +1,35 @@
+import { fetchAllItems } from "@/app/api/settings/item";
+// import ItemsSearch from "./ItemsSearch";
+// import ItemsSearchLoading from "./ItemsSearchLoading";
+import { SearchParams } from "@/app/utils/fetchUtil";
+import { TypeEnum } from "@/app/utils/typeEnum";
+import { notFound } from "next/navigation";
+import { fetchPoWithStockInLines, PoResult } from "@/app/api/po";
+import { QcItemWithChecks } from "@/app/api/qc";
+import { fetchWarehouseList } from "@/app/api/warehouse";
+import { fetchQcItemCheck } from "@/app/api/qc/actions";
+import PickOrderDetail from "./PickOrderDetail";
+import PickOrderDetailLoading from "./PickOrderDetailLoading";
+
+interface SubComponents {
+ Loading: typeof PickOrderDetailLoading;
+}
+
+type Props = {
+ consoCode: string;
+};
+
+const PoDetailWrapper: React.FC & SubComponents = async ({ consoCode }) => {
+// const [poWithStockInLine, warehouse, qc] = await Promise.all([
+// fetchPoWithStockInLines(id),
+// fetchWarehouseList(),
+// fetchQcItemCheck(),
+// ]);
+ // const poWithStockInLine = await fetchPoWithStockInLines(id)
+
+ return ;
+};
+
+PoDetailWrapper.Loading = PickOrderDetailLoading;
+
+export default PoDetailWrapper;
diff --git a/src/components/PickOrderDetail/index.ts b/src/components/PickOrderDetail/index.ts
new file mode 100644
index 0000000..47ec0ac
--- /dev/null
+++ b/src/components/PickOrderDetail/index.ts
@@ -0,0 +1 @@
+export { default } from "./PickOrderDetailWrapper"
\ No newline at end of file
diff --git a/src/components/PickOrderSearch/ConsolidatePickOrderItemSum.tsx b/src/components/PickOrderSearch/ConsolidatePickOrderItemSum.tsx
new file mode 100644
index 0000000..7e30b64
--- /dev/null
+++ b/src/components/PickOrderSearch/ConsolidatePickOrderItemSum.tsx
@@ -0,0 +1,91 @@
+"use client";
+import dayjs from "dayjs";
+import arraySupport from "dayjs/plugin/arraySupport";
+import StyledDataGrid from "../StyledDataGrid";
+import {
+ Dispatch,
+ SetStateAction,
+ useCallback,
+ useEffect,
+ useMemo,
+ useState,
+} from "react";
+import { GridColDef } from "@mui/x-data-grid";
+import { CircularProgress, Grid, Typography } from "@mui/material";
+import { ByItemsSummary } from "@/app/api/pickorder";
+import { useTranslation } from "react-i18next";
+
+dayjs.extend(arraySupport);
+
+interface Props {
+ rows: ByItemsSummary[] | undefined;
+ setRows: Dispatch>;
+}
+
+const ConsolidatePickOrderItemSum: React.FC = ({ rows, setRows }) => {
+ console.log(rows);
+ const { t } = useTranslation("pickOrder");
+
+ const columns = useMemo(
+ () => [
+ {
+ field: "name",
+ headerName: "name",
+ flex: 1,
+ renderCell: (params) => {
+ console.log(params.row.name);
+ return params.row.name;
+ },
+ },
+ {
+ field: "requiredQty",
+ headerName: "requiredQty",
+ flex: 1,
+ renderCell: (params) => {
+ console.log(params.row.requiredQty);
+ const requiredQty = params.row.requiredQty ?? 0;
+ return `${requiredQty} ${params.row.uomDesc}`;
+ },
+ },
+ {
+ field: "availableQty",
+ headerName: "availableQty",
+ flex: 1,
+ renderCell: (params) => {
+ console.log(params.row.availableQty);
+ const availableQty = params.row.availableQty ?? 0;
+ return `${availableQty} ${params.row.uomDesc}`;
+ },
+ },
+ ],
+ []
+ );
+ return (
+
+
+
+ {t("Items Included")}
+
+
+
+ {!rows ? (
+
+ ) : (
+
+ )}
+
+
+ );
+};
+
+export default ConsolidatePickOrderItemSum;
diff --git a/src/components/PickOrderSearch/ConsolidatePickOrderSum.tsx b/src/components/PickOrderSearch/ConsolidatePickOrderSum.tsx
new file mode 100644
index 0000000..b4fd99e
--- /dev/null
+++ b/src/components/PickOrderSearch/ConsolidatePickOrderSum.tsx
@@ -0,0 +1,115 @@
+"use client";
+import dayjs from "dayjs";
+import arraySupport from "dayjs/plugin/arraySupport";
+import StyledDataGrid from "../StyledDataGrid";
+import {
+ Dispatch,
+ SetStateAction,
+ useCallback,
+ useEffect,
+ useMemo,
+ useState,
+} from "react";
+import { GridColDef, GridInputRowSelectionModel } from "@mui/x-data-grid";
+import { Box, CircularProgress, Grid, Typography } from "@mui/material";
+import { PickOrderResult } from "@/app/api/pickorder";
+import { useTranslation } from "react-i18next";
+
+dayjs.extend(arraySupport);
+
+interface Props {
+ consoCode: string;
+ rows: Omit[] | undefined;
+ setRows: Dispatch<
+ SetStateAction[] | undefined>
+ >;
+ revertIds: GridInputRowSelectionModel;
+ setRevertIds: Dispatch>;
+}
+
+const ConsolidatePickOrderSum: React.FC = ({
+ consoCode,
+ rows,
+ setRows,
+ revertIds,
+ setRevertIds,
+}) => {
+ const { t } = useTranslation("pickOrder");
+ const columns = useMemo(
+ () => [
+ {
+ field: "code",
+ headerName: "code",
+ flex: 0.6,
+ },
+
+ {
+ field: "pickOrderLines",
+ headerName: "items",
+ flex: 1,
+ renderCell: (params) => {
+ console.log(params);
+ const pickOrderLine = params.row.pickOrderLines as any[];
+ return (
+
+ {pickOrderLine.map((item, index) => (
+ {`${item.itemName} x ${item.requiredQty} ${item.uomDesc}`} // Render each name in a span
+ ))}
+
+ );
+ },
+ },
+ ],
+ []
+ );
+
+ return (
+
+
+
+ {t("Pick Order Included")}
+
+
+
+ {!rows ? (
+
+ ) : (
+ {
+ setRevertIds(newRowSelectionModel);
+ }}
+ getRowHeight={(params) => {
+ return 100
+ }}
+ rows={rows}
+ columns={columns}
+ />
+ )}
+
+
+ );
+};
+
+export default ConsolidatePickOrderSum;
diff --git a/src/components/PickOrderSearch/ConsolidatedPickOrders.tsx b/src/components/PickOrderSearch/ConsolidatedPickOrders.tsx
index 445b59a..304c9fc 100644
--- a/src/components/PickOrderSearch/ConsolidatedPickOrders.tsx
+++ b/src/components/PickOrderSearch/ConsolidatedPickOrders.tsx
@@ -1,12 +1,372 @@
+import {
+ Autocomplete,
+ Box,
+ Button,
+ CircularProgress,
+ FormControl,
+ Grid,
+ Modal,
+ ModalProps,
+ TextField,
+ Typography,
+} from "@mui/material";
+import { GridToolbarContainer } from "@mui/x-data-grid";
+import {
+ FooterPropsOverrides,
+ GridColDef,
+ GridRowSelectionModel,
+ useGridApiRef,
+} from "@mui/x-data-grid";
+import { useCallback, useEffect, useMemo, useState } from "react";
+import { useTranslation } from "react-i18next";
+import StyledDataGrid from "../StyledDataGrid";
+import SearchResults, {
+ Column,
+ defaultPagingController,
+} from "../SearchResults/SearchResults";
+import {
+ ByItemsSummary,
+ ConsoPickOrderResult,
+ PickOrderLine,
+ PickOrderResult,
+} from "@/app/api/pickorder";
+import { useRouter, useSearchParams } from "next/navigation";
+import ConsolidatePickOrderItemSum from "./ConsolidatePickOrderItemSum";
+import ConsolidatePickOrderSum from "./ConsolidatePickOrderSum";
+import { GridInputRowSelectionModel } from "@mui/x-data-grid";
+import {
+ fetchConsoDetail,
+ fetchConsoPickOrderClient,
+ releasePickOrder,
+ ReleasePickOrderInputs,
+} from "@/app/api/pickorder/actions";
+import { EditNote } from "@mui/icons-material";
+import { fetchNameList, NameList } from "@/app/api/user/actions";
+import { useField } from "@mui/x-date-pickers/internals";
+import {
+ FormProvider,
+ SubmitErrorHandler,
+ SubmitHandler,
+ useForm,
+} from "react-hook-form";
+import { pickOrderStatusMap } from "@/app/utils/formatUtil";
interface Props {
+ filterArgs: Record;
+}
+const style = {
+ position: "absolute",
+ top: "50%",
+ left: "50%",
+ transform: "translate(-50%, -50%)",
+ bgcolor: "background.paper",
+ pt: 5,
+ px: 5,
+ pb: 10,
+ width: 1500,
+};
+interface DisableButton {
+ releaseBtn: boolean;
+ removeBtn: boolean;
}
-const ConsolidatedPickOrders: React.FC = ({
+const ConsolidatedPickOrders: React.FC = ({ filterArgs }) => {
+ const { t } = useTranslation("pickOrder");
+ const router = useRouter();
+ const apiRef = useGridApiRef();
+ const [filteredPickOrders, setFilteredPickOrders] = useState(
+ [] as ConsoPickOrderResult[]
+ );
+ const [isLoading, setIsLoading] = useState(false);
+ const [modalOpen, setModalOpen] = useState(false); //change back to false
+ const [consoCode, setConsoCode] = useState(); ///change back to undefined
+ const [revertIds, setRevertIds] = useState([]);
+ const [totalCount, setTotalCount] = useState();
+ const [usernameList, setUsernameList] = useState([]);
-}) => {
- return <>>
-}
+ const [byPickOrderRows, setByPickOrderRows] = useState<
+ Omit[] | undefined
+ >(undefined);
+ const [byItemsRows, setByItemsRows] = useState(
+ undefined
+ );
+ const [disableRelease, setDisableRelease] = useState(true);
+
+ const formProps = useForm();
+ const errors = formProps.formState.errors;
+
+ const openDetailModal = useCallback((consoCode: string) => {
+ setConsoCode(consoCode);
+ setModalOpen(true);
+ }, []);
+
+ const closeDetailModal = useCallback(() => {
+ setModalOpen(false);
+ setConsoCode(undefined);
+ }, []);
+
+ const onDetailClick = useCallback(
+ (pickOrder: any) => {
+ console.log(pickOrder);
+ const status = pickOrder.status
+ if (pickOrderStatusMap[status] >= 2) {
+ router.push(`/pickorder/detail?consoCode=${pickOrder.consoCode}`);
+ } else {
+ openDetailModal(pickOrder.consoCode);
+ }
+ },
+ [router, openDetailModal]
+ );
+ const columns = useMemo[]>(
+ () => [
+ {
+ name: "id",
+ label: t("Detail"),
+ onClick: onDetailClick,
+ buttonIcon: ,
+ },
+ {
+ name: "consoCode",
+ label: t("consoCode"),
+ },
+ {
+ name: "status",
+ label: t("status"),
+ },
+ ],
+ []
+ );
+ const [pagingController, setPagingController] = useState(
+ defaultPagingController
+ );
+
+ // pass conso code back to assign
+ // pass user back to assign
+ const fetchNewPageConsoPickOrder = useCallback(
+ async (
+ pagingController: Record,
+ filterArgs: Record
+ ) => {
+ setIsLoading(true);
+ const params = {
+ ...pagingController,
+ ...filterArgs,
+ };
+ const res = await fetchConsoPickOrderClient(params);
+ if (res) {
+ console.log(res);
+ setFilteredPickOrders(res.records);
+ setTotalCount(res.total);
+ }
+ setIsLoading(false);
+ },
+ []
+ );
+
+ useEffect(() => {
+ fetchNewPageConsoPickOrder(pagingController, filterArgs);
+ }, [fetchNewPageConsoPickOrder, pagingController, filterArgs]);
+
+ const isReleasable = useCallback((itemList: ByItemsSummary[]): boolean => {
+ var isReleasable = true;
+ for (const item of itemList) {
+ isReleasable = item.requiredQty >= item.availableQty;
+ if (!isReleasable) return isReleasable;
+ }
+ return isReleasable;
+ }, []);
+
+ const fetchConso = useCallback(
+ async (consoCode: string) => {
+ const res = await fetchConsoDetail(consoCode);
+ const nameListRes = await fetchNameList();
+ if (res) {
+ console.log(res);
+ setByPickOrderRows(res.pickOrders);
+ // for testing
+ // for (const item of res.items) {
+ // item.availableQty = 1000;
+ // }
+ setByItemsRows(res.items);
+ setDisableRelease(isReleasable(res.items));
+ } else {
+ console.log("error");
+ console.log(res);
+ }
+ if (nameListRes) {
+ console.log(nameListRes);
+ setUsernameList(nameListRes);
+ }
+ },
+ [isReleasable]
+ );
+
+ const closeHandler = useCallback>(
+ (...args) => {
+ closeDetailModal();
+ // reset();
+ },
+ [closeDetailModal]
+ );
+
+
+ const onChange = useCallback(
+ (
+ event: React.SyntheticEvent,
+ newValue: NameList
+ ) => {
+ console.log(newValue);
+ formProps.setValue("assignTo", newValue.id);
+ },
+ []
+ );
+
+ const onSubmit = useCallback>(
+ async (data, event) => {
+ console.log(data);
+ try {
+ const res = await releasePickOrder(data)
+ console.log(res)
+ if (res.status = 200) {
+ router.push(`/pickorder/detail?consoCode=${data.consoCode}`);
+ } else {
+ throw Error("hv error")
+ }
+ } catch (error) {
+ console.log(error)
+ }
+ },
+ [releasePickOrder]
+ );
+ const onSubmitError = useCallback>(
+ (errors) => {},
+ []
+ );
+
+ const handleConsolidate_revert = useCallback(() => {
+ console.log(revertIds);
+ }, [revertIds]);
+
+ useEffect(() => {
+ if (consoCode) {
+ fetchConso(consoCode);
+ formProps.setValue("consoCode", consoCode)
+ }
+ }, [consoCode]);
+
+ return (
+ <>
+
+
+ {isLoading ? (
+
+ ) : (
+
+ items={filteredPickOrders}
+ columns={columns}
+ pagingController={pagingController}
+ setPagingController={setPagingController}
+ totalCount={totalCount}
+ />
+ )}
+
+
+ {consoCode != undefined ? (
+
+
+
+
+
+
+ {consoCode}
+
+
+
+
+ option.name}
+ options={usernameList}
+ onChange={onChange}
+ renderInput={(params) => }
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : undefined}
+ >
+ );
+};
-export default ConsolidatedPickOrders;
\ No newline at end of file
+export default ConsolidatedPickOrders;
diff --git a/src/components/PickOrderSearch/PickOrderSearch.tsx b/src/components/PickOrderSearch/PickOrderSearch.tsx
index 747fbb1..4090fc3 100644
--- a/src/components/PickOrderSearch/PickOrderSearch.tsx
+++ b/src/components/PickOrderSearch/PickOrderSearch.tsx
@@ -1,24 +1,40 @@
-"use client"
-import { PickOrderResult } from "@/app/api/pickOrder";
+"use client";
+import { PickOrderResult } from "@/app/api/pickorder";
import { SearchParams } from "@/app/utils/fetchUtil";
import { useCallback, 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 {
+ 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 PickOrders from "./PickOrders";
+import ConsolidatedPickOrders from "./ConsolidatedPickOrders";
+
import { getServerI18n } from "@/i18n";
interface Props {
- pickOrders: PickOrderResult[];
+ pickOrders: PickOrderResult[];
}
-type SearchQuery = Partial>
+type SearchQuery = Partial<
+ Omit
+>;
type SearchParamNames = keyof SearchQuery;
@@ -27,76 +43,134 @@ const PickOrderSearch: React.FC = ({
}) => {
const { t } = useTranslation("pickOrder");
- const [filteredPickOrders, setFilteredPickOrders] = useState(pickOrders)
-
- const [tabIndex, setTabIndex] = useState(0);
- const handleTabChange = useCallback>(
- (_e, newValue) => {
- setTabIndex(newValue);
- },
- [],
- );
+ const [filteredPickOrders, setFilteredPickOrders] = useState(pickOrders);
+ const [filterArgs, setFilterArgs] = useState>({});
+ const [tabIndex, setTabIndex] = useState(0);
+ const handleTabChange = useCallback>(
+ (_e, newValue) => {
+ setTabIndex(newValue);
+ },
+ []
+ );
- const searchCriteria: Criterion[] = useMemo(() => [
- { label: t("Code"), paramName: "code", type: "text" },
- { label: t("Target Date From"), label2: t("Target Date To"), paramName: "targetDate", type: "dateRange" },
- {
- label: t("Type"), paramName: "type", type: "autocomplete",
- options: sortBy(
- uniqBy(pickOrders.map((po) => ({ value: po.type, label: t(upperCase(po.type)) })), "value"),
- "label")
- },
- {
- label: t("Status"), paramName: "status", type: "autocomplete",
- options: sortBy(
- uniqBy(pickOrders.map((po) => ({ value: po.status, label: t(upperFirst(po.status)) })), "value"),
- "label")
- },
- {
- label: t("Items"), paramName: "items", type: "autocomplete", // multiple: true,
- options: uniqBy(flatten(sortBy(
- pickOrders.map((po) => po.items ? po.items.map((item) => ({
- value: item.name, label: item.name,
- // group: item.type
- })) : []),
- "label")), "value")
- },
- ], [t])
+ const searchCriteria: Criterion[] = useMemo(
+ () => [
+ { label: t("Code"), paramName: "code", type: "text" },
+ {
+ label: t("Target Date From"),
+ label2: t("Target Date To"),
+ paramName: "targetDate",
+ type: "dateRange",
+ },
+ {
+ label: t("Type"),
+ paramName: "type",
+ type: "autocomplete",
+ options: sortBy(
+ uniqBy(
+ pickOrders.map((po) => ({
+ value: po.type,
+ label: t(upperCase(po.type)),
+ })),
+ "value"
+ ),
+ "label"
+ ),
+ },
+ {
+ label: t("Status"),
+ paramName: "status",
+ type: "autocomplete",
+ options: sortBy(
+ uniqBy(
+ pickOrders.map((po) => ({
+ value: po.status,
+ label: t(upperFirst(po.status)),
+ })),
+ "value"
+ ),
+ "label"
+ ),
+ },
+ {
+ label: t("Items"),
+ paramName: "items",
+ type: "autocomplete", // multiple: true,
+ options: uniqBy(
+ flatten(
+ sortBy(
+ pickOrders.map((po) =>
+ po.items
+ ? po.items.map((item) => ({
+ value: item.name,
+ label: item.name,
+ // group: item.type
+ }))
+ : []
+ ),
+ "label"
+ )
+ ),
+ "value"
+ ),
+ },
+ ],
+ [t]
+ );
- const onReset = useCallback(() => {
- setFilteredPickOrders(pickOrders)
- }, [pickOrders])
+ const onReset = useCallback(() => {
+ setFilteredPickOrders(pickOrders);
+ }, [pickOrders]);
- return (
- <>
- {
- setFilteredPickOrders(
- pickOrders.filter(
- (po) => {
- const poTargetDateStr = arrayToDayjs(po.targetDate)
+ return (
+ <>
+ {
+ setFilterArgs({ ...query }); // modify later
+ setFilteredPickOrders(
+ pickOrders.filter((po) => {
+ const poTargetDateStr = arrayToDayjs(po.targetDate);
- // console.log(intersectionWith(po.items?.map(item => item.name), query.items))
- return po.code.toLowerCase().includes(query.code.toLowerCase())
- && (isEmpty(query.targetDate) || poTargetDateStr.isSame(query.targetDate) || poTargetDateStr.isAfter(query.targetDate))
- && (isEmpty(query.targetDateTo) || poTargetDateStr.isSame(query.targetDateTo) || poTargetDateStr.isBefore(query.targetDateTo))
- && (intersectionWith(["All"], query.items).length > 0 || intersectionWith(po.items?.map(item => item.name), query.items).length > 0)
- && (query.status.toLowerCase() == "all" || po.status.toLowerCase().includes(query.status.toLowerCase()))
- && (query.type.toLowerCase() == "all" || po.type.toLowerCase().includes(query.type.toLowerCase()))
- }
- )
- )
- }}
- onReset={onReset}
- />
-
-
-
-
- {tabIndex === 0 && }
- >
- )
-}
+ // console.log(intersectionWith(po.items?.map(item => item.name), query.items))
+ return (
+ po.code.toLowerCase().includes(query.code.toLowerCase()) &&
+ (isEmpty(query.targetDate) ||
+ poTargetDateStr.isSame(query.targetDate) ||
+ poTargetDateStr.isAfter(query.targetDate)) &&
+ (isEmpty(query.targetDateTo) ||
+ poTargetDateStr.isSame(query.targetDateTo) ||
+ poTargetDateStr.isBefore(query.targetDateTo)) &&
+ (intersectionWith(["All"], query.items).length > 0 ||
+ intersectionWith(
+ po.items?.map((item) => item.name),
+ query.items
+ ).length > 0) &&
+ (query.status.toLowerCase() == "all" ||
+ po.status
+ .toLowerCase()
+ .includes(query.status.toLowerCase())) &&
+ (query.type.toLowerCase() == "all" ||
+ po.type.toLowerCase().includes(query.type.toLowerCase()))
+ );
+ })
+ );
+ }}
+ onReset={onReset}
+ />
+
+
+
+
+ {tabIndex === 0 && (
+
+ )}
+ {tabIndex === 1 && }
+ >
+ );
+};
-export default PickOrderSearch;
\ No newline at end of file
+export default PickOrderSearch;
diff --git a/src/components/PickOrderSearch/PickOrderSearchWrapper.tsx b/src/components/PickOrderSearch/PickOrderSearchWrapper.tsx
index 0d19df7..a06ae97 100644
--- a/src/components/PickOrderSearch/PickOrderSearchWrapper.tsx
+++ b/src/components/PickOrderSearch/PickOrderSearchWrapper.tsx
@@ -1,4 +1,4 @@
-import { fetchPickOrders } from "@/app/api/pickOrder";
+import { fetchPickOrders } from "@/app/api/pickorder";
import GeneralLoading from "../General/GeneralLoading";
import PickOrderSearch from "./PickOrderSearch";
@@ -10,7 +10,14 @@ const PickOrderSearchWrapper: React.FC & SubComponents = async () => {
const [
pickOrders
] = await Promise.all([
- fetchPickOrders()
+ fetchPickOrders({
+ code: undefined,
+ targetDateFrom: undefined,
+ targetDateTo: undefined,
+ type: undefined,
+ status: undefined,
+ itemName: undefined,
+ })
])
return
diff --git a/src/components/PickOrderSearch/PickOrders.tsx b/src/components/PickOrderSearch/PickOrders.tsx
index ea63b68..910962e 100644
--- a/src/components/PickOrderSearch/PickOrders.tsx
+++ b/src/components/PickOrderSearch/PickOrders.tsx
@@ -1,100 +1,157 @@
-import { Button, Grid } from "@mui/material";
+import { Button, CircularProgress, Grid } from "@mui/material";
import SearchResults, { Column } from "../SearchResults/SearchResults";
-import { PickOrderResult } from "@/app/api/pickOrder";
+import { PickOrderResult } from "@/app/api/pickorder";
import { useTranslation } from "react-i18next";
-import { useCallback, useMemo, useState } from "react";
+import { useCallback, useEffect, useMemo, useState } from "react";
import { isEmpty, upperCase, upperFirst } from "lodash";
import { arrayToDateString } from "@/app/utils/formatUtil";
+import { consolidatePickOrder, fetchPickOrderClient } from "@/app/api/pickorder/actions";
+import useUploadContext from "../UploadProvider/useUploadContext";
interface Props {
- filteredPickOrders: PickOrderResult[],
+ filteredPickOrders: PickOrderResult[];
+ filterArgs: Record;
}
-const PickOrders: React.FC = ({
- filteredPickOrders
-}) => {
- const { t } = useTranslation("pickOrder")
- const [selectedRows, setSelectedRows] = useState<(string | number)[]>([]);
+const PickOrders: React.FC = ({ filteredPickOrders, filterArgs }) => {
+ const { t } = useTranslation("pickOrder");
+ const [selectedRows, setSelectedRows] = useState<(string | number)[]>([]);
+ const [filteredPickOrder, setFilteredPickOrder] = useState(
+ [] as PickOrderResult[]
+ );
+ const { setIsUploading } = useUploadContext();
+ const [isLoading, setIsLoading] = useState(false);
+ const [pagingController, setPagingController] = useState({
+ pageNum: 0,
+ pageSize: 10,
+ });
+ const [totalCount, setTotalCount] = useState();
- const handleConsolidatedRows = useCallback(() => {
+ 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]);
- }, [selectedRows])
+ const fetchNewPagePickOrder = useCallback(
+ async (
+ pagingController: Record,
+ filterArgs: Record
+ ) => {
+ setIsLoading(true);
+ const params = {
+ ...pagingController,
+ ...filterArgs,
+ };
+ const res = await fetchPickOrderClient(params)
+ if (res) {
+ console.log(res);
+ setFilteredPickOrder(res.records);
+ setTotalCount(res.total);
+ }
+ setIsLoading(false);
+ },
+ []
+ );
- const columns = useMemo[]>(() => [
- {
- name: "id",
- label: "",
- type: "checkbox",
- disabled: (params) => {
- return !isEmpty(params.consoCode);
- }
- },
- {
- name: "code",
- label: t("Code"),
- },
- {
- name: "consoCode",
- label: t("Consolidated Code"),
- renderCell: (params) => {
- return params.consoCode ?? "N/A"
- }
+ useEffect(() => {
+ fetchNewPagePickOrder(pagingController, filterArgs);
+ }, [fetchNewPagePickOrder, pagingController, filterArgs]);
+
+ const columns = useMemo[]>(
+ () => [
+ {
+ name: "id",
+ label: "",
+ type: "checkbox",
+ disabled: (params) => {
+ return !isEmpty(params.consoCode);
},
- {
- name: "type",
- label: t("type"),
- renderCell: (params) => {
- return upperCase(params.type)
- }
+ },
+ {
+ name: "code",
+ label: t("Code"),
+ },
+ {
+ name: "consoCode",
+ label: t("Consolidated Code"),
+ renderCell: (params) => {
+ return params.consoCode ?? "";
},
- {
- name: "items",
- label: t("Items"),
- renderCell: (params) => {
- return params.items?.map((i) => i.name).join(", ")
- }
+ },
+ {
+ name: "type",
+ label: t("type"),
+ renderCell: (params) => {
+ return upperCase(params.type);
},
- {
- name: "targetDate",
- label: t("Target Date"),
- renderCell: (params) => {
- return arrayToDateString(params.targetDate)
- }
+ },
+ {
+ name: "items",
+ label: t("Items"),
+ renderCell: (params) => {
+ return params.items?.map((i) => i.name).join(", ");
},
- {
- name: "releasedBy",
- label: t("Released By"),
+ },
+ {
+ name: "targetDate",
+ label: t("Target Date"),
+ renderCell: (params) => {
+ return arrayToDateString(params.targetDate);
},
- {
- name: "status",
- label: t("Status"),
- renderCell: (params) => {
- return upperFirst(params.status)
- }
+ },
+ {
+ name: "releasedBy",
+ label: t("Released By"),
+ },
+ {
+ name: "status",
+ label: t("Status"),
+ renderCell: (params) => {
+ return upperFirst(params.status);
},
- ], [t])
+ },
+ ],
+ [t]
+ );
- return (
-
-
-
-
-
- items={filteredPickOrders} columns={columns} pagingController={{
- pageNum: 0,
- pageSize: 0
- }}
- checkboxIds={selectedRows}
- setCheckboxIds={setSelectedRows}
- />
-
-
- )
-}
+ return (
+
+
+
+
+
+ {isLoading ? (
+
+ ) : (
+
+ items={filteredPickOrder}
+ columns={columns}
+ pagingController={pagingController}
+ setPagingController={setPagingController}
+ totalCount={totalCount}
+ checkboxIds={selectedRows!!}
+ setCheckboxIds={setSelectedRows}
+ />
+ )}
+
+
+ );
+};
-export default PickOrders;
\ No newline at end of file
+export default PickOrders;
diff --git a/src/components/PoSearch/PoSearch.tsx b/src/components/PoSearch/PoSearch.tsx
index 67db55c..c50ac0e 100644
--- a/src/components/PoSearch/PoSearch.tsx
+++ b/src/components/PoSearch/PoSearch.tsx
@@ -152,7 +152,7 @@ const PoSearch: React.FC = ({
setTotalCount(res.total);
}
},
- [fetchPoListClient, pagingController]
+ [fetchPoListClient]
);
useEffect(() => {
diff --git a/src/components/SearchResults/SearchResults.tsx b/src/components/SearchResults/SearchResults.tsx
index 60a65d0..9cc7fdb 100644
--- a/src/components/SearchResults/SearchResults.tsx
+++ b/src/components/SearchResults/SearchResults.tsx
@@ -209,7 +209,24 @@ function SearchResults({
};
// checkbox
- const handleRowClick = useCallback((event: MouseEvent, id: string | number) => {
+ const handleRowClick = useCallback((event: MouseEvent, item: T, columns: Column[]) => {
+ // check is disabled or not
+ var disabled = false
+ columns.forEach((col) => {
+ if (isCheckboxColumn(col) && col.disabled) {
+ disabled = col.disabled(item)
+ if (disabled) {
+ return;
+ }
+ }
+ })
+
+ if (disabled) {
+ return;
+ }
+
+ // set id
+ const id = item.id
if (setCheckboxIds) {
const selectedIndex = checkboxIds.indexOf(id);
let newSelected: (string | number)[] = [];
@@ -257,7 +274,7 @@ function SearchResults({
hover
tabIndex={-1}
key={item.id}
- onClick={setCheckboxIds ? (event) => handleRowClick(event, item.id) : undefined}
+ onClick={setCheckboxIds? (event) => handleRowClick(event, item, columns) : undefined}
role={setCheckboxIds ? "checkbox" : undefined}
>
{columns.map((column, idx) => {
diff --git a/src/i18n/zh/common.json b/src/i18n/zh/common.json
index 3c9e332..9fbdfa6 100644
--- a/src/i18n/zh/common.json
+++ b/src/i18n/zh/common.json
@@ -1,4 +1,24 @@
{
+ "Overview": "概述",
+ "Qc Item": "品質檢驗項目",
+ "Dashboard": "儀表板",
+ "dashboard": "儀表板",
+ "Raw Material": "原料",
+ "Purchase Order": "採購訂單",
+ "Pick Order": "提料單",
+ "View item In-out And inventory Ledger": "存貨",
+ "Inventory": "存貨",
+ "Delivery": "送貨",
+ "Delivery Order": "送貨單",
+ "Scheduling": "生產計劃",
+ "Demand Forecast Setting": "粗排設定",
+ "Demand Forecast": "粗排",
+ "FG & Material Demand Forecast Detail": "成品 & 原料粗排細節",
+ "Detail Scheduling": "細排",
+ "FG Production Schedule": "成品生產計劃",
+ "Settings": "設定",
+ "Edit": "編輯",
+
"Search Criteria": "搜尋條件",
"All": "全部",
"No options": "沒有選項",