"use client"; import { PickOrderResult } from "@/app/api/pickOrder"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import SearchBox, { Criterion } from "../SearchBox"; import { flatten, intersectionWith, isEmpty, sortBy, uniqBy, upperCase, upperFirst, } from "lodash"; import { arrayToDayjs, } from "@/app/utils/formatUtil"; import { Button, Grid, Stack, Tab, Tabs, TabsProps, Typography, Box } from "@mui/material"; import PickOrders from "./FinishedGood"; import ConsolidatedPickOrders from "./ConsolidatedPickOrders"; import PickExecution from "./GoodPickExecution"; import CreatePickOrderModal from "./CreatePickOrderModal"; import NewCreateItem from "./newcreatitem"; import AssignAndRelease from "./AssignAndRelease"; import AssignTo from "./assignTo"; import { fetchAllItemsInClient, ItemCombo } from "@/app/api/settings/item/actions"; import { fetchPickOrderClient, autoAssignAndReleasePickOrder, autoAssignAndReleasePickOrderByStore } from "@/app/api/pickOrder/actions"; import Jobcreatitem from "./Jobcreatitem"; import { useSession } from "next-auth/react"; import { SessionWithTokens } from "@/config/authConfig"; import PickExecutionDetail from "./GoodPickExecutiondetail"; import GoodPickExecutionRecord from "./GoodPickExecutionRecord"; interface Props { pickOrders: PickOrderResult[]; } type SearchQuery = Partial< Omit >; type SearchParamNames = keyof SearchQuery; const PickOrderSearch: React.FC = ({ pickOrders }) => { const { t } = useTranslation("pickOrder"); const { data: session } = useSession() as { data: SessionWithTokens | null }; const currentUserId = session?.id ? parseInt(session.id) : undefined; const [isOpenCreateModal, setIsOpenCreateModal] = useState(false) const [items, setItems] = useState([]) const [printButtonsEnabled, setPrintButtonsEnabled] = useState(false); const [filteredPickOrders, setFilteredPickOrders] = useState(pickOrders); const [filterArgs, setFilterArgs] = useState>({}); const [searchQuery, setSearchQuery] = useState>({}); const [tabIndex, setTabIndex] = useState(0); const [totalCount, setTotalCount] = useState(); const [isAssigning, setIsAssigning] = useState(false); const [hideCompletedUntilNext, setHideCompletedUntilNext] = useState( typeof window !== 'undefined' && localStorage.getItem('hideCompletedUntilNext') === 'true' ); useEffect(() => { const onAssigned = () => { localStorage.removeItem('hideCompletedUntilNext'); setHideCompletedUntilNext(false); }; window.addEventListener('pickOrderAssigned', onAssigned); return () => window.removeEventListener('pickOrderAssigned', onAssigned); }, []); const handleAssignByStore = async (storeId: "2/F" | "4/F") => { if (!currentUserId) { console.error("Missing user id in session"); return; } setIsAssigning(true); try { const res = await autoAssignAndReleasePickOrderByStore(currentUserId, storeId); console.log("Assign by store result:", res); // ✅ Handle different response codes if (res.code === "SUCCESS") { console.log("✅ Successfully assigned pick order to store", storeId); // ✅ Trigger refresh to show newly assigned data window.dispatchEvent(new CustomEvent('pickOrderAssigned')); } else if (res.code === "USER_BUSY") { console.warn("⚠️ User already has pick orders in progress:", res.message); // ✅ Show warning but still refresh to show existing orders alert(`Warning: ${res.message}`); window.dispatchEvent(new CustomEvent('pickOrderAssigned')); } else if (res.code === "NO_ORDERS") { console.log("ℹ️ No available pick orders for store", storeId); alert(`Info: ${res.message}`); } else { console.log("ℹ️ Assignment result:", res.message); alert(`Info: ${res.message}`); } } catch (error) { console.error("❌ Error assigning by store:", error); alert("Error occurred during assignment"); } finally { setIsAssigning(false); } }; // ✅ Manual assignment handler - uses the action function const handleTabChange = useCallback>( (_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) }, []) useEffect(() => { if (tabIndex === 3) { const loadItems = async () => { try { const itemsData = await fetchAllItemsInClient(); console.log("PickOrderSearch loaded items:", itemsData.length); setItems(itemsData); } catch (error) { console.error("Error loading items in PickOrderSearch:", error); } }; // 如果还没有数据,则加载 if (items.length === 0) { loadItems(); } } }, [tabIndex, items.length]); useEffect(() => { const handleCompletionStatusChange = (event: CustomEvent) => { const { allLotsCompleted } = event.detail; setPrintButtonsEnabled(allLotsCompleted); console.log("Print buttons enabled:", allLotsCompleted); }; window.addEventListener('pickOrderCompletionStatus', handleCompletionStatusChange as EventListener); return () => { window.removeEventListener('pickOrderCompletionStatus', handleCompletionStatusChange as EventListener); }; }, []); const searchCriteria: Criterion[] = useMemo( () => { const baseCriteria: Criterion[] = [ { label: tabIndex === 3 ? t("Item Code") : t("Code"), paramName: "code", type: "text" }, { label: t("Type"), paramName: "type", type: "autocomplete", options: tabIndex === 3 ? [ { value: "Consumable", label: t("Consumable") }, { value: "Material", label: t("Material") }, { value: "Product", label: t("Product") } ] : sortBy( uniqBy( pickOrders.map((po) => ({ value: po.type, label: t(upperCase(po.type)), })), "value", ), "label", ), }, ]; // Add Job Order search for Create Item tab (tabIndex === 3) if (tabIndex === 3) { baseCriteria.splice(1, 0, { label: t("Job Order"), paramName: "jobOrderCode" as any, // Type assertion for now type: "text", }); baseCriteria.splice(2, 0, { label: t("Target Date"), paramName: "targetDate", type: "date", }); } else { baseCriteria.splice(1, 0, { label: t("Target Date From"), label2: t("Target Date To"), paramName: "targetDate", type: "dateRange", }); } // Add Items/Item Name criteria baseCriteria.push({ label: tabIndex === 3 ? t("Item Name") : t("Items"), paramName: "items", type: tabIndex === 3 ? "text" : "autocomplete", options: tabIndex === 3 ? [] : uniqBy( flatten( sortBy( pickOrders.map((po) => po.items ? po.items.map((item) => ({ value: item.name, label: item.name, })) : [], ), "label", ), ), "value", ), }); // Add Status criteria for non-Create Item tabs if (tabIndex !== 3) { baseCriteria.push({ label: t("Status"), paramName: "status", type: "autocomplete", options: sortBy( uniqBy( pickOrders.map((po) => ({ value: po.status, label: t(upperFirst(po.status)), })), "value", ), "label", ), }); } return baseCriteria; }, [pickOrders, t, tabIndex, items], ); const fetchNewPagePickOrder = useCallback( async ( pagingController: Record, filterArgs: Record, ) => { 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]) // 添加处理提料单创建成功的函数 const handlePickOrderCreated = useCallback(() => { // 切换到 Assign & Release 标签页 (tabIndex = 1) setTabIndex(2); }, []); return ( {/* Header section */} {t("Finished Good Order")} {/* Last 2 buttons aligned right */} {/* ✅ Updated print buttons with completion status */} {/* */} {/* Tabs section - ✅ Move the click handler here */} {/* Content section - NO overflow: 'auto' here */} {tabIndex === 0 && } {tabIndex === 1 && } {tabIndex === 2 && } ); }; export default PickOrderSearch;