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.
 
 

561 lines
21 KiB

  1. /** FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.0 | 2026-08-03 */
  2. export type FieldType = 'date' | 'text' | 'select' | 'number' | 'checkbox';
  3. import { NEXT_PUBLIC_API_URL } from "@/config/api";
  4. export interface ReportField {
  5. label: string;
  6. name: string;
  7. type: FieldType;
  8. placeholder?: string;
  9. required: boolean;
  10. options?: { label: string; value: string }[]; // For select types
  11. multiple?: boolean; // For select types - allow multiple selection
  12. dynamicOptions?: boolean; // For select types - load options dynamically
  13. dynamicOptionsEndpoint?: string; // API endpoint to fetch dynamic options
  14. dynamicOptionsParam?: string; // Parameter name to pass when fetching options
  15. allowInput?: boolean; // Allow user to input custom values (for select types)
  16. /** Typeahead options instead of preloading the full list (use with allowInput) */
  17. asyncSearch?: boolean;
  18. /** Minimum characters before asyncSearch fetches. Default 2. */
  19. asyncSearchMinChars?: number;
  20. /** When checkbox is checked, disable these field names (by `name`) */
  21. disablesFieldsWhenChecked?: string[];
  22. /** For date fields: restrict picker so value cannot be before today */
  23. minDate?: 'today';
  24. /** Disable the input (e.g. date locked to today) */
  25. disabled?: boolean;
  26. }
  27. export type ReportResponseType = 'pdf' | 'excel';
  28. export interface ReportDefinition {
  29. id: string;
  30. title: string;
  31. apiEndpoint: string;
  32. /** When 'excel', report page fetches JSON and builds .xlsx for download. Default 'pdf'. */
  33. responseType?: ReportResponseType;
  34. fields: ReportField[];
  35. }
  36. /** FP-MTMS Version Checklist | Functions Ref. No. 69 | v1.0.2 | 2026-09-10 */
  37. const asyncItemCodeField = (
  38. label = "貨品編號 Item Code",
  39. name = "itemCode",
  40. ): ReportField => ({
  41. label,
  42. name,
  43. type: "select",
  44. required: false,
  45. multiple: true,
  46. allowInput: true,
  47. asyncSearch: true,
  48. placeholder: "e.g. FA0591",
  49. });
  50. export const REPORTS: ReportDefinition[] = [
  51. //{
  52. // id: "rep-001",
  53. // title: "報告 1",
  54. // apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report1`,
  55. // fields: [
  56. // { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory
  57. // { label: "To Date", name: "toDate", type: "date", required: true }, // Mandatory
  58. // { label: "Item Code", name: "itemCode", type: "text", required: false, placeholder: "e.g. FG"},
  59. // { label: "Item Type", name: "itemType", type: "select", required: false,
  60. // options: [
  61. // { label: "FG", value: "FG" },
  62. // { label: "Material", value: "Mat" }
  63. // ] },
  64. // ]
  65. //},
  66. //{
  67. // id: "rep-002",
  68. // title: "報告 2",
  69. // apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report2`,
  70. // fields: [
  71. // { label: "Target Date", name: "targetDate", type: "date", required: false },
  72. // { label: "Item Code", name: "itemCode", type: "text", required: false },
  73. // { label: "Shift", name: "shift", type: "select", options: [
  74. // { label: "Day", value: "D" },
  75. // { label: "Night", value: "N" }
  76. // ], required: false}
  77. // ]
  78. //},
  79. //{
  80. // id: "rep-003",
  81. // title: "報告 3",
  82. // apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-report3`,
  83. // fields: [
  84. // { label: "From Date", name: "fromDate", type: "date", required: true }, // Mandatory
  85. // { label: "To Date", name: "toDate", type: "date", required: true }, // Mandatory
  86. // { label: "Item Code", name: "itemCode", type: "text", required: false, placeholder: "e.g. FG"},
  87. // { label: "Item Type", name: "itemType", type: "select", required: false,
  88. // options: [
  89. // { label: "FG", value: "FG" },
  90. // { label: "Material", value: "Mat" }
  91. // ] },
  92. // ]
  93. //},
  94. {
  95. id: "rep-004",
  96. title: "入倉追蹤報告",
  97. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-in-traceability`,
  98. fields: [
  99. { label: "入倉日期:由 Last In Date Start", name: "lastInDateStart", type: "date", required: false },
  100. { label: "入倉日期:至 Last In Date End", name: "lastInDateEnd", type: "date", required: false },
  101. asyncItemCodeField(),
  102. {
  103. label: "樓層 Store ID",
  104. name: "storeId",
  105. type: "select",
  106. required: false,
  107. options: [
  108. { label: "全部", value: "All" },
  109. { label: "1F", value: "1F" },
  110. { label: "2F", value: "2F" },
  111. { label: "3F", value: "3F" },
  112. { label: "4F", value: "4F" },
  113. ],
  114. },
  115. { label: "倉庫 Warehouse", name: "warehouse", type: "text", required: false, placeholder: "e.g. W201" },
  116. { label: "區域 Area", name: "area", type: "text", required: false, placeholder: "e.g. #A" },
  117. { label: "儲位 Slot", name: "slot", type: "text", required: false, placeholder: "e.g. 01" },
  118. { label: "批號 Lot No", name: "lotNo", type: "text", required: false, placeholder: "e.g. LT-202608" },
  119. {
  120. label: "PP/PF 分類",
  121. name: "poPrefix",
  122. type: "select",
  123. required: false,
  124. options: [
  125. { label: "全部", value: "All" },
  126. { label: "PP", value: "PP" },
  127. { label: "PF", value: "PF" },
  128. ],
  129. },
  130. ]
  131. },
  132. {
  133. id: "rep-008",
  134. title: "成品出倉報告",
  135. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-fg-delivery-report`,
  136. fields: [
  137. { label: "出貨日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false },
  138. { label: "出貨日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false },
  139. { label: "年份 Year", name: "year", type: "text", required: false, placeholder: "e.g. 2026" },
  140. asyncItemCodeField(),
  141. ]
  142. },
  143. /*
  144. { id: "rep-012",
  145. title: "庫存盤點報告",
  146. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-take-variance`,
  147. fields: [
  148. { label: "盤點日期:由 Stock Take Date Start", name: "stockTakeDateStart", type: "date", required: false },
  149. { label: "盤點日期:至 Stock Take Date End", name: "stockTakeDateEnd", type: "date", required: false },
  150. { label: "貨品編號 Item Code", name: "itemCode", type: "text", required: false},
  151. ]
  152. },
  153. */
  154. {
  155. id: "rep-012",
  156. title: "庫存盤點報告",
  157. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-take-variance-v2`,
  158. fields: [
  159. {
  160. label: "盤點輪次(可多選)",
  161. name: "stockTakeRoundId",
  162. type: "select",
  163. required: true,
  164. multiple: true,
  165. dynamicOptions: true,
  166. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/stock-take-rounds`,
  167. options: []
  168. },
  169. asyncItemCodeField("貨品編號"),
  170. {
  171. label: "倉庫樓層",
  172. name: "store_id",
  173. type: "select",
  174. required: false,
  175. options: [
  176. { label: "全部", value: "All" },
  177. { label: "1F", value: "1F" },
  178. { label: "2F", value: "2F" },
  179. { label: "3F", value: "3F" },
  180. { label: "4F", value: "4F" }
  181. ],
  182. },
  183. {
  184. label: "狀態",
  185. name: "status",
  186. type: "select",
  187. required: false,
  188. options: [
  189. { label: "全部", value: "All" },
  190. { label: "待盤點", value: "pending" },
  191. { label: "已審核", value: "completed" }
  192. ],
  193. },
  194. {
  195. label: "類型",
  196. name: "type",
  197. type: "select",
  198. required: false,
  199. multiple: true,
  200. options: [
  201. { label: "全部", value: "All" },
  202. { label: "PP", value: "PP" },
  203. { label: "PF", value: "PF" },
  204. { label: "TOA", value: "TOA" },
  205. { label: "工廠生產", value: "工廠生產" },
  206. { label: "倉存調整", value: "倉存調整" },
  207. { label: "期初存貨", value: "期初存貨" },
  208. { label: "採購入倉", value: "採購入倉" },
  209. { label: "其他入倉", value: "其他入倉" },
  210. ],
  211. },
  212. ]
  213. },
  214. /* Hidden for now: 庫存批次結餘報告 (rep-019)
  215. {
  216. id: "rep-019",
  217. title: "庫存批次結餘報告",
  218. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-lot-balance`,
  219. responseType: "excel",
  220. fields: [
  221. { label: "庫存日期 Stock Date(僅今天)", name: "stockDate", type: "date", required: true, disabled: true },
  222. { label: "貨品編號 Item Code", name: "itemCode", type: "text", required: false },
  223. { label: "倉位 Warehouse Code", name: "warehouseCode", type: "text", required: false, placeholder: "e.g. W200 or 2F-W200-#A-00" },
  224. {
  225. label: "樓層 Store ID",
  226. name: "storeId",
  227. type: "select",
  228. required: false,
  229. options: [
  230. { label: "全部", value: "All" },
  231. { label: "1F", value: "1F" },
  232. { label: "2F", value: "2F" },
  233. { label: "3F", value: "3F" },
  234. { label: "4F", value: "4F" },
  235. ],
  236. },
  237. { label: "批號 Lot No", name: "lotNo", type: "text", required: false, placeholder: "e.g. LT-202608" },
  238. ],
  239. },
  240. */
  241. {
  242. id: "rep-021",
  243. title: "庫存批次現況報告",
  244. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-lot-onhand`,
  245. responseType: "excel",
  246. fields: [
  247. asyncItemCodeField(),
  248. {
  249. label: "樓層 Store ID",
  250. name: "storeId",
  251. type: "select",
  252. required: false,
  253. options: [
  254. { label: "全部", value: "All" },
  255. { label: "1F", value: "1F" },
  256. { label: "2F", value: "2F" },
  257. { label: "3F", value: "3F" },
  258. { label: "4F", value: "4F" },
  259. ],
  260. },
  261. { label: "倉庫 Warehouse", name: "warehouse", type: "text", required: false, placeholder: "e.g. W201" },
  262. { label: "區域 Area", name: "area", type: "text", required: false, placeholder: "e.g. #A" },
  263. { label: "儲位 Slot", name: "slot", type: "text", required: false, placeholder: "e.g. 02" },
  264. {
  265. label: "盤點區域說明 Stock Take Section",
  266. name: "stockTakeSectionDescription",
  267. type: "select",
  268. required: false,
  269. dynamicOptions: true,
  270. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/warehouse/stockTakeSections`,
  271. options: [{ label: "全部", value: "All" }],
  272. },
  273. { label: "批號 Lot No", name: "lotNo", type: "text", required: false, placeholder: "e.g. LT-202608" },
  274. {
  275. label: "來源 Lot Origin",
  276. name: "lotOrigin",
  277. type: "select",
  278. required: false,
  279. options: [
  280. { label: "全部", value: "All" },
  281. { label: "PP", value: "PP" },
  282. { label: "PF", value: "PF" },
  283. { label: "其他", value: "other" },
  284. ],
  285. },
  286. ],
  287. },
  288. { id: "rep-011",
  289. title: "庫存明細報告",
  290. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-ledger`,
  291. fields: [
  292. { label: "庫存日期:由 Last In Date Start", name: "lastInDateStart", type: "date", required: false },
  293. { label: "庫存日期:至 Last In Date End", name: "lastInDateEnd", type: "date", required: false },
  294. asyncItemCodeField(),
  295. ]
  296. },
  297. {
  298. id: "rep-020",
  299. title: "庫存流水帳報告",
  300. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-lot-ledger`,
  301. responseType: "excel",
  302. fields: [
  303. { label: "期間起 Period From(永遠該月1日)", name: "lastInDateStart", type: "date", required: true },
  304. { label: "期間迄 Period To", name: "lastInDateEnd", type: "date", required: true },
  305. asyncItemCodeField(),
  306. ],
  307. },
  308. /*
  309. {
  310. id: "rep-007",
  311. title: "庫存結餘報告",
  312. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-balance`,
  313. fields: [
  314. {
  315. label: "盤點輪次 Stock Take Round",
  316. name: "stockTakeRoundId",
  317. type: "select",
  318. required: true,
  319. dynamicOptions: true,
  320. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/stock-take-rounds`,
  321. options: []
  322. },
  323. { label: "貨品編號 Item Code", name: "itemCode", type: "text", required: false},
  324. ]
  325. },
  326. */
  327. /** FP-MTMS Version Checklist | Functions Ref. No. 82 | v1.0.0 | 2026-09-10 */
  328. {
  329. id: "rep-007",
  330. title: "庫存結餘報告",
  331. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-balance`,
  332. fields: [
  333. { label: "庫存日期: Stock Date", name: "stockDate", type: "date", required: true },
  334. asyncItemCodeField(),
  335. ]
  336. },
  337. {
  338. id: "rep-014",
  339. title: "PO入倉記錄報告",
  340. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/grn-report`,
  341. responseType: "excel",
  342. fields: [
  343. { label: "收貨日期:由 Receipt Date Start", name: "receiptDateStart", type: "date", required: false },
  344. { label: "收貨日期:至 Receipt Date End", name: "receiptDateEnd", type: "date", required: false },
  345. asyncItemCodeField(),
  346. ],
  347. },
  348. { id: "rep-009",
  349. title: "成品出倉追蹤報告",
  350. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-fg-stock-out-traceability`,
  351. fields: [
  352. { label: "出貨日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false },
  353. { label: "出貨日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false },
  354. asyncItemCodeField(),
  355. { label: "提料員 Handler", name: "handler", type: "select", required: false,
  356. multiple: true,
  357. dynamicOptions: true,
  358. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/fg-stock-out-traceability-handlers`,
  359. options: [] },
  360. ]
  361. },
  362. { id: "rep-010",
  363. /** FP-MTMS Version Checklist | Functions Ref. No. 64 | v1.0.0 | 2026-08-11 */
  364. title: "庫存品質檢測報告",
  365. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-item-qc-fail`,
  366. fields: [
  367. { label: "QC 檢測日期:由 QC Date Start", name: "lastInDateStart", type: "date", required: false },
  368. { label: "QC 檢測日期:至 QC Date End", name: "lastInDateEnd", type: "date", required: false },
  369. { label: "QC 類型", name: "qcType", type: "select", required: false,
  370. options: [
  371. { label: "全部", value: "all" },
  372. { label: "IQC(採購)", value: "IQC" },
  373. { label: "EPQC(工單)", value: "EPQC" },
  374. ] },
  375. asyncItemCodeField(),
  376. {
  377. label: "QC 項目範圍",
  378. name: "qcItemScope",
  379. type: "select",
  380. required: false,
  381. options: [
  382. { label: "全部 QC 項目", value: "all" },
  383. { label: "只包含溫度濕度", value: "measurable" },
  384. ],
  385. },
  386. ]
  387. },
  388. { id: "rep-013",
  389. title: "貨品出倉追蹤報告",
  390. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-material-stock-out-traceability`,
  391. fields: [
  392. { label: "出倉日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false },
  393. { label: "出倉日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false },
  394. asyncItemCodeField(),
  395. { label: "提料人 Handler", name: "handler", type: "select", required: false,
  396. multiple: true,
  397. dynamicOptions: true,
  398. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/material-stock-out-traceability-handlers`,
  399. options: [] },
  400. ]
  401. },
  402. {
  403. id: "rep-006",
  404. title: "庫存材料消耗趨勢報告",
  405. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-item-consumption-trend`,
  406. fields: [
  407. { label: "材料消耗日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false },
  408. { label: "材料消耗日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false },
  409. { label: "年份 Year", name: "year", type: "text", required: false, placeholder: "e.g. 2026" },
  410. { label: "類別 Category", name: "stockCategory", type: "select", required: false,
  411. multiple: true,
  412. options: [
  413. { label: "All", value: "All" },
  414. { label: "MAT", value: "MAT" },
  415. { label: "WIP", value: "WIP" },
  416. { label: "NM", value: "NM" },
  417. { label: "FG", value: "FG" },
  418. { label: "CMB", value: "CMB" }
  419. ] },
  420. { label: "貨品編號 Item Code", name: "itemCode", type: "select", required: false,
  421. multiple: true,
  422. allowInput: true,
  423. dynamicOptions: true,
  424. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/stock-item-code-prefixes`,
  425. dynamicOptionsParam: "stockCategory",
  426. options: [] },
  427. ]
  428. },
  429. {
  430. id: "rep-005",
  431. title: "成品/半成品生產分析報告",
  432. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-semi-fg-production-analysis`,
  433. fields: [
  434. { label: "完成生產日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false, placeholder: "dd/mm/yyyy" },
  435. { label: "完成生產日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false, placeholder: "dd/mm/yyyy" },
  436. { label: "年份 Year", name: "year", type: "text", required: false, placeholder: "e.g. 2026" },
  437. { label: "類別 Category", name: "stockCategory", type: "select", required: false,
  438. multiple: true,
  439. options: [
  440. { label: "All", value: "All" },
  441. { label: "WIP", value: "WIP" },
  442. { label: "FG", value: "FG" },
  443. ] },
  444. { label: "貨品編號 Item Code", name: "itemCode", type: "select", required: false,
  445. multiple: true,
  446. allowInput: true,
  447. dynamicOptions: true,
  448. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/semi-fg-item-codes`,
  449. dynamicOptionsParam: "stockCategory",
  450. options: [] },
  451. ]
  452. },
  453. {
  454. id: "rep-015",
  455. title: "M18 BOM Shop 同步記錄",
  456. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/bom-shop-sync-history`,
  457. responseType: "excel",
  458. fields: [
  459. { label: "同步日期:由 Sync Date Start", name: "syncDateStart", type: "date", required: false },
  460. { label: "同步日期:至 Sync Date End", name: "syncDateEnd", type: "date", required: false },
  461. asyncItemCodeField("成品貨號 Finished Item Code", "finishedItemCode"),
  462. {
  463. label: "同步狀態 Sync Status",
  464. name: "syncStatus",
  465. type: "select",
  466. required: false,
  467. options: [
  468. { label: "全部 All", value: "all" },
  469. { label: "成功 Success", value: "success" },
  470. { label: "失敗 Failed", value: "failed" },
  471. ],
  472. },
  473. ],
  474. },
  475. {
  476. id: "rep-016",
  477. title: "成品出倉揀貨合規報告",
  478. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-do-user-pick-audit`,
  479. responseType: "excel",
  480. fields: [
  481. { label: "日期 Date", name: "dateStart", type: "date", required: true },
  482. {
  483. label: "提料人 Handler",
  484. name: "handler",
  485. type: "select",
  486. required: false,
  487. multiple: true,
  488. dynamicOptions: true,
  489. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/do-user-pick-audit-handlers`,
  490. options: [],
  491. },
  492. { label: "提票號碼", name: "ticketNo", type: "text", required: false },
  493. asyncItemCodeField(),
  494. {
  495. label: "樓層",
  496. name: "storeId",
  497. type: "select",
  498. required: false,
  499. options: [
  500. { label: "2F", value: "2F" },
  501. { label: "4F", value: "4F" },
  502. ],
  503. },
  504. ],
  505. },
  506. {
  507. id: "rep-017",
  508. title: "店鋪訂單補貨記錄",
  509. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/shop-order-replenishment`,
  510. responseType: "excel",
  511. fields: [
  512. // { label: "補貨日期:由 Reorder Date Start", name: "reorderDateStart", type: "date", required: false },
  513. //{ label: "補貨日期:至 Reorder Date End", name: "reorderDateEnd", type: "date", required: false },
  514. { label: "店鋪訂單日期:由 Shop Order Date Start", name: "shopOrderDateStart", type: "date", required: false },
  515. { label: "店鋪訂單日期:至 Shop Order Date End", name: "shopOrderDateEnd", type: "date", required: false },
  516. //{ label: "送貨日期:由 Delivered Date Start", name: "deliveredDateStart", type: "date", required: false },
  517. //{ label: "送貨日期:至 Delivered Date End", name: "deliveredDateEnd", type: "date", required: false },
  518. { label: "店鋪編號 Shop Code", name: "shopCode", type: "text", required: false, placeholder: "e.g. S001" },
  519. ],
  520. },
  521. {
  522. /** FP-MTMS Version Checklist | Functions Ref. No. 60 | v1.0.1 | 2026-08-11 */
  523. id: "rep-018",
  524. title: "送貨訂單與倉存單位不符報告",
  525. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-do-inventory-uom-mismatch`,
  526. responseType: "excel",
  527. fields: [
  528. {
  529. label: "預計送貨日期 Estimated Arrival Date",
  530. name: "deliveryDate",
  531. type: "date",
  532. required: true,
  533. minDate: "today",
  534. },
  535. {
  536. label: "送貨訂單樓層 Floor",
  537. name: "storeId",
  538. type: "select",
  539. required: false,
  540. options: [
  541. { label: "全部", value: "All" },
  542. { label: "2F", value: "2F" },
  543. { label: "4F", value: "4F" },
  544. ],
  545. },
  546. ],
  547. },
  548. ]