동기화
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package com.ga.api.controller.accounting;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class CloseJournalReq {
|
||||
@NotEmpty
|
||||
private List<Long> entryIds;
|
||||
@NotBlank
|
||||
private String journalNo;
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.ga.api.controller.accounting;
|
||||
|
||||
import com.ga.api.service.accounting.ContractAccountingService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.accounting.ContractAccountingEntryResp;
|
||||
import com.ga.core.vo.accounting.ContractAccountingEntrySearchParam;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "계약 회계 분개")
|
||||
@RestController
|
||||
@RequestMapping("/api/accounting-entries")
|
||||
@RequiredArgsConstructor
|
||||
public class ContractAccountingController {
|
||||
|
||||
private final ContractAccountingService service;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "분개 엔트리 목록 조회")
|
||||
@RequirePermission(menu = "ACCOUNTING_JOURNAL", perm = "READ")
|
||||
public ApiResponse<PageResponse<ContractAccountingEntryResp>> list(
|
||||
@ModelAttribute ContractAccountingEntrySearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@PostMapping("/generate")
|
||||
@Operation(summary = "자동 분개 생성 (paymentIds 또는 settleMonth)")
|
||||
@RequirePermission(menu = "ACCOUNTING_JOURNAL", perm = "CREATE")
|
||||
@DataChangeLog(menu = "ACCOUNTING_JOURNAL", table = "contract_accounting_entry")
|
||||
public ApiResponse<Integer> generate(@RequestBody GenerateEntriesReq req) {
|
||||
return ApiResponse.ok(service.generateFromPayments(req));
|
||||
}
|
||||
|
||||
@PutMapping("/close")
|
||||
@Operation(summary = "분개 마감 처리")
|
||||
@RequirePermission(menu = "ACCOUNTING_JOURNAL", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "ACCOUNTING_JOURNAL", table = "contract_accounting_entry")
|
||||
public ApiResponse<Integer> close(@Valid @RequestBody CloseJournalReq req) {
|
||||
return ApiResponse.ok(service.closeJournal(req));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ga.api.controller.accounting;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class GenerateEntriesReq {
|
||||
private List<Long> paymentIds;
|
||||
private String settleMonth;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.ga.api.controller.income;
|
||||
|
||||
import com.ga.api.service.income.AgentAnnualIncomeService;
|
||||
import com.ga.common.annotation.DataChangeLog;
|
||||
import com.ga.common.annotation.RequirePermission;
|
||||
import com.ga.common.model.ApiResponse;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.vo.income.AgentAnnualIncomeResp;
|
||||
import com.ga.core.vo.income.AgentAnnualIncomeSearchParam;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "연간 사업소득")
|
||||
@RestController
|
||||
@RequestMapping("/api/agent-annual-incomes")
|
||||
@RequiredArgsConstructor
|
||||
public class AgentAnnualIncomeController {
|
||||
|
||||
private final AgentAnnualIncomeService service;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "연간소득 목록 조회")
|
||||
@RequirePermission(menu = "ANNUAL_INCOME", perm = "READ")
|
||||
public ApiResponse<PageResponse<AgentAnnualIncomeResp>> list(
|
||||
@ModelAttribute AgentAnnualIncomeSearchParam param) {
|
||||
return ApiResponse.ok(service.list(param));
|
||||
}
|
||||
|
||||
@GetMapping("/{agentId}/{settleYear}")
|
||||
@Operation(summary = "연간소득 상세 조회")
|
||||
@RequirePermission(menu = "ANNUAL_INCOME", perm = "READ")
|
||||
public ApiResponse<AgentAnnualIncomeResp> detail(
|
||||
@PathVariable Long agentId,
|
||||
@PathVariable int settleYear) {
|
||||
return ApiResponse.ok(service.detail(agentId, settleYear));
|
||||
}
|
||||
|
||||
@PostMapping("/regenerate")
|
||||
@Operation(summary = "연도 전체 재집계")
|
||||
@RequirePermission(menu = "ANNUAL_INCOME", perm = "EXECUTE")
|
||||
@DataChangeLog(menu = "ANNUAL_INCOME", table = "agent_annual_income")
|
||||
public ApiResponse<Integer> regenerate(@RequestParam int year) {
|
||||
return ApiResponse.ok(service.regenerate(year));
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,14 @@ public class RegulatoryLimitController {
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@PutMapping("/{limitId}/activate")
|
||||
@RequirePermission(menu = "REGULATORY_LIMIT", perm = "UPDATE")
|
||||
@DataChangeLog(menu = "REGULATORY_LIMIT", table = "regulatory_limit")
|
||||
public ApiResponse<Void> activate(@PathVariable Long limitId) {
|
||||
limitService.activate(limitId);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/check-contract")
|
||||
@RequirePermission(menu = "REGULATORY_LIMIT", perm = "READ")
|
||||
public ApiResponse<ViolationResult> checkContract(@Valid @RequestBody ContractLimitCheckReq req) {
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.ga.api.service.accounting;
|
||||
|
||||
import com.ga.api.controller.accounting.CloseJournalReq;
|
||||
import com.ga.api.controller.accounting.GenerateEntriesReq;
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.accounting.ContractAccountingEntryMapper;
|
||||
import com.ga.core.mapper.settle.PaymentMapper;
|
||||
import com.ga.core.vo.accounting.ContractAccountingEntryResp;
|
||||
import com.ga.core.vo.accounting.ContractAccountingEntrySearchParam;
|
||||
import com.ga.core.vo.accounting.ContractAccountingEntryVO;
|
||||
import com.ga.core.vo.settle.PaymentVO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class ContractAccountingService {
|
||||
|
||||
private static final String DEBIT_ACCOUNT = "8350"; // 지급수수료
|
||||
private static final String CREDIT_ACCOUNT = "2530"; // 미지급금
|
||||
|
||||
private final ContractAccountingEntryMapper entryMapper;
|
||||
private final PaymentMapper paymentMapper;
|
||||
|
||||
public PageResponse<ContractAccountingEntryResp> list(ContractAccountingEntrySearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(entryMapper.selectList(param));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int generateFromPayments(GenerateEntriesReq req) {
|
||||
List<PaymentVO> payments = resolvePayments(req);
|
||||
if (payments.isEmpty()) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
|
||||
List<ContractAccountingEntryVO> entries = new ArrayList<>(payments.size());
|
||||
for (PaymentVO p : payments) {
|
||||
entries.add(buildEntry(p));
|
||||
}
|
||||
return entryMapper.insertBatch(entries);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int closeJournal(CloseJournalReq req) {
|
||||
if (req.getEntryIds() == null || req.getEntryIds().isEmpty()) {
|
||||
throw new BizException(ErrorCode.INVALID_PARAMETER);
|
||||
}
|
||||
return entryMapper.closeJournal(req.getEntryIds(), req.getJournalNo());
|
||||
}
|
||||
|
||||
private List<PaymentVO> resolvePayments(GenerateEntriesReq req) {
|
||||
if (req.getPaymentIds() != null && !req.getPaymentIds().isEmpty()) {
|
||||
List<PaymentVO> result = new ArrayList<>();
|
||||
for (Long id : req.getPaymentIds()) {
|
||||
PaymentVO p = paymentMapper.selectById(id);
|
||||
if (p != null) result.add(p);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (req.getSettleMonth() != null && !req.getSettleMonth().isBlank()) {
|
||||
return paymentMapper.selectBySettleMonth(req.getSettleMonth());
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private ContractAccountingEntryVO buildEntry(PaymentVO p) {
|
||||
ContractAccountingEntryVO vo = new ContractAccountingEntryVO();
|
||||
vo.setPaymentId(p.getPaymentId());
|
||||
vo.setEntryDate(LocalDate.now());
|
||||
vo.setDebitAccount(DEBIT_ACCOUNT);
|
||||
vo.setCreditAccount(CREDIT_ACCOUNT);
|
||||
vo.setAmount(p.getNetAmount() != null ? p.getNetAmount() : p.getPayAmount());
|
||||
vo.setDescription("commission payment " + p.getPaymentId());
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ga.api.service.income;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import com.ga.common.exception.ErrorCode;
|
||||
import com.ga.common.model.PageResponse;
|
||||
import com.ga.core.mapper.income.AgentAnnualIncomeMapper;
|
||||
import com.ga.core.vo.income.AgentAnnualIncomeResp;
|
||||
import com.ga.core.vo.income.AgentAnnualIncomeSearchParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class AgentAnnualIncomeService {
|
||||
|
||||
private final AgentAnnualIncomeMapper mapper;
|
||||
|
||||
public PageResponse<AgentAnnualIncomeResp> list(AgentAnnualIncomeSearchParam param) {
|
||||
param.startPage();
|
||||
return PageResponse.of(mapper.selectList(param));
|
||||
}
|
||||
|
||||
public AgentAnnualIncomeResp detail(Long agentId, int settleYear) {
|
||||
AgentAnnualIncomeResp resp = mapper.selectDetailById(agentId, settleYear);
|
||||
if (resp == null) throw new BizException(ErrorCode.NOT_FOUND);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int regenerate(int year) {
|
||||
return mapper.upsertAggregate(year);
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,24 @@ public class RegulatoryLimitService {
|
||||
limitMapper.updateStatus(limitId, false);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void activate(Long limitId) {
|
||||
RegulatoryLimitVO existing = limitMapper.selectById(limitId);
|
||||
if (existing == null) {
|
||||
throw new BizException(ErrorCode.NOT_FOUND);
|
||||
}
|
||||
if (Boolean.TRUE.equals(existing.getIsActive())) {
|
||||
throw new BizException(ErrorCode.INVALID_PARAMETER);
|
||||
}
|
||||
String today = LocalDate.now().format(DATE_FMT);
|
||||
RegulatoryLimitVO duplicate = limitMapper.selectActiveByType(
|
||||
existing.getLimitType(), existing.getProductCategory(), today);
|
||||
if (duplicate != null) {
|
||||
throw new BizException(ErrorCode.DUPLICATE_DATA);
|
||||
}
|
||||
limitMapper.updateStatus(limitId, true);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public RegulatoryLimitVO selectActiveByType(String limitType, String productCategory, String baseDate) {
|
||||
return limitMapper.selectActiveByType(limitType, productCategory, baseDate);
|
||||
|
||||
Reference in New Issue
Block a user