| @@ -8,6 +8,11 @@ export interface ReportOption { | |||||
| value: string; | value: string; | ||||
| } | } | ||||
| export interface TruckRoutingSummaryPrecheck { | |||||
| unpickedOrderCount: number; | |||||
| hasUnpickedOrders: boolean; | |||||
| } | |||||
| export async function fetchTruckRoutingStoreOptions(): Promise<ReportOption[]> { | export async function fetchTruckRoutingStoreOptions(): Promise<ReportOption[]> { | ||||
| const response = await clientAuthFetch( | const response = await clientAuthFetch( | ||||
| `${NEXT_PUBLIC_API_URL}/truck-routing-summary/store-options`, | `${NEXT_PUBLIC_API_URL}/truck-routing-summary/store-options`, | ||||
| @@ -50,3 +55,30 @@ export async function fetchTruckRoutingLaneOptions(storeId?: string): Promise<Re | |||||
| value: item?.value ?? "", | value: item?.value ?? "", | ||||
| })); | })); | ||||
| } | } | ||||
| export async function fetchTruckRoutingSummaryPrecheck(params: { | |||||
| storeId: string; | |||||
| truckLanceCode: string; | |||||
| date: string; | |||||
| }): Promise<TruckRoutingSummaryPrecheck> { | |||||
| const qs = new URLSearchParams({ | |||||
| storeId: params.storeId, | |||||
| truckLanceCode: params.truckLanceCode, | |||||
| date: params.date, | |||||
| }).toString(); | |||||
| const response = await clientAuthFetch( | |||||
| `${NEXT_PUBLIC_API_URL}/truck-routing-summary/precheck?${qs}`, | |||||
| { | |||||
| method: "GET", | |||||
| headers: { "Content-Type": "application/json" }, | |||||
| } | |||||
| ); | |||||
| if (!response.ok) { | |||||
| throw new Error(`Failed to precheck routing summary: ${response.status}`); | |||||
| } | |||||
| const data = await response.json(); | |||||
| return { | |||||
| unpickedOrderCount: Number(data?.unpickedOrderCount ?? 0), | |||||
| hasUnpickedOrders: Boolean(data?.hasUnpickedOrders), | |||||
| }; | |||||
| } | |||||
| @@ -44,6 +44,7 @@ import FGPickOrderTicketReleaseTable from "./FGPickOrderTicketReleaseTable"; | |||||
| import TruckRoutingSummaryTab, { TruckRoutingSummaryFilters } from "./TruckRoutingSummaryTab"; | import TruckRoutingSummaryTab, { TruckRoutingSummaryFilters } from "./TruckRoutingSummaryTab"; | ||||
| import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; | import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; | ||||
| import { NEXT_PUBLIC_API_URL } from "@/config/api"; | import { NEXT_PUBLIC_API_URL } from "@/config/api"; | ||||
| import { fetchTruckRoutingSummaryPrecheck } from "@/app/(main)/report/truckRoutingSummaryApi"; | |||||
| interface Props { | interface Props { | ||||
| // pickOrders: PickOrderResult[]; | // pickOrders: PickOrderResult[]; | ||||
| @@ -313,6 +314,27 @@ const [selectedPrinterForDraft, setSelectedPrinterForDraft] = useState<PrinterCo | |||||
| return; | return; | ||||
| } | } | ||||
| const precheck = await fetchTruckRoutingSummaryPrecheck({ | |||||
| storeId, | |||||
| truckLanceCode, | |||||
| date, | |||||
| }); | |||||
| if (precheck.hasUnpickedOrders) { | |||||
| const confirmResult = await Swal.fire({ | |||||
| title: "仍有訂單未執拾", | |||||
| text: `此車線仍有 ${precheck.unpickedOrderCount} 張訂單未執拾,是否仍要列印?`, | |||||
| icon: "warning", | |||||
| showCancelButton: true, | |||||
| confirmButtonText: "仍要列印", | |||||
| cancelButtonText: "取消", | |||||
| confirmButtonColor: "#8dba00", | |||||
| cancelButtonColor: "#F04438", | |||||
| }); | |||||
| if (!confirmResult.isConfirmed) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| const qs = new URLSearchParams({ | const qs = new URLSearchParams({ | ||||
| printerId: selectedPrinterForAllDraft.id.toString(), | printerId: selectedPrinterForAllDraft.id.toString(), | ||||
| printQty: "1", | printQty: "1", | ||||
| @@ -5,7 +5,12 @@ import { Box, Button, MenuItem, Stack, TextField, Typography } from "@mui/materi | |||||
| import DownloadIcon from "@mui/icons-material/Download"; | import DownloadIcon from "@mui/icons-material/Download"; | ||||
| import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; | import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; | ||||
| import { NEXT_PUBLIC_API_URL } from "@/config/api"; | import { NEXT_PUBLIC_API_URL } from "@/config/api"; | ||||
| import { fetchTruckRoutingLaneOptions, fetchTruckRoutingStoreOptions, ReportOption } from "@/app/(main)/report/truckRoutingSummaryApi"; | |||||
| import { | |||||
| fetchTruckRoutingLaneOptions, | |||||
| fetchTruckRoutingStoreOptions, | |||||
| fetchTruckRoutingSummaryPrecheck, | |||||
| ReportOption, | |||||
| } from "@/app/(main)/report/truckRoutingSummaryApi"; | |||||
| export type TruckRoutingSummaryFilters = { | export type TruckRoutingSummaryFilters = { | ||||
| storeId: string; | storeId: string; | ||||
| @@ -51,8 +56,20 @@ const TruckRoutingSummaryTab: React.FC<Props> = ({ onFiltersChange }) => { | |||||
| const onDownload = async () => { | const onDownload = async () => { | ||||
| if (!canDownload) return; | if (!canDownload) return; | ||||
| setLoading(true); | |||||
| try { | try { | ||||
| const precheck = await fetchTruckRoutingSummaryPrecheck({ | |||||
| storeId, | |||||
| truckLanceCode, | |||||
| date, | |||||
| }); | |||||
| if (precheck.hasUnpickedOrders) { | |||||
| const confirmed = window.confirm( | |||||
| `此車線仍有 ${precheck.unpickedOrderCount} 張訂單未執拾。\n是否仍要列印 / 下載送貨路線摘要?` | |||||
| ); | |||||
| if (!confirmed) return; | |||||
| } | |||||
| setLoading(true); | |||||
| const qs = new URLSearchParams({ | const qs = new URLSearchParams({ | ||||
| storeId, | storeId, | ||||
| truckLanceCode, | truckLanceCode, | ||||