diff --git a/src/app/(main)/bag/page.tsx b/src/app/(main)/bag/page.tsx
new file mode 100644
index 0000000..8e859ef
--- /dev/null
+++ b/src/app/(main)/bag/page.tsx
@@ -0,0 +1,35 @@
+import BagSearchWrapper from "@/components/BagSearch/BagSearchWrapper";
+import { I18nProvider, getServerI18n } from "@/i18n";
+import { Stack, Typography } from "@mui/material";
+import { Metadata } from "next";
+import React, { Suspense } from "react";
+
+export const metadata: Metadata = {
+ title: "Bag Usage Records"
+}
+
+const bagPage: React.FC = async () => {
+ const { t } = await getServerI18n("jo");
+
+ return (
+ <>
+
+
+ {t("Bag Usage")}
+
+
+
+ }>
+
+
+
+ >
+ )
+}
+
+export default bagPage;
\ No newline at end of file
diff --git a/src/app/(main)/jo/page.tsx b/src/app/(main)/jo/page.tsx
index 9027ebf..6e2f73a 100644
--- a/src/app/(main)/jo/page.tsx
+++ b/src/app/(main)/jo/page.tsx
@@ -23,7 +23,7 @@ const jo: React.FC = async () => {
rowGap={2}
>
- {t("Job Order")}
+ {t("Search Job Order/ Create Job Order")}
{/* TODO: Improve */}
diff --git a/src/app/api/bag/action.ts b/src/app/api/bag/action.ts
index 0232168..8d4bc21 100644
--- a/src/app/api/bag/action.ts
+++ b/src/app/api/bag/action.ts
@@ -44,4 +44,78 @@ export const getBagInfo = cache(async () => {
body: JSON.stringify(request),
}
);
- });
\ No newline at end of file
+ });
+
+ export interface BagUsageRecordResponse {
+ id: number;
+ bagId: number;
+ bagLotLineId: number;
+ jobId: number;
+ jobOrderCode: string;
+ stockOutLineId: number;
+ startQty: number;
+ consumedQty: number;
+ scrapQty: number;
+ endQty: number;
+ date: string;
+ time: string;
+ bagName?: string;
+ bagCode?: string;
+ lotNo?: string;
+}
+
+// 添加 API 调用函数:
+
+export const getBagUsageRecords = cache(async () => {
+ return serverFetchJson(
+ `${BASE_API_URL}/bag/bagUsageRecords`,
+ {
+ method: "GET",
+ next: { tags: ["bagUsageRecords"] },
+ }
+ );
+});
+export interface BagSummaryResponse {
+ id: number;
+ bagName: string;
+ bagCode: string;
+ takenBagBalance: number;
+ deleted: boolean;
+}
+export interface BagLotLineResponse {
+ id: number;
+ bagId: number;
+ lotNo: string;
+ stockOutLineId: number;
+ startQty: number;
+ consumedQty: number;
+ scrapQty: number;
+ balanceQty: number;
+ firstUseDate: string;
+ lastUseDate: string;
+}
+export interface BagConsumptionResponse {
+ id: number;
+ bagId: number;
+ bagLotLineId: number;
+ jobId: number;
+ jobOrderCode: string;
+ stockOutLineId: number;
+ startQty: number;
+ consumedQty: number;
+ scrapQty: number;
+ endQty: number;
+ date: string;
+ time: string;
+}
+export const fetchBags = cache(async () =>
+ serverFetchJson(`${BASE_API_URL}/bag/bags`, { method: "GET" })
+);
+
+export const fetchBagLotLines = cache(async (bagId: number) =>
+ serverFetchJson(`${BASE_API_URL}/bag/bags/${bagId}/lot-lines`, { method: "GET" })
+);
+
+export const fetchBagConsumptions = cache(async (bagLotLineId: number) =>
+ serverFetchJson(`${BASE_API_URL}/bag/lot-lines/${bagLotLineId}/consumptions`, { method: "GET" })
+);
\ No newline at end of file
diff --git a/src/app/api/do/actions.tsx b/src/app/api/do/actions.tsx
index 5d54928..5007a80 100644
--- a/src/app/api/do/actions.tsx
+++ b/src/app/api/do/actions.tsx
@@ -318,6 +318,30 @@ export async function printDNLabels(request: PrintDNLabelsRequest){
return { success: true, message: "Print job sent successfully (labels)"} as PrintDeliveryNoteResponse
}
-
+export interface Check4FTruckBatchResponse {
+ hasProblem: boolean;
+ problems: ProblemDoDto[];
+}
+export interface ProblemDoDto {
+ deliveryOrderId: number;
+ deliveryOrderCode: string;
+ targetDate: string;
+ availableTrucks: TruckInfoDto[];
+}
+export interface TruckInfoDto {
+ id: number;
+ truckLanceCode: string;
+ departureTime: string;
+ storeId: string;
+ shopCode: string;
+ shopName: string;
+}
+export const check4FTrucksBatch = cache(async (doIds: number[]) => {
+ return await serverFetchJson(`${BASE_API_URL}/do/check-4f-trucks-batch`, {
+ method: "POST",
+ body: JSON.stringify(doIds),
+ headers: { "Content-Type": "application/json" },
+ });
+});
diff --git a/src/app/api/jo/actions.ts b/src/app/api/jo/actions.ts
index 306e1f4..2b76c7c 100644
--- a/src/app/api/jo/actions.ts
+++ b/src/app/api/jo/actions.ts
@@ -166,7 +166,19 @@ export const printFGStockInLabel = cache(async(data: PrintFGStockInLabelRequest)
}
);
});
+export interface UpdateJoReqQtyRequest {
+ id: number;
+ reqQty: number;
+}
+// 添加更新 reqQty 的函数
+export const updateJoReqQty = cache(async (data: UpdateJoReqQtyRequest) => {
+ return serverFetchJson(`${BASE_API_URL}/jo/updateReqQty`, {
+ method: "POST",
+ body: JSON.stringify(data),
+ headers: { "Content-Type": "application/json" },
+ })
+})
export const recordSecondScanIssue = cache(async (
pickOrderId: number,
@@ -250,6 +262,7 @@ export interface ProductProcessWithLinesResponse {
bomDescription: string;
jobType: string;
isDark: string;
+ bomBaseQty: number;
isDense: number;
isFloat: string;
timeSequence: number;
@@ -262,6 +275,7 @@ export interface ProductProcessWithLinesResponse {
outputQty: number;
outputQtyUom: string;
productionPriority: number;
+ submitedBagRecord?: boolean;
jobOrderLines: JobOrderLineInfo[];
productProcessLines: ProductProcessLineResponse[];
@@ -417,6 +431,7 @@ export interface JobOrderProcessLineDetailResponse {
stopTime: string | number[];
totalPausedTimeMs?: number; // API 返回的是数组格式
status: string;
+ submitedBagRecord: boolean;
outputFromProcessQty: number;
outputFromProcessUom: string;
defectQty: number;
@@ -779,7 +794,14 @@ export const fetchProductProcessesByJobOrderId = cache(async (jobOrderId: number
}
);
});
-
+export const newProductProcessLine = cache(async (lineId: number) => {
+ return serverFetchJson(
+ `${BASE_API_URL}/product-process/Demo/ProcessLine/new/${lineId}`,
+ {
+ method: "POST",
+ }
+ );
+});
// 获取 process 的所有 lines
export const fetchProductProcessLines = cache(async (processId: number) => {
return serverFetchJson(
@@ -1129,4 +1151,20 @@ export const passProductProcessLine = async (lineId: number) => {
headers: { "Content-Type": "application/json" },
}
);
+};
+export interface UpdateProductProcessLineProcessingTimeSetupTimeChangeoverTimeRequest {
+ productProcessLineId: number;
+ processingTime: number;
+ setupTime: number;
+ changeoverTime: number;
+}
+export const updateProductProcessLineProcessingTimeSetupTimeChangeoverTime = async (lineId: number, request: UpdateProductProcessLineProcessingTimeSetupTimeChangeoverTimeRequest) => {
+ return serverFetchJson(
+ `${BASE_API_URL}/product-process/Demo/ProcessLine/update/processingTimeSetupTimeChangeoverTime/${lineId}`,
+ {
+ method: "POST",
+ body: JSON.stringify(request),
+ headers: { "Content-Type": "application/json" },
+ }
+ );
};
\ No newline at end of file
diff --git a/src/app/api/stockTake/actions.ts b/src/app/api/stockTake/actions.ts
index b0cea1a..5e0c0e6 100644
--- a/src/app/api/stockTake/actions.ts
+++ b/src/app/api/stockTake/actions.ts
@@ -1,10 +1,91 @@
+// actions.ts
"use server";
-
-import { serverFetchString } from "@/app/utils/fetchUtil";
+import { cache } from 'react';
+import { serverFetchJson } from "@/app/utils/fetchUtil"; // 改为 serverFetchJson
import { BASE_API_URL } from "@/config/api";
+export interface InventoryLotDetailResponse {
+ id: number;
+ inventoryLotId: number;
+ itemId: number;
+ itemCode: string;
+ itemName: string;
+ lotNo: string;
+ expiryDate: string;
+ productionDate: string;
+ stockInDate: string;
+ inQty: number;
+ outQty: number;
+ holdQty: number;
+ availableQty: number;
+ uom: string;
+ warehouseCode: string;
+ warehouseName: string;
+ warehouseSlot: string;
+ warehouseArea: string;
+ warehouse: string;
+ varianceQty: number | null;
+ status: string;
+ remarks: string | null;
+ stockTakeRecordStatus: string;
+ stockTakeRecordId: number | null;
+ firstStockTakeQty: number | null;
+ secondStockTakeQty: number | null;
+ firstBadQty: number | null;
+ secondBadQty: number | null;
+ approverQty: number | null;
+ approverBadQty: number | null;
+ finalQty: number | null;
+}
+
+export const getInventoryLotDetailsBySection = async (
+ stockTakeSection: string,
+ stockTakeId?: number | null
+) => {
+ console.log('🌐 [API] getInventoryLotDetailsBySection called with:', {
+ stockTakeSection,
+ stockTakeId
+ });
+
+ const encodedSection = encodeURIComponent(stockTakeSection);
+ let url = `${BASE_API_URL}/stockTakeRecord/inventoryLotDetailsBySection?stockTakeSection=${encodedSection}`;
+ if (stockTakeId != null && stockTakeId > 0) {
+ url += `&stockTakeId=${stockTakeId}`;
+ }
+
+ console.log(' [API] Full URL:', url);
+
+ const details = await serverFetchJson(
+ url,
+ {
+ method: "GET",
+ },
+ );
+
+ console.log('[API] Response received:', details);
+ return details;
+}
+export interface SaveStockTakeRecordRequest {
+ stockTakeRecordId?: number | null;
+ inventoryLotLineId: number;
+ qty: number;
+ badQty: number;
+ //stockTakerName: string;
+ remark?: string | null;
+}
+export interface AllPickedStockTakeListReponse {
+ id: number;
+ stockTakeSession: string;
+ lastStockTakeDate: string | null;
+ status: string|null;
+ currentStockTakeItemNumber: number;
+ totalInventoryLotNumber: number;
+ stockTakeId: number;
+ stockTakerName: string | null;
+ totalItemNumber: number;
+}
export const importStockTake = async (data: FormData) => {
- const importStockTake = await serverFetchString(
+ const importStockTake = await serverFetchJson(
`${BASE_API_URL}/stockTake/import`,
{
method: "POST",
@@ -12,4 +93,208 @@ export const importStockTake = async (data: FormData) => {
},
);
return importStockTake;
-}
\ No newline at end of file
+}
+
+export const getStockTakeRecords = async () => {
+ const stockTakeRecords = await serverFetchJson( // 改为 serverFetchJson
+ `${BASE_API_URL}/stockTakeRecord/AllPickedStockOutRecordList`,
+ {
+ method: "GET",
+ },
+ );
+ return stockTakeRecords;
+}
+export const getApproverStockTakeRecords = async () => {
+ const stockTakeRecords = await serverFetchJson( // 改为 serverFetchJson
+ `${BASE_API_URL}/stockTakeRecord/AllApproverStockTakeList`,
+ {
+ method: "GET",
+ },
+ );
+ return stockTakeRecords;
+}
+export const createStockTakeForSections = async () => {
+ const createStockTakeForSections = await serverFetchJson