This commit is contained in:
2026-08-19 09:55:29 +08:00
parent a381d443da
commit 80527fa15f
10 changed files with 82 additions and 31 deletions
@@ -2,6 +2,7 @@ package com.baiyue.firstleg.service;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
@@ -24,6 +25,7 @@ public class FirstlegDocumentNumberGenerator {
private final JdbcTemplate jdbc;
private final Clock clock;
@Autowired
public FirstlegDocumentNumberGenerator(JdbcTemplate jdbc) {
this(jdbc, Clock.system(BUSINESS_ZONE));
}
@@ -73,7 +73,7 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
direction VARCHAR(16) NOT NULL COMMENT '费用方向:RECEIVABLE应收、PAYABLE应付',
supplier_id BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空',
supplier_name VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空',
supplier_category VARCHAR(16) NULL COMMENT '费用项目供应商类别快照;应收为空',
supplier_category VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商',
business_date DATE NOT NULL COMMENT '费用业务日期',
amount DECIMAL(18,2) NOT NULL COMMENT 'CNY费用金额',
currency CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT '币种,首期固定CNY',
@@ -100,37 +100,43 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
) ENGINE=InnoDB COMMENT='柜次级人工应收应付费用来源;审核通过后自动同步Finance';
CREATE TABLE IF NOT EXISTS fl_container_fee_source_snapshot (
id BIGINT UNSIGNED NOT NULL,
source_fee_id BIGINT UNSIGNED NOT NULL,
source_version INT UNSIGNED NOT NULL,
tenant_id BIGINT UNSIGNED NOT NULL,
loading_plan_id BIGINT UNSIGNED NOT NULL,
container_booking_id BIGINT UNSIGNED NULL,
container_no VARCHAR(64) NULL,
fee_item_id BIGINT UNSIGNED NOT NULL,
fee_item_code VARCHAR(50) NOT NULL,
fee_item_name VARCHAR(128) NOT NULL,
direction VARCHAR(16) NOT NULL,
supplier_id BIGINT UNSIGNED NULL,
supplier_name VARCHAR(200) NULL,
supplier_category VARCHAR(16) NULL,
business_date DATE NOT NULL,
amount DECIMAL(18,2) NOT NULL,
currency CHAR(3) NOT NULL DEFAULT 'CNY',
review_status VARCHAR(16) NOT NULL,
reviewed_at DATETIME(3) NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
id BIGINT UNSIGNED NOT NULL COMMENT '柜次费用快照ID',
source_fee_id BIGINT UNSIGNED NOT NULL COMMENT '柜次费用来源ID',
source_version INT UNSIGNED NOT NULL COMMENT '费用来源版本',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
loading_plan_id BIGINT UNSIGNED NOT NULL COMMENT '柜次ID',
container_booking_id BIGINT UNSIGNED NULL COMMENT '订舱柜ID快照',
container_no VARCHAR(64) NULL COMMENT '柜号快照',
fee_item_id BIGINT UNSIGNED NOT NULL COMMENT '费用项目ID快照',
fee_item_code VARCHAR(50) NOT NULL COMMENT '费用项目编码快照',
fee_item_name VARCHAR(128) NOT NULL COMMENT '费用项目名称快照',
direction VARCHAR(16) NOT NULL COMMENT '费用方向',
supplier_id BIGINT UNSIGNED NULL COMMENT 'Warehouse供应商ID快照',
supplier_name VARCHAR(200) NULL COMMENT 'Warehouse供应商名称快照',
supplier_category VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商',
business_date DATE NOT NULL COMMENT '费用业务日期',
amount DECIMAL(18,2) NOT NULL COMMENT 'CNY费用金额',
currency CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT '币种,首期固定CNY',
review_status VARCHAR(16) NOT NULL COMMENT '审核状态快照',
reviewed_at DATETIME(3) NULL COMMENT '审核时间快照',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '快照创建时间',
PRIMARY KEY (id),
UNIQUE KEY uk_container_fee_source_version (loading_plan_id, source_fee_id, source_version),
KEY idx_container_fee_snapshot_tenant (tenant_id, loading_plan_id)
) ENGINE=InnoDB COMMENT='柜次费用不可变版本快照';
CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_id', "BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空' AFTER direction");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_name', "VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空' AFTER supplier_id");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_category', "VARCHAR(16) NULL COMMENT '费用项目供应商类别快照;应收为空' AFTER supplier_name");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_id', "BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空' AFTER direction");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_name', "VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空' AFTER supplier_id");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_category', "VARCHAR(16) NULL COMMENT '费用项目供应商类别快照;应收为空' AFTER supplier_name");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_id',
"BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空' AFTER direction");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_name',
"VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空' AFTER supplier_id");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'supplier_category',
"VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商' AFTER supplier_name");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_id',
"BIGINT UNSIGNED NULL COMMENT '应付Warehouse供应商ID快照;应收为空' AFTER direction");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_name',
"VARCHAR(200) NULL COMMENT '应付Warehouse供应商名称快照;应收为空' AFTER supplier_id");
CALL firstleg_finance_add_column('fl_inbound_fee_detail', 'supplier_category',
"VARCHAR(16) NULL COMMENT '费用项目供应商类别约束快照;为空表示任意启用供应商' AFTER supplier_name");
DROP PROCEDURE IF EXISTS firstleg_finance_add_column;
DROP PROCEDURE IF EXISTS firstleg_finance_assert_schema;
@@ -2,6 +2,7 @@ package com.baiyue.firstleg.service;
import com.baiyue.common.core.exception.BizException;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import java.time.Clock;
@@ -19,6 +20,18 @@ class FirstlegDocumentNumberGeneratorTest {
private static final Clock CLOCK = Clock.fixed(
Instant.parse("2026-08-18T02:00:00Z"), ZoneId.of("Asia/Shanghai"));
@Test
void startsAsASpringBeanWhenTheTestClockConstructorAlsoExists() {
JdbcTemplate jdbc = mock(JdbcTemplate.class);
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
context.registerBean(JdbcTemplate.class, () -> jdbc);
context.register(FirstlegDocumentNumberGenerator.class);
context.refresh();
assertThat(context.getBean(FirstlegDocumentNumberGenerator.class)).isNotNull();
}
}
@Test
void formatsAllOperationalDocumentPrefixes() {
JdbcTemplate jdbc = mock(JdbcTemplate.class);