From b2084bd4ad34c76bfcac48a39014de5d5dcb9722 Mon Sep 17 00:00:00 2001 From: "vluk@2fi-solutions.com.hk" Date: Fri, 8 May 2026 15:33:24 +0800 Subject: [PATCH] added isExtra to DO --- src/app/(main)/m18Syn/page.tsx | 90 +++++++++++++++++++++++++++++++++- src/app/api/do/actions.tsx | 9 +++- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/src/app/(main)/m18Syn/page.tsx b/src/app/(main)/m18Syn/page.tsx index 09705b5..3c82b3c 100644 --- a/src/app/(main)/m18Syn/page.tsx +++ b/src/app/(main)/m18Syn/page.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useRef, useState } from "react"; import { Box, Button, Paper, Stack, Tab, Tabs, TextField, Typography } from "@mui/material"; import { NEXT_PUBLIC_API_URL } from "@/config/api"; import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; @@ -32,20 +32,30 @@ export default function M18SynPage() { const [m18PoCode, setM18PoCode] = useState(""); const [isSyncingM18Po, setIsSyncingM18Po] = useState(false); const [m18PoSyncResult, setM18PoSyncResult] = useState(""); + const m18PoInFlightRef = useRef(false); const [m18DoCode, setM18DoCode] = useState(""); const [isSyncingM18Do, setIsSyncingM18Do] = useState(false); const [m18DoSyncResult, setM18DoSyncResult] = useState(""); + const m18DoInFlightRef = useRef(false); + + const [m18DoExtraCode, setM18DoExtraCode] = useState(""); + const [isSyncingM18DoExtra, setIsSyncingM18DoExtra] = useState(false); + const [m18DoExtraSyncResult, setM18DoExtraSyncResult] = useState(""); + const m18DoExtraInFlightRef = useRef(false); const [m18ProductCode, setM18ProductCode] = useState(""); const [isSyncingM18Product, setIsSyncingM18Product] = useState(false); const [m18ProductSyncResult, setM18ProductSyncResult] = useState(""); + const m18ProductInFlightRef = useRef(false); const handleSyncM18PoByCode = async () => { + if (m18PoInFlightRef.current) return; if (!m18PoCode.trim()) { alert("Please enter PO code."); return; } + m18PoInFlightRef.current = true; setIsSyncingM18Po(true); setM18PoSyncResult(""); try { @@ -64,14 +74,17 @@ export default function M18SynPage() { alert("M18 PO sync failed. Check console/network."); } finally { setIsSyncingM18Po(false); + m18PoInFlightRef.current = false; } }; const handleSyncM18DoByCode = async () => { + if (m18DoInFlightRef.current) return; if (!m18DoCode.trim()) { alert("Please enter DO / shop PO code."); return; } + m18DoInFlightRef.current = true; setIsSyncingM18Do(true); setM18DoSyncResult(""); try { @@ -90,14 +103,47 @@ export default function M18SynPage() { alert("M18 DO sync failed. Check console/network."); } finally { setIsSyncingM18Do(false); + m18DoInFlightRef.current = false; + } + }; + + /** DO(加單):M18 搜尋需含備註「(加單)」,本地 isEtra = true */ + const handleSyncM18DoExtraByCode = async () => { + if (m18DoExtraInFlightRef.current) return; + if (!m18DoExtraCode.trim()) { + alert("Please enter DO / shop PO code (加單)."); + return; + } + m18DoExtraInFlightRef.current = true; + setIsSyncingM18DoExtra(true); + setM18DoExtraSyncResult(""); + try { + const response = await clientAuthFetch( + `${NEXT_PUBLIC_API_URL}/m18/test/do-by-code-extra?code=${encodeURIComponent(m18DoExtraCode.trim())}`, + { method: "GET" }, + ); + if (response.status === 401 || response.status === 403) return; + const text = await response.text(); + setM18DoExtraSyncResult(text); + if (!response.ok) { + alert(`Sync failed: ${response.status}`); + } + } catch (e) { + console.error("M18 DO (加單) Sync By Code Error:", e); + alert("M18 DO (加單) sync failed. Check console/network."); + } finally { + setIsSyncingM18DoExtra(false); + m18DoExtraInFlightRef.current = false; } }; const handleSyncM18ProductByCode = async () => { + if (m18ProductInFlightRef.current) return; if (!m18ProductCode.trim()) { alert("Please enter M18 item / product code."); return; } + m18ProductInFlightRef.current = true; setIsSyncingM18Product(true); setM18ProductSyncResult(""); try { @@ -116,6 +162,7 @@ export default function M18SynPage() { alert("M18 product sync failed. Check console/network."); } finally { setIsSyncingM18Product(false); + m18ProductInFlightRef.current = false; } }; @@ -140,7 +187,8 @@ export default function M18SynPage() { setTabValue(v)} aria-label="M18 sync by code" centered variant="fullWidth"> - + + @@ -202,6 +250,43 @@ export default function M18SynPage() { +
+ + 與「2. DO」相同以單號從 M18 同步 shop PO/送貨單,但 M18 列表條件會限制備註含「(加單)」;同步寫入之 delivery_order.isEtra = true。 + + + setM18DoExtraCode(e.target.value)} + placeholder="e.g. 與一般 DO 相同單號,但須為加單單據" + sx={{ minWidth: 320 }} + /> + + + {m18DoExtraSyncResult ? ( + + ) : null} +
+
+ +
+ ); } diff --git a/src/app/api/do/actions.tsx b/src/app/api/do/actions.tsx index 7f144bc..7468979 100644 --- a/src/app/api/do/actions.tsx +++ b/src/app/api/do/actions.tsx @@ -25,6 +25,8 @@ export interface DoDetail { estimatedArrivalDate: string; completeDate: string; status: string; + /** 加單 DO */ + isEtra?: boolean; deliveryOrderLines: DoDetailLine[]; } @@ -49,7 +51,7 @@ export interface DoSearchAll { supplierName: string; shopName: string; shopAddress?: string; - + isEtra?: boolean; } export interface DoSearchLiteResponse { records: DoSearchAll[]; @@ -377,6 +379,8 @@ export async function fetchDoSearch( truckLanceCode?: string, /** 後端:All/null 為全部;2F/4F 依供應商白名單篩選 */ floor?: string | null, + /** null:不篩;true/false:只顯示加單或非加單 DO */ + isEtra?: boolean | null, ): Promise { // 构建请求体 const requestBody: any = { @@ -388,6 +392,7 @@ export async function fetchDoSearch( pageNum: pageNum || 1, pageSize: pageSize || 10, floor: floor && floor !== "All" ? floor : null, + ...(isEtra !== undefined && isEtra !== null ? { isEtra } : {}), }; // 如果日期不为空,转换为 LocalDateTime 格式 @@ -627,6 +632,7 @@ export async function fetchAllDoSearch( estArrStartDate: string, truckLanceCode?: string, floor?: string | null, + isEtra?: boolean | null, ): Promise { // 使用一个很大的 pageSize 来获取所有匹配的记录 const requestBody: any = { @@ -638,6 +644,7 @@ export async function fetchAllDoSearch( pageNum: 1, pageSize: 10000, // 使用一个很大的值来获取所有记录 floor: floor && floor !== "All" ? floor : null, + ...(isEtra !== undefined && isEtra !== null ? { isEtra } : {}), }; if (estArrStartDate) {