FPSMS-frontend
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

563 linhas
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. /* Hidden for now: 庫存流水帳報告 (rep-020)
  298. {
  299. id: "rep-020",
  300. title: "庫存流水帳報告",
  301. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-lot-ledger`,
  302. responseType: "excel",
  303. fields: [
  304. { label: "期間起 Period From(永遠該月1日)", name: "lastInDateStart", type: "date", required: true },
  305. { label: "期間迄 Period To", name: "lastInDateEnd", type: "date", required: true },
  306. { label: "貨品編號 Item Code", name: "itemCode", type: "text", required: false },
  307. ],
  308. },
  309. */
  310. /*
  311. {
  312. id: "rep-007",
  313. title: "庫存結餘報告",
  314. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-balance`,
  315. fields: [
  316. {
  317. label: "盤點輪次 Stock Take Round",
  318. name: "stockTakeRoundId",
  319. type: "select",
  320. required: true,
  321. dynamicOptions: true,
  322. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/stock-take-rounds`,
  323. options: []
  324. },
  325. { label: "貨品編號 Item Code", name: "itemCode", type: "text", required: false},
  326. ]
  327. },
  328. */
  329. /** FP-MTMS Version Checklist | Functions Ref. No. 82 | v1.0.0 | 2026-09-10 */
  330. {
  331. id: "rep-007",
  332. title: "庫存結餘報告",
  333. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-balance`,
  334. fields: [
  335. { label: "庫存日期: Stock Date", name: "stockDate", type: "date", required: true },
  336. asyncItemCodeField(),
  337. ]
  338. },
  339. {
  340. id: "rep-014",
  341. title: "PO入倉記錄報告",
  342. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/grn-report`,
  343. responseType: "excel",
  344. fields: [
  345. { label: "收貨日期:由 Receipt Date Start", name: "receiptDateStart", type: "date", required: false },
  346. { label: "收貨日期:至 Receipt Date End", name: "receiptDateEnd", type: "date", required: false },
  347. asyncItemCodeField(),
  348. ],
  349. },
  350. { id: "rep-009",
  351. title: "成品出倉追蹤報告",
  352. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-fg-stock-out-traceability`,
  353. fields: [
  354. { label: "出貨日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false },
  355. { label: "出貨日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false },
  356. asyncItemCodeField(),
  357. { label: "提料員 Handler", name: "handler", type: "select", required: false,
  358. multiple: true,
  359. dynamicOptions: true,
  360. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/fg-stock-out-traceability-handlers`,
  361. options: [] },
  362. ]
  363. },
  364. { id: "rep-010",
  365. /** FP-MTMS Version Checklist | Functions Ref. No. 64 | v1.0.0 | 2026-08-11 */
  366. title: "庫存品質檢測報告",
  367. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-item-qc-fail`,
  368. fields: [
  369. { label: "QC 檢測日期:由 QC Date Start", name: "lastInDateStart", type: "date", required: false },
  370. { label: "QC 檢測日期:至 QC Date End", name: "lastInDateEnd", type: "date", required: false },
  371. { label: "QC 類型", name: "qcType", type: "select", required: false,
  372. options: [
  373. { label: "全部", value: "all" },
  374. { label: "IQC(採購)", value: "IQC" },
  375. { label: "EPQC(工單)", value: "EPQC" },
  376. ] },
  377. asyncItemCodeField(),
  378. {
  379. label: "QC 項目範圍",
  380. name: "qcItemScope",
  381. type: "select",
  382. required: false,
  383. options: [
  384. { label: "全部 QC 項目", value: "all" },
  385. { label: "只包含溫度濕度", value: "measurable" },
  386. ],
  387. },
  388. ]
  389. },
  390. { id: "rep-013",
  391. title: "貨品出倉追蹤報告",
  392. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-material-stock-out-traceability`,
  393. fields: [
  394. { label: "出倉日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false },
  395. { label: "出倉日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false },
  396. asyncItemCodeField(),
  397. { label: "提料人 Handler", name: "handler", type: "select", required: false,
  398. multiple: true,
  399. dynamicOptions: true,
  400. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/material-stock-out-traceability-handlers`,
  401. options: [] },
  402. ]
  403. },
  404. {
  405. id: "rep-006",
  406. title: "庫存材料消耗趨勢報告",
  407. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-stock-item-consumption-trend`,
  408. fields: [
  409. { label: "材料消耗日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false },
  410. { label: "材料消耗日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false },
  411. { label: "年份 Year", name: "year", type: "text", required: false, placeholder: "e.g. 2026" },
  412. { label: "類別 Category", name: "stockCategory", type: "select", required: false,
  413. multiple: true,
  414. options: [
  415. { label: "All", value: "All" },
  416. { label: "MAT", value: "MAT" },
  417. { label: "WIP", value: "WIP" },
  418. { label: "NM", value: "NM" },
  419. { label: "FG", value: "FG" },
  420. { label: "CMB", value: "CMB" }
  421. ] },
  422. { label: "貨品編號 Item Code", name: "itemCode", type: "select", required: false,
  423. multiple: true,
  424. allowInput: true,
  425. dynamicOptions: true,
  426. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/stock-item-code-prefixes`,
  427. dynamicOptionsParam: "stockCategory",
  428. options: [] },
  429. ]
  430. },
  431. {
  432. id: "rep-005",
  433. title: "成品/半成品生產分析報告",
  434. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-semi-fg-production-analysis`,
  435. fields: [
  436. { label: "完成生產日期:由 Last Out Date Start", name: "lastOutDateStart", type: "date", required: false, placeholder: "dd/mm/yyyy" },
  437. { label: "完成生產日期:至 Last Out Date End", name: "lastOutDateEnd", type: "date", required: false, placeholder: "dd/mm/yyyy" },
  438. { label: "年份 Year", name: "year", type: "text", required: false, placeholder: "e.g. 2026" },
  439. { label: "類別 Category", name: "stockCategory", type: "select", required: false,
  440. multiple: true,
  441. options: [
  442. { label: "All", value: "All" },
  443. { label: "WIP", value: "WIP" },
  444. { label: "FG", value: "FG" },
  445. ] },
  446. { label: "貨品編號 Item Code", name: "itemCode", type: "select", required: false,
  447. multiple: true,
  448. allowInput: true,
  449. dynamicOptions: true,
  450. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/semi-fg-item-codes`,
  451. dynamicOptionsParam: "stockCategory",
  452. options: [] },
  453. ]
  454. },
  455. {
  456. id: "rep-015",
  457. title: "M18 BOM Shop 同步記錄",
  458. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/bom-shop-sync-history`,
  459. responseType: "excel",
  460. fields: [
  461. { label: "同步日期:由 Sync Date Start", name: "syncDateStart", type: "date", required: false },
  462. { label: "同步日期:至 Sync Date End", name: "syncDateEnd", type: "date", required: false },
  463. asyncItemCodeField("成品貨號 Finished Item Code", "finishedItemCode"),
  464. {
  465. label: "同步狀態 Sync Status",
  466. name: "syncStatus",
  467. type: "select",
  468. required: false,
  469. options: [
  470. { label: "全部 All", value: "all" },
  471. { label: "成功 Success", value: "success" },
  472. { label: "失敗 Failed", value: "failed" },
  473. ],
  474. },
  475. ],
  476. },
  477. {
  478. id: "rep-016",
  479. title: "成品出倉揀貨合規報告",
  480. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-do-user-pick-audit`,
  481. responseType: "excel",
  482. fields: [
  483. { label: "日期 Date", name: "dateStart", type: "date", required: true },
  484. {
  485. label: "提料人 Handler",
  486. name: "handler",
  487. type: "select",
  488. required: false,
  489. multiple: true,
  490. dynamicOptions: true,
  491. dynamicOptionsEndpoint: `${NEXT_PUBLIC_API_URL}/report/do-user-pick-audit-handlers`,
  492. options: [],
  493. },
  494. { label: "提票號碼", name: "ticketNo", type: "text", required: false },
  495. asyncItemCodeField(),
  496. {
  497. label: "樓層",
  498. name: "storeId",
  499. type: "select",
  500. required: false,
  501. options: [
  502. { label: "2F", value: "2F" },
  503. { label: "4F", value: "4F" },
  504. ],
  505. },
  506. ],
  507. },
  508. {
  509. id: "rep-017",
  510. title: "店鋪訂單補貨記錄",
  511. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/shop-order-replenishment`,
  512. responseType: "excel",
  513. fields: [
  514. // { label: "補貨日期:由 Reorder Date Start", name: "reorderDateStart", type: "date", required: false },
  515. //{ label: "補貨日期:至 Reorder Date End", name: "reorderDateEnd", type: "date", required: false },
  516. { label: "店鋪訂單日期:由 Shop Order Date Start", name: "shopOrderDateStart", type: "date", required: false },
  517. { label: "店鋪訂單日期:至 Shop Order Date End", name: "shopOrderDateEnd", type: "date", required: false },
  518. //{ label: "送貨日期:由 Delivered Date Start", name: "deliveredDateStart", type: "date", required: false },
  519. //{ label: "送貨日期:至 Delivered Date End", name: "deliveredDateEnd", type: "date", required: false },
  520. { label: "店鋪編號 Shop Code", name: "shopCode", type: "text", required: false, placeholder: "e.g. S001" },
  521. ],
  522. },
  523. {
  524. /** FP-MTMS Version Checklist | Functions Ref. No. 60 | v1.0.1 | 2026-08-11 */
  525. id: "rep-018",
  526. title: "送貨訂單與倉存單位不符報告",
  527. apiEndpoint: `${NEXT_PUBLIC_API_URL}/report/print-do-inventory-uom-mismatch`,
  528. responseType: "excel",
  529. fields: [
  530. {
  531. label: "預計送貨日期 Estimated Arrival Date",
  532. name: "deliveryDate",
  533. type: "date",
  534. required: true,
  535. minDate: "today",
  536. },
  537. {
  538. label: "送貨訂單樓層 Floor",
  539. name: "storeId",
  540. type: "select",
  541. required: false,
  542. options: [
  543. { label: "全部", value: "All" },
  544. { label: "2F", value: "2F" },
  545. { label: "4F", value: "4F" },
  546. ],
  547. },
  548. ],
  549. },
  550. ]