FPSMS-frontend
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

actions.ts 28 KiB

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