FPSMS-frontend
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1030 lines
27 KiB

  1. "use server";
  2. import { cache } from 'react';
  3. import { Pageable, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
  4. import { JobOrder, JoStatus, Machine, Operator } from ".";
  5. import { BASE_API_URL } from "@/config/api";
  6. import { revalidateTag } from "next/cache";
  7. import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";
  8. export interface SaveJo {
  9. bomId: number;
  10. planStart: string;
  11. planEnd: string;
  12. reqQty: number;
  13. type: string;
  14. //jobType?: string;
  15. jobTypeId?: number;
  16. }
  17. export interface SaveJoResponse {
  18. id: number;
  19. }
  20. export interface SearchJoResultRequest extends Pageable {
  21. code: string;
  22. itemName?: string;
  23. planStart?: string;
  24. planStartTo?: string;
  25. jobTypeName?: string;
  26. }
  27. export interface productProcessLineQtyRequest {
  28. productProcessLineId: number;
  29. outputFromProcessQty: number;
  30. outputFromProcessUom: string;
  31. defectQty: number;
  32. defectUom: string;
  33. scrapQty: number;
  34. scrapUom: string;
  35. }
  36. export interface SearchJoResultResponse {
  37. records: JobOrder[];
  38. total: number;
  39. }
  40. // DEPRECIATED
  41. export interface SearchJoResult {
  42. id: number;
  43. code: string;
  44. itemCode: string;
  45. name: string;
  46. reqQty: number;
  47. uom: string;
  48. status: JoStatus;
  49. }
  50. export interface UpdateJoRequest {
  51. id: number;
  52. status: string;
  53. }
  54. // For Jo Button Actions
  55. export interface CommonActionJoRequest {
  56. id: number;
  57. }
  58. export interface CommonActionJoResponse {
  59. id: number;
  60. entity: { status: JoStatus }
  61. }
  62. // For Jo Process
  63. export interface IsOperatorExistResponse<T> {
  64. id: number | null;
  65. name: string;
  66. code: string;
  67. type?: string;
  68. message: string | null;
  69. errorPosition: string | keyof T;
  70. entity: T;
  71. }
  72. export interface isCorrectMachineUsedResponse<T> {
  73. id: number | null;
  74. name: string;
  75. code: string;
  76. type?: string;
  77. message: string | null;
  78. errorPosition: string | keyof T;
  79. entity: T;
  80. }
  81. export interface JobOrderDetail {
  82. id: number;
  83. code: string;
  84. name: string;
  85. reqQty: number;
  86. uom: string;
  87. pickLines: any[];
  88. jobTypeName: string;
  89. status: string;
  90. }
  91. export interface UnassignedJobOrderPickOrder {
  92. pickOrderId: number;
  93. pickOrderCode: string;
  94. pickOrderConsoCode: string;
  95. pickOrderTargetDate: string;
  96. pickOrderStatus: string;
  97. jobOrderId: number;
  98. jobOrderCode: string;
  99. jobOrderName: string;
  100. reqQty: number;
  101. uom: string;
  102. planStart: string;
  103. planEnd: string;
  104. }
  105. export interface AssignJobOrderResponse {
  106. id: number | null;
  107. code: string | null;
  108. name: string | null;
  109. type: string | null;
  110. message: string | null;
  111. errorPosition: string | null;
  112. }
  113. export interface PrintPickRecordRequest{
  114. pickOrderId: number;
  115. printerId: number;
  116. printQty: number;
  117. }
  118. export interface PrintPickRecordResponse{
  119. success: boolean;
  120. message?: string
  121. }
  122. export interface PrintFGStockInLabelRequest {
  123. stockInLineId: number;
  124. printerId: number;
  125. printQty?: number;
  126. }
  127. export const printFGStockInLabel = cache(async(data: PrintFGStockInLabelRequest) => {
  128. const params = new URLSearchParams();
  129. if (data.stockInLineId) {
  130. params.append('stockInLineId', data.stockInLineId.toString());
  131. }
  132. params.append('printerId', data.printerId.toString());
  133. if (data.printQty !== undefined && data.printQty !== null) {
  134. params.append('printQty', data.printQty.toString());
  135. }
  136. return serverFetchWithNoContent(
  137. `${BASE_API_URL}/jo/print-FGPickRecordLabel?${params.toString()}`,
  138. {
  139. method: "GET",
  140. next: {
  141. tags: ["printFGStockInLabel"],
  142. },
  143. }
  144. );
  145. });
  146. export const recordSecondScanIssue = cache(async (
  147. pickOrderId: number,
  148. itemId: number,
  149. data: {
  150. qty: number; // verified qty (actual pick qty)
  151. missQty?: number; // 添加:miss qty
  152. badItemQty?: number; // 添加:bad item qty
  153. isMissing: boolean;
  154. isBad: boolean;
  155. reason: string;
  156. createdBy: number;
  157. type?: string; // type 也应该是可选的
  158. }
  159. ) => {
  160. return serverFetchJson<any>(
  161. `${BASE_API_URL}/jo/second-scan-issue/${pickOrderId}/${itemId}`,
  162. {
  163. method: "POST",
  164. headers: { "Content-Type": "application/json" },
  165. body: JSON.stringify(data),
  166. next: { tags: ["jo-second-scan"] },
  167. },
  168. );
  169. });
  170. export interface ProductProcessResponse {
  171. id: number;
  172. productProcessCode: string;
  173. status: string;
  174. startTime?: string;
  175. endTime?: string;
  176. date: string;
  177. bomId?: number;
  178. jobOrderId?: number;
  179. }
  180. export interface ProductProcessLineResponse {
  181. id: number,
  182. bomprocessId: number,
  183. operatorId: number,
  184. operatorName: string,
  185. equipmentId: number,
  186. handlerId: number,
  187. seqNo: number,
  188. name: string,
  189. description: string,
  190. equipment_name: string,
  191. equipmentDetailCode: string,
  192. status: string,
  193. byproductId: number,
  194. byproductName: string,
  195. byproductQty: number,
  196. byproductUom: string,
  197. scrapQty: number,
  198. defectQty: number,
  199. defectUom: string,
  200. outputFromProcessQty: number,
  201. outputFromProcessUom: string,
  202. durationInMinutes: number,
  203. prepTimeInMinutes: number,
  204. postProdTimeInMinutes: number,
  205. startTime: string,
  206. endTime: string,
  207. }
  208. export interface ProductProcessWithLinesResponse {
  209. id: number;
  210. productProcessCode: string;
  211. status: string;
  212. startTime?: string;
  213. endTime?: string;
  214. date: string;
  215. bomId?: number;
  216. jobOrderId?: number;
  217. jobOrderCode: string;
  218. jobOrderStatus: string;
  219. jobType: string;
  220. isDark: string;
  221. isDense: number;
  222. isFloat: string;
  223. timeSequence: number;
  224. complexity: number;
  225. scrapRate: number;
  226. allergicSubstance: string;
  227. itemId: number;
  228. itemCode: string;
  229. itemName: string;
  230. outputQty: number;
  231. outputQtyUom: string;
  232. productionPriority: number;
  233. jobOrderLines: JobOrderLineInfo[];
  234. productProcessLines: ProductProcessLineResponse[];
  235. }
  236. export interface UpdateProductProcessLineQtyRequest {
  237. productProcessLineId: number;
  238. outputFromProcessQty: number;
  239. outputFromProcessUom: string;
  240. byproductName: string;
  241. byproductQty: number;
  242. byproductUom: string;
  243. defectQty: number;
  244. defectUom: string;
  245. defect2Qty: number;
  246. defect2Uom: string;
  247. defect3Qty: number;
  248. defect3Uom: string;
  249. defectDescription: string;
  250. defectDescription2: string;
  251. defectDescription3: string;
  252. scrapQty: number;
  253. scrapUom: string;
  254. }
  255. export interface UpdateProductProcessLineQtyResponse {
  256. id: number;
  257. outputFromProcessQty: number;
  258. outputFromProcessUom: string;
  259. defectQty: number;
  260. defectUom: string;
  261. defect2Qty: number;
  262. defect2Uom: string;
  263. defect3Qty: number;
  264. defect3Uom: string;
  265. defectDescription: string;
  266. defectDescription2: string;
  267. defectDescription3: string;
  268. scrapQty: number;
  269. scrapUom: string;
  270. byproductName: string;
  271. byproductQty: number;
  272. byproductUom: string;
  273. }
  274. export interface AllProductProcessResponse {
  275. id: number;
  276. productProcessCode: string;
  277. status: string;
  278. startTime?: string;
  279. endTime?: string;
  280. date: string;
  281. bomId?: number;
  282. }
  283. export interface AllJoborderProductProcessInfoResponse {
  284. id: number;
  285. productProcessCode: string;
  286. status: string;
  287. startTime?: string;
  288. endTime?: string;
  289. date: string;
  290. matchStatus: string;
  291. bomId?: number;
  292. assignedTo: number;
  293. pickOrderId: number;
  294. itemName: string;
  295. requiredQty: number;
  296. jobOrderId: number;
  297. stockInLineId: number;
  298. jobOrderCode: string;
  299. productProcessLineCount: number;
  300. FinishedProductProcessLineCount: number;
  301. lines: ProductProcessInfoResponse[];
  302. }
  303. export interface ProductProcessInfoResponse {
  304. id: number;
  305. operatorId?: number;
  306. operatorName?: string;
  307. equipmentId?: number;
  308. equipmentName?: string;
  309. startTime?: string;
  310. endTime?: string;
  311. status: string;
  312. }
  313. export interface ProductProcessLineQrscanUpadteRequest {
  314. productProcessLineId: number;
  315. //operatorId?: number;
  316. //equipmentId?: number;
  317. equipmentTypeSubTypeEquipmentNo?: string;
  318. staffNo?: string;
  319. }
  320. export interface ProductProcessLineDetailResponse {
  321. id: number,
  322. productProcessId: number,
  323. bomProcessId: number,
  324. operatorId: number,
  325. equipmentType: string,
  326. operatorName: string,
  327. handlerId: number,
  328. seqNo: number,
  329. isDark: string,
  330. isDense: number,
  331. isFloat: string,
  332. outputQtyUom: string,
  333. outputQty: number,
  334. pickOrderId: number,
  335. jobOrderCode: string,
  336. jobOrderId: number,
  337. name: string,
  338. description: string,
  339. equipment: string,
  340. startTime: string,
  341. endTime: string,
  342. defectQty: number,
  343. defectUom: string,
  344. scrapQty: number,
  345. scrapUom: string,
  346. byproductId: number,
  347. byproductName: string,
  348. byproductQty: number,
  349. byproductUom: string | undefined,
  350. totalStockQty: number,
  351. insufficientStockQty: number,
  352. sufficientStockQty: number,
  353. productionPriority: number,
  354. productProcessLines: ProductProcessLineInfoResponse[],
  355. jobOrderLineInfo: JobOrderLineInfo[],
  356. }
  357. export interface JobOrderProcessLineDetailResponse {
  358. id: number;
  359. productProcessId: number;
  360. bomProcessId: number;
  361. operatorId: number;
  362. equipmentType: string | null;
  363. operatorName: string;
  364. handlerId: number;
  365. seqNo: number;
  366. durationInMinutes: number;
  367. name: string;
  368. description: string;
  369. equipmentId: number;
  370. startTime: string | number[]; // API 返回的是数组格式
  371. endTime: string | number[]; // API 返回的是数组格式
  372. status: string;
  373. outputFromProcessQty: number;
  374. outputFromProcessUom: string;
  375. defectQty: number;
  376. defectUom: string;
  377. defectDescription: string;
  378. defectQty2: number;
  379. defectUom2: string;
  380. defectDescription2: string;
  381. defectQty3: number;
  382. defectUom3: string;
  383. defectDescription3: string;
  384. scrapQty: number;
  385. scrapUom: string;
  386. byproductId: number;
  387. byproductName: string;
  388. byproductQty: number;
  389. byproductUom: string;
  390. productProcessIssueId: number;
  391. productProcessIssueStatus: string;
  392. }
  393. export interface JobOrderLineInfo {
  394. id: number,
  395. jobOrderId: number,
  396. jobOrderCode: string,
  397. itemId: number,
  398. itemCode: string,
  399. itemName: string,
  400. reqQty: number,
  401. stockQty: number,
  402. uom: string,
  403. shortUom: string,
  404. availableStatus: string,
  405. bomProcessId: number,
  406. bomProcessSeqNo: number,
  407. }
  408. export interface ProductProcessLineInfoResponse {
  409. id: number,
  410. bomprocessId: number,
  411. operatorId: number,
  412. operatorName: string,
  413. equipmentId: number,
  414. handlerId: number,
  415. seqNo: number,
  416. name: string,
  417. description: string,
  418. equipment_name: string,
  419. equipmentDetailCode: string,
  420. status: string,
  421. byproductId: number,
  422. byproductName: string,
  423. byproductQty: number,
  424. byproductUom: string,
  425. scrapQty: number,
  426. defectQty: number,
  427. defectUom: string,
  428. durationInMinutes: number,
  429. prepTimeInMinutes: number,
  430. postProdTimeInMinutes: number,
  431. outputFromProcessQty: number,
  432. outputFromProcessUom: string,
  433. startTime: string,
  434. endTime: string
  435. }
  436. export interface AllJoPickOrderResponse {
  437. id: number;
  438. pickOrderId: number | null;
  439. pickOrderCode: string | null;
  440. jobOrderId: number | null;
  441. jobOrderCode: string | null;
  442. jobOrderTypeId: number | null;
  443. jobOrderType: string | null;
  444. itemId: number;
  445. itemName: string;
  446. reqQty: number;
  447. uomId: number;
  448. uomName: string;
  449. jobOrderStatus: string;
  450. finishedPickOLineCount: number;
  451. }
  452. export interface UpdateJoPickOrderHandledByRequest {
  453. pickOrderId: number;
  454. itemId: number;
  455. userId: number;
  456. }
  457. export interface JobTypeResponse {
  458. id: number;
  459. name: string;
  460. }
  461. export interface SaveProductProcessIssueTimeRequest {
  462. productProcessLineId: number;
  463. reason: string;
  464. }
  465. export interface JobOrderLotsHierarchicalResponse {
  466. pickOrder: PickOrderInfoResponse;
  467. pickOrderLines: PickOrderLineWithLotsResponse[];
  468. }
  469. export interface PickOrderInfoResponse {
  470. id: number | null;
  471. code: string | null;
  472. consoCode: string | null;
  473. targetDate: string | null;
  474. type: string | null;
  475. status: string | null;
  476. assignTo: number | null;
  477. jobOrder: JobOrderBasicInfoResponse;
  478. }
  479. export interface JobOrderBasicInfoResponse {
  480. id: number;
  481. code: string;
  482. name: string;
  483. }
  484. export interface PickOrderLineWithLotsResponse {
  485. id: number;
  486. itemId: number | null;
  487. itemCode: string | null;
  488. itemName: string | null;
  489. requiredQty: number | null;
  490. uomCode: string | null;
  491. uomDesc: string | null;
  492. status: string | null;
  493. lots: LotDetailResponse[];
  494. }
  495. export interface LotDetailResponse {
  496. lotId: number | null;
  497. lotNo: string | null;
  498. expiryDate: string | null;
  499. location: string | null;
  500. availableQty: number | null;
  501. requiredQty: number | null;
  502. actualPickQty: number | null;
  503. processingStatus: string | null;
  504. lotAvailability: string | null;
  505. pickOrderId: number | null;
  506. pickOrderCode: string | null;
  507. pickOrderConsoCode: string | null;
  508. pickOrderLineId: number | null;
  509. stockOutLineId: number | null;
  510. suggestedPickLotId: number | null;
  511. stockOutLineQty: number | null;
  512. stockOutLineStatus: string | null;
  513. routerIndex: number | null;
  514. routerArea: string | null;
  515. routerRoute: string | null;
  516. uomShortDesc: string | null;
  517. matchStatus?: string | null;
  518. matchBy?: number | null;
  519. matchQty?: number | null;
  520. }
  521. export const saveProductProcessIssueTime = cache(async (request: SaveProductProcessIssueTimeRequest) => {
  522. return serverFetchJson<any>(
  523. `${BASE_API_URL}/product-process/Demo/ProcessLine/issue`,
  524. {
  525. method: "POST",
  526. headers: { "Content-Type": "application/json" },
  527. body: JSON.stringify(request),
  528. }
  529. );
  530. });
  531. export const saveProductProcessResumeTime = cache(async (productProcessIssueId: number) => {
  532. return serverFetchJson<any>(
  533. `${BASE_API_URL}/product-process/Demo/ProcessLine/resume/${productProcessIssueId}`,
  534. {
  535. method: "POST",
  536. }
  537. );
  538. });
  539. export const deleteJobOrder=cache(async (jobOrderId: number) => {
  540. return serverFetchJson<any>(
  541. `${BASE_API_URL}/jo/demo/deleteJobOrder/${jobOrderId}`,
  542. {
  543. method: "POST",
  544. }
  545. );
  546. });
  547. export const fetchAllJobTypes = cache(async () => {
  548. return serverFetchJson<JobTypeResponse[]>(
  549. `${BASE_API_URL}/jo/jobTypes`,
  550. {
  551. method: "GET",
  552. }
  553. );
  554. });
  555. export const updateJoPickOrderHandledBy = cache(async (request: UpdateJoPickOrderHandledByRequest) => {
  556. return serverFetchJson<any>(
  557. `${BASE_API_URL}/jo/update-jo-pick-order-handled-by`,
  558. {
  559. method: "POST",
  560. body: JSON.stringify(request),
  561. headers: { "Content-Type": "application/json" },
  562. },
  563. );
  564. });
  565. export const fetchJobOrderLotsHierarchicalByPickOrderId = cache(async (pickOrderId: number) => {
  566. return serverFetchJson<JobOrderLotsHierarchicalResponse>(
  567. `${BASE_API_URL}/jo/all-lots-hierarchical-by-pick-order/${pickOrderId}`,
  568. {
  569. method: "GET",
  570. next: { tags: ["jo-hierarchical"] },
  571. },
  572. );
  573. });
  574. export const fetchAllJoPickOrders = cache(async () => {
  575. return serverFetchJson<AllJoPickOrderResponse[]>(
  576. `${BASE_API_URL}/jo/AllJoPickOrder`,
  577. {
  578. method: "GET",
  579. }
  580. );
  581. });
  582. export const fetchProductProcessLineDetail = cache(async (lineId: number) => {
  583. return serverFetchJson<JobOrderProcessLineDetailResponse>(
  584. `${BASE_API_URL}/product-process/Demo/ProcessLine/detail/${lineId}`,
  585. {
  586. method: "GET",
  587. }
  588. );
  589. });
  590. export const updateProductProcessLineQty = cache(async (request: UpdateProductProcessLineQtyRequest) => {
  591. return serverFetchJson<UpdateProductProcessLineQtyResponse>(
  592. `${BASE_API_URL}/product-process/Demo/ProcessLine/update/qty/${request.productProcessLineId}`,
  593. {
  594. method: "POST",
  595. headers: { "Content-Type": "application/json" },
  596. body: JSON.stringify(request),
  597. }
  598. );
  599. });
  600. export const updateProductProcessLineQrscan = cache(async (request: ProductProcessLineQrscanUpadteRequest) => {
  601. const requestBody: any = {
  602. productProcessLineId: request.productProcessLineId,
  603. //operatorId: request.operatorId,
  604. //equipmentId: request.equipmentId,
  605. equipmentTypeSubTypeEquipmentNo: request.equipmentTypeSubTypeEquipmentNo,
  606. staffNo: request.staffNo,
  607. };
  608. if (request.equipmentTypeSubTypeEquipmentNo !== undefined) {
  609. requestBody["EquipmentType-SubType-EquipmentNo"] = request.equipmentTypeSubTypeEquipmentNo;
  610. }
  611. return serverFetchJson<any>(
  612. `${BASE_API_URL}/product-process/Demo/update`,
  613. {
  614. method: "POST",
  615. headers: { "Content-Type": "application/json" },
  616. body: JSON.stringify(requestBody),
  617. }
  618. );
  619. });
  620. export const fetchAllJoborderProductProcessInfo = cache(async () => {
  621. return serverFetchJson<AllJoborderProductProcessInfoResponse[]>(
  622. `${BASE_API_URL}/product-process/Demo/Process/all`,
  623. {
  624. method: "GET",
  625. next: { tags: ["productProcess"] },
  626. }
  627. );
  628. });
  629. /*
  630. export const updateProductProcessLineQty = async (request: UpdateProductProcessLineQtyRequest) => {
  631. return serverFetchJson<UpdateProductProcessLineQtyResponse>(
  632. `${BASE_API_URL}/product-process/lines/${request.productProcessLineId}/update/qty`,
  633. {
  634. method: "POST",
  635. headers: { "Content-Type": "application/json" },
  636. body: JSON.stringify(request),
  637. }
  638. );
  639. };
  640. */
  641. export const startProductProcessLine = async (lineId: number) => {
  642. return serverFetchJson<any>(
  643. `${BASE_API_URL}/product-process/Demo/ProcessLine/start/${lineId}`,
  644. {
  645. method: "POST",
  646. headers: { "Content-Type": "application/json" },
  647. }
  648. );
  649. };
  650. export const completeProductProcessLine = async (lineId: number) => {
  651. return serverFetchJson<any>(
  652. `${BASE_API_URL}/product-process/Demo/ProcessLine/complete/${lineId}`,
  653. {
  654. method: "POST",
  655. headers: { "Content-Type": "application/json" },
  656. }
  657. );
  658. };
  659. // 查询所有 production processes
  660. export const fetchProductProcesses = cache(async () => {
  661. return serverFetchJson<{ content: ProductProcessResponse[] }>(
  662. `${BASE_API_URL}/product-process`,
  663. {
  664. method: "GET",
  665. next: { tags: ["productProcess"] },
  666. }
  667. );
  668. });
  669. // 根据 ID 查询
  670. export const fetchProductProcessById = cache(async (id: number) => {
  671. return serverFetchJson<ProductProcessResponse>(
  672. `${BASE_API_URL}/product-process/${id}`,
  673. {
  674. method: "GET",
  675. next: { tags: ["productProcess"] },
  676. }
  677. );
  678. });
  679. export const updateProductProcessPriority = cache(async (productProcessId: number, productionPriority: number) => {
  680. return serverFetchJson<any>(
  681. `${BASE_API_URL}/product-process/Demo/Process/update/priority/${productProcessId}/${productionPriority}`,
  682. {
  683. method: "POST",
  684. }
  685. );
  686. });
  687. // 根据 Job Order ID 查询
  688. export const fetchProductProcessesByJobOrderId = cache(async (jobOrderId: number) => {
  689. return serverFetchJson<ProductProcessWithLinesResponse[]>(
  690. `${BASE_API_URL}/product-process/demo/joid/${jobOrderId}`,
  691. {
  692. method: "GET",
  693. next: { tags: ["productProcess"] },
  694. }
  695. );
  696. });
  697. // 获取 process 的所有 lines
  698. export const fetchProductProcessLines = cache(async (processId: number) => {
  699. return serverFetchJson<ProductProcessLineResponse[]>(
  700. `${BASE_API_URL}/product-process/${processId}/lines`,
  701. {
  702. method: "GET",
  703. next: { tags: ["productProcessLines"] },
  704. }
  705. );
  706. });
  707. // 创建 production process
  708. export const createProductProcess = async (data: {
  709. bomId: number;
  710. jobOrderId?: number;
  711. date?: string;
  712. }) => {
  713. return serverFetchJson<{ id: number; productProcessCode: string; linesCreated: number }>(
  714. `${BASE_API_URL}/product-process`,
  715. {
  716. method: "POST",
  717. headers: { "Content-Type": "application/json" },
  718. body: JSON.stringify(data),
  719. }
  720. );
  721. };
  722. // 更新 line 产出数据
  723. export const updateLineOutput = async (lineId: number, data: {
  724. outputQty?: number;
  725. outputUom?: string;
  726. defectQty?: number;
  727. defectUom?: string;
  728. scrapQty?: number;
  729. scrapUom?: string;
  730. byproductName?: string;
  731. byproductQty?: number;
  732. byproductUom?: string;
  733. }) => {
  734. return serverFetchJson<ProductProcessLineResponse>(
  735. `${BASE_API_URL}/product-process/lines/${lineId}/output`,
  736. {
  737. method: "PUT",
  738. headers: { "Content-Type": "application/json" },
  739. body: JSON.stringify(data),
  740. }
  741. );
  742. };
  743. export const updateSecondQrScanStatus = cache(async (pickOrderId: number, itemId: number, userId: number, qty: number) => {
  744. return serverFetchJson<any>(
  745. `${BASE_API_URL}/jo/update-match-status`,
  746. {
  747. method: "POST",
  748. body: JSON.stringify({
  749. pickOrderId,
  750. itemId,
  751. userId,
  752. qty
  753. }),
  754. headers: {
  755. 'Content-Type': 'application/json',
  756. },
  757. next: { tags: ["update-match-status"] },
  758. },
  759. );
  760. });
  761. export const submitSecondScanQuantity = cache(async (
  762. pickOrderId: number,
  763. itemId: number,
  764. data: { qty: number; isMissing?: boolean; isBad?: boolean; reason?: string }
  765. ) => {
  766. return serverFetchJson<any>(
  767. `${BASE_API_URL}/jo/second-scan-submit/${pickOrderId}/${itemId}`,
  768. {
  769. method: "POST",
  770. headers: { "Content-Type": "application/json" },
  771. body: JSON.stringify(data),
  772. next: { tags: ["jo-second-scan"] },
  773. },
  774. );
  775. });
  776. // 获取未分配的 Job Order pick orders
  777. export const fetchUnassignedJobOrderPickOrders = cache(async () => {
  778. return serverFetchJson<UnassignedJobOrderPickOrder[]>(
  779. `${BASE_API_URL}/jo/unassigned-job-order-pick-orders`,
  780. {
  781. method: "GET",
  782. next: { tags: ["jo-unassigned"] },
  783. },
  784. );
  785. });
  786. // 分配 Job Order pick order 给用户
  787. export const assignJobOrderPickOrder = async (pickOrderId: number, userId: number) => {
  788. return serverFetchJson<AssignJobOrderResponse>(
  789. `${BASE_API_URL}/jo/assign-job-order-pick-order/${pickOrderId}/${userId}`,
  790. {
  791. method: "POST",
  792. headers: { "Content-Type": "application/json" },
  793. }
  794. );
  795. };
  796. export const unAssignJobOrderPickOrder = async (pickOrderId: number) => {
  797. return serverFetchJson<AssignJobOrderResponse>(
  798. `${BASE_API_URL}/jo/unassign-job-order-pick-order/${pickOrderId}`,
  799. {
  800. method: "POST",
  801. headers: { "Content-Type": "application/json" },
  802. }
  803. );
  804. };
  805. // 获取 Job Order 分层数据
  806. export const fetchJobOrderLotsHierarchical = cache(async (userId: number) => {
  807. return serverFetchJson<JobOrderLotsHierarchicalResponse>(
  808. `${BASE_API_URL}/jo/all-lots-hierarchical/${userId}`,
  809. {
  810. method: "GET",
  811. next: { tags: ["jo-hierarchical"] },
  812. },
  813. );
  814. });
  815. export const fetchCompletedJobOrderPickOrders = cache(async (userId: number) => {
  816. return serverFetchJson<any>(
  817. `${BASE_API_URL}/jo/completed-job-order-pick-orders/${userId}`,
  818. {
  819. method: "GET",
  820. next: { tags: ["jo-completed"] },
  821. },
  822. );
  823. });
  824. // 获取已完成的 Job Order pick orders
  825. export const fetchCompletedJobOrderPickOrdersrecords = cache(async (userId: number) => {
  826. return serverFetchJson<any>(
  827. `${BASE_API_URL}/jo/completed-job-order-pick-orders-only/${userId}`,
  828. {
  829. method: "GET",
  830. next: { tags: ["jo-completed"] },
  831. },
  832. );
  833. });
  834. // 获取已完成的 Job Order pick order records
  835. export const fetchCompletedJobOrderPickOrderRecords = cache(async (userId: number) => {
  836. return serverFetchJson<any[]>(
  837. `${BASE_API_URL}/jo/completed-job-order-pick-order-records/${userId}`,
  838. {
  839. method: "GET",
  840. next: { tags: ["jo-records"] },
  841. },
  842. );
  843. });
  844. export const fetchJobOrderDetailByCode = cache(async (code: string) => {
  845. return serverFetchJson<JobOrderDetail>(
  846. `${BASE_API_URL}/jo/detailByCode/${code}`,
  847. {
  848. method: "GET",
  849. next: { tags: ["jo"] },
  850. },
  851. );
  852. });
  853. export const isOperatorExist = async (username: string) => {
  854. const isExist = await serverFetchJson<IsOperatorExistResponse<Operator>>(
  855. `${BASE_API_URL}/jop/isOperatorExist`,
  856. {
  857. method: "POST",
  858. body: JSON.stringify({ username }),
  859. headers: { "Content-Type": "application/json" },
  860. },
  861. );
  862. revalidateTag("po");
  863. return isExist;
  864. };
  865. export const isCorrectMachineUsed = async (machineCode: string) => {
  866. const isExist = await serverFetchJson<isCorrectMachineUsedResponse<Machine>>(
  867. `${BASE_API_URL}/jop/isCorrectMachineUsed`,
  868. {
  869. method: "POST",
  870. body: JSON.stringify({ machineCode }),
  871. headers: { "Content-Type": "application/json" },
  872. },
  873. );
  874. revalidateTag("po");
  875. return isExist;
  876. };
  877. export const fetchJos = cache(async (data?: SearchJoResultRequest) => {
  878. const queryStr = convertObjToURLSearchParams(data)
  879. console.log("queryStr", queryStr)
  880. const fullUrl = `${BASE_API_URL}/jo/getRecordByPage?${queryStr}`;
  881. console.log("fetchJos full URL:", fullUrl);
  882. console.log("fetchJos BASE_API_URL:", BASE_API_URL);
  883. const response = await serverFetchJson<SearchJoResultResponse>(
  884. `${BASE_API_URL}/jo/getRecordByPage?${queryStr}`,
  885. {
  886. method: "GET",
  887. headers: { "Content-Type": "application/json" },
  888. next: {
  889. tags: ["jos"]
  890. }
  891. }
  892. )
  893. console.log("fetchJos response:", response)
  894. return response
  895. })
  896. export const updateJo = cache(async (data: UpdateJoRequest) => {
  897. return serverFetchJson<SaveJoResponse>(`${BASE_API_URL}/jo/update`,
  898. {
  899. method: "POST",
  900. body: JSON.stringify(data),
  901. headers: { "Content-Type": "application/json" },
  902. })
  903. })
  904. export const releaseJo = cache(async (data: CommonActionJoRequest) => {
  905. const response = serverFetchJson<CommonActionJoResponse>(`${BASE_API_URL}/jo/release`,
  906. {
  907. method: "POST",
  908. body: JSON.stringify(data),
  909. headers: { "Content-Type": "application/json" },
  910. })
  911. // Invalidate the cache after releasing
  912. revalidateTag("jo");
  913. return response;
  914. })
  915. export const startJo = cache(async (data: CommonActionJoRequest) => {
  916. const response = serverFetchJson<CommonActionJoResponse>(`${BASE_API_URL}/jo/start`,
  917. {
  918. method: "POST",
  919. body: JSON.stringify(data),
  920. headers: { "Content-Type": "application/json" },
  921. })
  922. // Invalidate the cache after starting
  923. revalidateTag("jo");
  924. return response;
  925. })
  926. export const manualCreateJo = cache(async (data: SaveJo) => {
  927. return serverFetchJson<SaveJoResponse>(`${BASE_API_URL}/jo/manualCreate`, {
  928. method: "POST",
  929. body: JSON.stringify(data),
  930. headers: { "Content-Type": "application/json" }
  931. })
  932. })
  933. export const fetchCompletedJobOrderPickOrdersWithCompletedSecondScan = cache(async (userId: number) => {
  934. return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-orders-with-completed-second-scan/${userId}`, {
  935. method: "GET",
  936. headers: { "Content-Type": "application/json" }
  937. })
  938. })
  939. export const fetchCompletedJobOrderPickOrderLotDetails = cache(async (pickOrderId: number) => {
  940. return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-order-lot-details/${pickOrderId}`, {
  941. method: "GET",
  942. headers: { "Content-Type": "application/json" }
  943. })
  944. })
  945. export const fetchCompletedJobOrderPickOrderLotDetailsForCompletedPick = cache(async (pickOrderId: number) => {
  946. return serverFetchJson<any[]>(`${BASE_API_URL}/jo/completed-job-order-pick-order-lot-details-completed-pick/${pickOrderId}`, {
  947. method: "GET",
  948. headers: { "Content-Type": "application/json" }
  949. })
  950. })
  951. export async function PrintPickRecord(request: PrintPickRecordRequest){
  952. const params = new URLSearchParams();
  953. params.append('pickOrderId', request.pickOrderId.toString())
  954. params.append('printerId', request.printerId.toString())
  955. if (request.printQty !== null && request.printQty !== undefined) {
  956. params.append('printQty', request.printQty.toString());
  957. }
  958. //const response = await serverFetchWithNoContent(`${BASE_API_URL}/jo/print-PickRecord?${params.toString()}`,{
  959. const response = await serverFetchWithNoContent(`${BASE_API_URL}/jo/print-PickRecord?${params.toString()}`,{
  960. method: "GET"
  961. });
  962. return { success: true, message: "Print job sent successfully (Pick Record)" } as PrintPickRecordResponse;
  963. }