From 4f5a2f0cb9ea160fee09c17eee1b4f435a0b3e9e Mon Sep 17 00:00:00 2001 From: GA Pro Date: Wed, 13 May 2026 00:24:28 +0900 Subject: [PATCH] =?UTF-8?q?feat(core):=20CommissionStatement=20VO=20?= =?UTF-8?q?=EC=84=B8=ED=8A=B8=20+=20Mapper=20+=20StatementType/Status=20En?= =?UTF-8?q?um=20(=EB=8F=84=EB=A9=94=EC=9D=B8=20P0-3-b)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V25 명세서 스키마와 ga-core 동기화. 발급/생성 로직은 P0-3-c. 신규: - vo/settle/StatementType {MONTHLY, ANNUAL, PROOF} - vo/settle/StatementStatus {GENERATED, SENT, DOWNLOADED, CANCELLED} CommissionStatement VO 세트: - CommissionStatementVO (BaseVO 상속) - CommissionStatementResp (agentName/statementTypeName/issueStatusName 표시) - CommissionStatementSaveReq (@Valid: @NotNull agentId, @NotBlank settleMonth(@Size 6), statementType, fileFormat) - CommissionStatementSearchParam (agentId/settleMonth/statementType/issueStatus + fromDate/toDate) CommissionStatementMapper: - selectList / selectDetailById / selectById / selectByAgentMonth / insert / update / updateStatus - XML: VOMap/RespMap, STATEMENT_TYPE/STATUS 코드명 서브쿼리, 날짜 범위 PostgreSQL 캐스트, COALESCE 기본값, 동적 update - selectByAgentMonth는 UNIQUE(agent_id, settle_month, statement_type) 기반 — 재발급 시 기존 row 갱신 판단에 사용 --- .../settle/CommissionStatementMapper.java | 30 +++ .../vo/settle/CommissionStatementResp.java | 30 +++ .../vo/settle/CommissionStatementSaveReq.java | 23 +++ .../CommissionStatementSearchParam.java | 16 ++ .../core/vo/settle/CommissionStatementVO.java | 35 ++++ .../ga/core/vo/settle/StatementStatus.java | 7 + .../com/ga/core/vo/settle/StatementType.java | 7 + .../settle/CommissionStatementMapper.xml | 194 ++++++++++++++++++ 8 files changed, 342 insertions(+) create mode 100644 ga-core/src/main/java/com/ga/core/mapper/settle/CommissionStatementMapper.java create mode 100644 ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementResp.java create mode 100644 ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSaveReq.java create mode 100644 ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSearchParam.java create mode 100644 ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementVO.java create mode 100644 ga-core/src/main/java/com/ga/core/vo/settle/StatementStatus.java create mode 100644 ga-core/src/main/java/com/ga/core/vo/settle/StatementType.java create mode 100644 ga-core/src/main/resources/mapper/settle/CommissionStatementMapper.xml diff --git a/ga-core/src/main/java/com/ga/core/mapper/settle/CommissionStatementMapper.java b/ga-core/src/main/java/com/ga/core/mapper/settle/CommissionStatementMapper.java new file mode 100644 index 0000000..7e5ddcd --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/mapper/settle/CommissionStatementMapper.java @@ -0,0 +1,30 @@ +package com.ga.core.mapper.settle; + +import com.ga.core.vo.settle.CommissionStatementResp; +import com.ga.core.vo.settle.CommissionStatementSearchParam; +import com.ga.core.vo.settle.CommissionStatementVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface CommissionStatementMapper { + + List selectList(CommissionStatementSearchParam param); + + CommissionStatementResp selectDetailById(@Param("statementId") Long statementId); + + CommissionStatementVO selectById(@Param("statementId") Long statementId); + + /** UNIQUE(agent_id, settle_month, statement_type) 조회 — 재발급 판단용 */ + CommissionStatementVO selectByAgentMonth(@Param("agentId") Long agentId, + @Param("settleMonth") String settleMonth, + @Param("statementType") String statementType); + + int insert(CommissionStatementVO vo); + + int update(CommissionStatementVO vo); + + int updateStatus(@Param("statementId") Long statementId, @Param("issueStatus") String issueStatus); +} diff --git a/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementResp.java b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementResp.java new file mode 100644 index 0000000..3e5aad8 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementResp.java @@ -0,0 +1,30 @@ +package com.ga.core.vo.settle; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class CommissionStatementResp { + private Long statementId; + private Long agentId; + private String agentName; + private String settleMonth; + private String statementType; + private String statementTypeName; + + private BigDecimal grossAmount; + private BigDecimal incomeTaxAmount; + private BigDecimal localTaxAmount; + private BigDecimal vatAmount; + private BigDecimal deductionAmount; + private BigDecimal netAmount; + + private LocalDateTime issuedAt; + private String issuedBy; + private String filePath; + private String fileFormat; + private String issueStatus; + private String issueStatusName; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSaveReq.java b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSaveReq.java new file mode 100644 index 0000000..deee682 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSaveReq.java @@ -0,0 +1,23 @@ +package com.ga.core.vo.settle; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Data; + +@Data +public class CommissionStatementSaveReq { + + @NotNull(message = "설계사 ID는 필수입니다") + private Long agentId; + + @NotBlank(message = "정산월은 필수입니다") + @Size(min = 6, max = 6, message = "정산월은 6자리(YYYYMM)입니다") + private String settleMonth; + + @NotBlank(message = "명세서 유형은 필수입니다") + private String statementType; + + @Size(max = 10) + private String fileFormat; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSearchParam.java b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSearchParam.java new file mode 100644 index 0000000..6f0a6dd --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementSearchParam.java @@ -0,0 +1,16 @@ +package com.ga.core.vo.settle; + +import com.ga.common.model.SearchParam; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class CommissionStatementSearchParam extends SearchParam { + private Long agentId; + private String settleMonth; + private String statementType; + private String issueStatus; + private String fromDate; + private String toDate; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementVO.java b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementVO.java new file mode 100644 index 0000000..88d857f --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/settle/CommissionStatementVO.java @@ -0,0 +1,35 @@ +package com.ga.core.vo.settle; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class CommissionStatementVO { + private Long statementId; + private Long agentId; + private String settleMonth; + private String statementType; + + // 발급 시점 스냅샷 (동결값) + private BigDecimal grossAmount; + private BigDecimal incomeTaxAmount; + private BigDecimal localTaxAmount; + private BigDecimal vatAmount; + private BigDecimal deductionAmount; + private BigDecimal netAmount; + + // 발급 정보 + private LocalDateTime issuedAt; + private String issuedBy; + private String filePath; + private String fileFormat; + private String issueStatus; + + // 감사 4종 + private LocalDateTime createdAt; + private Long createdBy; + private LocalDateTime updatedAt; + private Long updatedBy; +} diff --git a/ga-core/src/main/java/com/ga/core/vo/settle/StatementStatus.java b/ga-core/src/main/java/com/ga/core/vo/settle/StatementStatus.java new file mode 100644 index 0000000..10b5ef5 --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/settle/StatementStatus.java @@ -0,0 +1,7 @@ +package com.ga.core.vo.settle; + +public enum StatementStatus { + GENERATED, SENT, DOWNLOADED, CANCELLED; + + public String code() { return this.name(); } +} diff --git a/ga-core/src/main/java/com/ga/core/vo/settle/StatementType.java b/ga-core/src/main/java/com/ga/core/vo/settle/StatementType.java new file mode 100644 index 0000000..fa2f46f --- /dev/null +++ b/ga-core/src/main/java/com/ga/core/vo/settle/StatementType.java @@ -0,0 +1,7 @@ +package com.ga.core.vo.settle; + +public enum StatementType { + MONTHLY, ANNUAL, PROOF; + + public String code() { return this.name(); } +} diff --git a/ga-core/src/main/resources/mapper/settle/CommissionStatementMapper.xml b/ga-core/src/main/resources/mapper/settle/CommissionStatementMapper.xml new file mode 100644 index 0000000..7a155f0 --- /dev/null +++ b/ga-core/src/main/resources/mapper/settle/CommissionStatementMapper.xml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s.statement_id, + s.agent_id, + a.agent_name, + s.settle_month, + s.statement_type, + (SELECT cc.code_name FROM common_code cc + WHERE cc.group_code = 'STATEMENT_TYPE' AND cc.code = s.statement_type) AS statement_type_name, + s.gross_amount, + s.income_tax_amount, + s.local_tax_amount, + s.vat_amount, + s.deduction_amount, + s.net_amount, + s.issued_at, + s.issued_by, + s.file_path, + s.file_format, + s.issue_status, + (SELECT cc.code_name FROM common_code cc + WHERE cc.group_code = 'STATEMENT_STATUS' AND cc.code = s.issue_status) AS issue_status_name + + + + + + + + + + + + + + + + + + + + INSERT INTO commission_statement ( + agent_id, settle_month, statement_type, + gross_amount, income_tax_amount, local_tax_amount, + vat_amount, deduction_amount, net_amount, + issued_at, issued_by, file_path, file_format, issue_status, + created_at, created_by + ) VALUES ( + #{agentId}, #{settleMonth}, #{statementType}, + #{grossAmount}, #{incomeTaxAmount}, #{localTaxAmount}, + COALESCE(#{vatAmount}, 0), COALESCE(#{deductionAmount}, 0), #{netAmount}, + #{issuedAt}, #{issuedBy}, #{filePath}, #{fileFormat}, + COALESCE(#{issueStatus}, 'GENERATED'), + NOW(), #{createdBy} + ) + + + + + + + UPDATE commission_statement + + gross_amount = #{grossAmount}, + income_tax_amount = #{incomeTaxAmount}, + local_tax_amount = #{localTaxAmount}, + vat_amount = #{vatAmount}, + deduction_amount = #{deductionAmount}, + net_amount = #{netAmount}, + issued_at = #{issuedAt}, + issued_by = #{issuedBy}, + file_path = #{filePath}, + file_format = #{fileFormat}, + issue_status = #{issueStatus}, + updated_at = NOW(), + updated_by = #{updatedBy} + + WHERE statement_id = #{statementId} + + + + + UPDATE commission_statement + SET issue_status = #{issueStatus}, updated_at = NOW() + WHERE statement_id = #{statementId} + + +