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

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
+1 -1
View File
@@ -27,7 +27,7 @@
| 费用项目与价格簿 | `controller/PlatformFeeItemController.java`、`PlatformPriceBookController.java`、`MerchantPriceBookController.java` |
| 价格簿查询内部切片 | `pricebookquery/application/port/in/PriceBookQueryUseCase.java`、`application/PriceBookQueryService.java`、`application/port/out/PriceBookQueryReader.java`、`adapter/out/persistence/PriceBookQueryMapper.java`;查询行模型位于 `application/model/PriceBookQueryRows.java` |
| 财务费用来源快照 | `controller/InternalFinanceFeeSourceController.java`;入库费用与柜次费用分别按来源 ID、版本向 Finance 提供不可变快照 |
| 柜次费用明细 | `controller/PlatformContainerFeeDetailController.java`、`service/ContainerFeeDetailService.java`、`dto/ContainerFeeDetailDtos.java`;Admin 消费端见 `../../apps/admin-web/src/modules/loading-lists/api/containerFees.ts` |
| 柜次费用明细 | `controller/PlatformContainerFeeDetailController.java`、`service/ContainerFeeDetailService.java`、`dto/ContainerFeeDetailDtos.java`;跨客户公共柜费使用 `allocation-groups` 按真实客户和订单原子分摊,入仓ID/入仓码同时填写或同时留空;契约 `src/main/resources/openapi/container-fees-v1.yaml`;Admin 消费端见 `../../apps/admin-web/src/modules/loading-lists/api/containerFees.ts` |
| 财务整柜成本分摊快照 | `loading/controller/InternalFinanceCostSnapshotController.java`、`loading/service/FinanceCostSnapshotService.java` |
| 分柜、预装、真实柜号后补与正式装柜清单生命周期 | `split/controller/PlatformSplitPreloadController.java`、`controller/PlatformLoadingListController.java`、`service/LoadingListService.java`;契约 `src/main/resources/openapi/loading-lists-v1.yaml`,详情阶段先查 `/loading-plans/{planId}/lifecycle`。创建柜次时原子生成唯一预装计划,加入入仓码明细时同步创建入库预装聚合与关联,不设推送步骤;同一 `planId` 在 `EDITING/LOADING` 返回 `PRELOAD`,`COMPLETED` 返回 `LOADING_LIST`。订舱关联、预装确认和 PDA task 创建不依赖真实集装箱号;可在 `EDITING/LOADING` 首次补录,最终 PDA 完成前必须存在;已有值纠正仅限 `EDITING` 且任务未领取、无物理作业事实 |
| 同柜不可拆组 | `loading/coload/controller/PlatformColoadGroupController.java`、`service/ColoadGroupService.java`、`persistence/ColoadGroupMapper.java`;契约 `src/main/resources/openapi/coload-groups-v1.yaml`。请求按订单 ID 建组,服务端冻结每票全部 `WAIT_SPLIT` 可用入仓片段与满箱数;仅要求同国内仓、同渠道,允许跨客户及不同目的仓港;分配、移除、取消均保持整组原子 |
@@ -51,6 +51,7 @@ public class PlatformContainerFeeDetailController {
public ApiResponse<List<ContainerFeeDetailEntity>> createAllocationGroup(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long loadingPlanId,
@Valid @RequestBody AllocationGroupRequest request) {
FirstlegScopeGuard.platform(user);
return ApiResponse.success(service.createAllocationGroup(loadingPlanId, user.userId(), request));
}
@@ -59,6 +60,7 @@ public class PlatformContainerFeeDetailController {
public ApiResponse<List<ContainerFeeDetailEntity>> approveAllocationGroup(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long loadingPlanId,
@PathVariable long groupId) {
FirstlegScopeGuard.platform(user);
return ApiResponse.success(service.approveAllocationGroup(loadingPlanId, groupId, user.userId(), user.username()));
}
@@ -67,6 +69,7 @@ public class PlatformContainerFeeDetailController {
public ApiResponse<List<ContainerFeeDetailEntity>> rejectAllocationGroup(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long loadingPlanId,
@PathVariable long groupId, @Valid @RequestBody RejectRequest request) {
FirstlegScopeGuard.platform(user);
return ApiResponse.success(service.rejectAllocationGroup(loadingPlanId, groupId, user.userId(), user.username(), request.reason()));
}
@@ -75,6 +78,7 @@ public class PlatformContainerFeeDetailController {
public ApiResponse<List<ContainerFeeDetailEntity>> adjustAllocationGroup(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long loadingPlanId,
@PathVariable long groupId, @Valid @RequestBody AllocationGroupAdjustRequest request) {
FirstlegScopeGuard.platform(user);
return ApiResponse.success(service.adjustAllocationGroup(loadingPlanId, groupId, user.userId(), request));
}
@@ -83,6 +87,7 @@ public class PlatformContainerFeeDetailController {
public ApiResponse<Void> voidAllocationGroup(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable long loadingPlanId,
@PathVariable long groupId, @Valid @RequestBody VersionRequest request) {
FirstlegScopeGuard.platform(user);
service.voidAllocationGroup(loadingPlanId, groupId, request.expectedSourceVersion(), user.userId());
return ApiResponse.success(null);
}
@@ -47,8 +47,10 @@ public final class ContainerFeeDetailDtos {
public record Allocation(
@NotNull @Min(1) Long customerId,
@NotNull @Min(1) Long inboundId,
@NotBlank @Size(max = 64) String inboundCode,
@NotNull @Min(1) Long orderId,
@NotBlank @Size(max = 64) String orderNo,
@Min(1) Long inboundId,
@Size(max = 64) String inboundCode,
@NotNull @DecimalMin(value = "0.00", inclusive = false) BigDecimal amount
) { }
@@ -22,6 +22,8 @@ public class ContainerFeeDetailEntity {
private Long id;
private Long tenantId;
private Long allocationGroupId;
private Long allocationOrderId;
private String allocationOrderNo;
private Long allocationInboundId;
private String allocationInboundCode;
private BigDecimal allocationGroupAmount;
@@ -24,6 +24,8 @@ public class ContainerFeeSourceSnapshotEntity {
private Integer sourceVersion;
private Long tenantId;
private Long allocationGroupId;
private Long allocationOrderId;
private String allocationOrderNo;
private Long allocationInboundId;
private String allocationInboundCode;
private BigDecimal allocationGroupAmount;
@@ -20,6 +20,8 @@ public class ContainerFeeSourceSnapshotRepository {
value.setSourceVersion(source.getSourceVersion());
value.setTenantId(source.getTenantId());
value.setAllocationGroupId(source.getAllocationGroupId());
value.setAllocationOrderId(source.getAllocationOrderId());
value.setAllocationOrderNo(source.getAllocationOrderNo());
value.setAllocationInboundId(source.getAllocationInboundId());
value.setAllocationInboundCode(source.getAllocationInboundCode());
value.setAllocationGroupAmount(source.getAllocationGroupAmount());
@@ -52,12 +52,15 @@ public class ContainerFeeDetailService {
PlanContext plan = requireOwnedPlan(tenantId, loadingPlanId);
List<InboundAllocationKey> owned = loading.items(loadingPlanId).stream()
.filter(item -> Long.valueOf(tenantId).equals(item.getAccountId()))
.map(item -> new InboundAllocationKey(item.getInboundId(), item.getInboundCode()))
.map(item -> new InboundAllocationKey(item.getOrderId(), text(item.getOrderNo()),
item.getInboundId(), text(item.getInboundCode())))
.distinct().toList();
if (owned.size() != 1) throw conflict("柜次包含多个入仓码,必须使用柜级费用分摊录入");
if (owned.size() != 1) throw conflict("柜次包含多个业务归属,必须使用柜级费用分摊录入");
FeeItemEntity item = requireItem(request.feeItemId(), request.direction());
ContainerFeeDetailEntity value = new ContainerFeeDetailEntity();
value.setTenantId(tenantId);
value.setAllocationOrderId(owned.get(0).orderId());
value.setAllocationOrderNo(owned.get(0).orderNo());
value.setAllocationInboundId(owned.get(0).inboundId());
value.setAllocationInboundCode(owned.get(0).inboundCode());
value.setAllocationGroupAmount(request.amount().setScale(2, RoundingMode.HALF_UP));
@@ -86,19 +89,25 @@ public class ContainerFeeDetailService {
if (allocated.compareTo(total) != 0) throw conflict("柜级费用分摊合计必须等于费用总额");
Map<InboundAllocationKey, Long> ownership = new HashMap<>();
loading.items(loadingPlanId).forEach(value -> ownership.put(
new InboundAllocationKey(value.getInboundId(), value.getInboundCode()), value.getAccountId()));
new InboundAllocationKey(value.getOrderId(), text(value.getOrderNo()), value.getInboundId(),
text(value.getInboundCode())), value.getAccountId()));
Set<InboundAllocationKey> unique = new HashSet<>();
long groupId = IdWorker.getId();
List<ContainerFeeDetailEntity> rows = new java.util.ArrayList<>();
for (Allocation allocation : request.allocations()) {
InboundAllocationKey key = new InboundAllocationKey(allocation.inboundId(), allocation.inboundCode().trim());
if (!unique.add(key)) throw conflict("同一入仓码不得重复分摊");
String inboundCode = text(allocation.inboundCode());
if ((allocation.inboundId() == null) != (inboundCode == null))
throw new BizException(ResultCode.VALIDATION_FAILED, "入仓ID与入仓码必须同时填写或同时留空");
InboundAllocationKey key = new InboundAllocationKey(allocation.orderId(), allocation.orderNo().trim(),
allocation.inboundId(), inboundCode);
if (!unique.add(key)) throw conflict("同一业务归属不得重复分摊");
if (!allocation.customerId().equals(ownership.get(key)))
throw conflict("分摊客户、入仓码与柜内真实归属不一致");
throw conflict("分摊客户、订单及入仓信息与柜内真实归属不一致");
ContainerFeeDetailEntity value = new ContainerFeeDetailEntity();
value.setId(IdWorker.getId()); value.setTenantId(allocation.customerId());
value.setAllocationGroupId(groupId); value.setAllocationInboundId(allocation.inboundId());
value.setAllocationInboundCode(allocation.inboundCode().trim()); value.setAllocationGroupAmount(total);
value.setAllocationGroupId(groupId); value.setAllocationOrderId(allocation.orderId());
value.setAllocationOrderNo(allocation.orderNo().trim()); value.setAllocationInboundId(allocation.inboundId());
value.setAllocationInboundCode(inboundCode); value.setAllocationGroupAmount(total);
value.setLoadingPlanId(loadingPlanId); value.setContainerBookingId(plan.plan().getContainerBookingId());
value.setContainerNo(plan.booking() == null ? null : plan.booking().getContainerNo());
value.setSourceVersion(1); value.setSourceStatus("ACTIVE"); value.setReviewStatus("PENDING");
@@ -359,5 +368,7 @@ public class ContainerFeeDetailService {
private record PlanContext(LoadingPlanEntity plan, ContainerBookingEntity booking) {
}
private record InboundAllocationKey(Long inboundId, String inboundCode) { }
private static String text(String value) { return value == null || value.isBlank() ? null : value.trim(); }
private record InboundAllocationKey(Long orderId, String orderNo, Long inboundId, String inboundCode) { }
}
@@ -70,12 +70,13 @@ public class FinanceFeeSourceSnapshotService {
nullSafe(detail.getSettlementMode()), nullSafe(detail.getPaidAt()),
nullSafe(detail.getPaymentMethod()), nullSafe(detail.getPaymentReferenceNo()),
nullSafe(detail.getPaymentVoucherFileIds()),
nullSafe(detail.getAllocationGroupId()), nullSafe(detail.getAllocationInboundId()),
nullSafe(detail.getAllocationGroupId()), nullSafe(detail.getAllocationOrderId()),
nullSafe(detail.getAllocationOrderNo()), nullSafe(detail.getAllocationInboundId()),
nullSafe(detail.getAllocationInboundCode()), nullSafe(detail.getAllocationGroupAmount()),
detail.getAmount().toPlainString(), nullSafe(detail.getCurrency()),
nullSafe(detail.getReviewStatus()));
return new FinanceFeeSourceSnapshot(detail.getTenantId(), "CONTAINER_FEE", feeId,
version, detail.getAllocationInboundId(), detail.getAllocationInboundCode(), null, containerId, detail.getContainerBookingId(),
version, detail.getAllocationInboundId(), detail.getAllocationInboundCode(), detail.getAllocationOrderId(), containerId, detail.getContainerBookingId(),
detail.getContainerNo(), detail.getTenantId(), null, detail.getSupplierId(),
detail.getSupplierName(), detail.getSupplierCategory(), detail.getSettlementMode(),
detail.getPaidAt(), detail.getPaymentMethod(), detail.getPaymentReferenceNo(),
@@ -65,6 +65,8 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_detail (
id BIGINT UNSIGNED NOT NULL COMMENT '柜次费用来源ID',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
allocation_group_id BIGINT UNSIGNED NULL COMMENT '柜级公共费用分摊组ID;单入仓直接费用为空',
allocation_order_id BIGINT UNSIGNED NULL COMMENT '本分摊行业务订单ID',
allocation_order_no VARCHAR(64) NULL COMMENT '本分摊行业务订单号',
allocation_inbound_id BIGINT UNSIGNED NULL COMMENT '本分摊行对应入仓单ID',
allocation_inbound_code VARCHAR(64) NULL COMMENT '本分摊行对应入仓码',
allocation_group_amount DECIMAL(18,2) NULL COMMENT '柜级原始费用总额快照',
@@ -123,6 +125,8 @@ CREATE TABLE IF NOT EXISTS fl_container_fee_source_snapshot (
source_version INT UNSIGNED NOT NULL COMMENT '费用来源版本',
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID和数据隔离键',
allocation_group_id BIGINT UNSIGNED NULL COMMENT '柜级公共费用分摊组ID',
allocation_order_id BIGINT UNSIGNED NULL COMMENT '分摊业务订单ID快照',
allocation_order_no VARCHAR(64) NULL COMMENT '分摊业务订单号快照',
allocation_inbound_id BIGINT UNSIGNED NULL COMMENT '分摊入仓单ID快照',
allocation_inbound_code VARCHAR(64) NULL COMMENT '分摊入仓码快照',
allocation_group_amount DECIMAL(18,2) NULL COMMENT '柜级原始费用总额快照',
@@ -196,8 +200,12 @@ CALL firstleg_finance_add_column('fl_container_fee_detail', 'payment_voucher_fil
"JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组' AFTER payment_reference_no");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'allocation_group_id',
"BIGINT UNSIGNED NULL COMMENT '柜级公共费用分摊组ID;单入仓直接费用为空' AFTER tenant_id");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'allocation_order_id',
"BIGINT UNSIGNED NULL COMMENT '本分摊行业务订单ID' AFTER allocation_group_id");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'allocation_order_no',
"VARCHAR(64) NULL COMMENT '本分摊行业务订单号' AFTER allocation_order_id");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'allocation_inbound_id',
"BIGINT UNSIGNED NULL COMMENT '本分摊行对应入仓单ID' AFTER allocation_group_id");
"BIGINT UNSIGNED NULL COMMENT '本分摊行对应入仓单ID' AFTER allocation_order_no");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'allocation_inbound_code',
"VARCHAR(64) NULL COMMENT '本分摊行对应入仓码' AFTER allocation_inbound_id");
CALL firstleg_finance_add_column('fl_container_fee_detail', 'allocation_group_amount',
@@ -214,8 +222,12 @@ CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'payment_vo
"JSON NULL COMMENT 'DIRECT_PAID付款凭证File ID数组' AFTER payment_reference_no");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'allocation_group_id',
"BIGINT UNSIGNED NULL COMMENT '柜级公共费用分摊组ID' AFTER tenant_id");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'allocation_order_id',
"BIGINT UNSIGNED NULL COMMENT '分摊业务订单ID快照' AFTER allocation_group_id");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'allocation_order_no',
"VARCHAR(64) NULL COMMENT '分摊业务订单号快照' AFTER allocation_order_id");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'allocation_inbound_id',
"BIGINT UNSIGNED NULL COMMENT '分摊入仓单ID快照' AFTER allocation_group_id");
"BIGINT UNSIGNED NULL COMMENT '分摊入仓单ID快照' AFTER allocation_order_no");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'allocation_inbound_code',
"VARCHAR(64) NULL COMMENT '分摊入仓码快照' AFTER allocation_inbound_id");
CALL firstleg_finance_add_column('fl_container_fee_source_snapshot', 'allocation_group_amount',
@@ -0,0 +1,45 @@
openapi: 3.0.3
info: { title: Firstleg Container Fee Allocation API, version: 1.0.0 }
paths:
/api/platform/v1/loading-plans/{loadingPlanId}/fee-details/allocation-groups:
post:
summary: 原子创建柜级公共费用分摊组
description: 客户、订单必填;入仓ID与入仓码同时填写或同时留空。各分摊金额必须大于0且合计等于费用总额。
security: [{ bearerAuth: [] }]
parameters: [{ $ref: '#/components/parameters/LoadingPlanId' }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/AllocationGroupRequest' } } } }
responses: { '200': { description: 按客户和业务归属生成的待审核费用行 }, '409': { description: 分摊合计或柜内真实归属不一致 } }
/api/platform/v1/loading-plans/{loadingPlanId}/fee-details/allocation-groups/{groupId}/{action}:
post:
summary: 整组审核、驳回、调整或作废柜级分摊费用
description: action 仅为 approve、reject、adjust、void;单行接口拒绝处理分摊组,避免部分成功。
security: [{ bearerAuth: [] }]
parameters:
- { $ref: '#/components/parameters/LoadingPlanId' }
- { in: path, name: groupId, required: true, schema: { type: string, pattern: '^[1-9][0-9]{0,19}$' } }
- { in: path, name: action, required: true, schema: { type: string, enum: [approve, reject, adjust, void] } }
responses: { '200': { description: 整组处理成功 }, '409': { description: 版本、状态或完整性冲突 } }
components:
parameters:
LoadingPlanId: { in: path, name: loadingPlanId, required: true, schema: { type: string, pattern: '^[1-9][0-9]{0,19}$' } }
schemas:
AllocationGroupRequest:
type: object
required: [fee, allocations]
properties:
fee: { type: object, description: 公共费用字段;amount为原始柜级总额 }
allocations:
type: array
minItems: 1
maxItems: 200
items:
type: object
required: [customerId, orderId, orderNo, amount]
properties:
customerId: { type: string }
orderId: { type: string }
orderNo: { type: string, maxLength: 64 }
inboundId: { type: string, nullable: true }
inboundCode: { type: string, maxLength: 64, nullable: true }
amount: { type: number, format: decimal, exclusiveMinimum: 0 }
securitySchemes: { bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT } }
@@ -3,6 +3,8 @@ package com.baiyue.firstleg.service;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.firstleg.dto.ContainerFeeDetailDtos;
import com.baiyue.firstleg.dto.ContainerFeeDetailDtos.AdjustRequest;
import com.baiyue.firstleg.dto.ContainerFeeDetailDtos.Allocation;
import com.baiyue.firstleg.dto.ContainerFeeDetailDtos.AllocationGroupRequest;
import com.baiyue.firstleg.entity.ContainerFeeDetailEntity;
import com.baiyue.firstleg.entity.FeeItemEntity;
import com.baiyue.firstleg.entity.LoadingPlanEntity;
@@ -233,15 +235,71 @@ class ContainerFeeDetailServiceTest {
assertThat(captor.getValue().getPaymentVoucherFileIds()).containsExactly(901L);
}
@Test
void createsAtomicCrossCustomerAllocationAndAllowsMissingInboundCode() {
LoadingPlanEntity plan = new LoadingPlanEntity();
plan.setId(41L);
when(loading.plan(41L)).thenReturn(plan);
LoadingPlanItemEntity first = loadingItem(10001L, 501L, "FL-501", null, null);
LoadingPlanItemEntity second = loadingItem(10002L, 502L, "FL-502", 602L, "IB-602");
when(loading.items(41L)).thenReturn(List.of(first, second));
when(feeItems.findItem(11L)).thenReturn(item());
var fee = new ContainerFeeDetailDtos.SaveRequest(11L, "RECEIVABLE",
LocalDate.of(2026, 8, 20), new BigDecimal("300.00"), "CNY", null, "柜级操作费");
var request = new AllocationGroupRequest(fee, List.of(
new Allocation(10001L, 501L, "FL-501", null, null, new BigDecimal("120.00")),
new Allocation(10002L, 502L, "FL-502", 602L, "IB-602", new BigDecimal("180.00"))));
List<ContainerFeeDetailEntity> result = service.createAllocationGroup(41L, 9L, request);
assertThat(result).hasSize(2);
ArgumentCaptor<ContainerFeeDetailEntity> captor = ArgumentCaptor.forClass(ContainerFeeDetailEntity.class);
verify(repository, org.mockito.Mockito.times(2)).insert(captor.capture());
assertThat(captor.getAllValues()).extracting(ContainerFeeDetailEntity::getTenantId)
.containsExactly(10001L, 10002L);
assertThat(captor.getAllValues().get(0).getAllocationOrderNo()).isEqualTo("FL-501");
assertThat(captor.getAllValues().get(0).getAllocationInboundId()).isNull();
assertThat(captor.getAllValues().get(0).getAllocationInboundCode()).isNull();
assertThat(captor.getAllValues()).extracting(ContainerFeeDetailEntity::getAllocationGroupId)
.doesNotContainNull().allMatch(captor.getAllValues().get(0).getAllocationGroupId()::equals);
}
@Test
void rejectsAllocationWhenInboundIdAndCodeAreOnlyPartiallyProvided() {
LoadingPlanEntity plan = new LoadingPlanEntity();
plan.setId(41L);
when(loading.plan(41L)).thenReturn(plan);
when(loading.items(41L)).thenReturn(List.of(loadingItem(10001L, 501L, "FL-501", null, null)));
when(feeItems.findItem(11L)).thenReturn(item());
var fee = new ContainerFeeDetailDtos.SaveRequest(11L, "RECEIVABLE",
LocalDate.of(2026, 8, 20), new BigDecimal("100.00"), "CNY", null, null);
var request = new AllocationGroupRequest(fee, List.of(
new Allocation(10001L, 501L, "FL-501", 601L, null, new BigDecimal("100.00"))));
assertThatThrownBy(() -> service.createAllocationGroup(41L, 9L, request))
.isInstanceOf(BizException.class).hasMessageContaining("同时填写或同时留空");
verify(repository, never()).insert(any());
}
private void ownedPlan() {
LoadingPlanEntity plan = new LoadingPlanEntity();
plan.setId(41L);
when(loading.plan(41L)).thenReturn(plan);
LoadingPlanItemEntity item = new LoadingPlanItemEntity();
item.setAccountId(10001L);
item.setOrderId(501L);
item.setOrderNo("FL-501");
when(loading.items(41L)).thenReturn(List.of(item));
}
private static LoadingPlanItemEntity loadingItem(long accountId, long orderId, String orderNo,
Long inboundId, String inboundCode) {
LoadingPlanItemEntity value = new LoadingPlanItemEntity();
value.setAccountId(accountId); value.setOrderId(orderId); value.setOrderNo(orderNo);
value.setInboundId(inboundId); value.setInboundCode(inboundCode);
return value;
}
private static FeeItemEntity item() {
FeeItemEntity value = new FeeItemEntity();
value.setId(11L);