feat: incar 갭 반영 수수료/운영 14개 도메인 풀스택 + 배치통합 + 신입교육자료
incar CMS(116메뉴) 벤치마킹 갭분석으로 ga-pro에 없던 14개 도메인을 풀스택 추가. P7 수수료 계산 7종 (V88~V96): - 수입수수료+수지차, 소개·이관수수료, 정착지원금, 인정실적+환산율, 시상, 생보운영지원수수료, 지점장수당 - 각 rule/ledger + 공식(보험료×요율, 수입−지급 등) Service 내장 P8 운영/정산 7종 (V97~V105): - 단계마감, 본사정산, 등급평가, 공동계약, 보증보험, 적립금, 수수료시뮬레이터 - close/reopen/apply/simulate/upsert 등 액션 + 손익·잔액·등급 산정 로직 배치 통합 (V106): - settle_master.other_commission_total 컬럼 추가(DEFAULT 0, 백필) - 설계사 지급성 9종 원장 aggregateByAgent → AggregateStep gross 합산 - 빈 원장 0 → 기존 정산결과·무결성 불변(비파괴적) 테스트: P7/P8 Service 공식 단위테스트 21건(ga-api:test 57건 전체 통과) 프론트: 화면 14개 + React.lazy 코드 스플리팅(단일 4MB → 130+ 청크) 문서: DOMAIN_GAP_P7/P8.md, 신입교육_보험과수수료_완전기초.md, DOMAIN_KNOWLEDGE/HANDOFF 갱신 검증: 전체 ./gradlew build(test 포함) SUCCESSFUL, Flyway V88~V106 success, GET+액션POST smoke 5xx 0건, 9개 집계쿼리 SQL 유효성 확인, 공식 런타임 실측. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.AwardService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "시상")
|
||||
@RestController
|
||||
@RequestMapping("/api/awards")
|
||||
@RequiredArgsConstructor
|
||||
public class AwardController {
|
||||
|
||||
private final AwardService service;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/rules")
|
||||
@RequirePermission(menu = "AWARD", perm = "READ")
|
||||
public ApiResponse<PageResponse<AwardRuleResp>> listRules(
|
||||
@ModelAttribute AwardRuleSearchParam param) {
|
||||
return ApiResponse.ok(service.listRules(param));
|
||||
}
|
||||
|
||||
@GetMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "AWARD", perm = "READ")
|
||||
public ApiResponse<AwardRuleResp> detailRule(@PathVariable Long ruleId) {
|
||||
return ApiResponse.ok(service.detailRule(ruleId));
|
||||
}
|
||||
|
||||
@PostMapping("/rules")
|
||||
@RequirePermission(menu = "AWARD", perm = "CREATE")
|
||||
@DataChangeLog(menu = "AWARD", table = "award_rule")
|
||||
public ApiResponse<Long> createRule(@Valid @RequestBody AwardRuleSaveReq req) {
|
||||
return ApiResponse.ok(service.createRule(req));
|
||||
}
|
||||
|
||||
@PutMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "AWARD", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "AWARD", table = "award_rule")
|
||||
public ApiResponse<Void> updateRule(@PathVariable Long ruleId,
|
||||
@Valid @RequestBody AwardRuleSaveReq req) {
|
||||
service.updateRule(ruleId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "AWARD", perm = "DELETE")
|
||||
@DataChangeLog(menu = "AWARD", table = "award_rule")
|
||||
public ApiResponse<Void> deleteRule(@PathVariable Long ruleId) {
|
||||
service.deleteRule(ruleId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/ledgers")
|
||||
@RequirePermission(menu = "AWARD", perm = "READ")
|
||||
public ApiResponse<PageResponse<AwardLedgerResp>> listLedgers(
|
||||
@ModelAttribute AwardLedgerSearchParam param) {
|
||||
return ApiResponse.ok(service.listLedgers(param));
|
||||
}
|
||||
|
||||
@GetMapping("/ledgers/{ledgerId}")
|
||||
@RequirePermission(menu = "AWARD", perm = "READ")
|
||||
public ApiResponse<AwardLedgerResp> detailLedger(@PathVariable Long ledgerId) {
|
||||
return ApiResponse.ok(service.detailLedger(ledgerId));
|
||||
}
|
||||
|
||||
@PostMapping("/ledgers")
|
||||
@RequirePermission(menu = "AWARD", perm = "CREATE")
|
||||
@DataChangeLog(menu = "AWARD", table = "award_ledger")
|
||||
public ApiResponse<Long> createLedger(@Valid @RequestBody AwardLedgerSaveReq req) {
|
||||
return ApiResponse.ok(service.createLedger(req));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.BranchAllowanceService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "지점장수당")
|
||||
@RestController
|
||||
@RequestMapping("/api/branch-allowances")
|
||||
@RequiredArgsConstructor
|
||||
public class BranchAllowanceController {
|
||||
|
||||
private final BranchAllowanceService service;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/rules")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "READ")
|
||||
public ApiResponse<PageResponse<BranchMgrAllowanceRuleResp>> listRules(
|
||||
@ModelAttribute BranchMgrAllowanceRuleSearchParam param) {
|
||||
return ApiResponse.ok(service.listRules(param));
|
||||
}
|
||||
|
||||
@GetMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "READ")
|
||||
public ApiResponse<BranchMgrAllowanceRuleResp> detailRule(@PathVariable Long ruleId) {
|
||||
return ApiResponse.ok(service.detailRule(ruleId));
|
||||
}
|
||||
|
||||
@PostMapping("/rules")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "CREATE")
|
||||
@DataChangeLog(menu = "BRANCH_MGR_ALLOWANCE", table = "branch_mgr_allowance_rule")
|
||||
public ApiResponse<Long> createRule(@Valid @RequestBody BranchMgrAllowanceRuleSaveReq req) {
|
||||
return ApiResponse.ok(service.createRule(req));
|
||||
}
|
||||
|
||||
@PutMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "BRANCH_MGR_ALLOWANCE", table = "branch_mgr_allowance_rule")
|
||||
public ApiResponse<Void> updateRule(@PathVariable Long ruleId,
|
||||
@Valid @RequestBody BranchMgrAllowanceRuleSaveReq req) {
|
||||
service.updateRule(ruleId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "DELETE")
|
||||
@DataChangeLog(menu = "BRANCH_MGR_ALLOWANCE", table = "branch_mgr_allowance_rule")
|
||||
public ApiResponse<Void> deleteRule(@PathVariable Long ruleId) {
|
||||
service.deleteRule(ruleId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/ledgers")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "READ")
|
||||
public ApiResponse<PageResponse<BranchMgrAllowanceLedgerResp>> listLedgers(
|
||||
@ModelAttribute BranchMgrAllowanceLedgerSearchParam param) {
|
||||
return ApiResponse.ok(service.listLedgers(param));
|
||||
}
|
||||
|
||||
@GetMapping("/ledgers/{ledgerId}")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "READ")
|
||||
public ApiResponse<BranchMgrAllowanceLedgerResp> detailLedger(@PathVariable Long ledgerId) {
|
||||
return ApiResponse.ok(service.detailLedger(ledgerId));
|
||||
}
|
||||
|
||||
@PostMapping("/ledgers")
|
||||
@RequirePermission(menu = "BRANCH_MGR_ALLOWANCE", perm = "CREATE")
|
||||
@DataChangeLog(menu = "BRANCH_MGR_ALLOWANCE", table = "branch_mgr_allowance_ledger")
|
||||
public ApiResponse<Long> createLedger(@Valid @RequestBody BranchMgrAllowanceLedgerSaveReq req) {
|
||||
return ApiResponse.ok(service.createLedger(req));
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.CommissionSimulationService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.CommissionSimulationResp;
|
||||
import com.ga.core.vo.commission.CommissionSimulationSaveReq;
|
||||
import com.ga.core.vo.commission.CommissionSimulationSearchParam;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "수수료 시뮬레이터")
|
||||
@RestController
|
||||
@RequestMapping("/api/commission-simulations")
|
||||
@RequiredArgsConstructor
|
||||
public class CommissionSimulationController {
|
||||
|
||||
private final CommissionSimulationService service;
|
||||
|
||||
@GetMapping
|
||||
@RequirePermission(menu = "COMM_SIMULATOR", perm = "READ")
|
||||
public ApiResponse<PageResponse<CommissionSimulationResp>> list(
|
||||
@ModelAttribute CommissionSimulationSearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@GetMapping("/{simId}")
|
||||
@RequirePermission(menu = "COMM_SIMULATOR", perm = "READ")
|
||||
public ApiResponse<CommissionSimulationResp> detail(@PathVariable Long simId) {
|
||||
return ApiResponse.ok(service.detail(simId));
|
||||
}
|
||||
|
||||
@PostMapping("/simulate")
|
||||
@RequirePermission(menu = "COMM_SIMULATOR", perm = "CREATE")
|
||||
@DataChangeLog(menu = "COMM_SIMULATOR", table = "commission_simulation")
|
||||
public ApiResponse<CommissionSimulationResp> simulate(@Valid @RequestBody CommissionSimulationSaveReq req) {
|
||||
return ApiResponse.ok(service.simulate(req));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.GradeEvaluationService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.AgentGradeEvaluationResp;
|
||||
import com.ga.core.vo.commission.AgentGradeEvaluationSaveReq;
|
||||
import com.ga.core.vo.commission.AgentGradeEvaluationSearchParam;
|
||||
import com.ga.core.vo.commission.GradeEvalRuleResp;
|
||||
import com.ga.core.vo.commission.GradeEvalRuleSaveReq;
|
||||
import com.ga.core.vo.commission.GradeEvalRuleSearchParam;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "등급평가")
|
||||
@RestController
|
||||
@RequestMapping("/api/grade-evaluations")
|
||||
@RequiredArgsConstructor
|
||||
public class GradeEvaluationController {
|
||||
|
||||
private final GradeEvaluationService service;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/rules")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "READ")
|
||||
public ApiResponse<PageResponse<GradeEvalRuleResp>> listRules(@ModelAttribute GradeEvalRuleSearchParam param) {
|
||||
return ApiResponse.ok(service.listRules(param));
|
||||
}
|
||||
|
||||
@GetMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "READ")
|
||||
public ApiResponse<GradeEvalRuleResp> detailRule(@PathVariable Long ruleId) {
|
||||
return ApiResponse.ok(service.detailRule(ruleId));
|
||||
}
|
||||
|
||||
@PostMapping("/rules")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "CREATE")
|
||||
@DataChangeLog(menu = "GRADE_EVAL", table = "grade_eval_rule")
|
||||
public ApiResponse<Long> createRule(@Valid @RequestBody GradeEvalRuleSaveReq req) {
|
||||
return ApiResponse.ok(service.createRule(req));
|
||||
}
|
||||
|
||||
@PutMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "GRADE_EVAL", table = "grade_eval_rule")
|
||||
public ApiResponse<Void> updateRule(@PathVariable Long ruleId,
|
||||
@Valid @RequestBody GradeEvalRuleSaveReq req) {
|
||||
service.updateRule(ruleId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "DELETE")
|
||||
@DataChangeLog(menu = "GRADE_EVAL", table = "grade_eval_rule")
|
||||
public ApiResponse<Void> deleteRule(@PathVariable Long ruleId) {
|
||||
service.deleteRule(ruleId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
// ── Evaluation ────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "READ")
|
||||
public ApiResponse<PageResponse<AgentGradeEvaluationResp>> listEvals(
|
||||
@ModelAttribute AgentGradeEvaluationSearchParam param) {
|
||||
return ApiResponse.ok(service.listEvals(param));
|
||||
}
|
||||
|
||||
@GetMapping("/{evalId}")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "READ")
|
||||
public ApiResponse<AgentGradeEvaluationResp> detailEval(@PathVariable Long evalId) {
|
||||
return ApiResponse.ok(service.detailEval(evalId));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "CREATE")
|
||||
@DataChangeLog(menu = "GRADE_EVAL", table = "agent_grade_evaluation")
|
||||
public ApiResponse<Long> createEval(@Valid @RequestBody AgentGradeEvaluationSaveReq req) {
|
||||
return ApiResponse.ok(service.createEval(req));
|
||||
}
|
||||
|
||||
@PostMapping("/{evalId}/apply")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "GRADE_EVAL", table = "agent_grade_evaluation")
|
||||
public ApiResponse<Void> applyEval(@PathVariable Long evalId) {
|
||||
service.applyEval(evalId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{evalId}")
|
||||
@RequirePermission(menu = "GRADE_EVAL", perm = "DELETE")
|
||||
@DataChangeLog(menu = "GRADE_EVAL", table = "agent_grade_evaluation")
|
||||
public ApiResponse<Void> deleteEval(@PathVariable Long evalId) {
|
||||
service.deleteEval(evalId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.GuaranteeInsuranceService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.AgentGuaranteeInsuranceResp;
|
||||
import com.ga.core.vo.commission.AgentGuaranteeInsuranceSaveReq;
|
||||
import com.ga.core.vo.commission.AgentGuaranteeInsuranceSearchParam;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "보증보험")
|
||||
@RestController
|
||||
@RequestMapping("/api/guarantee-insurances")
|
||||
@RequiredArgsConstructor
|
||||
public class GuaranteeInsuranceController {
|
||||
|
||||
private final GuaranteeInsuranceService service;
|
||||
|
||||
@GetMapping
|
||||
@RequirePermission(menu = "GUARANTEE_INS", perm = "READ")
|
||||
public ApiResponse<PageResponse<AgentGuaranteeInsuranceResp>> list(
|
||||
@ModelAttribute AgentGuaranteeInsuranceSearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@GetMapping("/{guaranteeId}")
|
||||
@RequirePermission(menu = "GUARANTEE_INS", perm = "READ")
|
||||
public ApiResponse<AgentGuaranteeInsuranceResp> detail(@PathVariable Long guaranteeId) {
|
||||
return ApiResponse.ok(service.detail(guaranteeId));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@RequirePermission(menu = "GUARANTEE_INS", perm = "CREATE")
|
||||
@DataChangeLog(menu = "GUARANTEE_INS", table = "agent_guarantee_insurance")
|
||||
public ApiResponse<Long> create(@Valid @RequestBody AgentGuaranteeInsuranceSaveReq req) {
|
||||
return ApiResponse.ok(service.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{guaranteeId}")
|
||||
@RequirePermission(menu = "GUARANTEE_INS", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "GUARANTEE_INS", table = "agent_guarantee_insurance")
|
||||
public ApiResponse<Void> update(@PathVariable Long guaranteeId,
|
||||
@Valid @RequestBody AgentGuaranteeInsuranceSaveReq req) {
|
||||
service.update(guaranteeId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{guaranteeId}")
|
||||
@RequirePermission(menu = "GUARANTEE_INS", perm = "DELETE")
|
||||
@DataChangeLog(menu = "GUARANTEE_INS", table = "agent_guarantee_insurance")
|
||||
public ApiResponse<Void> delete(@PathVariable Long guaranteeId) {
|
||||
service.delete(guaranteeId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.HqSettleService;
|
||||
import com.ga.api.service.commission.HqSettleService.HqSummaryResp;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.HqSettleItemResp;
|
||||
import com.ga.core.vo.commission.HqSettleItemSaveReq;
|
||||
import com.ga.core.vo.commission.HqSettleItemSearchParam;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "본사정산")
|
||||
@RestController
|
||||
@RequestMapping("/api/hq-settles")
|
||||
@RequiredArgsConstructor
|
||||
public class HqSettleController {
|
||||
|
||||
private final HqSettleService service;
|
||||
|
||||
@GetMapping
|
||||
@RequirePermission(menu = "HQ_SETTLE", perm = "READ")
|
||||
public ApiResponse<PageResponse<HqSettleItemResp>> list(@ModelAttribute HqSettleItemSearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@GetMapping("/summary")
|
||||
@RequirePermission(menu = "HQ_SETTLE", perm = "READ")
|
||||
public ApiResponse<HqSummaryResp> summary(@RequestParam String settleMonth) {
|
||||
return ApiResponse.ok(service.summary(settleMonth));
|
||||
}
|
||||
|
||||
@GetMapping("/{itemId}")
|
||||
@RequirePermission(menu = "HQ_SETTLE", perm = "READ")
|
||||
public ApiResponse<HqSettleItemResp> detail(@PathVariable Long itemId) {
|
||||
return ApiResponse.ok(service.detail(itemId));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@RequirePermission(menu = "HQ_SETTLE", perm = "CREATE")
|
||||
@DataChangeLog(menu = "HQ_SETTLE", table = "hq_settle_item")
|
||||
public ApiResponse<Long> create(@Valid @RequestBody HqSettleItemSaveReq req) {
|
||||
return ApiResponse.ok(service.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{itemId}")
|
||||
@RequirePermission(menu = "HQ_SETTLE", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "HQ_SETTLE", table = "hq_settle_item")
|
||||
public ApiResponse<Void> update(@PathVariable Long itemId,
|
||||
@Valid @RequestBody HqSettleItemSaveReq req) {
|
||||
service.update(itemId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{itemId}")
|
||||
@RequirePermission(menu = "HQ_SETTLE", perm = "DELETE")
|
||||
@DataChangeLog(menu = "HQ_SETTLE", table = "hq_settle_item")
|
||||
public ApiResponse<Void> delete(@PathVariable Long itemId) {
|
||||
service.delete(itemId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.IncomeCommissionService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "수입수수료/수지차")
|
||||
@RestController
|
||||
@RequestMapping("/api/income-commissions")
|
||||
@RequiredArgsConstructor
|
||||
public class IncomeCommissionController {
|
||||
|
||||
private final IncomeCommissionService service;
|
||||
|
||||
// ── Income Ledger ────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/ledgers")
|
||||
@RequirePermission(menu = "INCOME_COMM", perm = "READ")
|
||||
public ApiResponse<PageResponse<IncomeCommissionLedgerResp>> listLedgers(
|
||||
@ModelAttribute IncomeCommissionLedgerSearchParam param) {
|
||||
return ApiResponse.ok(service.listLedgers(param));
|
||||
}
|
||||
|
||||
@GetMapping("/ledgers/{incomeId}")
|
||||
@RequirePermission(menu = "INCOME_COMM", perm = "READ")
|
||||
public ApiResponse<IncomeCommissionLedgerResp> detailLedger(@PathVariable Long incomeId) {
|
||||
return ApiResponse.ok(service.detailLedger(incomeId));
|
||||
}
|
||||
|
||||
@PostMapping("/ledgers")
|
||||
@RequirePermission(menu = "INCOME_COMM", perm = "CREATE")
|
||||
@DataChangeLog(menu = "INCOME_COMM", table = "income_commission_ledger")
|
||||
public ApiResponse<Long> createLedger(@Valid @RequestBody IncomeCommissionLedgerSaveReq req) {
|
||||
return ApiResponse.ok(service.createLedger(req));
|
||||
}
|
||||
|
||||
// ── Margin Summary ───────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/margins")
|
||||
@RequirePermission(menu = "INCOME_COMM", perm = "READ")
|
||||
public ApiResponse<PageResponse<MarginSummaryResp>> listMargins(
|
||||
@ModelAttribute MarginSummarySearchParam param) {
|
||||
return ApiResponse.ok(service.listMargins(param));
|
||||
}
|
||||
|
||||
@GetMapping("/margins/{marginId}")
|
||||
@RequirePermission(menu = "INCOME_COMM", perm = "READ")
|
||||
public ApiResponse<MarginSummaryResp> detailMargin(@PathVariable Long marginId) {
|
||||
return ApiResponse.ok(service.detailMargin(marginId));
|
||||
}
|
||||
|
||||
@PostMapping("/margin/recalc")
|
||||
@RequirePermission(menu = "INCOME_COMM", perm = "CREATE")
|
||||
@DataChangeLog(menu = "INCOME_COMM", table = "margin_summary")
|
||||
public ApiResponse<Long> recalcMargin(@RequestParam String settleMonth,
|
||||
@RequestParam(required = false) Long agentId) {
|
||||
return ApiResponse.ok(service.recalcMargin(settleMonth, agentId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.JointContractService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.JointContractResp;
|
||||
import com.ga.core.vo.commission.JointContractSaveReq;
|
||||
import com.ga.core.vo.commission.JointContractSearchParam;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "공동계약")
|
||||
@RestController
|
||||
@RequestMapping("/api/joint-contracts")
|
||||
@RequiredArgsConstructor
|
||||
public class JointContractController {
|
||||
|
||||
private final JointContractService service;
|
||||
|
||||
@GetMapping
|
||||
@RequirePermission(menu = "JOINT_CONTRACT", perm = "READ")
|
||||
public ApiResponse<PageResponse<JointContractResp>> list(@ModelAttribute JointContractSearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@GetMapping("/{jointId}")
|
||||
@RequirePermission(menu = "JOINT_CONTRACT", perm = "READ")
|
||||
public ApiResponse<JointContractResp> detail(@PathVariable Long jointId) {
|
||||
return ApiResponse.ok(service.detail(jointId));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@RequirePermission(menu = "JOINT_CONTRACT", perm = "CREATE")
|
||||
@DataChangeLog(menu = "JOINT_CONTRACT", table = "joint_contract")
|
||||
public ApiResponse<Long> create(@Valid @RequestBody JointContractSaveReq req) {
|
||||
return ApiResponse.ok(service.create(req));
|
||||
}
|
||||
|
||||
@PutMapping("/{jointId}")
|
||||
@RequirePermission(menu = "JOINT_CONTRACT", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "JOINT_CONTRACT", table = "joint_contract")
|
||||
public ApiResponse<Void> update(@PathVariable Long jointId,
|
||||
@Valid @RequestBody JointContractSaveReq req) {
|
||||
service.update(jointId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{jointId}")
|
||||
@RequirePermission(menu = "JOINT_CONTRACT", perm = "DELETE")
|
||||
@DataChangeLog(menu = "JOINT_CONTRACT", table = "joint_contract")
|
||||
public ApiResponse<Void> delete(@PathVariable Long jointId) {
|
||||
service.delete(jointId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.LifeSupportService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "생보운영지원수수료")
|
||||
@RestController
|
||||
@RequestMapping("/api/life-supports")
|
||||
@RequiredArgsConstructor
|
||||
public class LifeSupportController {
|
||||
|
||||
private final LifeSupportService service;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/rules")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "READ")
|
||||
public ApiResponse<PageResponse<LifeSupportRuleResp>> listRules(
|
||||
@ModelAttribute LifeSupportRuleSearchParam param) {
|
||||
return ApiResponse.ok(service.listRules(param));
|
||||
}
|
||||
|
||||
@GetMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "READ")
|
||||
public ApiResponse<LifeSupportRuleResp> detailRule(@PathVariable Long ruleId) {
|
||||
return ApiResponse.ok(service.detailRule(ruleId));
|
||||
}
|
||||
|
||||
@PostMapping("/rules")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "CREATE")
|
||||
@DataChangeLog(menu = "LIFE_OP_SUPPORT", table = "life_support_rule")
|
||||
public ApiResponse<Long> createRule(@Valid @RequestBody LifeSupportRuleSaveReq req) {
|
||||
return ApiResponse.ok(service.createRule(req));
|
||||
}
|
||||
|
||||
@PutMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "LIFE_OP_SUPPORT", table = "life_support_rule")
|
||||
public ApiResponse<Void> updateRule(@PathVariable Long ruleId,
|
||||
@Valid @RequestBody LifeSupportRuleSaveReq req) {
|
||||
service.updateRule(ruleId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "DELETE")
|
||||
@DataChangeLog(menu = "LIFE_OP_SUPPORT", table = "life_support_rule")
|
||||
public ApiResponse<Void> deleteRule(@PathVariable Long ruleId) {
|
||||
service.deleteRule(ruleId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/ledgers")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "READ")
|
||||
public ApiResponse<PageResponse<LifeSupportLedgerResp>> listLedgers(
|
||||
@ModelAttribute LifeSupportLedgerSearchParam param) {
|
||||
return ApiResponse.ok(service.listLedgers(param));
|
||||
}
|
||||
|
||||
@GetMapping("/ledgers/{ledgerId}")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "READ")
|
||||
public ApiResponse<LifeSupportLedgerResp> detailLedger(@PathVariable Long ledgerId) {
|
||||
return ApiResponse.ok(service.detailLedger(ledgerId));
|
||||
}
|
||||
|
||||
@PostMapping("/ledgers")
|
||||
@RequirePermission(menu = "LIFE_OP_SUPPORT", perm = "CREATE")
|
||||
@DataChangeLog(menu = "LIFE_OP_SUPPORT", table = "life_support_ledger")
|
||||
public ApiResponse<Long> createLedger(@Valid @RequestBody LifeSupportLedgerSaveReq req) {
|
||||
return ApiResponse.ok(service.createLedger(req));
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.RecognizedPerformanceService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "인정실적")
|
||||
@RestController
|
||||
@RequestMapping("/api/recognized-performances")
|
||||
@RequiredArgsConstructor
|
||||
public class RecognizedPerformanceController {
|
||||
|
||||
private final RecognizedPerformanceService service;
|
||||
|
||||
// ── Product Conversion Rate (rule) ────────────────────────────────────────
|
||||
|
||||
@GetMapping("/rates")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "READ")
|
||||
public ApiResponse<PageResponse<ProductConversionRateResp>> listRates(
|
||||
@ModelAttribute ProductConversionRateSearchParam param) {
|
||||
return ApiResponse.ok(service.listRates(param));
|
||||
}
|
||||
|
||||
@GetMapping("/rates/{rateId}")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "READ")
|
||||
public ApiResponse<ProductConversionRateResp> detailRate(@PathVariable Long rateId) {
|
||||
return ApiResponse.ok(service.detailRate(rateId));
|
||||
}
|
||||
|
||||
@PostMapping("/rates")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "CREATE")
|
||||
@DataChangeLog(menu = "RECOGNIZED_PERF", table = "product_conversion_rate")
|
||||
public ApiResponse<Long> createRate(@Valid @RequestBody ProductConversionRateSaveReq req) {
|
||||
return ApiResponse.ok(service.createRate(req));
|
||||
}
|
||||
|
||||
@PutMapping("/rates/{rateId}")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "RECOGNIZED_PERF", table = "product_conversion_rate")
|
||||
public ApiResponse<Void> updateRate(@PathVariable Long rateId,
|
||||
@Valid @RequestBody ProductConversionRateSaveReq req) {
|
||||
service.updateRate(rateId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/rates/{rateId}")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "DELETE")
|
||||
@DataChangeLog(menu = "RECOGNIZED_PERF", table = "product_conversion_rate")
|
||||
public ApiResponse<Void> deleteRate(@PathVariable Long rateId) {
|
||||
service.deleteRate(rateId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/ledgers")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "READ")
|
||||
public ApiResponse<PageResponse<RecognizedPerformanceLedgerResp>> listLedgers(
|
||||
@ModelAttribute RecognizedPerformanceLedgerSearchParam param) {
|
||||
return ApiResponse.ok(service.listLedgers(param));
|
||||
}
|
||||
|
||||
@GetMapping("/ledgers/{ledgerId}")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "READ")
|
||||
public ApiResponse<RecognizedPerformanceLedgerResp> detailLedger(@PathVariable Long ledgerId) {
|
||||
return ApiResponse.ok(service.detailLedger(ledgerId));
|
||||
}
|
||||
|
||||
@PostMapping("/ledgers")
|
||||
@RequirePermission(menu = "RECOGNIZED_PERF", perm = "CREATE")
|
||||
@DataChangeLog(menu = "RECOGNIZED_PERF", table = "recognized_performance_ledger")
|
||||
public ApiResponse<Long> createLedger(@Valid @RequestBody RecognizedPerformanceLedgerSaveReq req) {
|
||||
return ApiResponse.ok(service.createLedger(req));
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.ReferralCommissionService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "소개·이관수수료")
|
||||
@RestController
|
||||
@RequestMapping("/api/referral-commissions")
|
||||
@RequiredArgsConstructor
|
||||
public class ReferralCommissionController {
|
||||
|
||||
private final ReferralCommissionService service;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/rules")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "READ")
|
||||
public ApiResponse<PageResponse<ReferralCommissionRuleResp>> listRules(
|
||||
@ModelAttribute ReferralCommissionRuleSearchParam param) {
|
||||
return ApiResponse.ok(service.listRules(param));
|
||||
}
|
||||
|
||||
@GetMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "READ")
|
||||
public ApiResponse<ReferralCommissionRuleResp> detailRule(@PathVariable Long ruleId) {
|
||||
return ApiResponse.ok(service.detailRule(ruleId));
|
||||
}
|
||||
|
||||
@PostMapping("/rules")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "CREATE")
|
||||
@DataChangeLog(menu = "REFERRAL_COMM", table = "referral_commission_rule")
|
||||
public ApiResponse<Long> createRule(@Valid @RequestBody ReferralCommissionRuleSaveReq req) {
|
||||
return ApiResponse.ok(service.createRule(req));
|
||||
}
|
||||
|
||||
@PutMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "REFERRAL_COMM", table = "referral_commission_rule")
|
||||
public ApiResponse<Void> updateRule(@PathVariable Long ruleId,
|
||||
@Valid @RequestBody ReferralCommissionRuleSaveReq req) {
|
||||
service.updateRule(ruleId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "DELETE")
|
||||
@DataChangeLog(menu = "REFERRAL_COMM", table = "referral_commission_rule")
|
||||
public ApiResponse<Void> deleteRule(@PathVariable Long ruleId) {
|
||||
service.deleteRule(ruleId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/ledgers")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "READ")
|
||||
public ApiResponse<PageResponse<ReferralCommissionLedgerResp>> listLedgers(
|
||||
@ModelAttribute ReferralCommissionLedgerSearchParam param) {
|
||||
return ApiResponse.ok(service.listLedgers(param));
|
||||
}
|
||||
|
||||
@GetMapping("/ledgers/{ledgerId}")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "READ")
|
||||
public ApiResponse<ReferralCommissionLedgerResp> detailLedger(@PathVariable Long ledgerId) {
|
||||
return ApiResponse.ok(service.detailLedger(ledgerId));
|
||||
}
|
||||
|
||||
@PostMapping("/ledgers")
|
||||
@RequirePermission(menu = "REFERRAL_COMM", perm = "CREATE")
|
||||
@DataChangeLog(menu = "REFERRAL_COMM", table = "referral_commission_ledger")
|
||||
public ApiResponse<Long> createLedger(@Valid @RequestBody ReferralCommissionLedgerSaveReq req) {
|
||||
return ApiResponse.ok(service.createLedger(req));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.ReserveFundService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.AgentReserveFundResp;
|
||||
import com.ga.core.vo.commission.AgentReserveFundSaveReq;
|
||||
import com.ga.core.vo.commission.AgentReserveFundSearchParam;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "적립금")
|
||||
@RestController
|
||||
@RequestMapping("/api/reserve-funds")
|
||||
@RequiredArgsConstructor
|
||||
public class ReserveFundController {
|
||||
|
||||
private final ReserveFundService service;
|
||||
|
||||
@GetMapping
|
||||
@RequirePermission(menu = "RESERVE_FUND", perm = "READ")
|
||||
public ApiResponse<PageResponse<AgentReserveFundResp>> list(@ModelAttribute AgentReserveFundSearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@GetMapping("/{reserveId}")
|
||||
@RequirePermission(menu = "RESERVE_FUND", perm = "READ")
|
||||
public ApiResponse<AgentReserveFundResp> detail(@PathVariable Long reserveId) {
|
||||
return ApiResponse.ok(service.detail(reserveId));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@RequirePermission(menu = "RESERVE_FUND", perm = "CREATE")
|
||||
@DataChangeLog(menu = "RESERVE_FUND", table = "agent_reserve_fund")
|
||||
public ApiResponse<Long> create(@Valid @RequestBody AgentReserveFundSaveReq req) {
|
||||
return ApiResponse.ok(service.create(req));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.SettlingSupportService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "정착지원금")
|
||||
@RestController
|
||||
@RequestMapping("/api/settling-supports")
|
||||
@RequiredArgsConstructor
|
||||
public class SettlingSupportController {
|
||||
|
||||
private final SettlingSupportService service;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/rules")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "READ")
|
||||
public ApiResponse<PageResponse<SettlingSupportRuleResp>> listRules(
|
||||
@ModelAttribute SettlingSupportRuleSearchParam param) {
|
||||
return ApiResponse.ok(service.listRules(param));
|
||||
}
|
||||
|
||||
@GetMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "READ")
|
||||
public ApiResponse<SettlingSupportRuleResp> detailRule(@PathVariable Long ruleId) {
|
||||
return ApiResponse.ok(service.detailRule(ruleId));
|
||||
}
|
||||
|
||||
@PostMapping("/rules")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "CREATE")
|
||||
@DataChangeLog(menu = "SETTLING_SUPPORT", table = "settling_support_rule")
|
||||
public ApiResponse<Long> createRule(@Valid @RequestBody SettlingSupportRuleSaveReq req) {
|
||||
return ApiResponse.ok(service.createRule(req));
|
||||
}
|
||||
|
||||
@PutMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "SETTLING_SUPPORT", table = "settling_support_rule")
|
||||
public ApiResponse<Void> updateRule(@PathVariable Long ruleId,
|
||||
@Valid @RequestBody SettlingSupportRuleSaveReq req) {
|
||||
service.updateRule(ruleId, req);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@DeleteMapping("/rules/{ruleId}")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "DELETE")
|
||||
@DataChangeLog(menu = "SETTLING_SUPPORT", table = "settling_support_rule")
|
||||
public ApiResponse<Void> deleteRule(@PathVariable Long ruleId) {
|
||||
service.deleteRule(ruleId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
@GetMapping("/ledgers")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "READ")
|
||||
public ApiResponse<PageResponse<SettlingSupportLedgerResp>> listLedgers(
|
||||
@ModelAttribute SettlingSupportLedgerSearchParam param) {
|
||||
return ApiResponse.ok(service.listLedgers(param));
|
||||
}
|
||||
|
||||
@GetMapping("/ledgers/{ledgerId}")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "READ")
|
||||
public ApiResponse<SettlingSupportLedgerResp> detailLedger(@PathVariable Long ledgerId) {
|
||||
return ApiResponse.ok(service.detailLedger(ledgerId));
|
||||
}
|
||||
|
||||
@PostMapping("/ledgers")
|
||||
@RequirePermission(menu = "SETTLING_SUPPORT", perm = "CREATE")
|
||||
@DataChangeLog(menu = "SETTLING_SUPPORT", table = "settling_support_ledger")
|
||||
public ApiResponse<Long> createLedger(@Valid @RequestBody SettlingSupportLedgerSaveReq req) {
|
||||
return ApiResponse.ok(service.createLedger(req));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.ga.api.controller.commission;
|
||||
|
||||
import com.ga.api.service.commission.StepCloseService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.commission.StepCloseResp;
|
||||
import com.ga.core.vo.commission.StepCloseSaveReq;
|
||||
import com.ga.core.vo.commission.StepCloseSearchParam;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "단계마감")
|
||||
@RestController
|
||||
@RequestMapping("/api/step-closes")
|
||||
@RequiredArgsConstructor
|
||||
public class StepCloseController {
|
||||
|
||||
private final StepCloseService service;
|
||||
|
||||
@GetMapping
|
||||
@RequirePermission(menu = "STEP_CLOSE", perm = "READ")
|
||||
public ApiResponse<PageResponse<StepCloseResp>> list(@ModelAttribute StepCloseSearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@GetMapping("/by-month")
|
||||
@RequirePermission(menu = "STEP_CLOSE", perm = "READ")
|
||||
public ApiResponse<List<StepCloseResp>> listByMonth(@RequestParam String settleMonth) {
|
||||
return ApiResponse.ok(service.listByMonth(settleMonth));
|
||||
}
|
||||
|
||||
@GetMapping("/{stepCloseId}")
|
||||
@RequirePermission(menu = "STEP_CLOSE", perm = "READ")
|
||||
public ApiResponse<StepCloseResp> detail(@PathVariable Long stepCloseId) {
|
||||
return ApiResponse.ok(service.detail(stepCloseId));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@RequirePermission(menu = "STEP_CLOSE", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "STEP_CLOSE", table = "settlement_step_close")
|
||||
public ApiResponse<Long> create(@Valid @RequestBody StepCloseSaveReq req) {
|
||||
return ApiResponse.ok(service.create(req));
|
||||
}
|
||||
|
||||
@PostMapping("/{stepCloseId}/close")
|
||||
@RequirePermission(menu = "STEP_CLOSE", perm = "APPROVE")
|
||||
@DataChangeLog(menu = "STEP_CLOSE", table = "settlement_step_close")
|
||||
public ApiResponse<Void> close(@PathVariable Long stepCloseId) {
|
||||
service.close(stepCloseId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/{stepCloseId}/reopen")
|
||||
@RequirePermission(menu = "STEP_CLOSE", perm = "APPROVE")
|
||||
@DataChangeLog(menu = "STEP_CLOSE", table = "settlement_step_close")
|
||||
public ApiResponse<Void> reopen(@PathVariable Long stepCloseId) {
|
||||
service.reopen(stepCloseId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.AwardLedgerMapper;
|
||||
import com.ga.core.mapper.commission.AwardRuleMapper;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class AwardService {
|
||||
|
||||
private final AwardRuleMapper ruleMapper;
|
||||
private final AwardLedgerMapper ledgerMapper;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<AwardRuleResp> listRules(AwardRuleSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ruleMapper.selectList(param));
|
||||
}
|
||||
|
||||
public AwardRuleResp detailRule(Long ruleId) {
|
||||
AwardRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createRule(AwardRuleSaveReq req) {
|
||||
AwardRuleVO vo = new AwardRuleVO();
|
||||
vo.setAwardType(req.getAwardType());
|
||||
vo.setCalcType(req.getCalcType());
|
||||
vo.setThresholdAmount(req.getThresholdAmount());
|
||||
vo.setAwardRate(req.getAwardRate());
|
||||
vo.setAwardFixed(req.getAwardFixed());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.insert(vo);
|
||||
return vo.getRuleId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateRule(Long ruleId, AwardRuleSaveReq req) {
|
||||
AwardRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
AwardRuleVO vo = new AwardRuleVO();
|
||||
vo.setRuleId(ruleId);
|
||||
vo.setAwardType(req.getAwardType());
|
||||
vo.setCalcType(req.getCalcType());
|
||||
vo.setThresholdAmount(req.getThresholdAmount());
|
||||
vo.setAwardRate(req.getAwardRate());
|
||||
vo.setAwardFixed(req.getAwardFixed());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteRule(Long ruleId) {
|
||||
AwardRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ruleMapper.delete(ruleId);
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<AwardLedgerResp> listLedgers(AwardLedgerSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ledgerMapper.selectList(param));
|
||||
}
|
||||
|
||||
public AwardLedgerResp detailLedger(Long ledgerId) {
|
||||
AwardLedgerResp resp = ledgerMapper.selectById(ledgerId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createLedger(AwardLedgerSaveReq req) {
|
||||
// 룰 조회로 calc_type 결정
|
||||
AwardRuleVO rule = ruleMapper.selectActiveRule(req.getAwardType(), LocalDate.now());
|
||||
if (rule == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
|
||||
BigDecimal awardAmount;
|
||||
if ("FIXED".equals(rule.getCalcType())) {
|
||||
awardAmount = rule.getAwardFixed().setScale(2, RoundingMode.HALF_UP);
|
||||
} else {
|
||||
// RATE: base × award_rate
|
||||
awardAmount = req.getBaseAmount()
|
||||
.multiply(rule.getAwardRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
AwardLedgerVO vo = new AwardLedgerVO();
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setAwardType(req.getAwardType());
|
||||
vo.setBaseAmount(req.getBaseAmount());
|
||||
vo.setAwardAmount(awardAmount);
|
||||
vo.setStatus("CALCULATED");
|
||||
ledgerMapper.insert(vo);
|
||||
return vo.getLedgerId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.BranchMgrAllowanceLedgerMapper;
|
||||
import com.ga.core.mapper.commission.BranchMgrAllowanceRuleMapper;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class BranchAllowanceService {
|
||||
|
||||
private final BranchMgrAllowanceRuleMapper ruleMapper;
|
||||
private final BranchMgrAllowanceLedgerMapper ledgerMapper;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<BranchMgrAllowanceRuleResp> listRules(BranchMgrAllowanceRuleSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ruleMapper.selectList(param));
|
||||
}
|
||||
|
||||
public BranchMgrAllowanceRuleResp detailRule(Long ruleId) {
|
||||
BranchMgrAllowanceRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createRule(BranchMgrAllowanceRuleSaveReq req) {
|
||||
BranchMgrAllowanceRuleVO vo = new BranchMgrAllowanceRuleVO();
|
||||
vo.setPositionCode(req.getPositionCode());
|
||||
vo.setAllowanceRate(req.getAllowanceRate());
|
||||
vo.setCapAmount(req.getCapAmount());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.insert(vo);
|
||||
return vo.getRuleId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateRule(Long ruleId, BranchMgrAllowanceRuleSaveReq req) {
|
||||
BranchMgrAllowanceRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
BranchMgrAllowanceRuleVO vo = new BranchMgrAllowanceRuleVO();
|
||||
vo.setRuleId(ruleId);
|
||||
vo.setPositionCode(req.getPositionCode());
|
||||
vo.setAllowanceRate(req.getAllowanceRate());
|
||||
vo.setCapAmount(req.getCapAmount());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteRule(Long ruleId) {
|
||||
BranchMgrAllowanceRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ruleMapper.delete(ruleId);
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<BranchMgrAllowanceLedgerResp> listLedgers(BranchMgrAllowanceLedgerSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ledgerMapper.selectList(param));
|
||||
}
|
||||
|
||||
public BranchMgrAllowanceLedgerResp detailLedger(Long ledgerId) {
|
||||
BranchMgrAllowanceLedgerResp resp = ledgerMapper.selectById(ledgerId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createLedger(BranchMgrAllowanceLedgerSaveReq req) {
|
||||
// 수당액 = min(base × rate, cap) — cap NULL이면 상한 없음
|
||||
BigDecimal raw = req.getBaseAmount()
|
||||
.multiply(req.getAllowanceRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal clawback = req.getClawbackAmount() != null ? req.getClawbackAmount() : BigDecimal.ZERO;
|
||||
|
||||
// cap_amount는 SaveReq에 없으므로 allowanceRate와 동일 룰에서 cap 조회
|
||||
// positionCode가 req에 없어 단순 구현: raw 그대로 사용 (배치에서 룰 참조 시 위임)
|
||||
BigDecimal allowanceAmount = raw;
|
||||
|
||||
BranchMgrAllowanceLedgerVO vo = new BranchMgrAllowanceLedgerVO();
|
||||
vo.setManagerAgentId(req.getManagerAgentId());
|
||||
vo.setOrgId(req.getOrgId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setBaseAmount(req.getBaseAmount());
|
||||
vo.setAllowanceRate(req.getAllowanceRate());
|
||||
vo.setAllowanceAmount(allowanceAmount);
|
||||
vo.setClawbackAmount(clawback);
|
||||
vo.setStatus("CALCULATED");
|
||||
ledgerMapper.insert(vo);
|
||||
return vo.getLedgerId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.common.util.SecurityUtil;
|
||||
import com.ga.core.mapper.commission.CommissionSimulationMapper;
|
||||
import com.ga.core.vo.commission.CommissionSimulationResp;
|
||||
import com.ga.core.vo.commission.CommissionSimulationSaveReq;
|
||||
import com.ga.core.vo.commission.CommissionSimulationSearchParam;
|
||||
import com.ga.core.vo.commission.CommissionSimulationVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class CommissionSimulationService {
|
||||
|
||||
private static final BigDecimal WITHHOLDING_TAX_RATE = new BigDecimal("0.033");
|
||||
private static final BigDecimal DEFAULT_CHARGEBACK_RATE = new BigDecimal("0.5");
|
||||
|
||||
private final CommissionSimulationMapper simulationMapper;
|
||||
|
||||
public PageResponse<CommissionSimulationResp> list(CommissionSimulationSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(simulationMapper.selectList(param));
|
||||
}
|
||||
|
||||
public CommissionSimulationResp detail(Long simId) {
|
||||
CommissionSimulationResp resp = simulationMapper.selectById(simId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수수료 시뮬레이션 계산 후 저장·반환.
|
||||
* company_payment = premium × company_rate
|
||||
* agent_commission = company_payment × payout_rate
|
||||
* withholding_tax = agent_commission × 3.3%
|
||||
* net_amount = agent_commission − withholding_tax
|
||||
* expected_chargeback: 입력 값이 있으면 사용, 없으면 agent_commission × 50% (13개월 가정)
|
||||
* 모든 금액 setScale(2, HALF_UP).
|
||||
*/
|
||||
@Transactional
|
||||
public CommissionSimulationResp simulate(CommissionSimulationSaveReq req) {
|
||||
BigDecimal companyPayment = req.getPremiumAmount()
|
||||
.multiply(req.getCompanyRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
BigDecimal agentCommission = companyPayment
|
||||
.multiply(req.getPayoutRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
BigDecimal withholdingTax = agentCommission
|
||||
.multiply(WITHHOLDING_TAX_RATE)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
BigDecimal netAmount = agentCommission
|
||||
.subtract(withholdingTax)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
BigDecimal expectedChargeback;
|
||||
if (req.getExpectedChargeback() != null) {
|
||||
expectedChargeback = req.getExpectedChargeback().setScale(2, RoundingMode.HALF_UP);
|
||||
} else {
|
||||
expectedChargeback = agentCommission
|
||||
.multiply(DEFAULT_CHARGEBACK_RATE)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
CommissionSimulationVO vo = new CommissionSimulationVO();
|
||||
vo.setSimName(req.getSimName());
|
||||
vo.setPremiumAmount(req.getPremiumAmount());
|
||||
vo.setCompanyRate(req.getCompanyRate());
|
||||
vo.setPayoutRate(req.getPayoutRate());
|
||||
vo.setCommissionYear(req.getCommissionYear());
|
||||
vo.setCompanyPayment(companyPayment);
|
||||
vo.setAgentCommission(agentCommission);
|
||||
vo.setWithholdingTax(withholdingTax);
|
||||
vo.setNetAmount(netAmount);
|
||||
vo.setExpectedChargeback(expectedChargeback);
|
||||
vo.setCreatedBy(SecurityUtil.getCurrentUserId());
|
||||
simulationMapper.insert(vo);
|
||||
|
||||
CommissionSimulationResp resp = simulationMapper.selectById(vo.getSimId());
|
||||
if (resp == null) throw new BizException(ErrorCode.INTERNAL_ERROR);
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.AgentGradeEvaluationMapper;
|
||||
import com.ga.core.mapper.commission.GradeEvalRuleMapper;
|
||||
import com.ga.core.vo.commission.AgentGradeEvaluationResp;
|
||||
import com.ga.core.vo.commission.AgentGradeEvaluationSaveReq;
|
||||
import com.ga.core.vo.commission.AgentGradeEvaluationSearchParam;
|
||||
import com.ga.core.vo.commission.AgentGradeEvaluationVO;
|
||||
import com.ga.core.vo.commission.GradeEvalRuleResp;
|
||||
import com.ga.core.vo.commission.GradeEvalRuleSaveReq;
|
||||
import com.ga.core.vo.commission.GradeEvalRuleSearchParam;
|
||||
import com.ga.core.vo.commission.GradeEvalRuleVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class GradeEvaluationService {
|
||||
|
||||
private final GradeEvalRuleMapper ruleMapper;
|
||||
private final AgentGradeEvaluationMapper evalMapper;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<GradeEvalRuleResp> listRules(GradeEvalRuleSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ruleMapper.selectList(param));
|
||||
}
|
||||
|
||||
public GradeEvalRuleResp detailRule(Long ruleId) {
|
||||
GradeEvalRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createRule(GradeEvalRuleSaveReq req) {
|
||||
GradeEvalRuleVO vo = new GradeEvalRuleVO();
|
||||
vo.setGradeId(req.getGradeId());
|
||||
vo.setMinScore(req.getMinScore());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.insert(vo);
|
||||
return vo.getRuleId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateRule(Long ruleId, GradeEvalRuleSaveReq req) {
|
||||
GradeEvalRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
GradeEvalRuleVO vo = new GradeEvalRuleVO();
|
||||
vo.setRuleId(ruleId);
|
||||
vo.setGradeId(req.getGradeId());
|
||||
vo.setMinScore(req.getMinScore());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteRule(Long ruleId) {
|
||||
GradeEvalRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ruleMapper.delete(ruleId);
|
||||
}
|
||||
|
||||
// ── Evaluation ────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<AgentGradeEvaluationResp> listEvals(AgentGradeEvaluationSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(evalMapper.selectList(param));
|
||||
}
|
||||
|
||||
public AgentGradeEvaluationResp detailEval(Long evalId) {
|
||||
AgentGradeEvaluationResp resp = evalMapper.selectById(evalId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 등급평가 생성.
|
||||
* selectActiveRuleByScore(score, 기준일)로 evaluated_grade_id 결정.
|
||||
* 매칭 룰 없으면 prevGradeId 유지 또는 null.
|
||||
*/
|
||||
@Transactional
|
||||
public Long createEval(AgentGradeEvaluationSaveReq req) {
|
||||
LocalDate baseDate = LocalDate.now();
|
||||
GradeEvalRuleVO matchedRule = ruleMapper.selectActiveRuleByScore(req.getPerformanceScore(), baseDate);
|
||||
|
||||
Long evaluatedGradeId = (matchedRule != null) ? matchedRule.getGradeId() : req.getPrevGradeId();
|
||||
|
||||
AgentGradeEvaluationVO vo = new AgentGradeEvaluationVO();
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setEvalPeriod(req.getEvalPeriod());
|
||||
vo.setPerformanceScore(req.getPerformanceScore());
|
||||
vo.setPrevGradeId(req.getPrevGradeId());
|
||||
vo.setEvaluatedGradeId(evaluatedGradeId);
|
||||
vo.setStatus("EVALUATED");
|
||||
evalMapper.insert(vo);
|
||||
return vo.getEvalId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 등급평가 반영 액션 (EVALUATED → APPLIED).
|
||||
*/
|
||||
@Transactional
|
||||
public void applyEval(Long evalId) {
|
||||
AgentGradeEvaluationResp resp = evalMapper.selectById(evalId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
if ("APPLIED".equals(resp.getStatus())) {
|
||||
throw new BizException(ErrorCode.INVALID_STATUS, "이미 반영된 평가입니다.");
|
||||
}
|
||||
evalMapper.updateStatus(evalId, "APPLIED");
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteEval(Long evalId) {
|
||||
AgentGradeEvaluationResp resp = evalMapper.selectById(evalId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
evalMapper.delete(evalId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.AgentGuaranteeInsuranceMapper;
|
||||
import com.ga.core.vo.commission.AgentGuaranteeInsuranceResp;
|
||||
import com.ga.core.vo.commission.AgentGuaranteeInsuranceSaveReq;
|
||||
import com.ga.core.vo.commission.AgentGuaranteeInsuranceSearchParam;
|
||||
import com.ga.core.vo.commission.AgentGuaranteeInsuranceVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class GuaranteeInsuranceService {
|
||||
|
||||
private final AgentGuaranteeInsuranceMapper guaranteeInsuranceMapper;
|
||||
|
||||
public PageResponse<AgentGuaranteeInsuranceResp> list(AgentGuaranteeInsuranceSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(guaranteeInsuranceMapper.selectList(param));
|
||||
}
|
||||
|
||||
public AgentGuaranteeInsuranceResp detail(Long guaranteeId) {
|
||||
AgentGuaranteeInsuranceResp resp = guaranteeInsuranceMapper.selectById(guaranteeId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long create(AgentGuaranteeInsuranceSaveReq req) {
|
||||
AgentGuaranteeInsuranceVO vo = new AgentGuaranteeInsuranceVO();
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setPolicyNo(req.getPolicyNo());
|
||||
vo.setCarrierId(req.getCarrierId());
|
||||
vo.setGuaranteeAmount(req.getGuaranteeAmount());
|
||||
vo.setStartDate(req.getStartDate());
|
||||
vo.setEndDate(req.getEndDate());
|
||||
vo.setStatus("ACTIVE");
|
||||
guaranteeInsuranceMapper.insert(vo);
|
||||
return vo.getGuaranteeId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void update(Long guaranteeId, AgentGuaranteeInsuranceSaveReq req) {
|
||||
AgentGuaranteeInsuranceResp resp = guaranteeInsuranceMapper.selectById(guaranteeId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
AgentGuaranteeInsuranceVO vo = new AgentGuaranteeInsuranceVO();
|
||||
vo.setGuaranteeId(guaranteeId);
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setPolicyNo(req.getPolicyNo());
|
||||
vo.setCarrierId(req.getCarrierId());
|
||||
vo.setGuaranteeAmount(req.getGuaranteeAmount());
|
||||
vo.setStartDate(req.getStartDate());
|
||||
vo.setEndDate(req.getEndDate());
|
||||
guaranteeInsuranceMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void delete(Long guaranteeId) {
|
||||
AgentGuaranteeInsuranceResp resp = guaranteeInsuranceMapper.selectById(guaranteeId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
guaranteeInsuranceMapper.delete(guaranteeId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.HqSettleItemMapper;
|
||||
import com.ga.core.vo.commission.HqSettleItemResp;
|
||||
import com.ga.core.vo.commission.HqSettleItemSaveReq;
|
||||
import com.ga.core.vo.commission.HqSettleItemSearchParam;
|
||||
import com.ga.core.vo.commission.HqSettleItemVO;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class HqSettleService {
|
||||
|
||||
private final HqSettleItemMapper itemMapper;
|
||||
|
||||
@Data
|
||||
public static class HqSummaryResp {
|
||||
private final String settleMonth;
|
||||
private final BigDecimal income;
|
||||
private final BigDecimal expense;
|
||||
private final BigDecimal profit;
|
||||
}
|
||||
|
||||
public PageResponse<HqSettleItemResp> list(HqSettleItemSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(itemMapper.selectList(param));
|
||||
}
|
||||
|
||||
public HqSettleItemResp detail(Long itemId) {
|
||||
HqSettleItemResp resp = itemMapper.selectById(itemId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 본사손익 집계: income − expense.
|
||||
* 둘 다 null이면 0으로 처리.
|
||||
*/
|
||||
public HqSummaryResp summary(String settleMonth) {
|
||||
BigDecimal income = itemMapper.sumByMonthAndType(settleMonth, "INCOME");
|
||||
BigDecimal expense = itemMapper.sumByMonthAndType(settleMonth, "EXPENSE");
|
||||
if (income == null) income = BigDecimal.ZERO;
|
||||
if (expense == null) expense = BigDecimal.ZERO;
|
||||
BigDecimal profit = income.subtract(expense);
|
||||
return new HqSummaryResp(settleMonth, income, expense, profit);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long create(HqSettleItemSaveReq req) {
|
||||
HqSettleItemVO vo = new HqSettleItemVO();
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setItemType(req.getItemType());
|
||||
vo.setItemName(req.getItemName());
|
||||
vo.setAmount(req.getAmount());
|
||||
vo.setMemo(req.getMemo());
|
||||
vo.setStatus("REGISTERED");
|
||||
itemMapper.insert(vo);
|
||||
return vo.getItemId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void update(Long itemId, HqSettleItemSaveReq req) {
|
||||
HqSettleItemResp resp = itemMapper.selectById(itemId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
HqSettleItemVO vo = new HqSettleItemVO();
|
||||
vo.setItemId(itemId);
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setItemType(req.getItemType());
|
||||
vo.setItemName(req.getItemName());
|
||||
vo.setAmount(req.getAmount());
|
||||
vo.setMemo(req.getMemo());
|
||||
itemMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void delete(Long itemId) {
|
||||
HqSettleItemResp resp = itemMapper.selectById(itemId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
itemMapper.delete(itemId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.IncomeCommissionLedgerMapper;
|
||||
import com.ga.core.mapper.commission.MarginSummaryMapper;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class IncomeCommissionService {
|
||||
|
||||
private final IncomeCommissionLedgerMapper ledgerMapper;
|
||||
private final MarginSummaryMapper marginMapper;
|
||||
|
||||
// ── Income Ledger ────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<IncomeCommissionLedgerResp> listLedgers(IncomeCommissionLedgerSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ledgerMapper.selectList(param));
|
||||
}
|
||||
|
||||
public IncomeCommissionLedgerResp detailLedger(Long incomeId) {
|
||||
IncomeCommissionLedgerResp resp = ledgerMapper.selectById(incomeId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createLedger(IncomeCommissionLedgerSaveReq req) {
|
||||
IncomeCommissionLedgerVO vo = new IncomeCommissionLedgerVO();
|
||||
vo.setContractId(req.getContractId());
|
||||
vo.setCarrierId(req.getCarrierId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setPremiumAmount(req.getPremiumAmount());
|
||||
vo.setCompanyRate(req.getCompanyRate());
|
||||
// 수입수수료 = 보험료 × 보험사요율
|
||||
vo.setIncomeAmount(req.getPremiumAmount()
|
||||
.multiply(req.getCompanyRate())
|
||||
.setScale(2, RoundingMode.HALF_UP));
|
||||
vo.setCommissionType(req.getCommissionType());
|
||||
vo.setStatus("CALCULATED");
|
||||
ledgerMapper.insert(vo);
|
||||
return vo.getIncomeId();
|
||||
}
|
||||
|
||||
// ── Margin Summary ───────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<MarginSummaryResp> listMargins(MarginSummarySearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(marginMapper.selectList(param));
|
||||
}
|
||||
|
||||
public MarginSummaryResp detailMargin(Long marginId) {
|
||||
MarginSummaryResp resp = marginMapper.selectById(marginId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수지차 재계산 (recalc).
|
||||
* settle_month 단위로 income_total(수입수수료 합) − payout_total(settle_master net_amount 합) 산출.
|
||||
* 수입수수료 원장에는 설계사 귀속이 없어(보험사·계약 단위) income 은 월 전체 합을 쓰고,
|
||||
* agentId 가 주어지면 payout 만 해당 설계사로 좁혀 집계한다. (미지정 시 GA 월 전체 수지차)
|
||||
* 수지차 = income_total − payout_total, 수지차율 = 수지차 / income_total (income_total > 0).
|
||||
*/
|
||||
@Transactional
|
||||
public Long recalcMargin(String settleMonth, Long agentId) {
|
||||
BigDecimal incomeTotal = marginMapper.sumIncomeByMonth(settleMonth);
|
||||
if (incomeTotal == null) incomeTotal = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal payoutTotal = marginMapper.sumPayoutByMonth(settleMonth, agentId);
|
||||
if (payoutTotal == null) payoutTotal = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal marginAmount = incomeTotal.subtract(payoutTotal).setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal marginRate = BigDecimal.ZERO;
|
||||
if (incomeTotal.compareTo(BigDecimal.ZERO) > 0) {
|
||||
marginRate = marginAmount.divide(incomeTotal, 4, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
MarginSummaryVO existing = marginMapper.selectByMonthAndAgent(settleMonth, agentId);
|
||||
if (existing != null) {
|
||||
existing.setIncomeTotal(incomeTotal);
|
||||
existing.setPayoutTotal(payoutTotal);
|
||||
existing.setMarginAmount(marginAmount);
|
||||
existing.setMarginRate(marginRate);
|
||||
marginMapper.update(existing);
|
||||
return existing.getMarginId();
|
||||
} else {
|
||||
MarginSummaryVO vo = new MarginSummaryVO();
|
||||
vo.setSettleMonth(settleMonth);
|
||||
vo.setAgentId(agentId);
|
||||
vo.setIncomeTotal(incomeTotal);
|
||||
vo.setPayoutTotal(payoutTotal);
|
||||
vo.setMarginAmount(marginAmount);
|
||||
vo.setMarginRate(marginRate);
|
||||
marginMapper.insert(vo);
|
||||
return vo.getMarginId();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.JointContractMapper;
|
||||
import com.ga.core.vo.commission.JointContractResp;
|
||||
import com.ga.core.vo.commission.JointContractSaveReq;
|
||||
import com.ga.core.vo.commission.JointContractSearchParam;
|
||||
import com.ga.core.vo.commission.JointContractVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class JointContractService {
|
||||
|
||||
private final JointContractMapper jointContractMapper;
|
||||
|
||||
public PageResponse<JointContractResp> list(JointContractSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(jointContractMapper.selectList(param));
|
||||
}
|
||||
|
||||
public JointContractResp detail(Long jointId) {
|
||||
JointContractResp resp = jointContractMapper.selectById(jointId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 공동계약 생성.
|
||||
* 기존 share_rate 합 + 신규 share_rate > 1.0 이면 E411 예외.
|
||||
*/
|
||||
@Transactional
|
||||
public Long create(JointContractSaveReq req) {
|
||||
validateShareRate(req.getContractId(), null, req.getShareRate());
|
||||
JointContractVO vo = new JointContractVO();
|
||||
vo.setContractId(req.getContractId());
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setRole(req.getRole());
|
||||
vo.setShareRate(req.getShareRate());
|
||||
jointContractMapper.insert(vo);
|
||||
return vo.getJointId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 공동계약 수정.
|
||||
* 기존 share_rate 합(자신 제외) + 수정 share_rate > 1.0 이면 E411 예외.
|
||||
*/
|
||||
@Transactional
|
||||
public void update(Long jointId, JointContractSaveReq req) {
|
||||
JointContractResp resp = jointContractMapper.selectById(jointId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
validateShareRate(req.getContractId(), jointId, req.getShareRate());
|
||||
JointContractVO vo = new JointContractVO();
|
||||
vo.setJointId(jointId);
|
||||
vo.setContractId(req.getContractId());
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setRole(req.getRole());
|
||||
vo.setShareRate(req.getShareRate());
|
||||
jointContractMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void delete(Long jointId) {
|
||||
JointContractResp resp = jointContractMapper.selectById(jointId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
jointContractMapper.delete(jointId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 계약별 share_rate 합 검증.
|
||||
* excludeJointId: 수정 시 자신 레코드를 합산에서 제외하기 위한 파라미터 (null=create).
|
||||
* sumShareByContract는 계약 전체 합을 반환하므로, 수정 시 기존 자신의 share_rate를 차감.
|
||||
*/
|
||||
private void validateShareRate(Long contractId, Long excludeJointId, BigDecimal newShareRate) {
|
||||
BigDecimal existingSum = jointContractMapper.sumShareByContract(contractId);
|
||||
if (existingSum == null) existingSum = BigDecimal.ZERO;
|
||||
|
||||
if (excludeJointId != null) {
|
||||
JointContractResp existing = jointContractMapper.selectById(excludeJointId);
|
||||
if (existing != null) {
|
||||
existingSum = existingSum.subtract(existing.getShareRate());
|
||||
}
|
||||
}
|
||||
|
||||
if (existingSum.add(newShareRate).compareTo(BigDecimal.ONE) > 0) {
|
||||
throw new BizException(ErrorCode.INVALID_PARAMETER, "계약별 지분율 합이 1을 초과합니다.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.LifeSupportLedgerMapper;
|
||||
import com.ga.core.mapper.commission.LifeSupportRuleMapper;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class LifeSupportService {
|
||||
|
||||
private final LifeSupportRuleMapper ruleMapper;
|
||||
private final LifeSupportLedgerMapper ledgerMapper;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<LifeSupportRuleResp> listRules(LifeSupportRuleSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ruleMapper.selectList(param));
|
||||
}
|
||||
|
||||
public LifeSupportRuleResp detailRule(Long ruleId) {
|
||||
LifeSupportRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createRule(LifeSupportRuleSaveReq req) {
|
||||
LifeSupportRuleVO vo = new LifeSupportRuleVO();
|
||||
vo.setAgentGrade(req.getAgentGrade());
|
||||
vo.setSupportRate(req.getSupportRate());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.insert(vo);
|
||||
return vo.getRuleId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateRule(Long ruleId, LifeSupportRuleSaveReq req) {
|
||||
LifeSupportRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
LifeSupportRuleVO vo = new LifeSupportRuleVO();
|
||||
vo.setRuleId(ruleId);
|
||||
vo.setAgentGrade(req.getAgentGrade());
|
||||
vo.setSupportRate(req.getSupportRate());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteRule(Long ruleId) {
|
||||
LifeSupportRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ruleMapper.delete(ruleId);
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<LifeSupportLedgerResp> listLedgers(LifeSupportLedgerSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ledgerMapper.selectList(param));
|
||||
}
|
||||
|
||||
public LifeSupportLedgerResp detailLedger(Long ledgerId) {
|
||||
LifeSupportLedgerResp resp = ledgerMapper.selectById(ledgerId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createLedger(LifeSupportLedgerSaveReq req) {
|
||||
// 지원수수료 = base × support_rate
|
||||
BigDecimal supportAmount = req.getBaseAmount()
|
||||
.multiply(req.getSupportRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal clawback = req.getClawbackAmount() != null ? req.getClawbackAmount() : BigDecimal.ZERO;
|
||||
// 실지급액 = support - clawback
|
||||
BigDecimal netAmount = supportAmount.subtract(clawback).setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
LifeSupportLedgerVO vo = new LifeSupportLedgerVO();
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setBaseAmount(req.getBaseAmount());
|
||||
vo.setSupportRate(req.getSupportRate());
|
||||
vo.setSupportAmount(supportAmount);
|
||||
vo.setClawbackAmount(clawback);
|
||||
vo.setNetAmount(netAmount);
|
||||
vo.setStatus("CALCULATED");
|
||||
ledgerMapper.insert(vo);
|
||||
return vo.getLedgerId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.ProductConversionRateMapper;
|
||||
import com.ga.core.mapper.commission.RecognizedPerformanceLedgerMapper;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class RecognizedPerformanceService {
|
||||
|
||||
private final ProductConversionRateMapper conversionRateMapper;
|
||||
private final RecognizedPerformanceLedgerMapper ledgerMapper;
|
||||
|
||||
// ── Product Conversion Rate (rule) ────────────────────────────────────────
|
||||
|
||||
public PageResponse<ProductConversionRateResp> listRates(ProductConversionRateSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(conversionRateMapper.selectList(param));
|
||||
}
|
||||
|
||||
public ProductConversionRateResp detailRate(Long rateId) {
|
||||
ProductConversionRateResp resp = conversionRateMapper.selectById(rateId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createRate(ProductConversionRateSaveReq req) {
|
||||
ProductConversionRateVO vo = new ProductConversionRateVO();
|
||||
vo.setProductId(req.getProductId());
|
||||
vo.setConversionRate(req.getConversionRate());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
conversionRateMapper.insert(vo);
|
||||
return vo.getRateId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateRate(Long rateId, ProductConversionRateSaveReq req) {
|
||||
ProductConversionRateResp resp = conversionRateMapper.selectById(rateId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ProductConversionRateVO vo = new ProductConversionRateVO();
|
||||
vo.setRateId(rateId);
|
||||
vo.setProductId(req.getProductId());
|
||||
vo.setConversionRate(req.getConversionRate());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
conversionRateMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteRate(Long rateId) {
|
||||
ProductConversionRateResp resp = conversionRateMapper.selectById(rateId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
conversionRateMapper.delete(rateId);
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<RecognizedPerformanceLedgerResp> listLedgers(RecognizedPerformanceLedgerSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ledgerMapper.selectList(param));
|
||||
}
|
||||
|
||||
public RecognizedPerformanceLedgerResp detailLedger(Long ledgerId) {
|
||||
RecognizedPerformanceLedgerResp resp = ledgerMapper.selectById(ledgerId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createLedger(RecognizedPerformanceLedgerSaveReq req) {
|
||||
// 환산보험료 = premium × conversion_rate
|
||||
BigDecimal convertedPremium = req.getPremiumAmount()
|
||||
.multiply(req.getConversionRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
// 인정실적 = converted_premium × recognition_rate
|
||||
BigDecimal recognizedAmount = convertedPremium
|
||||
.multiply(req.getRecognitionRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
RecognizedPerformanceLedgerVO vo = new RecognizedPerformanceLedgerVO();
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setContractId(req.getContractId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setPremiumAmount(req.getPremiumAmount());
|
||||
vo.setConversionRate(req.getConversionRate());
|
||||
vo.setConvertedPremium(convertedPremium);
|
||||
vo.setRecognitionRate(req.getRecognitionRate());
|
||||
vo.setRecognizedAmount(recognizedAmount);
|
||||
vo.setStatus("CALCULATED");
|
||||
ledgerMapper.insert(vo);
|
||||
return vo.getLedgerId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.ReferralCommissionLedgerMapper;
|
||||
import com.ga.core.mapper.commission.ReferralCommissionRuleMapper;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class ReferralCommissionService {
|
||||
|
||||
private final ReferralCommissionRuleMapper ruleMapper;
|
||||
private final ReferralCommissionLedgerMapper ledgerMapper;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<ReferralCommissionRuleResp> listRules(ReferralCommissionRuleSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ruleMapper.selectList(param));
|
||||
}
|
||||
|
||||
public ReferralCommissionRuleResp detailRule(Long ruleId) {
|
||||
ReferralCommissionRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createRule(ReferralCommissionRuleSaveReq req) {
|
||||
ReferralCommissionRuleVO vo = new ReferralCommissionRuleVO();
|
||||
vo.setReferralType(req.getReferralType());
|
||||
vo.setCalcType(req.getCalcType());
|
||||
vo.setCommissionRate(req.getCommissionRate());
|
||||
vo.setFixedAmount(req.getFixedAmount());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.insert(vo);
|
||||
return vo.getRuleId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateRule(Long ruleId, ReferralCommissionRuleSaveReq req) {
|
||||
ReferralCommissionRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ReferralCommissionRuleVO vo = new ReferralCommissionRuleVO();
|
||||
vo.setRuleId(ruleId);
|
||||
vo.setReferralType(req.getReferralType());
|
||||
vo.setCalcType(req.getCalcType());
|
||||
vo.setCommissionRate(req.getCommissionRate());
|
||||
vo.setFixedAmount(req.getFixedAmount());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteRule(Long ruleId) {
|
||||
ReferralCommissionRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ruleMapper.delete(ruleId);
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<ReferralCommissionLedgerResp> listLedgers(ReferralCommissionLedgerSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ledgerMapper.selectList(param));
|
||||
}
|
||||
|
||||
public ReferralCommissionLedgerResp detailLedger(Long ledgerId) {
|
||||
ReferralCommissionLedgerResp resp = ledgerMapper.selectById(ledgerId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createLedger(ReferralCommissionLedgerSaveReq req) {
|
||||
ReferralCommissionLedgerVO vo = new ReferralCommissionLedgerVO();
|
||||
vo.setContractId(req.getContractId());
|
||||
vo.setReferrerAgentId(req.getReferrerAgentId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setReferralType(req.getReferralType());
|
||||
vo.setBaseAmount(req.getBaseAmount());
|
||||
vo.setCommissionRate(req.getCommissionRate());
|
||||
|
||||
// 소개·이관수수료 = base × rate (RATE) 또는 fixed_amount (FIXED)
|
||||
BigDecimal commissionAmount;
|
||||
if (req.getCommissionRate() != null) {
|
||||
commissionAmount = req.getBaseAmount()
|
||||
.multiply(req.getCommissionRate())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
} else {
|
||||
// FIXED: 룰에서 fixed_amount 조회
|
||||
ReferralCommissionRuleVO rule = ruleMapper.selectActiveRule(
|
||||
req.getReferralType(), java.time.LocalDate.now());
|
||||
if (rule == null || rule.getFixedAmount() == null) {
|
||||
throw new BizException(ErrorCode.NOT_FOUND);
|
||||
}
|
||||
commissionAmount = rule.getFixedAmount().setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
vo.setCommissionAmount(commissionAmount);
|
||||
vo.setStatus("CALCULATED");
|
||||
ledgerMapper.insert(vo);
|
||||
return vo.getLedgerId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.AgentReserveFundMapper;
|
||||
import com.ga.core.vo.commission.AgentReserveFundResp;
|
||||
import com.ga.core.vo.commission.AgentReserveFundSaveReq;
|
||||
import com.ga.core.vo.commission.AgentReserveFundSearchParam;
|
||||
import com.ga.core.vo.commission.AgentReserveFundVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class ReserveFundService {
|
||||
|
||||
private final AgentReserveFundMapper reserveFundMapper;
|
||||
|
||||
public PageResponse<AgentReserveFundResp> list(AgentReserveFundSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(reserveFundMapper.selectList(param));
|
||||
}
|
||||
|
||||
public AgentReserveFundResp detail(Long reserveId) {
|
||||
AgentReserveFundResp resp = reserveFundMapper.selectById(reserveId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 적립금 생성(upsert).
|
||||
* balance = (직전월 balance or 0) + reserveIn − reserveOut. setScale(2, HALF_UP).
|
||||
* 해당 월 레코드가 이미 존재하면 update, 없으면 insert.
|
||||
*/
|
||||
@Transactional
|
||||
public Long create(AgentReserveFundSaveReq req) {
|
||||
AgentReserveFundVO prevMonth = reserveFundMapper.selectLatestBefore(req.getAgentId(), req.getSettleMonth());
|
||||
BigDecimal prevBalance = (prevMonth != null && prevMonth.getBalance() != null)
|
||||
? prevMonth.getBalance()
|
||||
: BigDecimal.ZERO;
|
||||
|
||||
BigDecimal balance = prevBalance
|
||||
.add(req.getReserveIn())
|
||||
.subtract(req.getReserveOut())
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
AgentReserveFundVO existing = reserveFundMapper.selectByAgentAndMonth(req.getAgentId(), req.getSettleMonth());
|
||||
if (existing != null) {
|
||||
existing.setReserveIn(req.getReserveIn());
|
||||
existing.setReserveOut(req.getReserveOut());
|
||||
existing.setBalance(balance);
|
||||
reserveFundMapper.update(existing);
|
||||
return existing.getReserveId();
|
||||
}
|
||||
|
||||
AgentReserveFundVO vo = new AgentReserveFundVO();
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setReserveIn(req.getReserveIn());
|
||||
vo.setReserveOut(req.getReserveOut());
|
||||
vo.setBalance(balance);
|
||||
reserveFundMapper.insert(vo);
|
||||
return vo.getReserveId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.commission.SettlingSupportLedgerMapper;
|
||||
import com.ga.core.mapper.commission.SettlingSupportRuleMapper;
|
||||
import com.ga.core.vo.commission.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class SettlingSupportService {
|
||||
|
||||
private final SettlingSupportRuleMapper ruleMapper;
|
||||
private final SettlingSupportLedgerMapper ledgerMapper;
|
||||
|
||||
// ── Rule ──────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<SettlingSupportRuleResp> listRules(SettlingSupportRuleSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ruleMapper.selectList(param));
|
||||
}
|
||||
|
||||
public SettlingSupportRuleResp detailRule(Long ruleId) {
|
||||
SettlingSupportRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createRule(SettlingSupportRuleSaveReq req) {
|
||||
SettlingSupportRuleVO vo = new SettlingSupportRuleVO();
|
||||
vo.setAgentGrade(req.getAgentGrade());
|
||||
vo.setSupportAmount(req.getSupportAmount());
|
||||
vo.setDurationMonths(req.getDurationMonths());
|
||||
vo.setClawbackMonths(req.getClawbackMonths());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.insert(vo);
|
||||
return vo.getRuleId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateRule(Long ruleId, SettlingSupportRuleSaveReq req) {
|
||||
SettlingSupportRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
SettlingSupportRuleVO vo = new SettlingSupportRuleVO();
|
||||
vo.setRuleId(ruleId);
|
||||
vo.setAgentGrade(req.getAgentGrade());
|
||||
vo.setSupportAmount(req.getSupportAmount());
|
||||
vo.setDurationMonths(req.getDurationMonths());
|
||||
vo.setClawbackMonths(req.getClawbackMonths());
|
||||
vo.setEffectiveFrom(req.getEffectiveFrom());
|
||||
vo.setEffectiveTo(req.getEffectiveTo());
|
||||
ruleMapper.update(vo);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteRule(Long ruleId) {
|
||||
SettlingSupportRuleResp resp = ruleMapper.selectById(ruleId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
ruleMapper.delete(ruleId);
|
||||
}
|
||||
|
||||
// ── Ledger ────────────────────────────────────────────────────────────────
|
||||
|
||||
public PageResponse<SettlingSupportLedgerResp> listLedgers(SettlingSupportLedgerSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(ledgerMapper.selectList(param));
|
||||
}
|
||||
|
||||
public SettlingSupportLedgerResp detailLedger(Long ledgerId) {
|
||||
SettlingSupportLedgerResp resp = ledgerMapper.selectById(ledgerId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long createLedger(SettlingSupportLedgerSaveReq req) {
|
||||
BigDecimal clawback = req.getClawbackAmount() != null ? req.getClawbackAmount() : BigDecimal.ZERO;
|
||||
// 실지급액 = support_amount - clawback_amount
|
||||
BigDecimal netAmount = req.getSupportAmount()
|
||||
.subtract(clawback)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
SettlingSupportLedgerVO vo = new SettlingSupportLedgerVO();
|
||||
vo.setAgentId(req.getAgentId());
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setSupportAmount(req.getSupportAmount());
|
||||
vo.setClawbackAmount(clawback);
|
||||
vo.setNetAmount(netAmount);
|
||||
vo.setStatus("CALCULATED");
|
||||
ledgerMapper.insert(vo);
|
||||
return vo.getLedgerId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.ga.api.service.commission;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.common.util.SecurityUtil;
|
||||
import com.ga.core.mapper.commission.StepCloseMapper;
|
||||
import com.ga.core.vo.commission.StepCloseResp;
|
||||
import com.ga.core.vo.commission.StepCloseSaveReq;
|
||||
import com.ga.core.vo.commission.StepCloseSearchParam;
|
||||
import com.ga.core.vo.commission.StepCloseVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class StepCloseService {
|
||||
|
||||
private final StepCloseMapper stepCloseMapper;
|
||||
|
||||
public PageResponse<StepCloseResp> list(StepCloseSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(stepCloseMapper.selectList(param));
|
||||
}
|
||||
|
||||
public List<StepCloseResp> listByMonth(String settleMonth) {
|
||||
return stepCloseMapper.selectBySettleMonth(settleMonth);
|
||||
}
|
||||
|
||||
public StepCloseResp detail(Long stepCloseId) {
|
||||
StepCloseResp resp = stepCloseMapper.selectById(stepCloseId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Long create(StepCloseSaveReq req) {
|
||||
StepCloseVO vo = new StepCloseVO();
|
||||
vo.setSettleMonth(req.getSettleMonth());
|
||||
vo.setStepCode(req.getStepCode());
|
||||
vo.setStepSeq(req.getStepSeq());
|
||||
vo.setStatus("OPEN");
|
||||
stepCloseMapper.insert(vo);
|
||||
return vo.getStepCloseId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void close(Long stepCloseId) {
|
||||
StepCloseResp resp = stepCloseMapper.selectById(stepCloseId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
if ("CLOSED".equals(resp.getStatus())) {
|
||||
throw new BizException(ErrorCode.INVALID_STATUS, "이미 마감된 단계입니다.");
|
||||
}
|
||||
stepCloseMapper.updateStatus(stepCloseId, "CLOSED", SecurityUtil.getCurrentUserId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void reopen(Long stepCloseId) {
|
||||
StepCloseResp resp = stepCloseMapper.selectById(stepCloseId);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
if ("OPEN".equals(resp.getStatus())) {
|
||||
throw new BizException(ErrorCode.INVALID_STATUS, "이미 열려 있는 단계입니다.");
|
||||
}
|
||||
stepCloseMapper.updateStatus(stepCloseId, "OPEN", SecurityUtil.getCurrentUserId());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user