yeg
2026-09-16 3a024caa497b8923635c02e0c8c0df07f2918f81
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.talentcard.server.business.admin;
 
import com.talentcard.server.business.DatabaseRows;
import com.talentcard.server.business.PageResult;
import com.talentcard.server.business.payment.PaymentReconciliationService;
import com.talentcard.server.common.BusinessException;
import com.talentcard.server.common.ErrorCode;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
 
import java.util.List;
import java.util.Map;
 
@Service
public class PaymentReconciliationAdminService {
    private final JdbcTemplate jdbc;
    private final PaymentReconciliationService reconciliation;
    public PaymentReconciliationAdminService(JdbcTemplate jdbc, PaymentReconciliationService reconciliation) { this.jdbc = jdbc; this.reconciliation = reconciliation; }
 
    public PageResult<Map<String, Object>> issues(String status, int page, int size) {
        int current = Math.max(1, page), limit = Math.min(Math.max(1, size), 100);
        String value = status == null || status.isBlank() ? "open" : status.trim().toLowerCase();
        if (!List.of("open", "resolved", "ignored", "all").contains(value)) throw new BusinessException(ErrorCode.BAD_REQUEST, "Invalid reconciliation status");
        boolean all = "all".equals(value);
        List<Map<String, Object>> records = DatabaseRows.normalize(jdbc.queryForList("select * from payment_reconciliation_issue" + (all ? "" : " where status = ?") + " order by detected_at desc, id desc limit ? offset ?", all ? new Object[] { limit, (current - 1) * limit } : new Object[] { value, limit, (current - 1) * limit }));
        Long total = all ? jdbc.queryForObject("select count(*) from payment_reconciliation_issue", Long.class) : jdbc.queryForObject("select count(*) from payment_reconciliation_issue where status = ?", Long.class, value);
        return new PageResult<>(records, current, limit, total == null ? 0 : total);
    }
    public Map<String, Object> close(Long id, String status, String operator) {
        String target = status == null ? "" : status.trim().toLowerCase();
        if (!List.of("resolved", "ignored").contains(target)) throw new BusinessException(ErrorCode.BAD_REQUEST, "Invalid reconciliation resolution");
        int affected = jdbc.update("update payment_reconciliation_issue set status = ?, resolved_at = now(), resolved_by = ? where id = ? and status = 'open'", target, operator == null || operator.isBlank() ? "admin" : operator.trim(), id);
        if (affected == 0) throw new BusinessException(ErrorCode.CONFLICT, "Reconciliation issue is already closed or does not exist");
        return Map.of("id", id, "status", target);
    }
    public Map<String, Object> run(int pendingAfterMinutes) { return reconciliation.reconcile(Math.max(1, Math.min(pendingAfterMinutes, 1440))); }
}