This commit is contained in:
2026-08-12 16:58:45 +08:00
parent 600f3b7861
commit 4562e3f1d1
11 changed files with 146 additions and 8 deletions
@@ -21,6 +21,8 @@ public final class ContainerFeeDetailDtos {
@NotNull @DecimalMin("0.00") BigDecimal amount,
@NotBlank @Pattern(regexp = "CNY") String currency,
@NotNull Boolean settlementIncluded,
Long partnerId,
@Size(max = 200) String partnerName,
@Size(max = 500) String remark
) {
}
@@ -33,11 +35,13 @@ public final class ContainerFeeDetailDtos {
@NotNull @DecimalMin("0.00") BigDecimal amount,
@NotBlank @Pattern(regexp = "CNY") String currency,
@NotNull Boolean settlementIncluded,
Long partnerId,
@Size(max = 200) String partnerName,
@Size(max = 500) String remark
) {
public SaveRequest values() {
return new SaveRequest(feeItemId, direction, businessDate, amount, currency,
settlementIncluded, remark);
settlementIncluded, partnerId, partnerName, remark);
}
}
@@ -25,6 +25,8 @@ public class ContainerFeeDetailEntity {
private String feeItemCodeSnapshot;
private String feeItemNameSnapshot;
private String direction;
private Long partnerId;
private String partnerName;
private LocalDate businessDate;
private BigDecimal amount;
private String currency;
@@ -13,6 +13,7 @@ import com.baiyue.firstleg.repository.SmartLoadingRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.math.RoundingMode;
import java.time.LocalDateTime;
@@ -140,10 +141,17 @@ public class ContainerFeeDetailService {
private static void apply(ContainerFeeDetailEntity value, FeeItemEntity item,
SaveRequest request, long operatorId) {
if ("PAYABLE".equals(request.direction())
&& (request.partnerId() == null || request.partnerId() <= 0
|| !StringUtils.hasText(request.partnerName()))) {
throw new BizException(ResultCode.VALIDATION_FAILED, "应付柜次费用必须选择有效往来单位");
}
value.setFeeItemId(item.getId());
value.setFeeItemCodeSnapshot(item.getFeeCode());
value.setFeeItemNameSnapshot(item.getFeeTypeName());
value.setDirection(request.direction());
value.setPartnerId("PAYABLE".equals(request.direction()) ? request.partnerId() : null);
value.setPartnerName("PAYABLE".equals(request.direction()) ? request.partnerName().trim() : null);
value.setBusinessDate(request.businessDate());
value.setAmount(request.amount().setScale(2, RoundingMode.HALF_UP));
value.setCurrency(request.currency());
@@ -61,11 +61,13 @@ public class FinanceFeeSourceSnapshotService {
String canonical = String.join("|", "CONTAINER_FEE", String.valueOf(feeId),
String.valueOf(version), String.valueOf(detail.getTenantId()), String.valueOf(containerId),
nullSafe(detail.getFeeItemCodeSnapshot()), nullSafe(detail.getDirection()),
nullSafe(detail.getPartnerId()), nullSafe(detail.getPartnerName()),
detail.getAmount().toPlainString(), nullSafe(detail.getCurrency()),
String.valueOf(detail.getSettlementIncluded()));
return new FinanceFeeSourceSnapshot(detail.getTenantId(), "CONTAINER_FEE", feeId,
version, null, null, null, containerId, detail.getContainerBookingId(),
detail.getContainerNo(), detail.getTenantId(), null, null, null, detail.getFeeItemId(),
detail.getContainerNo(), detail.getTenantId(), null, detail.getPartnerId(),
detail.getPartnerName(), detail.getFeeItemId(),
detail.getFeeItemCodeSnapshot(), detail.getFeeItemNameSnapshot(), detail.getDirection(),
detail.getBusinessDate(), detail.getCurrency(), detail.getAmount(), detail.getReviewStatus(),
publicationStatus, Boolean.TRUE.equals(detail.getSettlementIncluded()),
@@ -37,8 +37,6 @@ CALL firstleg_finance_add_column('fl_inbound_outbox', 'locked_by',
CALL firstleg_finance_add_column('fl_inbound_outbox', 'last_error',
"VARCHAR(500) NULL COMMENT '最近一次投递失败摘要,不记录令牌' AFTER locked_by");
DROP PROCEDURE IF EXISTS firstleg_finance_add_column;
DROP PROCEDURE IF EXISTS firstleg_finance_add_index;
DELIMITER $$
CREATE PROCEDURE firstleg_finance_add_index(
@@ -73,6 +71,8 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
fee_item_code_snapshot VARCHAR(50) NOT NULL COMMENT '费用项目稳定编码快照',
fee_item_name_snapshot VARCHAR(128) NOT NULL COMMENT '费用项目名称快照',
direction VARCHAR(16) NOT NULL COMMENT '费用方向:RECEIVABLE应收、PAYABLE应付',
partner_id BIGINT UNSIGNED NULL COMMENT '应付往来单位ID快照;应收为空',
partner_name VARCHAR(200) 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',
@@ -99,6 +99,12 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
CONSTRAINT chk_container_fee_source CHECK (source_status IN ('ACTIVE', 'VOIDED'))
) ENGINE=InnoDB COMMENT='柜次级人工应收应付费用来源;审核通过且参与结算后同步Finance';
CALL firstleg_finance_add_column('fl_container_fee_detail', 'partner_id',
"BIGINT UNSIGNED NULL COMMENT '应付往来单位ID快照;应收为空' AFTER direction");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'partner_name',
"VARCHAR(200) NULL COMMENT '应付往来单位名称快照;应收为空' AFTER partner_id");
DROP PROCEDURE IF EXISTS firstleg_finance_add_column;
DROP PROCEDURE IF EXISTS firstleg_finance_assert_schema;
DELIMITER $$
CREATE PROCEDURE firstleg_finance_assert_schema()
@@ -113,6 +119,11 @@ BEGIN
WHERE table_schema = DATABASE() AND table_name = 'fl_container_fee_detail') THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:柜次费用表不存在';
END IF;
IF (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'fl_container_fee_detail'
AND column_name IN ('partner_id', 'partner_name')) <> 2 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Firstleg Finance迁移失败:柜次费用往来单位快照字段不完整';
END IF;
END$$
DELIMITER ;
CALL firstleg_finance_assert_schema();