完善财务费用来源与柜级分摊

This commit is contained in:
2026-09-02 17:07:03 +08:00
parent 6cd477a037
commit 3bdaba2c60
34 changed files with 625 additions and 71 deletions
@@ -23,10 +23,24 @@ CALL finance_fee_source_add_column('fin_fee_source', 'source_type',
"VARCHAR(32) NULL COMMENT '来源费用类型:INBOUND_FEE入库单费用、CONTAINER_FEE柜子费用' AFTER customer_id");
CALL finance_fee_source_add_column('fin_fee_source', 'source_no',
"VARCHAR(64) NULL COMMENT '来源入库单号或柜号快照,可为空' AFTER source_type");
CALL finance_fee_source_add_column('fin_fee_source', 'business_type',
"VARCHAR(32) NULL COMMENT '来源业务类型,如海外入仓、采购、卡车或柜级分摊' AFTER source_no");
CALL finance_fee_source_add_column('fin_fee_source', 'business_id',
"BIGINT UNSIGNED NULL COMMENT '来源业务记录ID,可为空' AFTER business_type");
CALL finance_fee_source_add_column('fin_fee_source', 'business_no',
"VARCHAR(128) NULL COMMENT '来源业务编号快照,可为空' AFTER business_id");
CALL finance_fee_source_add_column('fin_fee_source', 'inbound_code',
"VARCHAR(64) NULL COMMENT '来源入仓码快照;并非所有费用必填' AFTER business_no");
CALL finance_fee_source_add_column('fin_fee_source', 'warehouse_id',
"BIGINT UNSIGNED NULL COMMENT '来源海外仓或业务仓ID,可为空' AFTER inbound_code");
CALL finance_fee_source_add_column('fin_fee_source', 'direction',
"VARCHAR(16) NULL COMMENT '费用方向:RECEIVABLE应收、PAYABLE应付' AFTER source_no");
CALL finance_fee_source_add_column('fin_fee_source', 'container_id',
"BIGINT UNSIGNED NULL COMMENT '来源Firstleg装柜计划ID,可为空' AFTER inbound_id");
CALL finance_fee_source_add_column('fin_fee_source', 'container_booking_id',
"BIGINT UNSIGNED NULL COMMENT '来源订舱柜ID,可为空' AFTER container_id");
CALL finance_fee_source_add_column('fin_fee_source', 'container_no',
"VARCHAR(64) NULL COMMENT '真实集装箱号快照,可为空' AFTER container_booking_id");
CALL finance_fee_source_add_column('fin_fee_source', 'fee_item_code',
"VARCHAR(64) NULL COMMENT '来源费用项目编码快照' AFTER container_id");
CALL finance_fee_source_add_column('fin_fee_source', 'source_hash',
@@ -77,6 +91,8 @@ CALL finance_fee_source_add_column('fin_cost', 'source_fee_version',
"INT UNSIGNED NULL COMMENT '来源费用版本' AFTER source_fee_id");
CALL finance_fee_source_add_column('fin_cost', 'source_hash',
"CHAR(64) NULL COMMENT '来源不可变快照SHA-256' AFTER source_fee_version");
CALL finance_fee_source_add_column('fin_cost', 'warehouse_id',
"BIGINT UNSIGNED NULL COMMENT '业务直接已付成本关联仓库ID,可为空' AFTER container_id");
CALL finance_fee_source_add_column('fin_cost', 'paid_at',
"DATETIME(3) NULL COMMENT '直接已付时间' AFTER voucher_file_ids");
CALL finance_fee_source_add_column('fin_cost', 'payment_method',
@@ -86,6 +102,22 @@ CALL finance_fee_source_add_column('fin_cost', 'payment_reference_no',
DROP PROCEDURE IF EXISTS finance_fee_source_add_column;
SET @finance_fee_source_index_ddl = (
SELECT IF(
(SELECT COUNT(*) FROM information_schema.statistics
WHERE table_schema=DATABASE() AND table_name='fin_fee_source'
AND index_name='uk_fin_fee_source')=4,
'SELECT 1',
IF(EXISTS(SELECT 1 FROM information_schema.statistics
WHERE table_schema=DATABASE() AND table_name='fin_fee_source' AND index_name='uk_fin_fee_source'),
'ALTER TABLE fin_fee_source DROP INDEX uk_fin_fee_source, ADD UNIQUE KEY uk_fin_fee_source(source_system,source_type,source_fee_id,source_fee_version)',
'ALTER TABLE fin_fee_source ADD UNIQUE KEY uk_fin_fee_source(source_system,source_type,source_fee_id,source_fee_version)')
)
);
PREPARE finance_fee_source_index_stmt FROM @finance_fee_source_index_ddl;
EXECUTE finance_fee_source_index_stmt;
DEALLOCATE PREPARE finance_fee_source_index_stmt;
DROP PROCEDURE IF EXISTS finance_fee_source_add_index;
DELIMITER $$
CREATE PROCEDURE finance_fee_source_add_index()
@@ -104,7 +136,9 @@ CALL finance_fee_source_add_index();
DROP PROCEDURE IF EXISTS finance_fee_source_add_index;
ALTER TABLE fin_cost
MODIFY COLUMN cost_type VARCHAR(24) NOT NULL COMMENT '成本归属类型:SINGLE_ORDER单票、CONTAINER_SHARED整柜公共、SOURCE_DIRECT_PAID来源直接已付';
MODIFY COLUMN cost_type VARCHAR(24) NOT NULL COMMENT '成本归属类型:SINGLE_ORDER单票、CONTAINER_SHARED整柜公共、SOURCE_DIRECT_PAID来源直接已付',
MODIFY COLUMN cost_origin VARCHAR(24) NOT NULL DEFAULT 'MANUAL' COMMENT '成本来源:MANUAL人工补充、FIRSTLEG_DIRECT_PAID头程直接已付、BUSINESS_DIRECT_PAID其他业务直接已付',
MODIFY COLUMN source_hash VARCHAR(71) NULL COMMENT '来源不可变快照SHA-256,兼容sha256前缀格式';
DROP PROCEDURE IF EXISTS finance_fee_source_replace_cost_checks;
DELIMITER $$
CREATE PROCEDURE finance_fee_source_replace_cost_checks()
@@ -121,7 +155,7 @@ BEGIN
ADD CONSTRAINT chk_fin_cost_target CHECK (
(cost_type='SINGLE_ORDER' AND order_id IS NOT NULL AND container_id IS NULL)
OR (cost_type='CONTAINER_SHARED' AND container_id IS NOT NULL)
OR (cost_type='SOURCE_DIRECT_PAID' AND (order_id IS NOT NULL OR inbound_id IS NOT NULL OR container_id IS NOT NULL))
OR (cost_type='SOURCE_DIRECT_PAID' AND (order_id IS NOT NULL OR inbound_id IS NOT NULL OR container_id IS NOT NULL OR warehouse_id IS NOT NULL))
),
ADD CONSTRAINT chk_fin_cost_origin CHECK (
(cost_origin='MANUAL' AND source_system IS NULL AND source_type IS NULL AND source_fee_id IS NULL AND source_fee_version IS NULL AND source_hash IS NULL)
@@ -129,6 +163,10 @@ BEGIN
AND source_fee_id IS NOT NULL AND source_fee_version IS NOT NULL AND source_hash IS NOT NULL
AND status IN ('CONFIRMED','VOIDED') AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER'))
OR (cost_origin='BUSINESS_DIRECT_PAID' AND source_system NOT IN ('', 'FIRSTLEG') AND source_type IS NOT NULL
AND source_fee_id IS NOT NULL AND source_fee_version IS NOT NULL AND source_hash IS NOT NULL
AND status IN ('CONFIRMED','VOIDED') AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER'))
);
END$$
DELIMITER ;
@@ -152,12 +190,12 @@ ALTER TABLE fin_fee_source
MODIFY COLUMN source_type VARCHAR(32) NOT NULL COMMENT '来源费用类型:INBOUND_FEE入库单费用、CONTAINER_FEE柜子费用',
MODIFY COLUMN direction VARCHAR(16) NOT NULL COMMENT '费用方向:RECEIVABLE应收、PAYABLE应付',
MODIFY COLUMN fee_item_code VARCHAR(64) NOT NULL COMMENT '来源费用项目编码快照',
MODIFY COLUMN source_hash CHAR(64) NOT NULL COMMENT 'Firstleg费用来源完整快照SHA-256哈希',
MODIFY COLUMN source_snapshot JSON NOT NULL COMMENT 'Firstleg费用来源完整不可变JSON快照',
MODIFY COLUMN source_hash VARCHAR(71) NOT NULL COMMENT '业务费用来源完整快照SHA-256哈希,兼容sha256前缀格式',
MODIFY COLUMN source_snapshot JSON NOT NULL COMMENT '业务费用来源完整不可变JSON快照',
MODIFY COLUMN status VARCHAR(16) NOT NULL DEFAULT 'AVAILABLE' COMMENT '费用来源状态:AVAILABLE可结算、SUPERSEDED已被新版本替代、VOIDED已作废',
MODIFY COLUMN updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '来源状态最后更新时间,数据修改时自动刷新';
ALTER TABLE fin_inbox_event
MODIFY COLUMN payload_hash CHAR(64) NOT NULL COMMENT '规范化事件内容SHA-256哈希,用于同事件ID冲突检测',
MODIFY COLUMN payload_hash VARCHAR(71) NOT NULL COMMENT '规范化事件内容SHA-256哈希,兼容sha256前缀格式',
MODIFY COLUMN status VARCHAR(16) NOT NULL DEFAULT 'RECEIVED' COMMENT '事件处理状态:RECEIVED已接收、PROCESSED已完成、FAILED处理失败';
DROP PROCEDURE IF EXISTS finance_fee_source_assert_schema;
@@ -187,7 +225,7 @@ BEGIN
WHERE table_schema = DATABASE() AND table_name = 'fin_cost'
AND column_name IN ('cost_origin','source_system','source_type','source_fee_id',
'source_fee_version','source_hash','paid_at','payment_method',
'payment_reference_no')) <> 9 THEN
'payment_reference_no','warehouse_id')) <> 10 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Finance直接已付成本字段不完整';
END IF;
IF (SELECT COUNT(*) FROM information_schema.statistics
+13 -8
View File
@@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS fin_fee_source (
payment_method VARCHAR(32) NULL COMMENT 'DIRECT_PAID付款方式:ONLINE、BANK_TRANSFER、CASH、OTHER',
payment_reference_no VARCHAR(128) NULL COMMENT 'DIRECT_PAID付款流水号',
payment_voucher_file_ids JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组',
source_hash CHAR(64) NOT NULL COMMENT 'Firstleg费用来源完整快照SHA-256哈希',
source_hash VARCHAR(71) NOT NULL COMMENT '业务费用来源完整快照SHA-256哈希,兼容sha256前缀格式',
source_snapshot JSON NOT NULL COMMENT 'Firstleg费用来源完整不可变JSON快照',
review_status VARCHAR(16) NOT NULL DEFAULT 'DRAFT' COMMENT 'Finance费用状态:DRAFT草稿、PENDING待审核、APPROVED已通过、REJECTED已驳回',
review_reason VARCHAR(500) NULL COMMENT 'Finance费用审核说明或驳回原因',
@@ -61,7 +61,7 @@ CREATE TABLE IF NOT EXISTS fin_inbox_event (
source_system VARCHAR(32) NOT NULL COMMENT '事件来源系统标识',
event_type VARCHAR(64) NOT NULL COMMENT '来源事件类型',
payload JSON NOT NULL COMMENT '来源事件原始JSON载荷快照',
payload_hash CHAR(64) NOT NULL COMMENT '规范化事件内容SHA-256哈希,用于同事件ID冲突检测',
payload_hash VARCHAR(71) NOT NULL COMMENT '规范化事件内容SHA-256哈希,兼容sha256前缀格式',
result_resource_id BIGINT UNSIGNED NULL COMMENT '成功处理生成或定位的费用来源快照ID',
error_code VARCHAR(64) NULL COMMENT '处理失败时的稳定FIN错误码',
status VARCHAR(16) NOT NULL DEFAULT 'RECEIVED' COMMENT '事件处理状态:RECEIVED已接收、PROCESSED已完成、FAILED处理失败',
@@ -221,21 +221,22 @@ CREATE TABLE IF NOT EXISTS fin_cost (
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
cost_no VARCHAR(64) NOT NULL COMMENT '客户范围内唯一成本编号',
cost_type VARCHAR(24) NOT NULL COMMENT '成本归属类型:SINGLE_ORDER单票、CONTAINER_SHARED整柜公共、SOURCE_DIRECT_PAID来源直接已付',
cost_origin VARCHAR(24) NOT NULL DEFAULT 'MANUAL' COMMENT '成本来源:MANUAL人工补充、FIRSTLEG_DIRECT_PAID头程直接已付',
source_system VARCHAR(32) NULL COMMENT '来源系统,头程直接已付固定FIRSTLEG',
cost_origin VARCHAR(24) NOT NULL DEFAULT 'MANUAL' COMMENT '成本来源:MANUAL人工补充、FIRSTLEG_DIRECT_PAID头程直接已付、BUSINESS_DIRECT_PAID其他业务直接已付',
source_system VARCHAR(32) NULL COMMENT '直接已付来源系统,如FIRSTLEG或LASTLEG',
source_type VARCHAR(32) NULL COMMENT '来源费用类型快照',
source_fee_id BIGINT UNSIGNED NULL COMMENT '来源费用ID',
source_fee_version INT UNSIGNED NULL COMMENT '来源费用版本',
source_hash CHAR(64) NULL COMMENT '来源不可变快照SHA-256',
source_hash VARCHAR(71) NULL COMMENT '来源不可变快照SHA-256,兼容sha256前缀格式',
order_id BIGINT UNSIGNED NULL COMMENT '成本归属的头程订单ID,单票成本必填',
inbound_id BIGINT UNSIGNED NULL COMMENT '成本关联的入库单ID,可为空',
container_id BIGINT UNSIGNED NULL COMMENT 'Firstleg装柜计划ID,整柜公共成本必填',
warehouse_id BIGINT UNSIGNED NULL COMMENT '业务直接已付成本关联仓库ID,可为空',
supplier_id BIGINT UNSIGNED NULL COMMENT 'Warehouse公共往来单位或供应商引用ID',
supplier_name_snapshot VARCHAR(200) NULL COMMENT '登记成本时供应商或成本对象名称快照',
fee_item_code VARCHAR(64) NOT NULL COMMENT '成本费用项目编码快照',
fee_item_name VARCHAR(200) NOT NULL COMMENT '成本费用项目名称快照',
currency_code CHAR(3) NOT NULL DEFAULT 'CNY' COMMENT 'ISO 4217三位币种代码,首期仅CNY',
cost_amount DECIMAL(20,6) NOT NULL COMMENT '成本总金额;仅FIRSTLEG_DIRECT_PAID且CONFIRMED计入已线下支付供应商款',
cost_amount DECIMAL(20,6) NOT NULL COMMENT '成本总金额;来源直接已付且CONFIRMED计入已线下支付供应商款',
voucher_file_ids JSON NOT NULL COMMENT 'File服务财务凭证文件ID字符串数组JSON',
paid_at DATETIME(3) NULL COMMENT '直接已付时间;人工补充成本可为空',
payment_method VARCHAR(32) NULL COMMENT '直接已付方式:ONLINE、BANK_TRANSFER、CASH、OTHER',
@@ -265,7 +266,7 @@ CREATE TABLE IF NOT EXISTS fin_cost (
CONSTRAINT chk_fin_cost_target CHECK (
(cost_type = 'SINGLE_ORDER' AND order_id IS NOT NULL AND container_id IS NULL)
OR (cost_type = 'CONTAINER_SHARED' AND container_id IS NOT NULL)
OR (cost_type = 'SOURCE_DIRECT_PAID' AND (order_id IS NOT NULL OR inbound_id IS NOT NULL OR container_id IS NOT NULL))
OR (cost_type = 'SOURCE_DIRECT_PAID' AND (order_id IS NOT NULL OR inbound_id IS NOT NULL OR container_id IS NOT NULL OR warehouse_id IS NOT NULL))
),
CONSTRAINT chk_fin_cost_origin CHECK (
(cost_origin='MANUAL' AND source_system IS NULL AND source_type IS NULL AND source_fee_id IS NULL AND source_fee_version IS NULL AND source_hash IS NULL)
@@ -273,8 +274,12 @@ CREATE TABLE IF NOT EXISTS fin_cost (
AND source_fee_id IS NOT NULL AND source_fee_version IS NOT NULL AND source_hash IS NOT NULL
AND status IN ('CONFIRMED','VOIDED') AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER'))
OR (cost_origin='BUSINESS_DIRECT_PAID' AND source_system NOT IN ('', 'FIRSTLEG') AND source_type IS NOT NULL
AND source_fee_id IS NOT NULL AND source_fee_version IS NOT NULL AND source_hash IS NOT NULL
AND status IN ('CONFIRMED','VOIDED') AND paid_at IS NOT NULL
AND payment_method IN ('ONLINE','BANK_TRANSFER','CASH','OTHER'))
)
) ENGINE=InnoDB COMMENT='成本事实;人工补充成本与头程直接已付来源成本统一留痕';
) ENGINE=InnoDB COMMENT='成本事实;人工补充成本与业务直接已付来源成本统一留痕';
CREATE TABLE IF NOT EXISTS fin_cost_allocation (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',