feat: P12(#2) 지급대상건 구성·수정 — 정산월 지급대상 배치 구성/확정 (PL 자율진행)
incar 지급대상건구성/수정/조회 대응. 기존 settle_master 건별 confirm/hold 위에 정산월 단위 지급대상 배치를 구성→포함/제외 편집→확정하는 워크플로우 레이어 추가 (AccountingClose DRAFT/마감 패턴 준용, settle_master 상태는 미변경=결합 최소화). - DB(V115): payment_batch(배치 마스터, status DRAFT/FINALIZED/CANCELLED, total_count/ total_payable) + payment_batch_item(건, settle_id FK, payable 스냅샷, included/exclude_reason, UNIQUE(batch_id,settle_id)) + 메뉴 PAYMENT_TARGET(GRP_SETTLE) + 권한 READ/CREATE/UPDATE/ EXECUTE + 공통코드 PAYMENT_BATCH_STATUS. - core: PaymentBatch/Item VO/Resp/SaveReq/SearchParam/Enum + Mapper. insertFromSettleMaster (INSERT-SELECT 자동채움: settle_month·payable>0·status!=PAID) + recalcTotals + updateInclude. - api: PaymentBatchService create(자동채움+집계)/list/detail/updateItem(DRAFT만,재집계)/ finalize(포함0건 거부)/cancel/export. Controller /api/payment-batches. - frontend: PaymentTarget 화면(배치 목록 + 구성 모달 + 상세 Drawer items 포함/제외 토글 + 합계 + 확정/취소/엑셀) + api 모듈 + App 라우트. export 권한 READ로 정렬. 검증: build+test SUCCESSFUL, Flyway V115(schema v115). 라이브 e2e: 202603 create→39건 자동채움(합 15,438,386.9) → 1건 제외 → 38건 재집계(정확히 −35,079) → finalize → 확정후 수정 400 차단 → cancel. 테스트 배치 정리. 스펙 docs/DOMAIN_GAP_P12. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package com.ga.core.mapper.settle;
|
||||
|
||||
import com.ga.core.vo.settle.PaymentBatchItemResp;
|
||||
import com.ga.core.vo.settle.PaymentBatchItemVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* payment_batch_item Mapper — 지급대상건 (V115)
|
||||
*/
|
||||
@Mapper
|
||||
public interface PaymentBatchItemMapper {
|
||||
|
||||
/**
|
||||
* settle_master 에서 해당 정산월 지급대상(payable_amount>0, status!='PAID')을
|
||||
* payment_batch_item 으로 일괄 INSERT-SELECT.
|
||||
* included=true 로 전체 포함 초기화.
|
||||
* 배치 생성(create) 트랜잭션 내 단일 SQL 로 처리 — 효율적.
|
||||
*/
|
||||
int insertFromSettleMaster(@Param("batchId") Long batchId,
|
||||
@Param("settleMonth") String settleMonth);
|
||||
|
||||
/**
|
||||
* VO 리스트 일괄 INSERT (수동 구성 또는 단위 테스트용).
|
||||
* insertFromSettleMaster 가 메인 경로이므로 보조 용도.
|
||||
*/
|
||||
int insertBatch(@Param("list") List<PaymentBatchItemVO> list);
|
||||
|
||||
/**
|
||||
* 배치 ID 기준 전체 items 조회 — 설계사명(agentName) 조인 포함.
|
||||
* PaymentBatchMapper.selectById 의 collection 에서도 참조.
|
||||
*/
|
||||
List<PaymentBatchItemResp> selectByBatchId(@Param("batchId") Long batchId);
|
||||
|
||||
/** 단건 조회 (updateInclude 전 DRAFT 검증 등 Service 용도) */
|
||||
PaymentBatchItemVO selectById(@Param("itemId") Long itemId);
|
||||
|
||||
/**
|
||||
* 포함/제외 수정.
|
||||
* included=false 시 excludeReason 기록; included=true 로 복원 시 excludeReason=null 로 초기화.
|
||||
* 호출 후 PaymentBatchMapper.recalcTotals 반드시 실행.
|
||||
*/
|
||||
int updateInclude(@Param("itemId") Long itemId,
|
||||
@Param("included") Boolean included,
|
||||
@Param("excludeReason") String excludeReason);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.ga.core.mapper.settle;
|
||||
|
||||
import com.ga.core.vo.settle.PaymentBatchResp;
|
||||
import com.ga.core.vo.settle.PaymentBatchSearchParam;
|
||||
import com.ga.core.vo.settle.PaymentBatchVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* payment_batch Mapper — 지급대상 배치 마스터 (V115)
|
||||
*/
|
||||
@Mapper
|
||||
public interface PaymentBatchMapper {
|
||||
|
||||
/**
|
||||
* 배치 생성 (DRAFT 상태로 INSERT).
|
||||
* useGeneratedKeys=true 로 vo.batchId 에 채번된 PK 주입.
|
||||
*/
|
||||
int insert(PaymentBatchVO vo);
|
||||
|
||||
/**
|
||||
* 배치 목록 조회 — settleMonth / status 필터, PageHelper 호환.
|
||||
* 상태명(statusName) 포함, items 는 null.
|
||||
*/
|
||||
List<PaymentBatchResp> selectList(PaymentBatchSearchParam param);
|
||||
|
||||
/**
|
||||
* 배치 단건 상세 조회.
|
||||
* ResultMap 의 collection 으로 items(PaymentBatchItemResp) 자동 populate.
|
||||
*/
|
||||
PaymentBatchResp selectById(@Param("batchId") Long batchId);
|
||||
|
||||
/**
|
||||
* 포함 건수 / 포함 payable 합계 재집계 UPDATE.
|
||||
* total_count = COUNT(*) WHERE batch_id=? AND included=true
|
||||
* total_payable = SUM(payable_amount) WHERE batch_id=? AND included=true
|
||||
* updateItem 후 반드시 호출.
|
||||
*/
|
||||
int recalcTotals(@Param("batchId") Long batchId);
|
||||
|
||||
/**
|
||||
* 배치 상태 변경 (DRAFT→FINALIZED / DRAFT→CANCELLED 등).
|
||||
* FINALIZED 시 finalized_at=now(), finalized_by=userId 도 함께 기록.
|
||||
*/
|
||||
int updateStatus(@Param("batchId") Long batchId,
|
||||
@Param("status") String status,
|
||||
@Param("userId") Long userId);
|
||||
|
||||
/** 페이징 count 쿼리 */
|
||||
int countByCondition(PaymentBatchSearchParam param);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 지급대상건 API 응답 — 설계사명 조인 포함.
|
||||
*/
|
||||
@Data
|
||||
public class PaymentBatchItemResp {
|
||||
private Long itemId;
|
||||
private Long batchId;
|
||||
private Long settleId;
|
||||
private Long agentId;
|
||||
/** agent.agent_name 조인 */
|
||||
private String agentName;
|
||||
private BigDecimal payableAmount;
|
||||
/** 포함 여부 */
|
||||
private Boolean included;
|
||||
/** 제외 사유 */
|
||||
private String excludeReason;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 지급대상건 포함/제외 수정 요청.
|
||||
* included=false 시 excludeReason 필수는 Service 레이어에서 검증.
|
||||
*/
|
||||
@Data
|
||||
public class PaymentBatchItemUpdateReq {
|
||||
/** 포함 여부 */
|
||||
@NotNull
|
||||
private Boolean included;
|
||||
/** 제외 사유 (included=false 시 권장) */
|
||||
private String excludeReason;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* payment_batch_item — 지급대상건 (V115)
|
||||
* INSERT / UPDATE 전용. 조인 필드 없음.
|
||||
*/
|
||||
@Data
|
||||
public class PaymentBatchItemVO {
|
||||
private Long itemId;
|
||||
/** FK payment_batch.batch_id */
|
||||
private Long batchId;
|
||||
/** FK settle_master.settle_id (스냅샷 원본 키) */
|
||||
private Long settleId;
|
||||
/** FK agent.agent_id */
|
||||
private Long agentId;
|
||||
/** settle_master.payable_amount 스냅샷 */
|
||||
private BigDecimal payableAmount;
|
||||
/** 포함 여부 (기본 true) */
|
||||
private Boolean included;
|
||||
/** 제외 사유 (included=false 시 기록) */
|
||||
private String excludeReason;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 지급대상 배치 API 응답 — 상태명 조인 포함.
|
||||
* selectById 시 items(List<PaymentBatchItemResp>)가 채워진다.
|
||||
*/
|
||||
@Data
|
||||
public class PaymentBatchResp {
|
||||
private Long batchId;
|
||||
private String settleMonth;
|
||||
private String batchName;
|
||||
/** DRAFT / FINALIZED / CANCELLED */
|
||||
private String status;
|
||||
/** 공통코드 PAYMENT_BATCH_STATUS */
|
||||
private String statusName;
|
||||
private Integer totalCount;
|
||||
private BigDecimal totalPayable;
|
||||
private LocalDateTime createdAt;
|
||||
private Long createdBy;
|
||||
private LocalDateTime finalizedAt;
|
||||
private Long finalizedBy;
|
||||
/** users.user_name 조인 */
|
||||
private String finalizedByName;
|
||||
private LocalDateTime updatedAt;
|
||||
/** 상세 조회 시 populate (목록 조회에서는 null) */
|
||||
private List<PaymentBatchItemResp> items;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 지급대상 배치 생성 요청.
|
||||
* settleMonth: 배치 구성 대상 정산월 (settle_master 조회 기준)
|
||||
* batchName: 배치 구분명 (동일월 복수 배치 허용)
|
||||
*/
|
||||
@Data
|
||||
public class PaymentBatchSaveReq {
|
||||
/** 정산월 (YYYYMM) */
|
||||
@NotBlank
|
||||
private String settleMonth;
|
||||
/** 배치명 */
|
||||
@NotBlank
|
||||
private String batchName;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
import com.ga.common.model.SearchParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 지급대상 배치 목록 검색 조건.
|
||||
* status 는 부모 SearchParam 에 이미 있음.
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PaymentBatchSearchParam extends SearchParam {
|
||||
/** 정산월 (YYYYMM) */
|
||||
private String settleMonth;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
/**
|
||||
* 지급대상 배치 상태 코드 (common_code_group: PAYMENT_BATCH_STATUS, V115)
|
||||
* DB payment_batch.status: DRAFT / FINALIZED / CANCELLED
|
||||
*/
|
||||
public enum PaymentBatchStatus {
|
||||
DRAFT, // 작성중
|
||||
FINALIZED, // 확정
|
||||
CANCELLED; // 취소
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ga.core.vo.settle;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* payment_batch — 지급대상 배치 마스터 (V115)
|
||||
* INSERT / UPDATE 전용. 조인 필드 없음.
|
||||
*/
|
||||
@Data
|
||||
public class PaymentBatchVO {
|
||||
private Long batchId;
|
||||
/** 정산월 (YYYYMM) */
|
||||
private String settleMonth;
|
||||
/** 배치명 */
|
||||
private String batchName;
|
||||
/** DRAFT / FINALIZED / CANCELLED */
|
||||
private String status;
|
||||
/** 포함 건수 (included=true 합산) */
|
||||
private Integer totalCount;
|
||||
/** 포함 건 payable 합계 */
|
||||
private BigDecimal totalPayable;
|
||||
private LocalDateTime createdAt;
|
||||
private Long createdBy;
|
||||
/** 확정 일시 (FINALIZED 시 기록) */
|
||||
private LocalDateTime finalizedAt;
|
||||
/** 확정 처리자 (FINALIZED 시 기록) */
|
||||
private Long finalizedBy;
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ga.core.mapper.settle.PaymentBatchItemMapper">
|
||||
|
||||
<!-- VO ResultMap: INSERT/UPDATE 전용 -->
|
||||
<resultMap id="VOMap" type="com.ga.core.vo.settle.PaymentBatchItemVO"/>
|
||||
|
||||
<!-- Resp ResultMap: 설계사명 조인 포함 -->
|
||||
<resultMap id="RespMap" type="com.ga.core.vo.settle.PaymentBatchItemResp">
|
||||
<id property="itemId" column="item_id"/>
|
||||
<result property="batchId" column="batch_id"/>
|
||||
<result property="settleId" column="settle_id"/>
|
||||
<result property="agentId" column="agent_id"/>
|
||||
<result property="agentName" column="agent_name"/>
|
||||
<result property="payableAmount" column="payable_amount"/>
|
||||
<result property="included" column="included"/>
|
||||
<result property="excludeReason" column="exclude_reason"/>
|
||||
<result property="createdAt" column="created_at"/>
|
||||
</resultMap>
|
||||
|
||||
<!--
|
||||
settle_master → payment_batch_item 일괄 INSERT-SELECT.
|
||||
배치 생성(create) 시 단 1번의 SQL 로 지급대상 전체를 스냅샷.
|
||||
|
||||
조건:
|
||||
settle_month = #{settleMonth}
|
||||
payable_amount > 0 (지급할 금액이 있는 건만)
|
||||
status != 'PAID' (이미 지급완료된 건 제외)
|
||||
|
||||
inserted 컬럼:
|
||||
batch_id = #{batchId} (생성된 배치 PK)
|
||||
settle_id = 원본 settle_master.settle_id
|
||||
agent_id = 원본 settle_master.agent_id
|
||||
payable_amount = 원본 settle_master.payable_amount (스냅샷)
|
||||
included = true (기본 전체 포함)
|
||||
created_at = NOW()
|
||||
-->
|
||||
<insert id="insertFromSettleMaster">
|
||||
INSERT INTO payment_batch_item
|
||||
(batch_id, settle_id, agent_id, payable_amount, included, created_at)
|
||||
SELECT
|
||||
#{batchId},
|
||||
sm.settle_id,
|
||||
sm.agent_id,
|
||||
sm.payable_amount,
|
||||
true,
|
||||
NOW()
|
||||
FROM settle_master sm
|
||||
WHERE sm.settle_month = #{settleMonth}
|
||||
AND sm.payable_amount > 0
|
||||
AND sm.status != 'PAID'
|
||||
</insert>
|
||||
|
||||
<!--
|
||||
VO 리스트 일괄 INSERT (수동 구성 또는 단위 테스트 보조용).
|
||||
insertFromSettleMaster 가 운영 메인 경로.
|
||||
-->
|
||||
<insert id="insertBatch">
|
||||
INSERT INTO payment_batch_item
|
||||
(batch_id, settle_id, agent_id, payable_amount, included, exclude_reason, created_at)
|
||||
VALUES
|
||||
<foreach collection="list" item="i" separator=",">
|
||||
(#{i.batchId}, #{i.settleId}, #{i.agentId}, #{i.payableAmount},
|
||||
#{i.included}, #{i.excludeReason}, NOW())
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<!--
|
||||
배치 items 전체 조회 — 설계사명 조인 포함.
|
||||
PaymentBatchMapper 의 RespDetailMap collection 에서 참조하며
|
||||
Service 직접 호출도 지원.
|
||||
정렬: 설계사 ID ASC (화면 일관성).
|
||||
-->
|
||||
<select id="selectByBatchId" resultMap="RespMap">
|
||||
SELECT i.item_id,
|
||||
i.batch_id,
|
||||
i.settle_id,
|
||||
i.agent_id,
|
||||
a.agent_name,
|
||||
i.payable_amount,
|
||||
i.included,
|
||||
i.exclude_reason,
|
||||
i.created_at
|
||||
FROM payment_batch_item i
|
||||
LEFT JOIN agent a ON a.agent_id = i.agent_id
|
||||
WHERE i.batch_id = #{batchId}
|
||||
ORDER BY i.agent_id ASC, i.item_id ASC
|
||||
</select>
|
||||
|
||||
<!--
|
||||
단건 조회 (VO — 조인 없음).
|
||||
Service 에서 batchId 로 DRAFT 여부 검증 후 updateInclude 호출 패턴.
|
||||
-->
|
||||
<select id="selectById" resultMap="VOMap">
|
||||
SELECT item_id, batch_id, settle_id, agent_id,
|
||||
payable_amount, included, exclude_reason, created_at
|
||||
FROM payment_batch_item
|
||||
WHERE item_id = #{itemId}
|
||||
</select>
|
||||
|
||||
<!--
|
||||
포함/제외 수정.
|
||||
included=true 로 복원 시 exclude_reason 은 NULL 로 초기화.
|
||||
included=false 시 전달된 excludeReason 기록.
|
||||
호출 후 PaymentBatchMapper.recalcTotals(batchId) 반드시 실행.
|
||||
-->
|
||||
<update id="updateInclude">
|
||||
UPDATE payment_batch_item
|
||||
SET included = #{included},
|
||||
exclude_reason = CASE WHEN #{included} = true THEN NULL ELSE #{excludeReason} END
|
||||
WHERE item_id = #{itemId}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ga.core.mapper.settle.PaymentBatchMapper">
|
||||
|
||||
<!-- VO ResultMap: INSERT/UPDATE 전용, 조인 없음 -->
|
||||
<resultMap id="VOMap" type="com.ga.core.vo.settle.PaymentBatchVO"/>
|
||||
|
||||
<!--
|
||||
목록 조회용 ResultMap: 상태명 포함, items 없음.
|
||||
목록에서 items 를 채울 필요가 없으므로 collection 미포함.
|
||||
-->
|
||||
<resultMap id="RespListMap" type="com.ga.core.vo.settle.PaymentBatchResp">
|
||||
<id property="batchId" column="batch_id"/>
|
||||
<result property="settleMonth" column="settle_month"/>
|
||||
<result property="batchName" column="batch_name"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="statusName" column="status_name"/>
|
||||
<result property="totalCount" column="total_count"/>
|
||||
<result property="totalPayable" column="total_payable"/>
|
||||
<result property="createdAt" column="created_at"/>
|
||||
<result property="createdBy" column="created_by"/>
|
||||
<result property="finalizedAt" column="finalized_at"/>
|
||||
<result property="finalizedBy" column="finalized_by"/>
|
||||
<result property="finalizedByName" column="finalized_by_name"/>
|
||||
<result property="updatedAt" column="updated_at"/>
|
||||
</resultMap>
|
||||
|
||||
<!--
|
||||
상세 조회용 ResultMap: RespListMap 의 모든 컬럼 +
|
||||
items collection (PaymentBatchItemMapper.selectByBatchId 호출).
|
||||
select N+1 방지를 위해 별도 mapper select 참조.
|
||||
-->
|
||||
<resultMap id="RespDetailMap" type="com.ga.core.vo.settle.PaymentBatchResp"
|
||||
extends="RespListMap">
|
||||
<collection property="items"
|
||||
ofType="com.ga.core.vo.settle.PaymentBatchItemResp"
|
||||
select="com.ga.core.mapper.settle.PaymentBatchItemMapper.selectByBatchId"
|
||||
column="batch_id"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 목록 SELECT 공통 컬럼 -->
|
||||
<sql id="batchCols">
|
||||
b.batch_id,
|
||||
b.settle_month,
|
||||
b.batch_name,
|
||||
b.status,
|
||||
(SELECT cc.code_name FROM common_code cc
|
||||
WHERE cc.group_code = 'PAYMENT_BATCH_STATUS' AND cc.code = b.status) AS status_name,
|
||||
b.total_count,
|
||||
b.total_payable,
|
||||
b.created_at,
|
||||
b.created_by,
|
||||
b.finalized_at,
|
||||
b.finalized_by,
|
||||
u.user_name AS finalized_by_name,
|
||||
b.updated_at
|
||||
</sql>
|
||||
|
||||
<!-- JOIN 절: finalized_by → users -->
|
||||
<sql id="batchJoins">
|
||||
FROM payment_batch b
|
||||
LEFT JOIN users u ON u.user_id = b.finalized_by
|
||||
</sql>
|
||||
|
||||
<!--
|
||||
배치 생성 INSERT.
|
||||
useGeneratedKeys=true 로 채번된 batch_id 를 vo.batchId 에 주입.
|
||||
status 기본값 DRAFT, total_count/total_payable 기본 0.
|
||||
-->
|
||||
<insert id="insert" parameterType="com.ga.core.vo.settle.PaymentBatchVO"
|
||||
useGeneratedKeys="true" keyProperty="batchId">
|
||||
INSERT INTO payment_batch
|
||||
(settle_month, batch_name, status, total_count, total_payable,
|
||||
created_at, created_by)
|
||||
VALUES
|
||||
(#{settleMonth}, #{batchName}, 'DRAFT', 0, 0,
|
||||
NOW(), #{createdBy})
|
||||
</insert>
|
||||
|
||||
<!--
|
||||
배치 목록 조회 — PageHelper startPage() 호환.
|
||||
settleMonth / status (SearchParam 상속) 필터.
|
||||
최신 순(batch_id DESC) 정렬.
|
||||
-->
|
||||
<select id="selectList" resultMap="RespListMap">
|
||||
SELECT <include refid="batchCols"/>
|
||||
<include refid="batchJoins"/>
|
||||
<where>
|
||||
<if test="settleMonth != null and settleMonth != ''">
|
||||
AND b.settle_month = #{settleMonth}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
AND b.status = #{status}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY b.batch_id DESC
|
||||
</select>
|
||||
|
||||
<!--
|
||||
배치 단건 상세 조회.
|
||||
RespDetailMap 의 collection 이 selectByBatchId 를 자동 호출해
|
||||
items 목록을 채운다.
|
||||
-->
|
||||
<select id="selectById" resultMap="RespDetailMap">
|
||||
SELECT <include refid="batchCols"/>
|
||||
<include refid="batchJoins"/>
|
||||
WHERE b.batch_id = #{batchId}
|
||||
</select>
|
||||
|
||||
<!--
|
||||
포함 건수 / 합계 재집계.
|
||||
updateItem 호출 직후 반드시 실행.
|
||||
total_count : included=true 인 항목 수
|
||||
total_payable: included=true 인 항목의 payable_amount 합계 (없으면 0)
|
||||
-->
|
||||
<update id="recalcTotals">
|
||||
UPDATE payment_batch
|
||||
SET total_count = (
|
||||
SELECT COUNT(*)
|
||||
FROM payment_batch_item
|
||||
WHERE batch_id = #{batchId}
|
||||
AND included = true
|
||||
),
|
||||
total_payable = (
|
||||
SELECT COALESCE(SUM(payable_amount), 0)
|
||||
FROM payment_batch_item
|
||||
WHERE batch_id = #{batchId}
|
||||
AND included = true
|
||||
),
|
||||
updated_at = NOW()
|
||||
WHERE batch_id = #{batchId}
|
||||
</update>
|
||||
|
||||
<!--
|
||||
배치 상태 변경.
|
||||
FINALIZED 시에만 finalized_at / finalized_by 기록.
|
||||
CANCELLED 등 다른 상태 전이 시에는 NULL 로 두지 않고 기존 값 유지.
|
||||
-->
|
||||
<update id="updateStatus">
|
||||
UPDATE payment_batch
|
||||
SET status = #{status},
|
||||
finalized_at = CASE WHEN #{status} = 'FINALIZED' THEN NOW() ELSE finalized_at END,
|
||||
finalized_by = CASE WHEN #{status} = 'FINALIZED' THEN #{userId} ELSE finalized_by END,
|
||||
updated_at = NOW()
|
||||
WHERE batch_id = #{batchId}
|
||||
</update>
|
||||
|
||||
<!-- 페이징 count 쿼리 -->
|
||||
<select id="countByCondition" resultType="int">
|
||||
SELECT COUNT(*)
|
||||
FROM payment_batch b
|
||||
<where>
|
||||
<if test="settleMonth != null and settleMonth != ''">
|
||||
AND b.settle_month = #{settleMonth}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
AND b.status = #{status}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user