feat: ga-core + ga-api + ga-batch + V13-V15 + Docker + frontend skeleton

ga-core (22 tables):
- user/role: VO + Mapper + XML (login + RBAC)
- org: Grade, Organization (CTE recursive tree), Agent + history
- product: InsuranceCompany, Product, Contract
- rule: CommissionRate, PayoutRule, OverrideRule, ChargebackRule, ExceptionTypeCode
- receive: CompanyProfile, FieldMapping, CodeMapping, RawCommissionData, ParseError
- ledger: Recruit, Maintain, Exception (batch insert + cursor)
- settle: SettleMaster (UPSERT), Override, Chargeback, Payment, Reconciliation, BatchJobLog
- All XMLs use EncryptTypeHandler for PII fields

ga-api:
- AuthController: login (lock on N fails), refresh, me, password, logout
- Domain controllers: Agent, Organization, Contract, Company, Product, Rule,
  Receive, Ledger (recruit/maintain/exception + approve), Settle (confirm/hold/release),
  Payment, User, Role (matrix), BatchTrigger
- All use @RequirePermission + @DataChangeLog

ga-batch:
- MonthlySettlementJob: 8 Steps (receiveData, transformData, reconcile,
  calcRecruit, calcMaintain, chargebackException, calcOverride, aggregate)
- DataReceiver strategy + ManualReceiver, MappingEngine stub
- CommissionCalculator (pct/tax via MoneyUtil), JobLauncherController

DB V13~V15:
- V13: 14 indexes (settle_master, ledgers, contract, chargeback, payment, raw, logs)
- V14: create_monthly_partition() helper function
- V15: v_agent_monthly_summary, v_org_settle_summary, v_chargeback_risk views

Infra:
- docker-compose: postgres + redis + api + batch + frontend
- Multi-stage Dockerfile (gradle build → JRE)

ga-frontend (skeleton):
- Vite + React 18 + TypeScript + AntD 5 + AG Grid + React Query + Zustand
- API request layer (axios + JWT), LoginPage, MainLayout (dynamic menu), Dashboard
- nginx.conf for /api proxying
This commit is contained in:
GA Pro
2026-05-09 22:00:53 +09:00
parent cef4e48e27
commit 7f3c564605
147 changed files with 6987 additions and 79 deletions
@@ -0,0 +1,29 @@
package com.ga.core.mapper.ledger;
import com.ga.core.vo.ledger.ExceptionLedgerResp;
import com.ga.core.vo.ledger.ExceptionLedgerVO;
import com.ga.core.vo.ledger.LedgerSearchParam;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Mapper
public interface ExceptionLedgerMapper {
List<ExceptionLedgerResp> selectList(LedgerSearchParam param);
ExceptionLedgerResp selectDetailById(@Param("ledgerId") Long ledgerId);
ExceptionLedgerVO selectById(@Param("ledgerId") Long ledgerId);
int insert(ExceptionLedgerVO vo);
int update(ExceptionLedgerVO vo);
int updateApprove(@Param("ledgerId") Long ledgerId,
@Param("status") String status,
@Param("approverId") Long approverId);
int decrementRecurring(@Param("ledgerId") Long ledgerId);
/** 정산월별 PLUS/MINUS 합계 */
List<Map<String, Object>> aggregateByAgent(@Param("settleMonth") String settleMonth);
BigDecimal sumPlusByMonth(@Param("settleMonth") String settleMonth);
BigDecimal sumMinusByMonth(@Param("settleMonth") String settleMonth);
}
@@ -0,0 +1,27 @@
package com.ga.core.mapper.ledger;
import com.ga.core.vo.ledger.LedgerExcelVO;
import com.ga.core.vo.ledger.LedgerResp;
import com.ga.core.vo.ledger.LedgerSearchParam;
import com.ga.core.vo.ledger.LedgerVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.cursor.Cursor;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Mapper
public interface MaintainLedgerMapper {
List<LedgerResp> selectList(LedgerSearchParam param);
LedgerResp selectDetailById(@Param("ledgerId") Long ledgerId);
LedgerVO selectById(@Param("ledgerId") Long ledgerId);
Cursor<LedgerExcelVO> selectCursorForExcel(LedgerSearchParam param);
int insert(LedgerVO vo);
int batchInsert(@Param("list") List<LedgerVO> list);
int update(LedgerVO vo);
int deleteBySettleMonth(@Param("settleMonth") String settleMonth);
List<Map<String, Object>> aggregateByAgent(@Param("settleMonth") String settleMonth);
BigDecimal sumByMonth(@Param("settleMonth") String settleMonth);
}
@@ -0,0 +1,30 @@
package com.ga.core.mapper.ledger;
import com.ga.core.vo.ledger.LedgerExcelVO;
import com.ga.core.vo.ledger.LedgerResp;
import com.ga.core.vo.ledger.LedgerSearchParam;
import com.ga.core.vo.ledger.LedgerVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.cursor.Cursor;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Mapper
public interface RecruitLedgerMapper {
List<LedgerResp> selectList(LedgerSearchParam param);
LedgerResp selectDetailById(@Param("ledgerId") Long ledgerId);
LedgerVO selectById(@Param("ledgerId") Long ledgerId);
Cursor<LedgerExcelVO> selectCursorForExcel(LedgerSearchParam param);
int insert(LedgerVO vo);
int batchInsert(@Param("list") List<LedgerVO> list);
int update(LedgerVO vo);
int deleteBySettleMonth(@Param("settleMonth") String settleMonth);
/** 정산월 기준 설계사별 합계 (정산 마스터용) */
List<Map<String, Object>> aggregateByAgent(@Param("settleMonth") String settleMonth);
/** 정산월 합계 */
BigDecimal sumByMonth(@Param("settleMonth") String settleMonth);
}
@@ -0,0 +1,32 @@
package com.ga.core.mapper.org;
import com.ga.core.vo.org.AgentExcelVO;
import com.ga.core.vo.org.AgentOrgHistoryVO;
import com.ga.core.vo.org.AgentResp;
import com.ga.core.vo.org.AgentSearchParam;
import com.ga.core.vo.org.AgentVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.cursor.Cursor;
import java.util.List;
@Mapper
public interface AgentMapper {
AgentResp selectDetailById(@Param("agentId") Long agentId);
AgentVO selectById(@Param("agentId") Long agentId);
List<AgentResp> selectList(AgentSearchParam param);
Cursor<AgentExcelVO> selectCursorForExcel(AgentSearchParam param);
int existsByLicenseNo(@Param("licenseNo") String licenseNo);
int insert(AgentVO vo);
int update(AgentVO vo);
int updateStatus(@Param("agentId") Long agentId, @Param("status") String status);
int updateOrgGrade(@Param("agentId") Long agentId,
@Param("orgId") Long orgId,
@Param("gradeId") Long gradeId);
/** 이력 */
List<AgentOrgHistoryVO> selectHistory(@Param("agentId") Long agentId);
int insertHistory(AgentOrgHistoryVO vo);
}
@@ -0,0 +1,17 @@
package com.ga.core.mapper.org;
import com.ga.core.vo.org.GradeVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface GradeMapper {
List<GradeVO> selectAll();
List<GradeVO> selectActive();
GradeVO selectById(@Param("gradeId") Long gradeId);
int insert(GradeVO vo);
int update(GradeVO vo);
int deleteById(@Param("gradeId") Long gradeId);
}
@@ -0,0 +1,24 @@
package com.ga.core.mapper.org;
import com.ga.core.vo.org.OrganizationResp;
import com.ga.core.vo.org.OrganizationVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface OrganizationMapper {
List<OrganizationResp> selectAllForTree();
List<OrganizationResp> selectList(@Param("keyword") String keyword,
@Param("orgType") String orgType,
@Param("isActive") String isActive);
OrganizationVO selectById(@Param("orgId") Long orgId);
/** 자기 자신 + 모든 하위 조직 ID (CTE 재귀) */
List<Long> selectDescendantIds(@Param("orgId") Long orgId);
int insert(OrganizationVO vo);
int update(OrganizationVO vo);
int deleteById(@Param("orgId") Long orgId);
int countChildren(@Param("orgId") Long orgId);
int countAgents(@Param("orgId") Long orgId);
}
@@ -0,0 +1,21 @@
package com.ga.core.mapper.product;
import com.ga.core.vo.product.ContractResp;
import com.ga.core.vo.product.ContractSearchParam;
import com.ga.core.vo.product.ContractVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ContractMapper {
List<ContractResp> selectList(ContractSearchParam param);
ContractResp selectDetailById(@Param("contractId") Long contractId);
ContractVO selectById(@Param("contractId") Long contractId);
int existsByPolicyNo(@Param("policyNo") String policyNo);
int insert(ContractVO vo);
int update(ContractVO vo);
int updateStatus(@Param("contractId") Long contractId, @Param("status") String status);
int countByAgent(@Param("agentId") Long agentId, @Param("status") String status);
}
@@ -0,0 +1,18 @@
package com.ga.core.mapper.product;
import com.ga.core.vo.product.InsuranceCompanyVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface InsuranceCompanyMapper {
List<InsuranceCompanyVO> selectAll();
List<InsuranceCompanyVO> selectActive();
InsuranceCompanyVO selectById(@Param("companyId") Long companyId);
InsuranceCompanyVO selectByCode(@Param("companyCode") String companyCode);
int insert(InsuranceCompanyVO vo);
int update(InsuranceCompanyVO vo);
int deleteById(@Param("companyId") Long companyId);
}
@@ -0,0 +1,22 @@
package com.ga.core.mapper.product;
import com.ga.core.vo.product.ProductResp;
import com.ga.core.vo.product.ProductVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ProductMapper {
List<ProductResp> selectList(@Param("companyId") Long companyId,
@Param("insuranceType") String insuranceType,
@Param("keyword") String keyword,
@Param("isActive") String isActive);
ProductResp selectDetailById(@Param("productId") Long productId);
ProductVO selectById(@Param("productId") Long productId);
int existsByCode(@Param("companyId") Long companyId, @Param("productCode") String productCode);
int insert(ProductVO vo);
int update(ProductVO vo);
int deleteById(@Param("productId") Long productId);
}
@@ -0,0 +1,54 @@
package com.ga.core.mapper.receive;
import com.ga.core.vo.receive.*;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ReceiveMapper {
// company_profile
List<CompanyProfileVO> selectAllProfiles();
CompanyProfileVO selectProfile(@Param("companyCode") String companyCode);
int insertProfile(CompanyProfileVO vo);
int updateProfile(CompanyProfileVO vo);
// field_mapping
List<CompanyFieldMappingVO> selectFieldMappings(@Param("companyCode") String companyCode,
@Param("targetTable") String targetTable);
int insertFieldMapping(CompanyFieldMappingVO vo);
int updateFieldMapping(CompanyFieldMappingVO vo);
int deleteFieldMapping(@Param("mappingId") Long mappingId);
// code_mapping
List<CodeMappingVO> selectCodeMappings(@Param("companyCode") String companyCode,
@Param("codeType") String codeType);
String findTargetCode(@Param("companyCode") String companyCode,
@Param("codeType") String codeType,
@Param("sourceCode") String sourceCode);
int insertCodeMapping(CodeMappingVO vo);
int updateCodeMapping(CodeMappingVO vo);
int deleteCodeMapping(@Param("codeId") Long codeId);
// raw_commission_data
int insertRaw(RawCommissionDataVO vo);
int insertRawBatch(@Param("list") List<RawCommissionDataVO> list);
List<RawCommissionDataVO> selectRawList(@Param("companyCode") String companyCode,
@Param("settleMonth") String settleMonth,
@Param("parseStatus") String parseStatus);
int updateRawStatus(@Param("rawId") Long rawId,
@Param("parseStatus") String parseStatus,
@Param("mappedLedgerId") Long mappedLedgerId,
@Param("mappedTable") String mappedTable);
// parse_error_log
List<ParseErrorLogVO> selectErrors(@Param("companyCode") String companyCode,
@Param("resolveStatus") String resolveStatus);
int insertError(ParseErrorLogVO vo);
int resolveError(@Param("errorId") Long errorId,
@Param("status") String status,
@Param("note") String note,
@Param("userId") Long userId);
}
@@ -0,0 +1,60 @@
package com.ga.core.mapper.rule;
import com.ga.core.vo.rule.*;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
/**
* 수수료 규정 Mapper. 5개 테이블을 통합한 인터페이스.
*/
@Mapper
public interface RuleMapper {
// === commission_rate ===
List<CommissionRateVO> selectCommissionRates(@Param("productId") Long productId,
@Param("year") Integer year);
/** 계약일에 유효한 보험사 수수료율 */
BigDecimal findCompanyRate(@Param("productId") Long productId,
@Param("year") Integer year,
@Param("baseDate") LocalDate baseDate);
int insertCommissionRate(CommissionRateVO vo);
int updateCommissionRate(CommissionRateVO vo);
int deleteCommissionRate(@Param("rateId") Long rateId);
// === payout_rule ===
List<PayoutRuleVO> selectPayoutRules(@Param("gradeId") Long gradeId,
@Param("insuranceType") String insuranceType);
BigDecimal findPayoutRate(@Param("gradeId") Long gradeId,
@Param("insuranceType") String insuranceType,
@Param("year") Integer year,
@Param("baseDate") LocalDate baseDate);
int insertPayoutRule(PayoutRuleVO vo);
int updatePayoutRule(PayoutRuleVO vo);
int deletePayoutRule(@Param("ruleId") Long ruleId);
// === override_rule ===
List<OverrideRuleVO> selectOverrideRules();
int insertOverrideRule(OverrideRuleVO vo);
int updateOverrideRule(OverrideRuleVO vo);
int deleteOverrideRule(@Param("overrideId") Long overrideId);
// === chargeback_rule ===
List<ChargebackRuleVO> selectChargebackRules(@Param("companyCode") String companyCode);
BigDecimal findChargebackRate(@Param("companyCode") String companyCode,
@Param("insuranceType") String insuranceType,
@Param("lapseMonth") Integer lapseMonth,
@Param("baseDate") LocalDate baseDate);
int insertChargebackRule(ChargebackRuleVO vo);
int updateChargebackRule(ChargebackRuleVO vo);
int deleteChargebackRule(@Param("cbRuleId") Long cbRuleId);
// === exception_type_code ===
List<ExceptionTypeCodeVO> selectExceptionCodes();
ExceptionTypeCodeVO selectExceptionCode(@Param("exceptionCode") String exceptionCode);
int insertExceptionCode(ExceptionTypeCodeVO vo);
int updateExceptionCode(ExceptionTypeCodeVO vo);
}
@@ -0,0 +1,18 @@
package com.ga.core.mapper.settle;
import com.ga.core.vo.settle.BatchJobLogVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface BatchJobLogMapper {
int insert(BatchJobLogVO vo);
int update(BatchJobLogVO vo);
BatchJobLogVO selectById(@Param("jobId") Long jobId);
BatchJobLogVO selectLatest(@Param("jobName") String jobName);
List<BatchJobLogVO> selectList(@Param("jobName") String jobName,
@Param("settleMonth") String settleMonth);
int isRunning(@Param("jobName") String jobName);
}
@@ -0,0 +1,23 @@
package com.ga.core.mapper.settle;
import com.ga.core.vo.settle.ChargebackVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Mapper
public interface ChargebackMapper {
int insert(ChargebackVO vo);
int insertBatch(@Param("list") List<ChargebackVO> list);
List<ChargebackVO> selectByAgent(@Param("agentId") Long agentId,
@Param("settleMonth") String settleMonth);
int updatePaid(@Param("cbId") Long cbId,
@Param("paidAmount") BigDecimal paidAmount,
@Param("status") String status);
List<Map<String, Object>> aggregateByAgent(@Param("settleMonth") String settleMonth);
BigDecimal sumByMonth(@Param("settleMonth") String settleMonth);
}
@@ -0,0 +1,21 @@
package com.ga.core.mapper.settle;
import com.ga.core.vo.settle.OverrideSettleVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Mapper
public interface OverrideSettleMapper {
int insert(OverrideSettleVO vo);
int insertBatch(@Param("list") List<OverrideSettleVO> list);
List<OverrideSettleVO> selectByUpper(@Param("upperAgentId") Long upperAgentId,
@Param("settleMonth") String settleMonth);
int deleteBySettleMonth(@Param("settleMonth") String settleMonth);
/** 정산월 + 상위설계사별 override 합계 */
List<Map<String, Object>> aggregateByUpper(@Param("settleMonth") String settleMonth);
BigDecimal sumByMonth(@Param("settleMonth") String settleMonth);
}
@@ -0,0 +1,22 @@
package com.ga.core.mapper.settle;
import com.ga.core.vo.settle.PaymentResp;
import com.ga.core.vo.settle.PaymentVO;
import com.ga.core.vo.settle.SettleSearchParam;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface PaymentMapper {
List<PaymentResp> selectList(SettleSearchParam param);
PaymentVO selectById(@Param("paymentId") Long paymentId);
int insert(PaymentVO vo);
int insertBatch(@Param("list") List<PaymentVO> list);
int updateStatus(@Param("paymentId") Long paymentId,
@Param("status") String status,
@Param("failReason") String failReason);
int updateTransferFile(@Param("paymentIds") List<Long> paymentIds,
@Param("transferFileId") Long transferFileId);
}
@@ -0,0 +1,16 @@
package com.ga.core.mapper.settle;
import com.ga.core.vo.settle.ReconciliationVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ReconciliationMapper {
List<ReconciliationVO> selectByMonth(@Param("settleMonth") String settleMonth);
int upsert(ReconciliationVO vo);
int resolve(@Param("reconId") Long reconId,
@Param("note") String note,
@Param("userId") Long userId);
}
@@ -0,0 +1,35 @@
package com.ga.core.mapper.settle;
import com.ga.core.vo.settle.SettleMasterResp;
import com.ga.core.vo.settle.SettleMasterVO;
import com.ga.core.vo.settle.SettleSearchParam;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface SettleMasterMapper {
List<SettleMasterResp> selectList(SettleSearchParam param);
SettleMasterResp selectDetail(@Param("agentId") Long agentId,
@Param("settleMonth") String settleMonth);
SettleMasterVO selectByAgentAndMonth(@Param("agentId") Long agentId,
@Param("settleMonth") String settleMonth);
SettleMasterVO selectById(@Param("settleId") Long settleId);
/** 정산 마스터 UPSERT (agent_id + settle_month UNIQUE) */
int upsert(SettleMasterVO vo);
int updateStatus(@Param("settleId") Long settleId,
@Param("status") String status,
@Param("userId") Long userId);
int updateHold(@Param("settleId") Long settleId,
@Param("reason") String reason);
/** 월 요약 (전체) */
Map<String, Object> selectMonthSummary(@Param("settleMonth") String settleMonth);
/** 조직별 월 합계 */
List<Map<String, Object>> selectOrgSummary(@Param("settleMonth") String settleMonth);
}
@@ -0,0 +1,24 @@
package com.ga.core.mapper.user;
import com.ga.core.vo.user.RoleVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface RoleMapper {
List<RoleVO> selectAll();
RoleVO selectById(@Param("roleId") Long roleId);
int insert(RoleVO vo);
int update(RoleVO vo);
int deleteById(@Param("roleId") Long roleId);
/** 역할의 (menu_id, perm_code) 권한 목록 */
List<java.util.Map<String, Object>> selectRolePermissions(@Param("roleId") Long roleId);
int deleteRolePermissions(@Param("roleId") Long roleId);
int insertRolePermission(@Param("roleId") Long roleId,
@Param("menuId") Long menuId,
@Param("permCode") String permCode,
@Param("isGranted") String isGranted);
}
@@ -0,0 +1,33 @@
package com.ga.core.mapper.user;
import com.ga.core.vo.user.UserResp;
import com.ga.core.vo.user.UserSearchParam;
import com.ga.core.vo.user.UserVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserMapper {
UserVO selectById(@Param("userId") Long userId);
UserVO selectByLoginId(@Param("loginId") String loginId);
UserResp selectDetailById(@Param("userId") Long userId);
List<UserResp> selectList(UserSearchParam param);
int countByCondition(UserSearchParam param);
int insert(UserVO vo);
int update(UserVO vo);
int updatePassword(@Param("userId") Long userId, @Param("password") String password);
int updateLastLogin(@Param("userId") Long userId);
int incrementFailCount(@Param("userId") Long userId);
int resetFailCount(@Param("userId") Long userId);
int updateStatus(@Param("userId") Long userId, @Param("status") String status);
List<String> selectRoleCodes(@Param("userId") Long userId);
int insertUserRole(@Param("userId") Long userId, @Param("roleId") Long roleId);
int deleteUserRoles(@Param("userId") Long userId);
}
@@ -0,0 +1,33 @@
package com.ga.core.vo.ledger;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class ExceptionLedgerResp {
private Long ledgerId;
private Long contractId;
private Long agentId;
private String agentName;
private String orgName;
private String exceptionCode;
private String exceptionName;
private String direction;
private String policyNo;
private String companyCode;
private String insuranceType;
private BigDecimal amount;
private BigDecimal taxAmount;
private String settleMonth;
private String description;
private String approveStatus;
private String approveStatusName;
private Long approverId;
private String approverName;
private LocalDateTime approveDate;
private String recurringYn;
private Integer recurringLeft;
private String status;
}
@@ -0,0 +1,21 @@
package com.ga.core.vo.ledger;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ExceptionLedgerSaveReq {
@NotNull private Long agentId;
@NotBlank private String exceptionCode;
@NotBlank private String settleMonth;
@NotNull private BigDecimal amount;
private String policyNo;
private String companyCode;
private String insuranceType;
private String description;
private String recurringYn;
private Integer recurringMonths;
}
@@ -0,0 +1,32 @@
package com.ga.core.vo.ledger;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class ExceptionLedgerVO {
private Long ledgerId;
private Long contractId;
private Long agentId;
private String exceptionCode;
private String policyNo;
private String companyCode;
private String insuranceType;
private Integer commissionYear;
private BigDecimal amount;
private BigDecimal taxAmount;
private String settleMonth;
private String description;
private String approveStatus; // PENDING / APPROVED / REJECTED
private Long approverId;
private LocalDateTime approveDate;
private String recurringYn;
private Integer recurringMonths;
private Integer recurringLeft;
private String status;
private Integer version;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
@@ -0,0 +1,36 @@
package com.ga.core.vo.ledger;
import com.ga.common.annotation.ExcelColumn;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class LedgerExcelVO {
@ExcelColumn(header = "정산월", order = 1, width = 10)
private String settleMonth;
@ExcelColumn(header = "증권번호", order = 2, width = 18)
private String policyNo;
@ExcelColumn(header = "설계사명", order = 3, width = 12)
private String agentName;
@ExcelColumn(header = "소속", order = 4, width = 18)
private String orgName;
@ExcelColumn(header = "보험사", order = 5, width = 14)
private String companyName;
@ExcelColumn(header = "상품", order = 6, width = 24)
private String productName;
@ExcelColumn(header = "보험종류", order = 7, width = 10, codeGroup = "INSURANCE_TYPE")
private String insuranceType;
@ExcelColumn(header = "보험료", order = 8, width = 14, format = "#,##0")
private BigDecimal premium;
@ExcelColumn(header = "회사수수료율", order = 9, width = 12, format = "0.00")
private BigDecimal companyRate;
@ExcelColumn(header = "회사수수료", order = 10, width = 14, format = "#,##0")
private BigDecimal companyAmount;
@ExcelColumn(header = "지급율", order = 11, width = 10, format = "0.00")
private BigDecimal payoutRate;
@ExcelColumn(header = "설계사수수료", order = 12, width = 14, format = "#,##0")
private BigDecimal agentAmount;
@ExcelColumn(header = "세액", order = 13, width = 12, format = "#,##0")
private BigDecimal taxAmount;
}
@@ -0,0 +1,39 @@
package com.ga.core.vo.ledger;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class LedgerResp {
private Long ledgerId;
private Long contractId;
private Long agentId;
private String agentName;
private String orgName;
private String policyNo;
private String contractorName;
private LocalDate contractDate;
private String companyCode;
private String companyName;
private String productCode;
private String productName;
private String insuranceType;
private String insuranceTypeName;
private Integer commissionYear;
private BigDecimal premium;
private String payMethod;
private BigDecimal companyRate;
private BigDecimal companyAmount;
private BigDecimal payoutRate;
private BigDecimal agentAmount;
private BigDecimal taxAmount;
private String reconcileStatus;
private BigDecimal reconcileDiff;
private String advanceYn;
private String chargebackYn;
private String settleMonth;
private String status;
private String statusName;
}
@@ -0,0 +1,19 @@
package com.ga.core.vo.ledger;
import com.ga.common.model.SearchParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class LedgerSearchParam extends SearchParam {
private String settleMonth;
private Long agentId;
private Long orgId;
private String companyCode;
private String insuranceType;
private String reconcileStatus;
private String chargebackYn;
private String advanceYn;
private String policyNo;
}
@@ -0,0 +1,38 @@
package com.ga.core.vo.ledger;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* recruit_ledger / maintain_ledger 공통 VO. 두 테이블 구조가 동일하므로 같은 VO 사용.
*/
@Data
public class LedgerVO {
private Long ledgerId;
private Long contractId;
private Long agentId;
private String policyNo;
private String companyCode;
private String productCode;
private String insuranceType;
private Integer commissionYear;
private BigDecimal premium;
private String payMethod;
private BigDecimal companyRate;
private BigDecimal companyAmount;
private BigDecimal payoutRate;
private BigDecimal agentAmount;
private BigDecimal taxAmount;
private String reconcileStatus;
private BigDecimal reconcileDiff;
private String advanceYn;
private BigDecimal advanceAmount;
private String chargebackYn;
private String settleMonth;
private String status;
private Integer version;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
@@ -0,0 +1,36 @@
package com.ga.core.vo.org;
import com.ga.common.annotation.ExcelColumn;
import lombok.Data;
import java.time.LocalDate;
@Data
public class AgentExcelVO {
@ExcelColumn(header = "설계사명", order = 1, width = 12, required = true)
private String agentName;
@ExcelColumn(header = "사번", order = 2, width = 14)
private String licenseNo;
@ExcelColumn(header = "소속", order = 3, width = 18)
private String orgName;
@ExcelColumn(header = "직급", order = 4, width = 10)
private String gradeName;
@ExcelColumn(header = "전화번호", order = 5, width = 16)
private String phone;
@ExcelColumn(header = "이메일", order = 6, width = 24)
private String email;
@ExcelColumn(header = "주민번호", order = 7, width = 16, masked = true)
private String residentNo;
@ExcelColumn(header = "상태", order = 8, width = 10, codeGroup = "AGENT_STATUS")
private String status;
@ExcelColumn(header = "입사일", order = 9, width = 12, format = "yyyy-MM-dd")
private LocalDate joinDate;
}
@@ -0,0 +1,21 @@
package com.ga.core.vo.org;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class AgentOrgHistoryVO {
private Long historyId;
private Long agentId;
private Long fromOrgId;
private Long toOrgId;
private Long fromGradeId;
private Long toGradeId;
private String changeType; // TRANSFER / PROMOTE / DEMOTE / JOIN / LEAVE
private LocalDate changeDate;
private String changeReason;
private LocalDateTime createdAt;
private Long createdBy;
}
@@ -0,0 +1,25 @@
package com.ga.core.vo.org;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class AgentResp {
private Long agentId;
private String agentName;
private String licenseNo;
private String phone; // 마스킹
private String email;
private String status;
private String statusName;
private Long orgId;
private String orgName;
private Long gradeId;
private String gradeName;
private LocalDate joinDate;
private LocalDate leaveDate;
private Integer contractCount;
private BigDecimal totalCommission;
}
@@ -0,0 +1,29 @@
package com.ga.core.vo.org;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.time.LocalDate;
@Data
public class AgentSaveReq {
@NotBlank(message = "설계사명은 필수입니다")
@Size(max = 50)
private String agentName;
@NotNull(message = "소속을 선택해주세요")
private Long orgId;
@NotNull(message = "직급을 선택해주세요")
private Long gradeId;
private String residentNo;
private String licenseNo;
private String phone;
private String email;
private String bankCode;
private String accountNo;
private LocalDate joinDate;
}
@@ -0,0 +1,13 @@
package com.ga.core.vo.org;
import com.ga.common.model.SearchParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class AgentSearchParam extends SearchParam {
private Long orgId;
private Long gradeId;
private Boolean includeSubOrgs; // 하위 조직 포함 여부
}
@@ -0,0 +1,25 @@
package com.ga.core.vo.org;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class AgentVO {
private Long agentId;
private Long orgId;
private Long gradeId;
private String agentName;
private String residentNo; // EncryptTypeHandler
private String licenseNo;
private String phone;
private String email;
private String bankCode;
private String accountNo; // EncryptTypeHandler
private String status;
private LocalDate joinDate;
private LocalDate leaveDate;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
@@ -0,0 +1,14 @@
package com.ga.core.vo.org;
import lombok.Data;
@Data
public class GradeVO {
private Long gradeId;
private String gradeName;
private Integer gradeLevel;
private String gradeGroup;
private String description;
private String isActive;
private Integer sortOrder;
}
@@ -0,0 +1,24 @@
package com.ga.core.vo.org;
import lombok.Data;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
@Data
public class OrganizationResp {
private Long orgId;
private Long parentOrgId;
private String parentOrgName;
private String orgName;
private String orgType;
private String orgTypeName;
private Integer orgLevel;
private String region;
private LocalDate effectiveFrom;
private LocalDate effectiveTo;
private String isActive;
private Integer agentCount;
private List<OrganizationResp> children = new ArrayList<>();
}
@@ -0,0 +1,22 @@
package com.ga.core.vo.org;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class OrganizationVO {
private Long orgId;
private Long parentOrgId;
private String orgName;
private String orgType; // HQ / BR / TM
private Integer orgLevel;
private String region;
private LocalDate effectiveFrom;
private LocalDate effectiveTo;
private String isActive;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private Long createdBy;
}
@@ -0,0 +1,33 @@
package com.ga.core.vo.product;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class ContractResp {
private Long contractId;
private Long agentId;
private String agentName;
private String orgName;
private Long productId;
private String productCode;
private String productName;
private String companyCode;
private String companyName;
private String insuranceType;
private String policyNo;
private String contractorName;
private String insuredName;
private BigDecimal premium;
private String payCycle;
private String payCycleName;
private Integer payPeriod;
private Integer coveragePeriod;
private String status;
private String statusName;
private LocalDate contractDate;
private LocalDate effectiveDate;
private LocalDate lapseDate;
}
@@ -0,0 +1,26 @@
package com.ga.core.vo.product;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class ContractSaveReq {
@NotNull private Long agentId;
@NotNull private Long productId;
@NotBlank(message = "증권번호는 필수입니다")
private String policyNo;
private String contractorName;
private String insuredName;
@NotNull @Positive
private BigDecimal premium;
private String payCycle;
private Integer payPeriod;
private Integer coveragePeriod;
@NotNull private LocalDate contractDate;
private LocalDate effectiveDate;
}
@@ -0,0 +1,15 @@
package com.ga.core.vo.product;
import com.ga.common.model.SearchParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class ContractSearchParam extends SearchParam {
private Long agentId;
private Long productId;
private Long companyId;
private String insuranceType;
private String policyNo;
}
@@ -0,0 +1,28 @@
package com.ga.core.vo.product;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class ContractVO {
private Long contractId;
private Long agentId;
private Long productId;
private String policyNo;
private String contractorName;
private String insuredName;
private BigDecimal premium;
private String payCycle;
private Integer payPeriod;
private Integer coveragePeriod;
private String status;
private LocalDate contractDate;
private LocalDate effectiveDate;
private LocalDate lapseDate;
private LocalDate revivalDate;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
@@ -0,0 +1,16 @@
package com.ga.core.vo.product;
import lombok.Data;
@Data
public class InsuranceCompanyVO {
private Long companyId;
private String companyCode;
private String companyName;
private String companyType;
private String bizNo;
private String contactName;
private String contactPhone;
private String contactEmail;
private String isActive;
}
@@ -0,0 +1,22 @@
package com.ga.core.vo.product;
import lombok.Data;
import java.time.LocalDate;
@Data
public class ProductResp {
private Long productId;
private Long companyId;
private String companyCode;
private String companyName;
private String productCode;
private String productName;
private String insuranceType;
private String insuranceTypeName;
private String productGroup;
private String payPeriodType;
private String isActive;
private LocalDate launchDate;
private LocalDate endDate;
}
@@ -0,0 +1,19 @@
package com.ga.core.vo.product;
import lombok.Data;
import java.time.LocalDate;
@Data
public class ProductVO {
private Long productId;
private Long companyId;
private String productCode;
private String productName;
private String insuranceType;
private String productGroup;
private String payPeriodType;
private String isActive;
private LocalDate launchDate;
private LocalDate endDate;
}
@@ -0,0 +1,15 @@
package com.ga.core.vo.receive;
import lombok.Data;
@Data
public class CodeMappingVO {
private Long codeId;
private String companyCode;
private String codeType;
private String sourceCode;
private String sourceName;
private String targetCode;
private String targetName;
private String isActive;
}
@@ -0,0 +1,22 @@
package com.ga.core.vo.receive;
import lombok.Data;
import java.time.LocalDate;
@Data
public class CompanyFieldMappingVO {
private Long mappingId;
private String companyCode;
private String sourceField;
private Integer sourceColIndex;
private String targetTable;
private String targetField;
private String dataType;
private String transformRule;
private String defaultValue;
private String isRequired;
private Integer sortOrder;
private Integer version;
private LocalDate effectiveFrom;
}
@@ -0,0 +1,22 @@
package com.ga.core.vo.receive;
import lombok.Data;
@Data
public class CompanyProfileVO {
private String companyCode;
private String dataFormat;
private String receiveMethod;
private String fileEncoding;
private String delimiter;
private Integer headerRow;
private Integer dataStartRow;
private String sheetName;
private String dateFormat;
private String amountFormat;
private String apiUrl;
private String ftpHost;
private String ftpPath;
private String receiveSchedule;
private String isActive;
}
@@ -0,0 +1,21 @@
package com.ga.core.vo.receive;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class ParseErrorLogVO {
private Long errorId;
private Long rawId;
private String companyCode;
private String errorType;
private String errorField;
private String errorValue;
private String errorMessage;
private String resolveStatus; // OPEN / RESOLVED / IGNORED
private Long resolvedBy;
private String resolveNote;
private LocalDateTime resolvedAt;
private LocalDateTime createdAt;
}
@@ -0,0 +1,22 @@
package com.ga.core.vo.receive;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class RawCommissionDataVO {
private Long rawId;
private String companyCode;
private String batchId;
private String settleMonth;
private String dataType;
private String rawContent;
private String parseStatus; // PENDING / OK / ERROR
private Long mappedLedgerId;
private String mappedTable;
private String fileName;
private Integer rowNumber;
private LocalDateTime receivedAt;
private LocalDateTime parsedAt;
}
@@ -0,0 +1,21 @@
package com.ga.core.vo.rule;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class ChargebackRuleVO {
private Long cbRuleId;
private String companyCode;
private String insuranceType;
private Integer lapseMonthFrom;
private Integer lapseMonthTo;
private BigDecimal cbRate;
private String includeOverride;
private String installmentAllowed;
private Integer maxInstallments;
private LocalDate effectiveFrom;
private LocalDate effectiveTo;
}
@@ -0,0 +1,22 @@
package com.ga.core.vo.rule;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class CommissionRateVO {
private Long rateId;
private Long productId;
private Integer commissionYear;
private BigDecimal ratePct;
private String payMethodCond;
private BigDecimal minPremium;
private LocalDate effectiveFrom;
private LocalDate effectiveTo;
private Integer version;
private LocalDateTime createdAt;
private Long createdBy;
}
@@ -0,0 +1,16 @@
package com.ga.core.vo.rule;
import lombok.Data;
@Data
public class ExceptionTypeCodeVO {
private String exceptionCode;
private String exceptionName;
private String category;
private String direction; // PLUS / MINUS
private String autoCalcYn;
private String approvalRequired;
private String taxIncluded;
private String description;
private String isActive;
}
@@ -0,0 +1,19 @@
package com.ga.core.vo.rule;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class OverrideRuleVO {
private Long overrideId;
private Long fromGrade;
private Long toGrade;
private BigDecimal overridePct;
private String calcType;
private String insuranceTypeCond;
private BigDecimal capAmount;
private LocalDate effectiveFrom;
private LocalDate effectiveTo;
}
@@ -0,0 +1,23 @@
package com.ga.core.vo.rule;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class PayoutRuleVO {
private Long ruleId;
private Long gradeId;
private String insuranceType;
private Integer commissionYear;
private BigDecimal payoutPct;
private String payMethodCond;
private String performanceGrade;
private LocalDate effectiveFrom;
private LocalDate effectiveTo;
private Integer version;
private LocalDateTime createdAt;
private Long createdBy;
}
@@ -0,0 +1,24 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class BatchJobLogVO {
private Long jobId;
private String jobName;
private String jobParams;
private String settleMonth;
private String status;
private String currentStep;
private Integer progressPct;
private Integer totalCount;
private Integer processedCount;
private Integer errorCount;
private String errorMessage;
private LocalDateTime startedAt;
private LocalDateTime finishedAt;
private Integer durationSec;
private Long triggeredBy;
}
@@ -0,0 +1,24 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class ChargebackVO {
private Long cbId;
private Long contractId;
private Long agentId;
private String policyNo;
private Integer lapseMonth;
private BigDecimal cbRate;
private BigDecimal cbAmount;
private BigDecimal paidAmount;
private BigDecimal remainAmount;
private String settleMonth;
private Integer installmentNo;
private Integer maxInstallments;
private String status;
private LocalDateTime createdAt;
}
@@ -0,0 +1,19 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class OverrideSettleVO {
private Long osId;
private Long settleId;
private Long upperAgentId;
private Long lowerAgentId;
private String settleMonth;
private BigDecimal baseAmount;
private BigDecimal overridePct;
private BigDecimal overrideAmount;
private LocalDateTime calcDate;
}
@@ -0,0 +1,23 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class PaymentResp {
private Long paymentId;
private Long settleId;
private Long agentId;
private String agentName;
private String bankCode;
private String bankName;
private String accountNo; // 마스킹된 형태로 응답
private BigDecimal payAmount;
private LocalDate payDate;
private String payStatus;
private String payStatusName;
private String failReason;
private String settleMonth;
}
@@ -0,0 +1,23 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class PaymentVO {
private Long paymentId;
private Long settleId;
private Long agentId;
private BigDecimal payAmount;
private String bankCode;
private String accountNo; // 암호화
private LocalDate payDate;
private String payStatus; // PENDING / SENT / DONE / FAIL
private Long transferFileId;
private String failReason;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
@@ -0,0 +1,22 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class ReconciliationVO {
private Long reconId;
private String companyCode;
private String settleMonth;
private BigDecimal companyTotal;
private BigDecimal systemTotal;
private BigDecimal diffAmount;
private Integer diffCount;
private String status; // PENDING / MATCHED / DIFF
private String resolveNote;
private Long resolvedBy;
private LocalDateTime resolvedAt;
private LocalDateTime createdAt;
}
@@ -0,0 +1,32 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class SettleMasterResp {
private Long settleId;
private Long agentId;
private String agentName;
private String orgName;
private String gradeName;
private String settleMonth;
private BigDecimal recruitTotal;
private BigDecimal maintainTotal;
private BigDecimal exceptionPlus;
private BigDecimal exceptionMinus;
private BigDecimal overrideTotal;
private BigDecimal chargebackTotal;
private BigDecimal grossAmount;
private BigDecimal taxAmount;
private BigDecimal netAmount;
private String status;
private String statusName;
private LocalDateTime calcDate;
private Long confirmedBy;
private String confirmedByName;
private LocalDateTime confirmedAt;
private String holdReason;
}
@@ -0,0 +1,27 @@
package com.ga.core.vo.settle;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class SettleMasterVO {
private Long settleId;
private Long agentId;
private String settleMonth;
private BigDecimal recruitTotal;
private BigDecimal maintainTotal;
private BigDecimal exceptionPlus;
private BigDecimal exceptionMinus;
private BigDecimal overrideTotal;
private BigDecimal chargebackTotal;
private BigDecimal grossAmount;
private BigDecimal taxAmount;
private BigDecimal netAmount;
private String status;
private LocalDateTime calcDate;
private Long confirmedBy;
private LocalDateTime confirmedAt;
private String holdReason;
}
@@ -0,0 +1,15 @@
package com.ga.core.vo.settle;
import com.ga.common.model.SearchParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class SettleSearchParam extends SearchParam {
private String settleMonth;
private Long agentId;
private Long orgId;
private Long gradeId;
private Boolean includeSubOrgs;
}
@@ -0,0 +1,14 @@
package com.ga.core.vo.user;
import lombok.Data;
@Data
public class RoleVO {
private Long roleId;
private String roleCode;
private String roleName;
private String roleDesc;
private Integer roleLevel;
private String isSystem;
private String isActive;
}
@@ -0,0 +1,25 @@
package com.ga.core.vo.user;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class UserResp {
private Long userId;
private String loginId;
private String userName;
private String email;
private String phone;
private Long agentId;
private String agentName;
private String orgName;
private String status;
private String statusName;
private Integer failCount;
private LocalDateTime lastLoginAt;
private LocalDateTime createdAt;
private List<String> roleCodes;
private List<String> roleNames;
}
@@ -0,0 +1,30 @@
package com.ga.core.vo.user;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.util.List;
@Data
public class UserSaveReq {
@NotBlank(message = "로그인 ID는 필수입니다")
@Size(min = 4, max = 50)
private String loginId;
@NotBlank(message = "사용자명은 필수입니다")
@Size(max = 50)
private String userName;
@Email(message = "이메일 형식이 올바르지 않습니다")
private String email;
private String phone;
private Long agentId;
private String status;
private List<Long> roleIds;
/** 신규 등록 시에만 사용. 수정 시는 별도 API. */
private String password;
}
@@ -0,0 +1,12 @@
package com.ga.core.vo.user;
import com.ga.common.model.SearchParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class UserSearchParam extends SearchParam {
private Long roleId;
private Long orgId;
}
@@ -0,0 +1,24 @@
package com.ga.core.vo.user;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class UserVO {
private Long userId;
private String loginId;
private String password;
private String userName;
private String email;
private String phone;
private Long agentId;
private String status; // ACTIVE / LOCKED / RETIRED
private Integer failCount;
private LocalDateTime lastLoginAt;
private LocalDateTime pwdChangedAt;
private LocalDateTime createdAt;
private Long createdBy;
private LocalDateTime updatedAt;
private Long updatedBy;
}
@@ -0,0 +1,107 @@
<?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.ledger.ExceptionLedgerMapper">
<resultMap id="VOMap" type="com.ga.core.vo.ledger.ExceptionLedgerVO"/>
<resultMap id="RespMap" type="com.ga.core.vo.ledger.ExceptionLedgerResp"/>
<sql id="cols">
l.ledger_id, l.contract_id, l.agent_id, a.agent_name, o.org_name,
l.exception_code, ec.exception_name, ec.direction,
l.policy_no, l.company_code, l.insurance_type,
l.amount, l.tax_amount, l.settle_month, l.description,
l.approve_status,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code='APPROVE_STATUS' AND cc.code=l.approve_status) AS approve_status_name,
l.approver_id, u.user_name AS approver_name, l.approve_date,
l.recurring_yn, l.recurring_left, l.status
</sql>
<sql id="joins">
FROM exception_ledger l
LEFT JOIN agent a ON a.agent_id = l.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
LEFT JOIN exception_type_code ec ON ec.exception_code = l.exception_code
LEFT JOIN users u ON u.user_id = l.approver_id
</sql>
<select id="selectList" resultMap="RespMap">
SELECT <include refid="cols"/> <include refid="joins"/>
<where>
<if test="settleMonth != null and settleMonth != ''">AND l.settle_month = #{settleMonth}</if>
<if test="agentId != null">AND l.agent_id = #{agentId}</if>
<if test="orgId != null">AND a.org_id = #{orgId}</if>
<if test="status != null and status != ''">AND l.approve_status = #{status}</if>
</where>
ORDER BY l.created_at DESC, l.ledger_id DESC
</select>
<select id="selectDetailById" resultMap="RespMap">
SELECT <include refid="cols"/> <include refid="joins"/>
WHERE l.ledger_id = #{ledgerId}
</select>
<select id="selectById" resultMap="VOMap">
SELECT * FROM exception_ledger WHERE ledger_id = #{ledgerId}
</select>
<insert id="insert" parameterType="com.ga.core.vo.ledger.ExceptionLedgerVO"
useGeneratedKeys="true" keyProperty="ledgerId">
INSERT INTO exception_ledger (contract_id, agent_id, exception_code, policy_no,
company_code, insurance_type, commission_year, amount, tax_amount,
settle_month, description, approve_status, recurring_yn, recurring_months,
recurring_left, status, version, created_at)
VALUES (#{contractId}, #{agentId}, #{exceptionCode}, #{policyNo},
#{companyCode}, #{insuranceType}, #{commissionYear}, #{amount}, #{taxAmount},
#{settleMonth}, #{description}, COALESCE(#{approveStatus},'PENDING'),
COALESCE(#{recurringYn},'N'), #{recurringMonths}, #{recurringLeft},
COALESCE(#{status},'NEW'), 1, #{createdAt})
</insert>
<update id="update" parameterType="com.ga.core.vo.ledger.ExceptionLedgerVO">
UPDATE exception_ledger SET
amount = #{amount}, tax_amount = #{taxAmount},
description = #{description}, status = #{status},
version = version + 1, updated_at = NOW()
WHERE ledger_id = #{ledgerId} AND version = #{version}
</update>
<update id="updateApprove">
UPDATE exception_ledger SET
approve_status = #{status},
approver_id = #{approverId},
approve_date = NOW(),
updated_at = NOW()
WHERE ledger_id = #{ledgerId}
</update>
<update id="decrementRecurring">
UPDATE exception_ledger SET recurring_left = recurring_left - 1
WHERE ledger_id = #{ledgerId} AND recurring_left &gt; 0
</update>
<select id="aggregateByAgent" resultType="map">
SELECT l.agent_id AS "agentId",
SUM(CASE WHEN ec.direction = 'PLUS' THEN l.amount ELSE 0 END) AS "plus",
SUM(CASE WHEN ec.direction = 'MINUS' THEN l.amount ELSE 0 END) AS "minus"
FROM exception_ledger l
JOIN exception_type_code ec ON ec.exception_code = l.exception_code
WHERE l.settle_month = #{settleMonth} AND l.approve_status = 'APPROVED'
GROUP BY l.agent_id
</select>
<select id="sumPlusByMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(l.amount), 0)
FROM exception_ledger l
JOIN exception_type_code ec ON ec.exception_code = l.exception_code
WHERE l.settle_month = #{settleMonth} AND ec.direction = 'PLUS' AND l.approve_status = 'APPROVED'
</select>
<select id="sumMinusByMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(l.amount), 0)
FROM exception_ledger l
JOIN exception_type_code ec ON ec.exception_code = l.exception_code
WHERE l.settle_month = #{settleMonth} AND ec.direction = 'MINUS' AND l.approve_status = 'APPROVED'
</select>
</mapper>
@@ -0,0 +1,110 @@
<?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.ledger.MaintainLedgerMapper">
<resultMap id="VOMap" type="com.ga.core.vo.ledger.LedgerVO"/>
<resultMap id="RespMap" type="com.ga.core.vo.ledger.LedgerResp"/>
<resultMap id="ExcelMap" type="com.ga.core.vo.ledger.LedgerExcelVO"/>
<sql id="cols">
l.ledger_id, l.contract_id, l.agent_id, a.agent_name, o.org_name,
l.policy_no, ct.contractor_name, ct.contract_date,
l.company_code, ic.company_name, l.product_code, p.product_name,
l.insurance_type, l.commission_year, l.premium, l.pay_method,
l.company_rate, l.company_amount, l.payout_rate, l.agent_amount, l.tax_amount,
l.reconcile_status, l.reconcile_diff, l.advance_yn, l.chargeback_yn,
l.settle_month, l.status
</sql>
<sql id="joins">
FROM maintain_ledger l
LEFT JOIN agent a ON a.agent_id = l.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
LEFT JOIN contract ct ON ct.contract_id = l.contract_id
LEFT JOIN insurance_company ic ON ic.company_code = l.company_code
LEFT JOIN product p ON p.product_id = ct.product_id
</sql>
<sql id="whereCond">
<where>
<if test="settleMonth != null and settleMonth != ''">AND l.settle_month = #{settleMonth}</if>
<if test="agentId != null">AND l.agent_id = #{agentId}</if>
<if test="orgId != null">AND a.org_id = #{orgId}</if>
<if test="companyCode != null and companyCode != ''">AND l.company_code = #{companyCode}</if>
<if test="insuranceType != null and insuranceType != ''">AND l.insurance_type = #{insuranceType}</if>
<if test="reconcileStatus != null and reconcileStatus != ''">AND l.reconcile_status = #{reconcileStatus}</if>
<if test="policyNo != null and policyNo != ''">AND l.policy_no = #{policyNo}</if>
<if test="status != null and status != ''">AND l.status = #{status}</if>
</where>
</sql>
<select id="selectList" resultMap="RespMap">
SELECT <include refid="cols"/> <include refid="joins"/> <include refid="whereCond"/>
ORDER BY l.settle_month DESC, l.agent_id
</select>
<select id="selectDetailById" resultMap="RespMap">
SELECT <include refid="cols"/> <include refid="joins"/>
WHERE l.ledger_id = #{ledgerId}
</select>
<select id="selectById" resultMap="VOMap">
SELECT * FROM maintain_ledger WHERE ledger_id = #{ledgerId}
</select>
<select id="selectCursorForExcel" resultMap="ExcelMap" fetchSize="500" resultSetType="FORWARD_ONLY">
SELECT l.settle_month, l.policy_no, a.agent_name, o.org_name,
ic.company_name, p.product_name, l.insurance_type, l.premium,
l.company_rate, l.company_amount, l.payout_rate, l.agent_amount, l.tax_amount
<include refid="joins"/> <include refid="whereCond"/>
ORDER BY l.ledger_id
</select>
<insert id="insert" parameterType="com.ga.core.vo.ledger.LedgerVO" useGeneratedKeys="true" keyProperty="ledgerId">
INSERT INTO maintain_ledger (contract_id, agent_id, policy_no, company_code, product_code,
insurance_type, commission_year, premium, pay_method, company_rate, company_amount,
payout_rate, agent_amount, tax_amount, reconcile_status, settle_month, status, version, created_at)
VALUES (#{contractId}, #{agentId}, #{policyNo}, #{companyCode}, #{productCode},
#{insuranceType}, #{commissionYear}, #{premium}, #{payMethod},
#{companyRate}, #{companyAmount}, #{payoutRate}, #{agentAmount}, #{taxAmount},
COALESCE(#{reconcileStatus},'PENDING'), #{settleMonth},
COALESCE(#{status},'CALCULATED'), 1, #{createdAt})
</insert>
<insert id="batchInsert">
INSERT INTO maintain_ledger (contract_id, agent_id, policy_no, company_code, product_code,
insurance_type, commission_year, premium, pay_method, company_rate, company_amount,
payout_rate, agent_amount, tax_amount, settle_month, status, version, created_at)
VALUES
<foreach collection="list" item="r" separator=",">
(#{r.contractId}, #{r.agentId}, #{r.policyNo}, #{r.companyCode}, #{r.productCode},
#{r.insuranceType}, #{r.commissionYear}, #{r.premium}, #{r.payMethod},
#{r.companyRate}, #{r.companyAmount}, #{r.payoutRate}, #{r.agentAmount}, #{r.taxAmount},
#{r.settleMonth}, COALESCE(#{r.status},'CALCULATED'), 1, NOW())
</foreach>
</insert>
<update id="update" parameterType="com.ga.core.vo.ledger.LedgerVO">
UPDATE maintain_ledger SET
company_rate = #{companyRate}, company_amount = #{companyAmount},
payout_rate = #{payoutRate}, agent_amount = #{agentAmount}, tax_amount = #{taxAmount},
reconcile_status = #{reconcileStatus}, status = #{status},
version = version + 1, updated_at = NOW()
WHERE ledger_id = #{ledgerId} AND version = #{version}
</update>
<delete id="deleteBySettleMonth">
DELETE FROM maintain_ledger WHERE settle_month = #{settleMonth} AND status = 'CALCULATED'
</delete>
<select id="aggregateByAgent" resultType="map">
SELECT agent_id AS "agentId", SUM(agent_amount) AS "total"
FROM maintain_ledger WHERE settle_month = #{settleMonth} GROUP BY agent_id
</select>
<select id="sumByMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(agent_amount), 0) FROM maintain_ledger WHERE settle_month = #{settleMonth}
</select>
</mapper>
@@ -0,0 +1,127 @@
<?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.ledger.RecruitLedgerMapper">
<resultMap id="VOMap" type="com.ga.core.vo.ledger.LedgerVO"/>
<resultMap id="RespMap" type="com.ga.core.vo.ledger.LedgerResp"/>
<resultMap id="ExcelMap" type="com.ga.core.vo.ledger.LedgerExcelVO"/>
<sql id="ledgerJoinCols">
l.ledger_id, l.contract_id, l.agent_id, a.agent_name, o.org_name,
l.policy_no, ct.contractor_name, ct.contract_date,
l.company_code, ic.company_name,
l.product_code, p.product_name,
l.insurance_type,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code='INSURANCE_TYPE' AND cc.code=l.insurance_type) AS insurance_type_name,
l.commission_year, l.premium, l.pay_method,
l.company_rate, l.company_amount, l.payout_rate, l.agent_amount, l.tax_amount,
l.reconcile_status, l.reconcile_diff, l.advance_yn, l.chargeback_yn,
l.settle_month, l.status,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code='LEDGER_STATUS' AND cc.code=l.status) AS status_name
</sql>
<sql id="ledgerJoins">
FROM recruit_ledger l
LEFT JOIN agent a ON a.agent_id = l.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
LEFT JOIN contract ct ON ct.contract_id = l.contract_id
LEFT JOIN insurance_company ic ON ic.company_code = l.company_code
LEFT JOIN product p ON p.product_id = ct.product_id
</sql>
<sql id="ledgerWhere">
<where>
<if test="settleMonth != null and settleMonth != ''">AND l.settle_month = #{settleMonth}</if>
<if test="agentId != null">AND l.agent_id = #{agentId}</if>
<if test="orgId != null">AND a.org_id = #{orgId}</if>
<if test="companyCode != null and companyCode != ''">AND l.company_code = #{companyCode}</if>
<if test="insuranceType != null and insuranceType != ''">AND l.insurance_type = #{insuranceType}</if>
<if test="reconcileStatus != null and reconcileStatus != ''">AND l.reconcile_status = #{reconcileStatus}</if>
<if test="chargebackYn != null and chargebackYn != ''">AND l.chargeback_yn = #{chargebackYn}</if>
<if test="advanceYn != null and advanceYn != ''">AND l.advance_yn = #{advanceYn}</if>
<if test="policyNo != null and policyNo != ''">AND l.policy_no = #{policyNo}</if>
<if test="status != null and status != ''">AND l.status = #{status}</if>
</where>
</sql>
<select id="selectList" resultMap="RespMap">
SELECT <include refid="ledgerJoinCols"/>
<include refid="ledgerJoins"/>
<include refid="ledgerWhere"/>
ORDER BY l.settle_month DESC, l.agent_id, l.ledger_id DESC
</select>
<select id="selectDetailById" resultMap="RespMap">
SELECT <include refid="ledgerJoinCols"/>
<include refid="ledgerJoins"/>
WHERE l.ledger_id = #{ledgerId}
</select>
<select id="selectById" resultMap="VOMap">
SELECT * FROM recruit_ledger WHERE ledger_id = #{ledgerId}
</select>
<select id="selectCursorForExcel" resultMap="ExcelMap" fetchSize="500" resultSetType="FORWARD_ONLY">
SELECT l.settle_month, l.policy_no, a.agent_name, o.org_name,
ic.company_name, p.product_name, l.insurance_type, l.premium,
l.company_rate, l.company_amount, l.payout_rate, l.agent_amount, l.tax_amount
<include refid="ledgerJoins"/>
<include refid="ledgerWhere"/>
ORDER BY l.ledger_id
</select>
<insert id="insert" parameterType="com.ga.core.vo.ledger.LedgerVO" useGeneratedKeys="true" keyProperty="ledgerId">
INSERT INTO recruit_ledger (contract_id, agent_id, policy_no, company_code, product_code,
insurance_type, commission_year, premium, pay_method, company_rate, company_amount,
payout_rate, agent_amount, tax_amount, reconcile_status, reconcile_diff,
advance_yn, advance_amount, chargeback_yn, settle_month, status, version, created_at)
VALUES (#{contractId}, #{agentId}, #{policyNo}, #{companyCode}, #{productCode},
#{insuranceType}, #{commissionYear}, #{premium}, #{payMethod},
#{companyRate}, #{companyAmount}, #{payoutRate}, #{agentAmount}, #{taxAmount},
COALESCE(#{reconcileStatus},'PENDING'), #{reconcileDiff},
COALESCE(#{advanceYn},'N'), #{advanceAmount}, COALESCE(#{chargebackYn},'N'),
#{settleMonth}, COALESCE(#{status},'CALCULATED'), COALESCE(#{version},1),
#{createdAt})
</insert>
<insert id="batchInsert">
INSERT INTO recruit_ledger (contract_id, agent_id, policy_no, company_code, product_code,
insurance_type, commission_year, premium, pay_method, company_rate, company_amount,
payout_rate, agent_amount, tax_amount, settle_month, status, version, created_at)
VALUES
<foreach collection="list" item="r" separator=",">
(#{r.contractId}, #{r.agentId}, #{r.policyNo}, #{r.companyCode}, #{r.productCode},
#{r.insuranceType}, #{r.commissionYear}, #{r.premium}, #{r.payMethod},
#{r.companyRate}, #{r.companyAmount}, #{r.payoutRate}, #{r.agentAmount}, #{r.taxAmount},
#{r.settleMonth}, COALESCE(#{r.status},'CALCULATED'), 1, NOW())
</foreach>
</insert>
<update id="update" parameterType="com.ga.core.vo.ledger.LedgerVO">
UPDATE recruit_ledger SET
company_rate = #{companyRate}, company_amount = #{companyAmount},
payout_rate = #{payoutRate}, agent_amount = #{agentAmount}, tax_amount = #{taxAmount},
reconcile_status = #{reconcileStatus}, reconcile_diff = #{reconcileDiff},
chargeback_yn = #{chargebackYn}, status = #{status},
version = version + 1, updated_at = NOW()
WHERE ledger_id = #{ledgerId} AND version = #{version}
</update>
<delete id="deleteBySettleMonth">
DELETE FROM recruit_ledger WHERE settle_month = #{settleMonth} AND status = 'CALCULATED'
</delete>
<select id="aggregateByAgent" resultType="map">
SELECT agent_id AS "agentId",
SUM(agent_amount) AS "total"
FROM recruit_ledger
WHERE settle_month = #{settleMonth}
GROUP BY agent_id
</select>
<select id="sumByMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(agent_amount), 0) FROM recruit_ledger WHERE settle_month = #{settleMonth}
</select>
</mapper>
@@ -0,0 +1,157 @@
<?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.org.AgentMapper">
<resultMap id="AgentVOMap" type="com.ga.core.vo.org.AgentVO">
<id property="agentId" column="agent_id"/>
<result property="orgId" column="org_id"/>
<result property="gradeId" column="grade_id"/>
<result property="agentName" column="agent_name"/>
<result property="residentNo" column="resident_no" typeHandler="com.ga.common.mybatis.EncryptTypeHandler"/>
<result property="licenseNo" column="license_no"/>
<result property="phone" column="phone"/>
<result property="email" column="email"/>
<result property="bankCode" column="bank_code"/>
<result property="accountNo" column="account_no" typeHandler="com.ga.common.mybatis.EncryptTypeHandler"/>
<result property="status" column="status"/>
<result property="joinDate" column="join_date"/>
<result property="leaveDate" column="leave_date"/>
<result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/>
</resultMap>
<resultMap id="AgentRespMap" type="com.ga.core.vo.org.AgentResp"/>
<resultMap id="AgentExcelMap" type="com.ga.core.vo.org.AgentExcelVO">
<result property="residentNo" column="resident_no" typeHandler="com.ga.common.mybatis.EncryptTypeHandler"/>
</resultMap>
<resultMap id="AgentHistoryMap" type="com.ga.core.vo.org.AgentOrgHistoryVO"/>
<sql id="agentJoinCols">
a.agent_id, a.agent_name, a.license_no, a.phone, a.email, a.status,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code='AGENT_STATUS' AND cc.code=a.status) AS status_name,
a.org_id, o.org_name,
a.grade_id, g.grade_name,
a.join_date, a.leave_date
</sql>
<select id="selectDetailById" resultMap="AgentRespMap">
SELECT <include refid="agentJoinCols"/>,
(SELECT COUNT(*) FROM contract c WHERE c.agent_id = a.agent_id AND c.status = 'ACTIVE') AS contract_count,
(SELECT COALESCE(SUM(s.net_amount),0) FROM settle_master s WHERE s.agent_id = a.agent_id) AS total_commission
FROM agent a
LEFT JOIN organization o ON o.org_id = a.org_id
LEFT JOIN grade g ON g.grade_id = a.grade_id
WHERE a.agent_id = #{agentId}
</select>
<select id="selectById" resultMap="AgentVOMap">
SELECT * FROM agent WHERE agent_id = #{agentId}
</select>
<select id="selectList" resultMap="AgentRespMap">
SELECT <include refid="agentJoinCols"/>
FROM agent a
LEFT JOIN organization o ON o.org_id = a.org_id
LEFT JOIN grade g ON g.grade_id = a.grade_id
<where>
<if test="searchKeyword != null and searchKeyword != ''">
<choose>
<when test="searchType == 'license'">
AND a.license_no = #{searchKeyword}
</when>
<otherwise>
AND a.agent_name LIKE CONCAT('%', #{searchKeyword}, '%')
</otherwise>
</choose>
</if>
<if test="status != null and status != ''">AND a.status = #{status}</if>
<if test="gradeId != null">AND a.grade_id = #{gradeId}</if>
<if test="orgId != null">
<choose>
<when test="includeSubOrgs == true">
AND a.org_id IN (
WITH RECURSIVE d AS (
SELECT org_id FROM organization WHERE org_id = #{orgId}
UNION ALL
SELECT o.org_id FROM organization o JOIN d ON o.parent_org_id = d.org_id
)
SELECT org_id FROM d
)
</when>
<otherwise>
AND a.org_id = #{orgId}
</otherwise>
</choose>
</if>
</where>
ORDER BY a.agent_id DESC
</select>
<!-- 엑셀 다운로드용 Cursor (스트리밍) -->
<select id="selectCursorForExcel" resultMap="AgentExcelMap" fetchSize="500" resultSetType="FORWARD_ONLY">
SELECT a.agent_name, a.license_no, o.org_name, g.grade_name,
a.phone, a.email, a.resident_no, a.status, a.join_date
FROM agent a
LEFT JOIN organization o ON o.org_id = a.org_id
LEFT JOIN grade g ON g.grade_id = a.grade_id
<where>
<if test="status != null and status != ''">AND a.status = #{status}</if>
<if test="orgId != null">AND a.org_id = #{orgId}</if>
</where>
ORDER BY a.agent_id
</select>
<select id="existsByLicenseNo" resultType="int">
SELECT COUNT(*) FROM agent WHERE license_no = #{licenseNo}
</select>
<insert id="insert" parameterType="com.ga.core.vo.org.AgentVO" useGeneratedKeys="true" keyProperty="agentId">
INSERT INTO agent (org_id, grade_id, agent_name, resident_no, license_no, phone, email,
bank_code, account_no, status, join_date, created_at)
VALUES (#{orgId}, #{gradeId}, #{agentName},
#{residentNo,typeHandler=com.ga.common.mybatis.EncryptTypeHandler},
#{licenseNo}, #{phone}, #{email}, #{bankCode},
#{accountNo,typeHandler=com.ga.common.mybatis.EncryptTypeHandler},
COALESCE(#{status},'ACTIVE'), #{joinDate}, #{createdAt})
</insert>
<update id="update" parameterType="com.ga.core.vo.org.AgentVO">
UPDATE agent SET
org_id = #{orgId},
grade_id = #{gradeId},
agent_name = #{agentName},
resident_no = #{residentNo,typeHandler=com.ga.common.mybatis.EncryptTypeHandler},
license_no = #{licenseNo},
phone = #{phone},
email = #{email},
bank_code = #{bankCode},
account_no = #{accountNo,typeHandler=com.ga.common.mybatis.EncryptTypeHandler},
status = #{status},
join_date = #{joinDate},
leave_date = #{leaveDate},
updated_at = #{updatedAt}
WHERE agent_id = #{agentId}
</update>
<update id="updateStatus">
UPDATE agent SET status = #{status}, updated_at = NOW() WHERE agent_id = #{agentId}
</update>
<update id="updateOrgGrade">
UPDATE agent SET org_id = #{orgId}, grade_id = #{gradeId}, updated_at = NOW()
WHERE agent_id = #{agentId}
</update>
<select id="selectHistory" resultMap="AgentHistoryMap">
SELECT * FROM agent_org_history WHERE agent_id = #{agentId} ORDER BY change_date DESC, history_id DESC
</select>
<insert id="insertHistory" parameterType="com.ga.core.vo.org.AgentOrgHistoryVO" useGeneratedKeys="true" keyProperty="historyId">
INSERT INTO agent_org_history (agent_id, from_org_id, to_org_id, from_grade_id, to_grade_id,
change_type, change_date, change_reason, created_at, created_by)
VALUES (#{agentId}, #{fromOrgId}, #{toOrgId}, #{fromGradeId}, #{toGradeId},
#{changeType}, #{changeDate}, #{changeReason}, #{createdAt}, #{createdBy})
</insert>
</mapper>
@@ -0,0 +1,38 @@
<?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.org.GradeMapper">
<resultMap id="GradeMap" type="com.ga.core.vo.org.GradeVO"/>
<sql id="cols">grade_id, grade_name, grade_level, grade_group, description, is_active, sort_order</sql>
<select id="selectAll" resultMap="GradeMap">
SELECT <include refid="cols"/> FROM grade ORDER BY grade_level, sort_order
</select>
<select id="selectActive" resultMap="GradeMap">
SELECT <include refid="cols"/> FROM grade WHERE is_active = 'Y' ORDER BY grade_level, sort_order
</select>
<select id="selectById" resultMap="GradeMap">
SELECT <include refid="cols"/> FROM grade WHERE grade_id = #{gradeId}
</select>
<insert id="insert" parameterType="com.ga.core.vo.org.GradeVO" useGeneratedKeys="true" keyProperty="gradeId">
INSERT INTO grade (grade_name, grade_level, grade_group, description, is_active, sort_order)
VALUES (#{gradeName}, #{gradeLevel}, #{gradeGroup}, #{description},
COALESCE(#{isActive},'Y'), COALESCE(#{sortOrder},0))
</insert>
<update id="update" parameterType="com.ga.core.vo.org.GradeVO">
UPDATE grade SET
grade_name = #{gradeName}, grade_level = #{gradeLevel},
grade_group = #{gradeGroup}, description = #{description},
is_active = #{isActive}, sort_order = #{sortOrder}
WHERE grade_id = #{gradeId}
</update>
<delete id="deleteById">DELETE FROM grade WHERE grade_id = #{gradeId}</delete>
</mapper>
@@ -0,0 +1,84 @@
<?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.org.OrganizationMapper">
<resultMap id="OrgVOMap" type="com.ga.core.vo.org.OrganizationVO"/>
<resultMap id="OrgRespMap" type="com.ga.core.vo.org.OrganizationResp"/>
<select id="selectAllForTree" resultMap="OrgRespMap">
SELECT o.org_id, o.parent_org_id, p.org_name AS parent_org_name,
o.org_name, o.org_type,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code = 'ORG_TYPE' AND cc.code = o.org_type) AS org_type_name,
o.org_level, o.region, o.effective_from, o.effective_to, o.is_active,
(SELECT COUNT(*) FROM agent a WHERE a.org_id = o.org_id AND a.status = 'ACTIVE') AS agent_count
FROM organization o
LEFT JOIN organization p ON p.org_id = o.parent_org_id
WHERE o.is_active = 'Y'
ORDER BY o.org_level, o.org_id
</select>
<select id="selectList" resultMap="OrgRespMap">
SELECT o.org_id, o.parent_org_id, p.org_name AS parent_org_name,
o.org_name, o.org_type, o.org_level, o.region,
o.effective_from, o.effective_to, o.is_active
FROM organization o
LEFT JOIN organization p ON p.org_id = o.parent_org_id
<where>
<if test="keyword != null and keyword != ''">
AND o.org_name LIKE CONCAT('%', #{keyword}, '%')
</if>
<if test="orgType != null and orgType != ''">AND o.org_type = #{orgType}</if>
<if test="isActive != null and isActive != ''">AND o.is_active = #{isActive}</if>
</where>
ORDER BY o.org_level, o.sort_order, o.org_id
</select>
<select id="selectById" resultMap="OrgVOMap">
SELECT * FROM organization WHERE org_id = #{orgId}
</select>
<!-- 자기 자신 + 모든 하위 조직 (재귀 CTE) -->
<select id="selectDescendantIds" resultType="long">
WITH RECURSIVE descendants AS (
SELECT org_id FROM organization WHERE org_id = #{orgId}
UNION ALL
SELECT o.org_id FROM organization o
JOIN descendants d ON o.parent_org_id = d.org_id
)
SELECT org_id FROM descendants
</select>
<insert id="insert" parameterType="com.ga.core.vo.org.OrganizationVO" useGeneratedKeys="true" keyProperty="orgId">
INSERT INTO organization (parent_org_id, org_name, org_type, org_level, region,
effective_from, effective_to, is_active, created_at, created_by)
VALUES (#{parentOrgId}, #{orgName}, #{orgType}, #{orgLevel}, #{region},
#{effectiveFrom}, #{effectiveTo}, COALESCE(#{isActive},'Y'),
#{createdAt}, #{createdBy})
</insert>
<update id="update" parameterType="com.ga.core.vo.org.OrganizationVO">
UPDATE organization SET
parent_org_id = #{parentOrgId},
org_name = #{orgName},
org_type = #{orgType},
org_level = #{orgLevel},
region = #{region},
effective_from = #{effectiveFrom},
effective_to = #{effectiveTo},
is_active = #{isActive},
updated_at = #{updatedAt}
WHERE org_id = #{orgId}
</update>
<delete id="deleteById">DELETE FROM organization WHERE org_id = #{orgId}</delete>
<select id="countChildren" resultType="int">
SELECT COUNT(*) FROM organization WHERE parent_org_id = #{orgId}
</select>
<select id="countAgents" resultType="int">
SELECT COUNT(*) FROM agent WHERE org_id = #{orgId} AND status = 'ACTIVE'
</select>
</mapper>
@@ -0,0 +1,108 @@
<?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.product.ContractMapper">
<resultMap id="ContractVOMap" type="com.ga.core.vo.product.ContractVO"/>
<resultMap id="ContractRespMap" type="com.ga.core.vo.product.ContractResp"/>
<sql id="contractCols">
ct.contract_id, ct.agent_id, a.agent_name, o.org_name,
ct.product_id, p.product_code, p.product_name,
c.company_code, c.company_name, p.insurance_type,
ct.policy_no, ct.contractor_name, ct.insured_name, ct.premium,
ct.pay_cycle,
(SELECT cc.code_name FROM common_code cc
WHERE cc.group_code='PAY_CYCLE' AND cc.code=ct.pay_cycle) AS pay_cycle_name,
ct.pay_period, ct.coverage_period,
ct.status,
(SELECT cc.code_name FROM common_code cc
WHERE cc.group_code='CONTRACT_STATUS' AND cc.code=ct.status) AS status_name,
ct.contract_date, ct.effective_date, ct.lapse_date
</sql>
<select id="selectList" resultMap="ContractRespMap">
SELECT <include refid="contractCols"/>
FROM contract ct
JOIN agent a ON a.agent_id = ct.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
JOIN product p ON p.product_id = ct.product_id
JOIN insurance_company c ON c.company_id = p.company_id
<where>
<if test="agentId != null">AND ct.agent_id = #{agentId}</if>
<if test="productId != null">AND ct.product_id = #{productId}</if>
<if test="companyId != null">AND p.company_id = #{companyId}</if>
<if test="insuranceType != null and insuranceType != ''">AND p.insurance_type = #{insuranceType}</if>
<if test="policyNo != null and policyNo != ''">AND ct.policy_no = #{policyNo}</if>
<if test="status != null and status != ''">AND ct.status = #{status}</if>
<if test="searchKeyword != null and searchKeyword != ''">
AND (ct.contractor_name LIKE CONCAT('%', #{searchKeyword}, '%')
OR ct.insured_name LIKE CONCAT('%', #{searchKeyword}, '%')
OR ct.policy_no = #{searchKeyword})
</if>
<if test="startDate != null and startDate != ''">
AND ct.contract_date &gt;= #{startDate}::date
</if>
<if test="endDate != null and endDate != ''">
AND ct.contract_date &lt;= #{endDate}::date
</if>
</where>
ORDER BY ct.contract_date DESC, ct.contract_id DESC
</select>
<select id="selectDetailById" resultMap="ContractRespMap">
SELECT <include refid="contractCols"/>
FROM contract ct
JOIN agent a ON a.agent_id = ct.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
JOIN product p ON p.product_id = ct.product_id
JOIN insurance_company c ON c.company_id = p.company_id
WHERE ct.contract_id = #{contractId}
</select>
<select id="selectById" resultMap="ContractVOMap">
SELECT * FROM contract WHERE contract_id = #{contractId}
</select>
<select id="existsByPolicyNo" resultType="int">
SELECT COUNT(*) FROM contract WHERE policy_no = #{policyNo}
</select>
<insert id="insert" parameterType="com.ga.core.vo.product.ContractVO" useGeneratedKeys="true" keyProperty="contractId">
INSERT INTO contract (agent_id, product_id, policy_no, contractor_name, insured_name,
premium, pay_cycle, pay_period, coverage_period, status,
contract_date, effective_date, created_at)
VALUES (#{agentId}, #{productId}, #{policyNo}, #{contractorName}, #{insuredName},
#{premium}, #{payCycle}, #{payPeriod}, #{coveragePeriod},
COALESCE(#{status},'ACTIVE'),
#{contractDate}, #{effectiveDate}, #{createdAt})
</insert>
<update id="update" parameterType="com.ga.core.vo.product.ContractVO">
UPDATE contract SET
agent_id = #{agentId},
product_id = #{productId},
contractor_name = #{contractorName},
insured_name = #{insuredName},
premium = #{premium},
pay_cycle = #{payCycle},
pay_period = #{payPeriod},
coverage_period = #{coveragePeriod},
status = #{status},
effective_date = #{effectiveDate},
lapse_date = #{lapseDate},
revival_date = #{revivalDate},
updated_at = #{updatedAt}
WHERE contract_id = #{contractId}
</update>
<update id="updateStatus">
UPDATE contract SET status = #{status}, updated_at = NOW() WHERE contract_id = #{contractId}
</update>
<select id="countByAgent" resultType="int">
SELECT COUNT(*) FROM contract WHERE agent_id = #{agentId}
<if test="status != null and status != ''">AND status = #{status}</if>
</select>
</mapper>
@@ -0,0 +1,51 @@
<?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.product.InsuranceCompanyMapper">
<resultMap id="CompanyMap" type="com.ga.core.vo.product.InsuranceCompanyVO"/>
<sql id="cols">
company_id, company_code, company_name, company_type, biz_no,
contact_name, contact_phone, contact_email, is_active
</sql>
<select id="selectAll" resultMap="CompanyMap">
SELECT <include refid="cols"/> FROM insurance_company ORDER BY company_id
</select>
<select id="selectActive" resultMap="CompanyMap">
SELECT <include refid="cols"/> FROM insurance_company WHERE is_active='Y' ORDER BY company_id
</select>
<select id="selectById" resultMap="CompanyMap">
SELECT <include refid="cols"/> FROM insurance_company WHERE company_id = #{companyId}
</select>
<select id="selectByCode" resultMap="CompanyMap">
SELECT <include refid="cols"/> FROM insurance_company WHERE company_code = #{companyCode}
</select>
<insert id="insert" parameterType="com.ga.core.vo.product.InsuranceCompanyVO"
useGeneratedKeys="true" keyProperty="companyId">
INSERT INTO insurance_company (company_code, company_name, company_type, biz_no,
contact_name, contact_phone, contact_email, is_active)
VALUES (#{companyCode}, #{companyName}, #{companyType}, #{bizNo},
#{contactName}, #{contactPhone}, #{contactEmail}, COALESCE(#{isActive},'Y'))
</insert>
<update id="update" parameterType="com.ga.core.vo.product.InsuranceCompanyVO">
UPDATE insurance_company SET
company_name = #{companyName},
company_type = #{companyType},
biz_no = #{bizNo},
contact_name = #{contactName},
contact_phone = #{contactPhone},
contact_email = #{contactEmail},
is_active = #{isActive}
WHERE company_id = #{companyId}
</update>
<delete id="deleteById">DELETE FROM insurance_company WHERE company_id = #{companyId}</delete>
</mapper>
@@ -0,0 +1,68 @@
<?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.product.ProductMapper">
<resultMap id="ProductVOMap" type="com.ga.core.vo.product.ProductVO"/>
<resultMap id="ProductRespMap" type="com.ga.core.vo.product.ProductResp"/>
<select id="selectList" resultMap="ProductRespMap">
SELECT p.product_id, p.company_id, c.company_code, c.company_name,
p.product_code, p.product_name, p.insurance_type,
(SELECT cc.code_name FROM common_code cc
WHERE cc.group_code='INSURANCE_TYPE' AND cc.code=p.insurance_type) AS insurance_type_name,
p.product_group, p.pay_period_type, p.is_active, p.launch_date, p.end_date
FROM product p
JOIN insurance_company c ON c.company_id = p.company_id
<where>
<if test="companyId != null">AND p.company_id = #{companyId}</if>
<if test="insuranceType != null and insuranceType != ''">AND p.insurance_type = #{insuranceType}</if>
<if test="keyword != null and keyword != ''">
AND (p.product_name LIKE CONCAT('%', #{keyword}, '%')
OR p.product_code = #{keyword})
</if>
<if test="isActive != null and isActive != ''">AND p.is_active = #{isActive}</if>
</where>
ORDER BY p.product_id DESC
</select>
<select id="selectDetailById" resultMap="ProductRespMap">
SELECT p.product_id, p.company_id, c.company_code, c.company_name,
p.product_code, p.product_name, p.insurance_type,
p.product_group, p.pay_period_type, p.is_active, p.launch_date, p.end_date
FROM product p
JOIN insurance_company c ON c.company_id = p.company_id
WHERE p.product_id = #{productId}
</select>
<select id="selectById" resultMap="ProductVOMap">
SELECT * FROM product WHERE product_id = #{productId}
</select>
<select id="existsByCode" resultType="int">
SELECT COUNT(*) FROM product WHERE company_id = #{companyId} AND product_code = #{productCode}
</select>
<insert id="insert" parameterType="com.ga.core.vo.product.ProductVO" useGeneratedKeys="true" keyProperty="productId">
INSERT INTO product (company_id, product_code, product_name, insurance_type,
product_group, pay_period_type, is_active, launch_date, end_date)
VALUES (#{companyId}, #{productCode}, #{productName}, #{insuranceType},
#{productGroup}, #{payPeriodType}, COALESCE(#{isActive},'Y'),
#{launchDate}, #{endDate})
</insert>
<update id="update" parameterType="com.ga.core.vo.product.ProductVO">
UPDATE product SET
product_name = #{productName},
insurance_type = #{insuranceType},
product_group = #{productGroup},
pay_period_type = #{payPeriodType},
is_active = #{isActive},
launch_date = #{launchDate},
end_date = #{endDate}
WHERE product_id = #{productId}
</update>
<delete id="deleteById">DELETE FROM product WHERE product_id = #{productId}</delete>
</mapper>
@@ -0,0 +1,171 @@
<?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.receive.ReceiveMapper">
<resultMap id="ProfileMap" type="com.ga.core.vo.receive.CompanyProfileVO"/>
<resultMap id="FieldMap" type="com.ga.core.vo.receive.CompanyFieldMappingVO"/>
<resultMap id="CodeMap" type="com.ga.core.vo.receive.CodeMappingVO"/>
<resultMap id="RawMap" type="com.ga.core.vo.receive.RawCommissionDataVO"/>
<resultMap id="ErrorMap" type="com.ga.core.vo.receive.ParseErrorLogVO"/>
<!-- profile -->
<select id="selectAllProfiles" resultMap="ProfileMap">
SELECT * FROM company_profile ORDER BY company_code
</select>
<select id="selectProfile" resultMap="ProfileMap">
SELECT * FROM company_profile WHERE company_code = #{companyCode}
</select>
<insert id="insertProfile" parameterType="com.ga.core.vo.receive.CompanyProfileVO">
INSERT INTO company_profile (company_code, data_format, receive_method, file_encoding,
delimiter, header_row, data_start_row, sheet_name, date_format, amount_format,
api_url, ftp_host, ftp_path, receive_schedule, is_active)
VALUES (#{companyCode}, #{dataFormat}, #{receiveMethod}, COALESCE(#{fileEncoding},'UTF-8'),
#{delimiter}, COALESCE(#{headerRow},1), COALESCE(#{dataStartRow},2),
#{sheetName}, #{dateFormat}, #{amountFormat},
#{apiUrl}, #{ftpHost}, #{ftpPath}, #{receiveSchedule}, COALESCE(#{isActive},'Y'))
</insert>
<update id="updateProfile" parameterType="com.ga.core.vo.receive.CompanyProfileVO">
UPDATE company_profile SET
data_format = #{dataFormat}, receive_method = #{receiveMethod},
file_encoding = #{fileEncoding}, delimiter = #{delimiter},
header_row = #{headerRow}, data_start_row = #{dataStartRow},
sheet_name = #{sheetName}, date_format = #{dateFormat},
amount_format = #{amountFormat}, api_url = #{apiUrl},
ftp_host = #{ftpHost}, ftp_path = #{ftpPath},
receive_schedule = #{receiveSchedule}, is_active = #{isActive}
WHERE company_code = #{companyCode}
</update>
<!-- field_mapping -->
<select id="selectFieldMappings" resultMap="FieldMap">
SELECT * FROM company_field_mapping
WHERE company_code = #{companyCode}
<if test="targetTable != null and targetTable != ''">AND target_table = #{targetTable}</if>
ORDER BY target_table, sort_order
</select>
<insert id="insertFieldMapping" parameterType="com.ga.core.vo.receive.CompanyFieldMappingVO"
useGeneratedKeys="true" keyProperty="mappingId">
INSERT INTO company_field_mapping (company_code, source_field, source_col_index,
target_table, target_field, data_type, transform_rule, default_value,
is_required, sort_order, version, effective_from)
VALUES (#{companyCode}, #{sourceField}, #{sourceColIndex},
#{targetTable}, #{targetField}, #{dataType}, #{transformRule}, #{defaultValue},
COALESCE(#{isRequired},'N'), COALESCE(#{sortOrder},0),
COALESCE(#{version},1), COALESCE(#{effectiveFrom}, CURRENT_DATE))
</insert>
<update id="updateFieldMapping" parameterType="com.ga.core.vo.receive.CompanyFieldMappingVO">
UPDATE company_field_mapping SET
source_field = #{sourceField}, source_col_index = #{sourceColIndex},
target_table = #{targetTable}, target_field = #{targetField},
data_type = #{dataType}, transform_rule = #{transformRule},
default_value = #{defaultValue}, is_required = #{isRequired},
sort_order = #{sortOrder}
WHERE mapping_id = #{mappingId}
</update>
<delete id="deleteFieldMapping">DELETE FROM company_field_mapping WHERE mapping_id = #{mappingId}</delete>
<!-- code_mapping -->
<select id="selectCodeMappings" resultMap="CodeMap">
SELECT * FROM code_mapping
WHERE company_code = #{companyCode}
<if test="codeType != null and codeType != ''">AND code_type = #{codeType}</if>
ORDER BY code_type, source_code
</select>
<select id="findTargetCode" resultType="string">
SELECT target_code FROM code_mapping
WHERE company_code = #{companyCode} AND code_type = #{codeType}
AND source_code = #{sourceCode} AND is_active = 'Y'
LIMIT 1
</select>
<insert id="insertCodeMapping" parameterType="com.ga.core.vo.receive.CodeMappingVO"
useGeneratedKeys="true" keyProperty="codeId">
INSERT INTO code_mapping (company_code, code_type, source_code, source_name,
target_code, target_name, is_active)
VALUES (#{companyCode}, #{codeType}, #{sourceCode}, #{sourceName},
#{targetCode}, #{targetName}, COALESCE(#{isActive},'Y'))
</insert>
<update id="updateCodeMapping" parameterType="com.ga.core.vo.receive.CodeMappingVO">
UPDATE code_mapping SET
source_name = #{sourceName}, target_code = #{targetCode},
target_name = #{targetName}, is_active = #{isActive}
WHERE code_id = #{codeId}
</update>
<delete id="deleteCodeMapping">DELETE FROM code_mapping WHERE code_id = #{codeId}</delete>
<!-- raw -->
<insert id="insertRaw" parameterType="com.ga.core.vo.receive.RawCommissionDataVO"
useGeneratedKeys="true" keyProperty="rawId">
INSERT INTO raw_commission_data (company_code, batch_id, settle_month, data_type,
raw_content, parse_status, file_name, row_number, received_at)
VALUES (#{companyCode}, #{batchId}, #{settleMonth}, #{dataType},
#{rawContent}, COALESCE(#{parseStatus},'PENDING'),
#{fileName}, #{rowNumber}, NOW())
</insert>
<insert id="insertRawBatch">
INSERT INTO raw_commission_data (company_code, batch_id, settle_month, data_type,
raw_content, parse_status, file_name, row_number, received_at)
VALUES
<foreach collection="list" item="r" separator=",">
(#{r.companyCode}, #{r.batchId}, #{r.settleMonth}, #{r.dataType},
#{r.rawContent}, COALESCE(#{r.parseStatus},'PENDING'),
#{r.fileName}, #{r.rowNumber}, NOW())
</foreach>
</insert>
<select id="selectRawList" resultMap="RawMap">
SELECT * FROM raw_commission_data
<where>
<if test="companyCode != null and companyCode != ''">AND company_code = #{companyCode}</if>
<if test="settleMonth != null and settleMonth != ''">AND settle_month = #{settleMonth}</if>
<if test="parseStatus != null and parseStatus != ''">AND parse_status = #{parseStatus}</if>
</where>
ORDER BY received_at DESC
</select>
<update id="updateRawStatus">
UPDATE raw_commission_data SET
parse_status = #{parseStatus},
mapped_ledger_id = #{mappedLedgerId},
mapped_table = #{mappedTable},
parsed_at = NOW()
WHERE raw_id = #{rawId}
</update>
<!-- error -->
<select id="selectErrors" resultMap="ErrorMap">
SELECT * FROM parse_error_log
<where>
<if test="companyCode != null and companyCode != ''">AND company_code = #{companyCode}</if>
<if test="resolveStatus != null and resolveStatus != ''">AND resolve_status = #{resolveStatus}</if>
</where>
ORDER BY created_at DESC
</select>
<insert id="insertError" parameterType="com.ga.core.vo.receive.ParseErrorLogVO"
useGeneratedKeys="true" keyProperty="errorId">
INSERT INTO parse_error_log (raw_id, company_code, error_type, error_field, error_value,
error_message, resolve_status, created_at)
VALUES (#{rawId}, #{companyCode}, #{errorType}, #{errorField}, #{errorValue},
#{errorMessage}, COALESCE(#{resolveStatus},'OPEN'), NOW())
</insert>
<update id="resolveError">
UPDATE parse_error_log SET
resolve_status = #{status}, resolve_note = #{note},
resolved_by = #{userId}, resolved_at = NOW()
WHERE error_id = #{errorId}
</update>
</mapper>
@@ -0,0 +1,196 @@
<?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.rule.RuleMapper">
<resultMap id="CommRateMap" type="com.ga.core.vo.rule.CommissionRateVO"/>
<resultMap id="PayoutMap" type="com.ga.core.vo.rule.PayoutRuleVO"/>
<resultMap id="OverrideMap" type="com.ga.core.vo.rule.OverrideRuleVO"/>
<resultMap id="ChargebackMap" type="com.ga.core.vo.rule.ChargebackRuleVO"/>
<resultMap id="ExceptionMap" type="com.ga.core.vo.rule.ExceptionTypeCodeVO"/>
<!-- ============ commission_rate ============ -->
<select id="selectCommissionRates" resultMap="CommRateMap">
SELECT * FROM commission_rate
<where>
<if test="productId != null">AND product_id = #{productId}</if>
<if test="year != null">AND commission_year = #{year}</if>
</where>
ORDER BY product_id, commission_year, effective_from DESC, version DESC
</select>
<select id="findCompanyRate" resultType="java.math.BigDecimal">
SELECT rate_pct FROM commission_rate
WHERE product_id = #{productId} AND commission_year = #{year}
AND effective_from &lt;= #{baseDate}
AND (effective_to IS NULL OR effective_to &gt;= #{baseDate})
ORDER BY effective_from DESC, version DESC
LIMIT 1
</select>
<insert id="insertCommissionRate" parameterType="com.ga.core.vo.rule.CommissionRateVO"
useGeneratedKeys="true" keyProperty="rateId">
INSERT INTO commission_rate (product_id, commission_year, rate_pct, pay_method_cond,
min_premium, effective_from, effective_to, version,
created_at, created_by)
VALUES (#{productId}, #{commissionYear}, #{ratePct}, #{payMethodCond},
#{minPremium}, #{effectiveFrom}, #{effectiveTo}, COALESCE(#{version},1),
#{createdAt}, #{createdBy})
</insert>
<update id="updateCommissionRate" parameterType="com.ga.core.vo.rule.CommissionRateVO">
UPDATE commission_rate SET
rate_pct = #{ratePct}, pay_method_cond = #{payMethodCond},
min_premium = #{minPremium}, effective_from = #{effectiveFrom},
effective_to = #{effectiveTo}, version = #{version}
WHERE rate_id = #{rateId}
</update>
<delete id="deleteCommissionRate">DELETE FROM commission_rate WHERE rate_id = #{rateId}</delete>
<!-- ============ payout_rule ============ -->
<select id="selectPayoutRules" resultMap="PayoutMap">
SELECT * FROM payout_rule
<where>
<if test="gradeId != null">AND grade_id = #{gradeId}</if>
<if test="insuranceType != null and insuranceType != ''">AND insurance_type = #{insuranceType}</if>
</where>
ORDER BY grade_id, insurance_type, effective_from DESC
</select>
<select id="findPayoutRate" resultType="java.math.BigDecimal">
SELECT payout_pct FROM payout_rule
WHERE grade_id = #{gradeId}
AND insurance_type = #{insuranceType}
AND commission_year = #{year}
AND effective_from &lt;= #{baseDate}
AND (effective_to IS NULL OR effective_to &gt;= #{baseDate})
ORDER BY effective_from DESC, version DESC
LIMIT 1
</select>
<insert id="insertPayoutRule" parameterType="com.ga.core.vo.rule.PayoutRuleVO"
useGeneratedKeys="true" keyProperty="ruleId">
INSERT INTO payout_rule (grade_id, insurance_type, commission_year, payout_pct,
pay_method_cond, performance_grade, effective_from, effective_to,
version, created_at, created_by)
VALUES (#{gradeId}, #{insuranceType}, #{commissionYear}, #{payoutPct},
#{payMethodCond}, #{performanceGrade}, #{effectiveFrom}, #{effectiveTo},
COALESCE(#{version},1), #{createdAt}, #{createdBy})
</insert>
<update id="updatePayoutRule" parameterType="com.ga.core.vo.rule.PayoutRuleVO">
UPDATE payout_rule SET
payout_pct = #{payoutPct},
pay_method_cond = #{payMethodCond},
performance_grade = #{performanceGrade},
effective_from = #{effectiveFrom},
effective_to = #{effectiveTo},
version = #{version}
WHERE rule_id = #{ruleId}
</update>
<delete id="deletePayoutRule">DELETE FROM payout_rule WHERE rule_id = #{ruleId}</delete>
<!-- ============ override_rule ============ -->
<select id="selectOverrideRules" resultMap="OverrideMap">
SELECT * FROM override_rule ORDER BY from_grade, to_grade, effective_from DESC
</select>
<insert id="insertOverrideRule" parameterType="com.ga.core.vo.rule.OverrideRuleVO"
useGeneratedKeys="true" keyProperty="overrideId">
INSERT INTO override_rule (from_grade, to_grade, override_pct, calc_type,
insurance_type_cond, cap_amount, effective_from, effective_to)
VALUES (#{fromGrade}, #{toGrade}, #{overridePct}, #{calcType},
#{insuranceTypeCond}, #{capAmount}, #{effectiveFrom}, #{effectiveTo})
</insert>
<update id="updateOverrideRule" parameterType="com.ga.core.vo.rule.OverrideRuleVO">
UPDATE override_rule SET
override_pct = #{overridePct},
calc_type = #{calcType},
insurance_type_cond = #{insuranceTypeCond},
cap_amount = #{capAmount},
effective_from = #{effectiveFrom},
effective_to = #{effectiveTo}
WHERE override_id = #{overrideId}
</update>
<delete id="deleteOverrideRule">DELETE FROM override_rule WHERE override_id = #{overrideId}</delete>
<!-- ============ chargeback_rule ============ -->
<select id="selectChargebackRules" resultMap="ChargebackMap">
SELECT * FROM chargeback_rule
<where>
<if test="companyCode != null and companyCode != ''">AND company_code = #{companyCode}</if>
</where>
ORDER BY company_code NULLS FIRST, insurance_type, lapse_month_from, effective_from DESC
</select>
<select id="findChargebackRate" resultType="java.math.BigDecimal">
SELECT cb_rate FROM chargeback_rule
WHERE (company_code = #{companyCode} OR company_code IS NULL)
AND (insurance_type = #{insuranceType} OR insurance_type IS NULL)
AND #{lapseMonth} BETWEEN lapse_month_from AND lapse_month_to
AND effective_from &lt;= #{baseDate}
AND (effective_to IS NULL OR effective_to &gt;= #{baseDate})
ORDER BY (company_code IS NULL) ASC, (insurance_type IS NULL) ASC, effective_from DESC
LIMIT 1
</select>
<insert id="insertChargebackRule" parameterType="com.ga.core.vo.rule.ChargebackRuleVO"
useGeneratedKeys="true" keyProperty="cbRuleId">
INSERT INTO chargeback_rule (company_code, insurance_type, lapse_month_from, lapse_month_to,
cb_rate, include_override, installment_allowed, max_installments,
effective_from, effective_to)
VALUES (#{companyCode}, #{insuranceType}, #{lapseMonthFrom}, #{lapseMonthTo},
#{cbRate}, COALESCE(#{includeOverride},'N'),
COALESCE(#{installmentAllowed},'N'), #{maxInstallments},
#{effectiveFrom}, #{effectiveTo})
</insert>
<update id="updateChargebackRule" parameterType="com.ga.core.vo.rule.ChargebackRuleVO">
UPDATE chargeback_rule SET
cb_rate = #{cbRate},
include_override = #{includeOverride},
installment_allowed = #{installmentAllowed},
max_installments = #{maxInstallments},
effective_from = #{effectiveFrom},
effective_to = #{effectiveTo}
WHERE cb_rule_id = #{cbRuleId}
</update>
<delete id="deleteChargebackRule">DELETE FROM chargeback_rule WHERE cb_rule_id = #{cbRuleId}</delete>
<!-- ============ exception_type_code ============ -->
<select id="selectExceptionCodes" resultMap="ExceptionMap">
SELECT * FROM exception_type_code WHERE is_active = 'Y' ORDER BY direction, exception_code
</select>
<select id="selectExceptionCode" resultMap="ExceptionMap">
SELECT * FROM exception_type_code WHERE exception_code = #{exceptionCode}
</select>
<insert id="insertExceptionCode" parameterType="com.ga.core.vo.rule.ExceptionTypeCodeVO">
INSERT INTO exception_type_code (exception_code, exception_name, category, direction,
auto_calc_yn, approval_required, tax_included,
description, is_active)
VALUES (#{exceptionCode}, #{exceptionName}, #{category}, #{direction},
COALESCE(#{autoCalcYn},'N'), COALESCE(#{approvalRequired},'N'),
COALESCE(#{taxIncluded},'N'), #{description}, COALESCE(#{isActive},'Y'))
</insert>
<update id="updateExceptionCode" parameterType="com.ga.core.vo.rule.ExceptionTypeCodeVO">
UPDATE exception_type_code SET
exception_name = #{exceptionName},
category = #{category},
direction = #{direction},
auto_calc_yn = #{autoCalcYn},
approval_required = #{approvalRequired},
tax_included = #{taxIncluded},
description = #{description},
is_active = #{isActive}
WHERE exception_code = #{exceptionCode}
</update>
</mapper>
@@ -0,0 +1,55 @@
<?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.BatchJobLogMapper">
<resultMap id="LogMap" type="com.ga.core.vo.settle.BatchJobLogVO"/>
<insert id="insert" parameterType="com.ga.core.vo.settle.BatchJobLogVO" useGeneratedKeys="true" keyProperty="jobId">
INSERT INTO batch_job_log (job_name, job_params, settle_month, status,
started_at, triggered_by)
VALUES (#{jobName}, #{jobParams}, #{settleMonth}, COALESCE(#{status},'STARTED'),
NOW(), #{triggeredBy})
</insert>
<update id="update" parameterType="com.ga.core.vo.settle.BatchJobLogVO">
UPDATE batch_job_log SET
status = #{status},
current_step = #{currentStep},
progress_pct = #{progressPct},
total_count = #{totalCount},
processed_count = #{processedCount},
error_count = #{errorCount},
error_message = #{errorMessage},
finished_at = CASE WHEN #{status} IN ('COMPLETED','FAILED') THEN NOW() ELSE finished_at END,
duration_sec = CASE
WHEN #{status} IN ('COMPLETED','FAILED')
THEN EXTRACT(EPOCH FROM (NOW() - started_at))::int
ELSE duration_sec END
WHERE job_id = #{jobId}
</update>
<select id="selectById" resultMap="LogMap">
SELECT * FROM batch_job_log WHERE job_id = #{jobId}
</select>
<select id="selectLatest" resultMap="LogMap">
SELECT * FROM batch_job_log WHERE job_name = #{jobName}
ORDER BY started_at DESC LIMIT 1
</select>
<select id="selectList" resultMap="LogMap">
SELECT * FROM batch_job_log
<where>
<if test="jobName != null and jobName != ''">AND job_name = #{jobName}</if>
<if test="settleMonth != null and settleMonth != ''">AND settle_month = #{settleMonth}</if>
</where>
ORDER BY started_at DESC
</select>
<select id="isRunning" resultType="int">
SELECT COUNT(*) FROM batch_job_log
WHERE job_name = #{jobName} AND status IN ('STARTED','RUNNING')
</select>
</mapper>
@@ -0,0 +1,51 @@
<?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.ChargebackMapper">
<resultMap id="CBMap" type="com.ga.core.vo.settle.ChargebackVO"/>
<insert id="insert" parameterType="com.ga.core.vo.settle.ChargebackVO" useGeneratedKeys="true" keyProperty="cbId">
INSERT INTO chargeback (contract_id, agent_id, policy_no, lapse_month, cb_rate,
cb_amount, paid_amount, remain_amount, settle_month,
installment_no, max_installments, status, created_at)
VALUES (#{contractId}, #{agentId}, #{policyNo}, #{lapseMonth}, #{cbRate},
#{cbAmount}, COALESCE(#{paidAmount}, 0), #{remainAmount}, #{settleMonth},
#{installmentNo}, #{maxInstallments}, COALESCE(#{status},'NEW'), NOW())
</insert>
<insert id="insertBatch">
INSERT INTO chargeback (contract_id, agent_id, policy_no, lapse_month, cb_rate,
cb_amount, remain_amount, settle_month, status, created_at)
VALUES
<foreach collection="list" item="r" separator=",">
(#{r.contractId}, #{r.agentId}, #{r.policyNo}, #{r.lapseMonth}, #{r.cbRate},
#{r.cbAmount}, #{r.remainAmount}, #{r.settleMonth}, COALESCE(#{r.status},'NEW'), NOW())
</foreach>
</insert>
<select id="selectByAgent" resultMap="CBMap">
SELECT * FROM chargeback
WHERE agent_id = #{agentId}
<if test="settleMonth != null and settleMonth != ''">AND settle_month = #{settleMonth}</if>
ORDER BY created_at DESC
</select>
<update id="updatePaid">
UPDATE chargeback SET
paid_amount = paid_amount + #{paidAmount},
remain_amount = cb_amount - (paid_amount + #{paidAmount}),
status = #{status}
WHERE cb_id = #{cbId}
</update>
<select id="aggregateByAgent" resultType="map">
SELECT agent_id AS "agentId", SUM(cb_amount) AS "total"
FROM chargeback WHERE settle_month = #{settleMonth} GROUP BY agent_id
</select>
<select id="sumByMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(cb_amount), 0) FROM chargeback WHERE settle_month = #{settleMonth}
</select>
</mapper>
@@ -0,0 +1,45 @@
<?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.OverrideSettleMapper">
<resultMap id="VOMap" type="com.ga.core.vo.settle.OverrideSettleVO"/>
<insert id="insert" parameterType="com.ga.core.vo.settle.OverrideSettleVO" useGeneratedKeys="true" keyProperty="osId">
INSERT INTO override_settle (settle_id, upper_agent_id, lower_agent_id, settle_month,
base_amount, override_pct, override_amount, calc_date)
VALUES (#{settleId}, #{upperAgentId}, #{lowerAgentId}, #{settleMonth},
#{baseAmount}, #{overridePct}, #{overrideAmount}, NOW())
</insert>
<insert id="insertBatch">
INSERT INTO override_settle (settle_id, upper_agent_id, lower_agent_id, settle_month,
base_amount, override_pct, override_amount, calc_date)
VALUES
<foreach collection="list" item="r" separator=",">
(#{r.settleId}, #{r.upperAgentId}, #{r.lowerAgentId}, #{r.settleMonth},
#{r.baseAmount}, #{r.overridePct}, #{r.overrideAmount}, NOW())
</foreach>
</insert>
<select id="selectByUpper" resultMap="VOMap">
SELECT * FROM override_settle
WHERE upper_agent_id = #{upperAgentId} AND settle_month = #{settleMonth}
ORDER BY lower_agent_id
</select>
<delete id="deleteBySettleMonth">
DELETE FROM override_settle WHERE settle_month = #{settleMonth}
</delete>
<select id="aggregateByUpper" resultType="map">
SELECT upper_agent_id AS "agentId", SUM(override_amount) AS "total"
FROM override_settle WHERE settle_month = #{settleMonth}
GROUP BY upper_agent_id
</select>
<select id="sumByMonth" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(override_amount), 0) FROM override_settle WHERE settle_month = #{settleMonth}
</select>
</mapper>
@@ -0,0 +1,78 @@
<?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.PaymentMapper">
<resultMap id="VOMap" type="com.ga.core.vo.settle.PaymentVO">
<id property="paymentId" column="payment_id"/>
<result property="settleId" column="settle_id"/>
<result property="agentId" column="agent_id"/>
<result property="payAmount" column="pay_amount"/>
<result property="bankCode" column="bank_code"/>
<result property="accountNo" column="account_no" typeHandler="com.ga.common.mybatis.EncryptTypeHandler"/>
<result property="payDate" column="pay_date"/>
<result property="payStatus" column="pay_status"/>
<result property="transferFileId" column="transfer_file_id"/>
<result property="failReason" column="fail_reason"/>
<result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/>
</resultMap>
<resultMap id="RespMap" type="com.ga.core.vo.settle.PaymentResp"/>
<select id="selectList" resultMap="RespMap">
SELECT p.payment_id, p.settle_id, p.agent_id, a.agent_name,
p.bank_code,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code='BANK_CODE' AND cc.code=p.bank_code) AS bank_name,
p.pay_amount, p.pay_date,
p.pay_status,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code='PAYMENT_STATUS' AND cc.code=p.pay_status) AS pay_status_name,
p.fail_reason, s.settle_month
FROM payment p
JOIN settle_master s ON s.settle_id = p.settle_id
JOIN agent a ON a.agent_id = p.agent_id
<where>
<if test="settleMonth != null and settleMonth != ''">AND s.settle_month = #{settleMonth}</if>
<if test="agentId != null">AND p.agent_id = #{agentId}</if>
<if test="status != null and status != ''">AND p.pay_status = #{status}</if>
</where>
ORDER BY p.payment_id DESC
</select>
<select id="selectById" resultMap="VOMap">
SELECT * FROM payment WHERE payment_id = #{paymentId}
</select>
<insert id="insert" parameterType="com.ga.core.vo.settle.PaymentVO" useGeneratedKeys="true" keyProperty="paymentId">
INSERT INTO payment (settle_id, agent_id, pay_amount, bank_code, account_no,
pay_date, pay_status, created_at)
VALUES (#{settleId}, #{agentId}, #{payAmount}, #{bankCode},
#{accountNo,typeHandler=com.ga.common.mybatis.EncryptTypeHandler},
#{payDate}, COALESCE(#{payStatus},'PENDING'), NOW())
</insert>
<insert id="insertBatch">
INSERT INTO payment (settle_id, agent_id, pay_amount, bank_code, account_no,
pay_date, pay_status, created_at)
VALUES
<foreach collection="list" item="p" separator=",">
(#{p.settleId}, #{p.agentId}, #{p.payAmount}, #{p.bankCode},
#{p.accountNo,typeHandler=com.ga.common.mybatis.EncryptTypeHandler},
#{p.payDate}, COALESCE(#{p.payStatus},'PENDING'), NOW())
</foreach>
</insert>
<update id="updateStatus">
UPDATE payment SET pay_status = #{status},
fail_reason = #{failReason},
updated_at = NOW()
WHERE payment_id = #{paymentId}
</update>
<update id="updateTransferFile">
UPDATE payment SET transfer_file_id = #{transferFileId}, pay_status = 'SENT', updated_at = NOW()
WHERE payment_id IN
<foreach collection="paymentIds" item="id" open="(" separator="," close=")">#{id}</foreach>
</update>
</mapper>
@@ -0,0 +1,26 @@
<?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.ReconciliationMapper">
<resultMap id="ReconMap" type="com.ga.core.vo.settle.ReconciliationVO"/>
<select id="selectByMonth" resultMap="ReconMap">
SELECT * FROM reconciliation WHERE settle_month = #{settleMonth}
ORDER BY company_code
</select>
<insert id="upsert" parameterType="com.ga.core.vo.settle.ReconciliationVO">
INSERT INTO reconciliation (company_code, settle_month, company_total, system_total,
diff_amount, diff_count, status, created_at)
VALUES (#{companyCode}, #{settleMonth}, #{companyTotal}, #{systemTotal},
#{diffAmount}, #{diffCount}, COALESCE(#{status},'PENDING'), NOW())
</insert>
<update id="resolve">
UPDATE reconciliation SET status = 'MATCHED', resolve_note = #{note},
resolved_by = #{userId}, resolved_at = NOW()
WHERE recon_id = #{reconId}
</update>
</mapper>
@@ -0,0 +1,139 @@
<?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.SettleMasterMapper">
<resultMap id="VOMap" type="com.ga.core.vo.settle.SettleMasterVO"/>
<resultMap id="RespMap" type="com.ga.core.vo.settle.SettleMasterResp"/>
<sql id="cols">
s.settle_id, s.agent_id, a.agent_name, o.org_name, g.grade_name,
s.settle_month, s.recruit_total, s.maintain_total,
s.exception_plus, s.exception_minus, s.override_total, s.chargeback_total,
s.gross_amount, s.tax_amount, s.net_amount,
s.status,
(SELECT cc.code_name FROM common_code cc WHERE cc.group_code='SETTLE_STATUS' AND cc.code=s.status) AS status_name,
s.calc_date, s.confirmed_by, u.user_name AS confirmed_by_name,
s.confirmed_at, s.hold_reason
</sql>
<sql id="joins">
FROM settle_master s
LEFT JOIN agent a ON a.agent_id = s.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
LEFT JOIN grade g ON g.grade_id = a.grade_id
LEFT JOIN users u ON u.user_id = s.confirmed_by
</sql>
<select id="selectList" resultMap="RespMap">
SELECT <include refid="cols"/>
<include refid="joins"/>
<where>
<if test="settleMonth != null and settleMonth != ''">AND s.settle_month = #{settleMonth}</if>
<if test="agentId != null">AND s.agent_id = #{agentId}</if>
<if test="status != null and status != ''">AND s.status = #{status}</if>
<if test="gradeId != null">AND a.grade_id = #{gradeId}</if>
<if test="orgId != null">
<choose>
<when test="includeSubOrgs == true">
AND a.org_id IN (
WITH RECURSIVE d AS (
SELECT org_id FROM organization WHERE org_id = #{orgId}
UNION ALL
SELECT o2.org_id FROM organization o2 JOIN d ON o2.parent_org_id = d.org_id
) SELECT org_id FROM d
)
</when>
<otherwise>
AND a.org_id = #{orgId}
</otherwise>
</choose>
</if>
</where>
ORDER BY s.settle_month DESC, a.agent_id
</select>
<select id="selectDetail" resultMap="RespMap">
SELECT <include refid="cols"/>
<include refid="joins"/>
WHERE s.agent_id = #{agentId} AND s.settle_month = #{settleMonth}
</select>
<select id="selectByAgentAndMonth" resultMap="VOMap">
SELECT * FROM settle_master WHERE agent_id = #{agentId} AND settle_month = #{settleMonth}
</select>
<select id="selectById" resultMap="VOMap">
SELECT * FROM settle_master WHERE settle_id = #{settleId}
</select>
<insert id="upsert" parameterType="com.ga.core.vo.settle.SettleMasterVO">
INSERT INTO settle_master (agent_id, settle_month, recruit_total, maintain_total,
exception_plus, exception_minus, override_total, chargeback_total,
gross_amount, tax_amount, net_amount, status, calc_date)
VALUES (#{agentId}, #{settleMonth},
COALESCE(#{recruitTotal}, 0), COALESCE(#{maintainTotal}, 0),
COALESCE(#{exceptionPlus}, 0), COALESCE(#{exceptionMinus}, 0),
COALESCE(#{overrideTotal}, 0), COALESCE(#{chargebackTotal}, 0),
COALESCE(#{grossAmount}, 0), COALESCE(#{taxAmount}, 0), COALESCE(#{netAmount}, 0),
COALESCE(#{status},'CALCULATED'), NOW())
ON CONFLICT (agent_id, settle_month) DO UPDATE SET
recruit_total = EXCLUDED.recruit_total,
maintain_total = EXCLUDED.maintain_total,
exception_plus = EXCLUDED.exception_plus,
exception_minus = EXCLUDED.exception_minus,
override_total = EXCLUDED.override_total,
chargeback_total = EXCLUDED.chargeback_total,
gross_amount = EXCLUDED.gross_amount,
tax_amount = EXCLUDED.tax_amount,
net_amount = EXCLUDED.net_amount,
status = EXCLUDED.status,
calc_date = NOW()
WHERE settle_master.status NOT IN ('CONFIRMED','PAID')
</insert>
<update id="updateStatus">
UPDATE settle_master SET
status = #{status},
confirmed_by = #{userId},
confirmed_at = CASE WHEN #{status} = 'CONFIRMED' THEN NOW() ELSE confirmed_at END
WHERE settle_id = #{settleId}
</update>
<update id="updateHold">
UPDATE settle_master SET status = 'HOLD', hold_reason = #{reason} WHERE settle_id = #{settleId}
</update>
<select id="selectMonthSummary" resultType="map">
SELECT
COUNT(*) AS "agentCount",
SUM(recruit_total) AS "recruitTotal",
SUM(maintain_total) AS "maintainTotal",
SUM(exception_plus) AS "exceptionPlus",
SUM(exception_minus) AS "exceptionMinus",
SUM(override_total) AS "overrideTotal",
SUM(chargeback_total) AS "chargebackTotal",
SUM(gross_amount) AS "grossAmount",
SUM(tax_amount) AS "taxAmount",
SUM(net_amount) AS "netAmount",
SUM(CASE WHEN status='CONFIRMED' THEN 1 ELSE 0 END) AS "confirmedCount",
SUM(CASE WHEN status='HOLD' THEN 1 ELSE 0 END) AS "holdCount",
SUM(CASE WHEN status='PAID' THEN 1 ELSE 0 END) AS "paidCount"
FROM settle_master WHERE settle_month = #{settleMonth}
</select>
<select id="selectOrgSummary" resultType="map">
SELECT o.org_id AS "orgId",
o.org_name AS "orgName",
COUNT(s.settle_id) AS "agentCount",
COALESCE(SUM(s.gross_amount),0) AS "grossAmount",
COALESCE(SUM(s.net_amount),0) AS "netAmount"
FROM settle_master s
JOIN agent a ON a.agent_id = s.agent_id
JOIN organization o ON o.org_id = a.org_id
WHERE s.settle_month = #{settleMonth}
GROUP BY o.org_id, o.org_name
ORDER BY o.org_id
</select>
</mapper>
@@ -0,0 +1,51 @@
<?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.user.RoleMapper">
<resultMap id="RoleMap" type="com.ga.core.vo.user.RoleVO"/>
<select id="selectAll" resultMap="RoleMap">
SELECT role_id, role_code, role_name, role_desc, role_level, is_system, is_active
FROM role
ORDER BY role_level DESC, role_id
</select>
<select id="selectById" resultMap="RoleMap">
SELECT role_id, role_code, role_name, role_desc, role_level, is_system, is_active
FROM role WHERE role_id = #{roleId}
</select>
<insert id="insert" parameterType="com.ga.core.vo.user.RoleVO" useGeneratedKeys="true" keyProperty="roleId">
INSERT INTO role (role_code, role_name, role_desc, role_level, is_system, is_active)
VALUES (#{roleCode}, #{roleName}, #{roleDesc}, COALESCE(#{roleLevel},0),
COALESCE(#{isSystem},'N'), COALESCE(#{isActive},'Y'))
</insert>
<update id="update" parameterType="com.ga.core.vo.user.RoleVO">
UPDATE role SET role_name = #{roleName}, role_desc = #{roleDesc},
role_level = #{roleLevel}, is_active = #{isActive}
WHERE role_id = #{roleId} AND is_system = 'N'
</update>
<delete id="deleteById">
DELETE FROM role WHERE role_id = #{roleId} AND is_system = 'N'
</delete>
<select id="selectRolePermissions" resultType="map">
SELECT menu_id AS "menuId",
perm_code AS "permCode",
is_granted AS "isGranted"
FROM role_menu_permission WHERE role_id = #{roleId}
</select>
<delete id="deleteRolePermissions">
DELETE FROM role_menu_permission WHERE role_id = #{roleId}
</delete>
<insert id="insertRolePermission">
INSERT INTO role_menu_permission (role_id, menu_id, perm_code, is_granted)
VALUES (#{roleId}, #{menuId}, #{permCode}, COALESCE(#{isGranted},'Y'))
</insert>
</mapper>
@@ -0,0 +1,122 @@
<?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.user.UserMapper">
<resultMap id="UserVOMap" type="com.ga.core.vo.user.UserVO"/>
<resultMap id="UserRespMap" type="com.ga.core.vo.user.UserResp"/>
<sql id="UserCols">
u.user_id, u.login_id, u.password, u.user_name, u.email, u.phone, u.agent_id,
u.status, u.fail_count, u.last_login_at, u.pwd_changed_at,
u.created_at, u.created_by, u.updated_at, u.updated_by
</sql>
<select id="selectById" resultMap="UserVOMap">
SELECT <include refid="UserCols"/>
FROM users u WHERE u.user_id = #{userId}
</select>
<select id="selectByLoginId" resultMap="UserVOMap">
SELECT <include refid="UserCols"/>
FROM users u WHERE u.login_id = #{loginId}
</select>
<select id="selectDetailById" resultMap="UserRespMap">
SELECT u.user_id, u.login_id, u.user_name, u.email, u.phone,
u.agent_id, a.agent_name, o.org_name,
u.status,
(SELECT cc.code_name FROM common_code cc
WHERE cc.group_code = 'AGENT_STATUS' AND cc.code = u.status) AS status_name,
u.fail_count, u.last_login_at, u.created_at
FROM users u
LEFT JOIN agent a ON a.agent_id = u.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
WHERE u.user_id = #{userId}
</select>
<select id="selectList" resultMap="UserRespMap">
SELECT u.user_id, u.login_id, u.user_name, u.email, u.phone,
u.agent_id, a.agent_name, o.org_name,
u.status,
u.fail_count, u.last_login_at, u.created_at
FROM users u
LEFT JOIN agent a ON a.agent_id = u.agent_id
LEFT JOIN organization o ON o.org_id = a.org_id
<if test="roleId != null">
JOIN user_role ur ON ur.user_id = u.user_id AND ur.role_id = #{roleId}
</if>
<where>
<if test="searchKeyword != null and searchKeyword != ''">
AND (u.login_id LIKE CONCAT('%', #{searchKeyword}, '%')
OR u.user_name LIKE CONCAT('%', #{searchKeyword}, '%'))
</if>
<if test="status != null and status != ''">AND u.status = #{status}</if>
<if test="orgId != null">AND a.org_id = #{orgId}</if>
</where>
ORDER BY u.created_at DESC
</select>
<select id="countByCondition" resultType="int">
SELECT COUNT(*) FROM users u
<where>
<if test="status != null and status != ''">AND u.status = #{status}</if>
</where>
</select>
<insert id="insert" parameterType="com.ga.core.vo.user.UserVO" useGeneratedKeys="true" keyProperty="userId">
INSERT INTO users (login_id, password, user_name, email, phone, agent_id, status,
fail_count, pwd_changed_at, created_at, created_by)
VALUES (#{loginId}, #{password}, #{userName}, #{email}, #{phone}, #{agentId},
COALESCE(#{status},'ACTIVE'), 0, NOW(), #{createdAt}, #{createdBy})
</insert>
<update id="update" parameterType="com.ga.core.vo.user.UserVO">
UPDATE users SET
user_name = #{userName},
email = #{email},
phone = #{phone},
agent_id = #{agentId},
status = #{status},
updated_at = #{updatedAt},
updated_by = #{updatedBy}
WHERE user_id = #{userId}
</update>
<update id="updatePassword">
UPDATE users SET password = #{password}, pwd_changed_at = NOW(), fail_count = 0
WHERE user_id = #{userId}
</update>
<update id="updateLastLogin">
UPDATE users SET last_login_at = NOW(), fail_count = 0 WHERE user_id = #{userId}
</update>
<update id="incrementFailCount">
UPDATE users SET fail_count = fail_count + 1 WHERE user_id = #{userId}
</update>
<update id="resetFailCount">
UPDATE users SET fail_count = 0 WHERE user_id = #{userId}
</update>
<update id="updateStatus">
UPDATE users SET status = #{status} WHERE user_id = #{userId}
</update>
<select id="selectRoleCodes" resultType="string">
SELECT r.role_code FROM role r
JOIN user_role ur ON ur.role_id = r.role_id
WHERE ur.user_id = #{userId} AND r.is_active = 'Y'
</select>
<insert id="insertUserRole">
INSERT INTO user_role (user_id, role_id) VALUES (#{userId}, #{roleId})
ON CONFLICT DO NOTHING
</insert>
<delete id="deleteUserRoles">
DELETE FROM user_role WHERE user_id = #{userId}
</delete>
</mapper>