package com.erp.controller; import com.erp.dto.ApiResponse; import com.erp.service.NumberingRuleService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api/numbering-rule") @RequiredArgsConstructor @Slf4j public class NumberingRuleController { private final NumberingRuleService numberingRuleService; // ================================================================ // ■ 규칙 목록 / 단건 조회 // ================================================================ /** GET / → 회사별 채번 규칙 전체 목록 */ @GetMapping public ResponseEntity>>> getRuleList( @RequestAttribute("company_code") String companyCode) { List> list = numberingRuleService.getRuleList(companyCode); return ResponseEntity.ok(ApiResponse.success(list, "채번 규칙 목록을 조회했습니다.")); } /** GET /available → 메뉴 기반 사용 가능 규칙 (menuObjid 없음) */ @GetMapping("/available") public ResponseEntity>>> getAvailableRulesForMenu( @RequestAttribute("company_code") String companyCode) { List> list = numberingRuleService.getAvailableRulesForMenu(companyCode, null); return ResponseEntity.ok(ApiResponse.success(list, "사용 가능한 채번 규칙을 조회했습니다.")); } /** GET /available/{menuObjid} → 메뉴 기반 사용 가능 규칙 */ @GetMapping("/available/{menuObjid}") public ResponseEntity>>> getAvailableRulesForMenuWithId( @RequestAttribute("company_code") String companyCode, @PathVariable String menuObjid) { List> list = numberingRuleService.getAvailableRulesForMenu(companyCode, menuObjid); return ResponseEntity.ok(ApiResponse.success(list, "사용 가능한 채번 규칙을 조회했습니다.")); } /** GET /available-for-screen?tableName= → 화면 기반 사용 가능 규칙 */ @GetMapping("/available-for-screen") public ResponseEntity>>> getAvailableRulesForScreen( @RequestAttribute("company_code") String companyCode, @RequestParam(required = false) String tableName) { List> list = numberingRuleService.getAvailableRulesForScreen(companyCode, tableName); return ResponseEntity.ok(ApiResponse.success(list, "화면별 채번 규칙을 조회했습니다.")); } /** GET /by-column/{tableName}/{columnName} → 테이블+컬럼 기반 규칙 조회 */ @GetMapping("/by-column/{tableName}/{columnName}") public ResponseEntity>> getNumberingRuleByColumn( @RequestAttribute("company_code") String companyCode, @PathVariable String tableName, @PathVariable String columnName) { Map rule = numberingRuleService.getNumberingRuleByColumn( companyCode, tableName, columnName); if (rule == null) { return ResponseEntity.ok(ApiResponse.success(null, "채번 규칙을 찾을 수 없습니다.")); } return ResponseEntity.ok(ApiResponse.success(rule, "채번 규칙을 조회했습니다.")); } // ================================================================ // ■ 테스트 테이블 Operations // ================================================================ /** GET /test/list → 테스트용 규칙 목록 */ @GetMapping("/test/list") public ResponseEntity>>> getRulesFromTest( @RequestAttribute("company_code") String companyCode) { List> list = numberingRuleService.getRulesFromTest(companyCode, null); return ResponseEntity.ok(ApiResponse.success(list, "테스트 채번 규칙 목록을 조회했습니다.")); } /** GET /test/list/{menuObjid} → 테스트용 규칙 목록 (메뉴 필터) */ @GetMapping("/test/list/{menuObjid}") public ResponseEntity>>> getRulesFromTestWithMenu( @RequestAttribute("company_code") String companyCode, @PathVariable String menuObjid) { List> list = numberingRuleService.getRulesFromTest(companyCode, menuObjid); return ResponseEntity.ok(ApiResponse.success(list, "테스트 채번 규칙 목록을 조회했습니다.")); } /** GET /test/by-column/{tableName}/{columnName} → 테스트 테이블+컬럼 기반 조회 */ @GetMapping("/test/by-column/{tableName}/{columnName}") public ResponseEntity>> getTestRuleByColumn( @RequestAttribute("company_code") String companyCode, @PathVariable String tableName, @PathVariable String columnName) { Map rule = numberingRuleService.getNumberingRuleByColumn( companyCode, tableName, columnName); if (rule == null) { return ResponseEntity.ok(ApiResponse.success(null, "채번 규칙을 찾을 수 없습니다.")); } return ResponseEntity.ok(ApiResponse.success(rule, "채번 규칙을 조회했습니다.")); } /** POST /test/save → UPSERT */ @PostMapping("/test/save") public ResponseEntity>> saveRuleToTest( @RequestAttribute("company_code") String companyCode, @RequestBody Map body) { if (body.get("rule_id") == null || body.get("rule_name") == null) { return ResponseEntity.badRequest().body(ApiResponse.error("ruleId와 ruleName이 필요합니다.")); } Map result = numberingRuleService.saveRuleToTest(body, companyCode); return ResponseEntity.ok(ApiResponse.success(result, "테스트 채번 규칙이 저장되었습니다.")); } /** DELETE /test/{ruleId} → 테스트 규칙 삭제 */ @DeleteMapping("/test/{ruleId}") public ResponseEntity> deleteRuleFromTest( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId) { numberingRuleService.deleteRuleFromTest(ruleId, companyCode); return ResponseEntity.ok(ApiResponse.success(null, "테스트 채번 규칙이 삭제되었습니다.")); } /** POST /test/{ruleId}/preview → 테스트 미리보기 */ @PostMapping("/test/{ruleId}/preview") public ResponseEntity>> previewCodeFromTest( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId, @RequestBody(required = false) Map body) { @SuppressWarnings("unchecked") Map formData = body != null ? (Map) body.get("form_data") : null; String manualInputValue = body != null ? (String) body.get("manual_input_value") : null; String code = numberingRuleService.previewCode(ruleId, companyCode, formData, manualInputValue); return ResponseEntity.ok(ApiResponse.success(Map.of("code", code), "미리보기 생성이 완료되었습니다.")); } // ================================================================ // ■ 단건 CRUD // ================================================================ /** GET /{ruleId} → 단건 조회 */ @GetMapping("/{ruleId}") public ResponseEntity>> getRuleById( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId) { Map rule = numberingRuleService.getRuleById(ruleId, companyCode); if (rule == null) { return ResponseEntity.ok(ApiResponse.success(null, "채번 규칙을 찾을 수 없습니다.")); } return ResponseEntity.ok(ApiResponse.success(rule, "채번 규칙을 조회했습니다.")); } /** POST / → 규칙 생성 */ @PostMapping public ResponseEntity>> createRule( @RequestAttribute("company_code") String companyCode, @RequestAttribute(value = "user_id", required = false) String userId, @RequestBody Map body) { if (body.get("rule_id") == null || body.get("rule_name") == null || body.get("parts") == null) { return ResponseEntity.badRequest().body(ApiResponse.error("ruleId, ruleName, parts가 필요합니다.")); } if (userId != null) body.put("user_id", userId); Map result = numberingRuleService.createRule(body, companyCode); return ResponseEntity.status(201).body(ApiResponse.success(result, "채번 규칙이 생성되었습니다.")); } /** PUT /{ruleId} → 규칙 수정 */ @PutMapping("/{ruleId}") public ResponseEntity>> updateRule( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId, @RequestBody Map body) { Map result = numberingRuleService.updateRule(ruleId, body, companyCode); return ResponseEntity.ok(ApiResponse.success(result, "채번 규칙이 수정되었습니다.")); } /** DELETE /{ruleId} → 규칙 삭제 */ @DeleteMapping("/{ruleId}") public ResponseEntity> deleteRule( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId) { numberingRuleService.deleteRule(ruleId, companyCode); return ResponseEntity.ok(ApiResponse.success(null, "채번 규칙이 삭제되었습니다.")); } // ================================================================ // ■ 코드 생성 Actions // ================================================================ /** POST /{ruleId}/preview → 미리보기 (순번 증가 없음) */ @PostMapping("/{ruleId}/preview") public ResponseEntity>> previewCode( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId, @RequestBody(required = false) Map body) { @SuppressWarnings("unchecked") Map formData = body != null ? (Map) body.get("form_data") : null; String manualInputValue = body != null ? (String) body.get("manual_input_value") : null; String code = numberingRuleService.previewCode(ruleId, companyCode, formData, manualInputValue); return ResponseEntity.ok(ApiResponse.success(Map.of("code", code), "미리보기 생성이 완료되었습니다.")); } /** POST /{ruleId}/allocate → 코드 할당 (순번 증가) */ @PostMapping("/{ruleId}/allocate") public ResponseEntity>> allocateCode( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId, @RequestBody(required = false) Map body) { @SuppressWarnings("unchecked") Map formData = body != null ? (Map) body.get("form_data") : null; String userInputCode = body != null ? (String) body.get("user_input_code") : null; String code = numberingRuleService.allocateCode(ruleId, companyCode, formData, userInputCode); return ResponseEntity.ok(ApiResponse.success(Map.of("code", code), "코드 할당이 완료되었습니다.")); } /** POST /{ruleId}/generate (deprecated) → allocateCode 위임 */ @PostMapping("/{ruleId}/generate") public ResponseEntity>> generateCode( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId) { String code = numberingRuleService.generateCode(ruleId, companyCode); return ResponseEntity.ok(ApiResponse.success(Map.of("code", code), "코드 생성이 완료되었습니다.")); } /** POST /{ruleId}/reset → 순번 초기화 */ @PostMapping("/{ruleId}/reset") public ResponseEntity> resetSequence( @RequestAttribute("company_code") String companyCode, @PathVariable String ruleId) { numberingRuleService.resetSequence(ruleId, companyCode); return ResponseEntity.ok(ApiResponse.success(null, "시퀀스가 초기화되었습니다.")); } // ================================================================ // ■ Admin // ================================================================ /** POST /copy-for-company → 회사간 규칙 복제 (SUPER_ADMIN) */ @PostMapping("/copy-for-company") public ResponseEntity>> copyRulesForCompany( @RequestAttribute("company_code") String companyCode, @RequestBody Map body) { String sourceCompanyCode = (String) body.get("source_company_code"); String targetCompanyCode = (String) body.get("target_company_code"); if (sourceCompanyCode == null || targetCompanyCode == null) { return ResponseEntity.badRequest() .body(ApiResponse.error("sourceCompanyCode와 targetCompanyCode가 필요합니다.")); } Map result = numberingRuleService.copyRulesForCompany( sourceCompanyCode, targetCompanyCode); return ResponseEntity.ok(ApiResponse.success(result, "채번 규칙 복제가 완료되었습니다.")); } }