| @@ -74,6 +74,7 @@ public class SecurityConfig { | |||||
| return new BCryptPasswordEncoder(); | return new BCryptPasswordEncoder(); | ||||
| } | } | ||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 51 | v1.0.0 | 2026-08-05 */ | |||||
| @Bean | @Bean | ||||
| @Order(1) | @Order(1) | ||||
| public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||
| @@ -117,6 +118,12 @@ public class SecurityConfig { | |||||
| .hasAuthority("ITEM_TRACING") | .hasAuthority("ITEM_TRACING") | ||||
| .requestMatchers(HttpMethod.GET, "/inventoryLotLine/trace/location/**") | .requestMatchers(HttpMethod.GET, "/inventoryLotLine/trace/location/**") | ||||
| .hasAuthority("ITEM_TRACING") | .hasAuthority("ITEM_TRACING") | ||||
| /* 工單 生產流程 完成工單 */ | |||||
| .requestMatchers(HttpMethod.POST, "/product-process/Demo/ProcessLine/complete/**") | |||||
| .hasAuthority("PRODUCT_PROCESS") | |||||
| /* 工序「已完成」(Just Pass):僅 ADMIN */ | |||||
| .requestMatchers(HttpMethod.POST, "/product-process/Demo/ProcessLine/pass/**") | |||||
| .hasAuthority("ADMIN") | |||||
| .anyRequest().authenticated()) | .anyRequest().authenticated()) | ||||
| .httpBasic(httpBasic -> httpBasic.authenticationEntryPoint( | .httpBasic(httpBasic -> httpBasic.authenticationEntryPoint( | ||||
| (request, response, authException) -> sendUnauthorizedJson(response, "Unauthorized", "UNAUTHORIZED"))) | (request, response, authException) -> sendUnauthorizedJson(response, "Unauthorized", "UNAUTHORIZED"))) | ||||
| @@ -8,7 +8,7 @@ class DoUserPickAuditReportService( | |||||
| private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
| ) { | ) { | ||||
| /** | /** | ||||
| * FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.1 | 2026-08-05 | |||||
| * FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.2 | 2026-08-05 | |||||
| * DO workbench user-audit rows (Just issue only). | * DO workbench user-audit rows (Just issue only). | ||||
| * issueTypes may combine: 跳過提料(使用「已完成」)+多提+少提+擅自換批/揀錯批. | * issueTypes may combine: 跳過提料(使用「已完成」)+多提+少提+擅自換批/揀錯批. | ||||
| * 少提/多提 use POL-level SUM(stock_out_line.qty) vs pol.qty (multi-lot split OK if total matches). | * 少提/多提 use POL-level SUM(stock_out_line.qty) vs pol.qty (multi-lot split OK if total matches). | ||||
| @@ -183,7 +183,7 @@ class DoUserPickAuditReportService( | |||||
| return jdbcDao.queryForList(sql, args) as List<Map<String, Any?>> | return jdbcDao.queryForList(sql, args) as List<Map<String, Any?>> | ||||
| } | } | ||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.1 | 2026-08-05 */ | |||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.2 | 2026-08-05 */ | |||||
| fun getDistinctHandlers(): List<String> { | fun getDistinctHandlers(): List<String> { | ||||
| val sql = """ | val sql = """ | ||||
| SELECT DISTINCT TRIM(COALESCE(u.name, dop.handlerName, '')) AS handler | SELECT DISTINCT TRIM(COALESCE(u.name, dop.handlerName, '')) AS handler | ||||
| @@ -23,11 +23,11 @@ import java.io.ByteArrayOutputStream | |||||
| class DoUserPickAuditReportController( | class DoUserPickAuditReportController( | ||||
| private val doUserPickAuditReportService: DoUserPickAuditReportService, | private val doUserPickAuditReportService: DoUserPickAuditReportService, | ||||
| ) { | ) { | ||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.1 | 2026-08-05 */ | |||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.2 | 2026-08-05 */ | |||||
| @GetMapping("/do-user-pick-audit-handlers") | @GetMapping("/do-user-pick-audit-handlers") | ||||
| fun handlers(): List<String> = doUserPickAuditReportService.getDistinctHandlers() | fun handlers(): List<String> = doUserPickAuditReportService.getDistinctHandlers() | ||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.1 | 2026-08-05 */ | |||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 39 | v1.0.2 | 2026-08-05 */ | |||||
| @GetMapping("/print-do-user-pick-audit-excel") | @GetMapping("/print-do-user-pick-audit-excel") | ||||
| fun exportExcel( | fun exportExcel( | ||||
| @RequestParam(required = false) dateStart: String?, | @RequestParam(required = false) dateStart: String?, | ||||
| @@ -52,8 +52,8 @@ class DoUserPickAuditReportController( | |||||
| contentType = MediaType.parseMediaType( | contentType = MediaType.parseMediaType( | ||||
| "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | ||||
| ) | ) | ||||
| setContentDispositionFormData("attachment", "DoUserPickAudit.xlsx") | |||||
| set("filename", "DoUserPickAudit.xlsx") | |||||
| setContentDispositionFormData("attachment", "成品出倉揀貨合規報告.xlsx") | |||||
| set("filename", "成品出倉揀貨合規報告.xlsx") | |||||
| } | } | ||||
| return ResponseEntity(bytes, headers, HttpStatus.OK) | return ResponseEntity(bytes, headers, HttpStatus.OK) | ||||
| } | } | ||||
| @@ -187,6 +187,7 @@ public class GroupService extends AbstractBaseEntityService<Group, Long, GroupRe | |||||
| } | } | ||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 51 | v1.0.0 | 2026-08-05 */ | |||||
| @Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
| public List<Map<String, Object>> listAuth(Map<String, Object> args) { | public List<Map<String, Object>> listAuth(Map<String, Object> args) { | ||||
| @@ -200,7 +201,11 @@ public class GroupService extends AbstractBaseEntityService<Group, Long, GroupRe | |||||
| sql.append(" EXISTS(SELECT 1 FROM group_authority ga WHERE a.id = ga.authId AND groupId = :groupId) AS v"); | sql.append(" EXISTS(SELECT 1 FROM group_authority ga WHERE a.id = ga.authId AND groupId = :groupId) AS v"); | ||||
| } | } | ||||
| else if (args.containsKey("userId")) { | else if (args.containsKey("userId")) { | ||||
| sql.append(" EXISTS(SELECT 1 FROM user_authority ua WHERE a.id = ua.authId AND userId = :userId) AS v"); | |||||
| sql.append(" (EXISTS(SELECT 1 FROM user_authority ua WHERE a.id = ua.authId AND ua.userId = :userId)" | |||||
| + " OR EXISTS(SELECT 1 FROM user_group ug" | |||||
| + " JOIN `group` g ON g.deleted = 0 AND g.id = ug.groupId" | |||||
| + " JOIN group_authority ga ON ga.groupId = ug.groupId" | |||||
| + " WHERE ug.userId = :userId AND ga.authId = a.id)) AS v"); | |||||
| } | } | ||||
| else | else | ||||
| sql.append(" 0 AS v"); | sql.append(" 0 AS v"); | ||||
| @@ -0,0 +1,8 @@ | |||||
| --liquibase formatted sql | |||||
| --changeset fpsms:product_process_complete_authority | |||||
| --preconditions onFail:MARK_RAN | |||||
| --precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM authority WHERE authority = 'PRODUCT_PROCESS' | |||||
| --comment: FP-MTMS Version Checklist | Functions Ref. No. 51 | v1.0.0 | 2026-08-05 — Allow completing job order product process lines (工單 生產流程 完成工單) | |||||
| INSERT IGNORE INTO `authority` (`authority`, `name`, `module`, `description`) | |||||
| VALUES ('PRODUCT_PROCESS', '工單 生產流程 完成工單', 'JOB_ORDER', 'Allow completing job order product process lines'); | |||||