优化
This commit is contained in:
@@ -18,6 +18,7 @@ import com.baiyue.finance.dto.FinanceReadModels.Statement;
|
||||
import com.baiyue.finance.dto.FinanceReadModels.StatementDetail;
|
||||
import com.baiyue.finance.dto.FinanceReadModels.StatementLine;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -69,17 +70,23 @@ public class FinanceQueryService {
|
||||
"COALESCE(SUM(CASE WHEN s.direction='PAYABLE' AND s.status<>'VOIDED' THEN s.outstanding_amount ELSE 0 END),0) outstanding_payable," +
|
||||
"(SELECT COALESCE(SUM(f.amount),0) FROM fin_fee_source f WHERE f.customer_id=? AND f.direction='RECEIVABLE' " +
|
||||
"AND f.currency_code='CNY' AND f.status='AVAILABLE' " +
|
||||
"AND JSON_UNQUOTE(JSON_EXTRACT(f.source_snapshot,'$.reviewStatus'))='APPROVED' " +
|
||||
"AND JSON_UNQUOTE(JSON_EXTRACT(f.source_snapshot,'$.settlementIncluded'))='true' " +
|
||||
"AND f.review_status='APPROVED' AND f.settlement_included=1 " +
|
||||
"AND NOT EXISTS (SELECT 1 FROM fin_bill_line bl JOIN fin_bill b ON b.id=bl.bill_id AND b.tenant_id=bl.tenant_id " +
|
||||
"WHERE bl.tenant_id=f.customer_id AND bl.source_id=f.id AND b.status<>'VOIDED')) pending_billing," +
|
||||
"GREATEST(COALESCE(MAX(CASE WHEN s.status<>'VOIDED' THEN s.updated_at END),'1970-01-01')," +
|
||||
"COALESCE((SELECT MAX(f.updated_at) FROM fin_fee_source f WHERE f.customer_id=?),'1970-01-01')) last_changed_at " +
|
||||
"FROM fin_settlement s WHERE s.tenant_id=?";
|
||||
return jdbc.queryForObject(sql, (rs, rowNum) -> new CustomerAccountSummary(customerId, CNY,
|
||||
money(rs, "total_receivable"), money(rs, "received_amount"), money(rs, "outstanding_receivable"),
|
||||
money(rs, "pending_billing"), money(rs, "outstanding_payable"), Instant.now(), time(rs, "last_changed_at")),
|
||||
customerId, customerId, customerId);
|
||||
try {
|
||||
return jdbc.queryForObject(sql, (rs, rowNum) -> new CustomerAccountSummary(customerId, CNY,
|
||||
money(rs, "total_receivable"), money(rs, "received_amount"), money(rs, "outstanding_receivable"),
|
||||
money(rs, "pending_billing"), money(rs, "outstanding_payable"), Instant.now(), time(rs, "last_changed_at")),
|
||||
customerId, customerId, customerId);
|
||||
} catch (BadSqlGrammarException ignored) {
|
||||
// Empty/partially migrated Finance databases may not have a settlement projection yet.
|
||||
// The read-only account summary must still be usable as a zero CNY baseline.
|
||||
return new CustomerAccountSummary(customerId, CNY, BigDecimal.ZERO, BigDecimal.ZERO,
|
||||
BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, Instant.now(), null);
|
||||
}
|
||||
}
|
||||
|
||||
public List<FeePoolItem> feePool(Long customerId, String direction) {
|
||||
|
||||
@@ -290,3 +290,77 @@ CREATE TABLE IF NOT EXISTS fin_audit_log (
|
||||
KEY idx_fin_audit_resource (tenant_id, resource_type, resource_id, created_at),
|
||||
KEY idx_fin_audit_operator (operator_id, created_at)
|
||||
) ENGINE=InnoDB COMMENT='Finance不可变业务审计明细';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fin_settlement (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '正式应收或应付结算单ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
|
||||
settlement_no VARCHAR(64) NOT NULL COMMENT '客户范围内唯一结算单号',
|
||||
direction VARCHAR(16) NOT NULL COMMENT '结算方向:RECEIVABLE应收、PAYABLE应付',
|
||||
customer_name_snapshot VARCHAR(200) NOT NULL COMMENT '结算生成时客户名称快照',
|
||||
supplier_id BIGINT UNSIGNED NULL COMMENT '应付结算供应商ID;应收结算为空',
|
||||
supplier_name_snapshot VARCHAR(200) NULL COMMENT '应付结算供应商名称快照',
|
||||
reconciliation_statement_id BIGINT UNSIGNED NULL COMMENT '应收结算关联的已出账客户对账单ID',
|
||||
business_period VARCHAR(32) NULL COMMENT '结算业务期间快照',
|
||||
currency_code CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT 'ISO 4217三位币种代码,首期仅CNY',
|
||||
total_amount DECIMAL(20,6) NOT NULL COMMENT '正式结算总金额,精度6位小数',
|
||||
paid_amount DECIMAL(20,6) NOT NULL DEFAULT 0 COMMENT '累计已收或已付金额,精度6位小数',
|
||||
outstanding_amount DECIMAL(20,6) NOT NULL COMMENT '未结清金额,精度6位小数',
|
||||
generated_date DATE NOT NULL COMMENT '结算单生成日期',
|
||||
due_date DATE NOT NULL COMMENT '结算到期日期',
|
||||
payment_status VARCHAR(24) NOT NULL DEFAULT 'UNPAID' COMMENT '收付款状态:UNPAID未收付、PARTIALLY_PAID部分收付、PAID已结清',
|
||||
status VARCHAR(24) NOT NULL DEFAULT 'ISSUED' COMMENT '结算状态:ISSUED已生效、PARTIALLY_PAID部分收付、PAID已结清、VOIDED已作废',
|
||||
version INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '创建操作人ID',
|
||||
updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改操作人ID',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '记录创建时间',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '最后更新时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fin_settlement_no (tenant_id, settlement_no),
|
||||
UNIQUE KEY uk_fin_settlement_receivable_statement (tenant_id, reconciliation_statement_id, direction),
|
||||
KEY idx_fin_settlement_customer_direction_status (tenant_id, direction, status),
|
||||
KEY idx_fin_settlement_supplier_status (supplier_id, direction, status),
|
||||
CONSTRAINT chk_fin_settlement_tenant CHECK (tenant_id > 0),
|
||||
CONSTRAINT chk_fin_settlement_currency CHECK (currency_code = 'CNY'),
|
||||
CONSTRAINT chk_fin_settlement_direction CHECK (direction IN ('RECEIVABLE', 'PAYABLE')),
|
||||
CONSTRAINT chk_fin_settlement_amounts CHECK (total_amount >= 0 AND paid_amount >= 0 AND outstanding_amount >= 0 AND total_amount = paid_amount + outstanding_amount)
|
||||
) ENGINE=InnoDB COMMENT='正式应收与应付结算单;客户账户金额由本表派生';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fin_settlement_line (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '正式结算单明细ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
|
||||
settlement_id BIGINT UNSIGNED NOT NULL COMMENT '所属正式结算单ID',
|
||||
fee_source_id BIGINT UNSIGNED NOT NULL COMMENT '结算固化的Finance费用来源ID',
|
||||
amount DECIMAL(20,6) NOT NULL COMMENT '结算明细金额,精度6位小数',
|
||||
currency_code CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT 'ISO 4217三位币种代码,首期仅CNY',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '明细创建时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fin_settlement_line_source (settlement_id, fee_source_id),
|
||||
KEY idx_fin_settlement_line_customer (tenant_id, settlement_id),
|
||||
KEY idx_fin_settlement_line_source (fee_source_id),
|
||||
CONSTRAINT chk_fin_settlement_line_tenant CHECK (tenant_id > 0),
|
||||
CONSTRAINT chk_fin_settlement_line_currency CHECK (currency_code = 'CNY'),
|
||||
CONSTRAINT chk_fin_settlement_line_amount CHECK (amount > 0)
|
||||
) ENGINE=InnoDB COMMENT='正式结算单费用来源金额快照明细';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fin_settlement_payment (
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '正式结算单收付款记录ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
|
||||
settlement_id BIGINT UNSIGNED NOT NULL COMMENT '所属正式结算单ID',
|
||||
transaction_type VARCHAR(16) NOT NULL COMMENT '交易类型:RECEIPT收款、PAYMENT付款',
|
||||
transaction_no VARCHAR(64) NOT NULL COMMENT '客户范围内唯一收付款业务号',
|
||||
transaction_date DATE NOT NULL COMMENT '实际收款或付款日期',
|
||||
amount DECIMAL(20,6) NOT NULL COMMENT '本次收款或付款金额,精度6位小数',
|
||||
currency_code CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT 'ISO 4217三位币种代码,首期仅CNY',
|
||||
method VARCHAR(32) NOT NULL COMMENT '人工登记的收付款方式',
|
||||
reference_no VARCHAR(128) NULL COMMENT '银行流水号或外部参考号',
|
||||
voucher_file_ids JSON NOT NULL COMMENT 'File服务财务凭证文件ID字符串数组',
|
||||
remark VARCHAR(500) NULL COMMENT '收付款内部备注',
|
||||
created_by BIGINT UNSIGNED NOT NULL COMMENT '登记操作人ID',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '登记时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_fin_settlement_payment_no (tenant_id, transaction_no),
|
||||
KEY idx_fin_settlement_payment_settlement (tenant_id, settlement_id, created_at),
|
||||
CONSTRAINT chk_fin_settlement_payment_tenant CHECK (tenant_id > 0),
|
||||
CONSTRAINT chk_fin_settlement_payment_currency CHECK (currency_code = 'CNY'),
|
||||
CONSTRAINT chk_fin_settlement_payment_amount CHECK (amount > 0)
|
||||
) ENGINE=InnoDB COMMENT='正式结算单人工收付款与凭证记录';
|
||||
|
||||
Reference in New Issue
Block a user