优化
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@
|
|||||||
| 客户专属价格簿、柜级阶梯运费与调价边界 | `controller/PlatformPriceBookController.java`、`service/PlatformPriceBookService.java`、`pricing/ActivePriceBookEstimator.java`、`service/FbaPricingService.java`、`pricing/ContainerTierAmountAllocator.java`;公共价格簿固定 `customerId=0`,客户专属版本按客户独立发布与替换,计价优先专属 ACTIVE、缺失才回退公共 ACTIVE。`REGION_WEIGHT_TIER` 对同柜同客户有效成员聚合实际计费量命中一个阶梯,再按成员计费量守恒分摊;装柜成员变化调用 `recalculateUnlockedContainerCustomerFees`,已确认/已发送或客户已确认的版本不得改写。人工调整以系统基准量为中心限制上下 10%(含边界),保存版本、原因和二次确认;一件代发 `WAIT_PALLETIZE` 可在预装确认前试算,`markInboundCalculated` 只更新费用并保留该托盘化状态 |
|
| 客户专属价格簿、柜级阶梯运费与调价边界 | `controller/PlatformPriceBookController.java`、`service/PlatformPriceBookService.java`、`pricing/ActivePriceBookEstimator.java`、`service/FbaPricingService.java`、`pricing/ContainerTierAmountAllocator.java`;公共价格簿固定 `customerId=0`,客户专属版本按客户独立发布与替换,计价优先专属 ACTIVE、缺失才回退公共 ACTIVE。`REGION_WEIGHT_TIER` 对同柜同客户有效成员聚合实际计费量命中一个阶梯,再按成员计费量守恒分摊;装柜成员变化调用 `recalculateUnlockedContainerCustomerFees`,已确认/已发送或客户已确认的版本不得改写。人工调整以系统基准量为中心限制上下 10%(含边界),保存版本、原因和二次确认;一件代发 `WAIT_PALLETIZE` 可在预装确认前试算,`markInboundCalculated` 只更新费用并保留该托盘化状态 |
|
||||||
| 入库费用明细 | `controller/PlatformInboundFeeDetailController.java`、`service/InboundFeeDetailService.java`、`dto/InboundFeeDetailDtos.java`;`PRIVATE_LAST_MILE_DELIVERY` 是独立私人仓尾程派送费,只允许 `destinationType=PRIVATE`,按稳定费用代码校验而不按中文名判断;Admin 消费端见 `../../apps/admin-web/src/modules/unified-orders/api/inboundFeeDetails.ts` |
|
| 入库费用明细 | `controller/PlatformInboundFeeDetailController.java`、`service/InboundFeeDetailService.java`、`dto/InboundFeeDetailDtos.java`;`PRIVATE_LAST_MILE_DELIVERY` 是独立私人仓尾程派送费,只允许 `destinationType=PRIVATE`,按稳定费用代码校验而不按中文名判断;Admin 消费端见 `../../apps/admin-web/src/modules/unified-orders/api/inboundFeeDetails.ts` |
|
||||||
| 入库/柜次直接已付快照与凭证校验 | `service/FeePaymentSnapshotValidator.java`、`client/FeePaymentVoucherFileClient.java`;写入入口分别为 `InboundFeeDetailService.java`、`ContainerFeeDetailService.java`,File 业务类型固定 `FINANCE_VOUCHER` |
|
| 入库/柜次直接已付快照与凭证校验 | `service/FeePaymentSnapshotValidator.java`、`client/FeePaymentVoucherFileClient.java`;写入入口分别为 `InboundFeeDetailService.java`、`ContainerFeeDetailService.java`,File 业务类型固定 `FINANCE_VOUCHER` |
|
||||||
| 客户运营统计/在途柜量 | `customerstatistics/controller/PlatformCustomerTransitStatisticsController.java`、`customerstatistics/service/CustomerTransitStatisticsService.java`;契约见 `src/main/resources/openapi/customer-statistics-v1.yaml` |
|
| 首页实时指标、客户运营统计/在途柜量 | 首页物理在途柜 TEU 与待清关票数从 `dashboard/PlatformDashboardMetricsController.java` 进入,契约见 `src/main/resources/openapi/dashboard-metrics-v1.yaml`;客户维度统计为 `customerstatistics/adapter/in/web/PlatformCustomerTransitStatisticsController.java`、`customerstatistics/application/CustomerTransitStatisticsService.java`,契约见 `src/main/resources/openapi/customer-statistics-v1.yaml` |
|
||||||
| 费用项目与价格簿 | `controller/PlatformFeeItemController.java`、`PlatformPriceBookController.java`、`MerchantPriceBookController.java` |
|
| 费用项目与价格簿 | `controller/PlatformFeeItemController.java`、`PlatformPriceBookController.java`、`MerchantPriceBookController.java` |
|
||||||
| 客户入库结果与头程费用确认 | `controller/MerchantInboundBillingController.java`、`service/MerchantInboundBillingService.java`、`FbaPricingService.java`;查询与确认接口为 `/api/merchant/v1/first-leg/orders/{orderId}/inbound-billing`、`/confirm`,契约 `src/main/resources/openapi/firstleg-v1.yaml` |
|
| 客户入库结果与头程费用确认 | `controller/MerchantInboundBillingController.java`、`service/MerchantInboundBillingService.java`、`FbaPricingService.java`;查询与确认接口为 `/api/merchant/v1/first-leg/orders/{orderId}/inbound-billing`、`/confirm`,契约 `src/main/resources/openapi/firstleg-v1.yaml` |
|
||||||
| 价格簿查询内部切片 | `pricebookquery/application/port/in/PriceBookQueryUseCase.java`、`application/PriceBookQueryService.java`、`application/port/out/PriceBookQueryReader.java`、`adapter/out/persistence/PriceBookQueryMapper.java`;查询行模型位于 `application/model/PriceBookQueryRows.java` |
|
| 价格簿查询内部切片 | `pricebookquery/application/port/in/PriceBookQueryUseCase.java`、`application/PriceBookQueryService.java`、`application/port/out/PriceBookQueryReader.java`、`adapter/out/persistence/PriceBookQueryMapper.java`;查询行模型位于 `application/model/PriceBookQueryRows.java` |
|
||||||
|
|||||||
+12
@@ -129,6 +129,18 @@ public class PlatformDropshipPalletizationController {
|
|||||||
return printService.generateDropshipPallet(pallet, task.inboundCode(), requestId);
|
return printService.generateDropshipPallet(pallet, task.inboundCode(), requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tasks/{taskId}/pallets/print")
|
||||||
|
@PreAuthorize("hasAuthority('platform:firstleg:pda:view')")
|
||||||
|
public ResponseEntity<byte[]> printTaskPallets(@AuthenticationPrincipal AuthenticatedUser user,
|
||||||
|
@PathVariable @Positive long taskId,
|
||||||
|
@RequestParam @Positive long warehouseId,
|
||||||
|
@RequestHeader(value = "X-Request-Id", required = false) String requestId) {
|
||||||
|
FirstlegScopeGuard.platform(user);
|
||||||
|
Task task = service.task(taskId, warehouseId, user.userId());
|
||||||
|
return printService.generateDropshipPallets(
|
||||||
|
service.generatedPallets(taskId, warehouseId, user.userId()), task.inboundCode(), requestId);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/inbound-orders/{inboundId}/pallets")
|
@GetMapping("/inbound-orders/{inboundId}/pallets")
|
||||||
@PreAuthorize("hasAuthority('firstleg:inbound:list')")
|
@PreAuthorize("hasAuthority('firstleg:inbound:list')")
|
||||||
public ApiResponse<List<Pallet>> inboundPallets(@AuthenticationPrincipal AuthenticatedUser user,
|
public ApiResponse<List<Pallet>> inboundPallets(@AuthenticationPrincipal AuthenticatedUser user,
|
||||||
|
|||||||
@@ -67,10 +67,11 @@ public interface DropshipPalletizationMapper {
|
|||||||
PalletRow pallet(@Param("taskId") long taskId,@Param("palletId") long palletId,@Param("warehouseId") long warehouseId);
|
PalletRow pallet(@Param("taskId") long taskId,@Param("palletId") long palletId,@Param("warehouseId") long warehouseId);
|
||||||
@Select("""
|
@Select("""
|
||||||
SELECT p.* FROM fl_dropship_pallet p
|
SELECT p.* FROM fl_dropship_pallet p
|
||||||
WHERE p.task_id=#{taskId}
|
WHERE EXISTS(SELECT 1 FROM fl_dropship_pallet_carton c WHERE c.pallet_id=p.id AND c.task_id=#{taskId})
|
||||||
OR EXISTS(SELECT 1 FROM fl_dropship_pallet_carton c WHERE c.pallet_id=p.id AND c.task_id=#{taskId})
|
|
||||||
ORDER BY p.id
|
ORDER BY p.id
|
||||||
""") List<PalletRow> pallets(@Param("taskId") long taskId);
|
""") List<PalletRow> pallets(@Param("taskId") long taskId);
|
||||||
|
@Select("SELECT * FROM fl_dropship_pallet WHERE task_id=#{taskId} ORDER BY id")
|
||||||
|
List<PalletRow> generatedPallets(@Param("taskId") long taskId);
|
||||||
@Select("""
|
@Select("""
|
||||||
SELECT p.* FROM fl_dropship_pallet p
|
SELECT p.* FROM fl_dropship_pallet p
|
||||||
WHERE ((p.tenant_id=#{tenantId} AND p.inbound_id=#{inboundId})
|
WHERE ((p.tenant_id=#{tenantId} AND p.inbound_id=#{inboundId})
|
||||||
|
|||||||
@@ -156,6 +156,12 @@ public class DropshipPalletizationService {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Pallet> generatedPallets(long taskId,long warehouseId,long operatorId){
|
||||||
|
TaskRow task=requireTask(taskId,warehouseId);
|
||||||
|
if(task.getAssigneeId()!=null && task.getAssigneeId()!=operatorId) throw conflict("任务已由其他人员领取");
|
||||||
|
return mapper.generatedPallets(taskId).stream().map(p->palletView(p,task.getInboundCode())).toList();
|
||||||
|
}
|
||||||
|
|
||||||
private PalletRow requireAssignablePallet(TaskRow task,String palletNo){
|
private PalletRow requireAssignablePallet(TaskRow task,String palletNo){
|
||||||
PalletRow existing=mapper.palletByNo(palletNo);
|
PalletRow existing=mapper.palletByNo(palletNo);
|
||||||
if(existing==null) throw new BizException(ResultCode.NOT_FOUND,"托盘码不存在,请扫描测量审核后生成的 DP 托盘码");
|
if(existing==null) throw new BizException(ResultCode.NOT_FOUND,"托盘码不存在,请扫描测量审核后生成的 DP 托盘码");
|
||||||
|
|||||||
+25
-9
@@ -117,6 +117,30 @@ public class InboundCartonLabelPrintService {
|
|||||||
|
|
||||||
/** 一件代发 A4 托盘信息单:托盘号、Code 128 一维码和 SKU 归托明细。 */
|
/** 一件代发 A4 托盘信息单:托盘号、Code 128 一维码和 SKU 归托明细。 */
|
||||||
public ResponseEntity<byte[]> generateDropshipPallet(Pallet pallet, String inboundCode, String requestId) {
|
public ResponseEntity<byte[]> generateDropshipPallet(Pallet pallet, String inboundCode, String requestId) {
|
||||||
|
return generateDropshipPallets(List.of(pallet), inboundCode, requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 一票预生成托盘码合并为一个多页 PDF,避免 PDA 展开或逐个下载大量空托盘。 */
|
||||||
|
public ResponseEntity<byte[]> generateDropshipPallets(List<Pallet> pallets, String inboundCode, String requestId) {
|
||||||
|
if (pallets == null || pallets.isEmpty()) {
|
||||||
|
throw new BizException(ResultCode.CONFLICT, "托盘码尚未生成,不能打印");
|
||||||
|
}
|
||||||
|
List<PrintPdfClient.DropshipPalletDocument> documents = pallets.stream()
|
||||||
|
.map(pallet -> dropshipPalletDocument(pallet, inboundCode)).toList();
|
||||||
|
String fileName = pallets.size() == 1
|
||||||
|
? pallets.get(0).palletNo() + "-A4托盘信息单.pdf"
|
||||||
|
: inboundCode + "-" + pallets.size() + "托-A4托盘信息单.pdf";
|
||||||
|
PrintPdfClient.DropshipPalletA4PdfRequest request = new PrintPdfClient.DropshipPalletA4PdfRequest(
|
||||||
|
"DROPSHIP_PALLET_A4_V1", new PrintPdfClient.PageSpec(A4_WIDTH_MM, A4_HEIGHT_MM),
|
||||||
|
fileName, documents);
|
||||||
|
try {
|
||||||
|
return requirePdf(printClient.generateDropshipPalletA4Documents(internalToken, requestId, request));
|
||||||
|
} catch (FeignException | NoFallbackAvailableException exception) {
|
||||||
|
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "打印服务暂不可用,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PrintPdfClient.DropshipPalletDocument dropshipPalletDocument(Pallet pallet, String inboundCode) {
|
||||||
if (pallet == null || !StringUtils.hasText(pallet.palletNo())) {
|
if (pallet == null || !StringUtils.hasText(pallet.palletNo())) {
|
||||||
throw new BizException(ResultCode.CONFLICT, "托盘码尚未生成,不能打印");
|
throw new BizException(ResultCode.CONFLICT, "托盘码尚未生成,不能打印");
|
||||||
}
|
}
|
||||||
@@ -127,17 +151,9 @@ public class InboundCartonLabelPrintService {
|
|||||||
.map(item -> new PrintPdfClient.DropshipPalletSkuRow(item.inboundCode(), item.skuCode(),
|
.map(item -> new PrintPdfClient.DropshipPalletSkuRow(item.inboundCode(), item.skuCode(),
|
||||||
item.cargoName(), number(item.cartonCount()), number(item.skuQuantity())))
|
item.cargoName(), number(item.cartonCount()), number(item.skuQuantity())))
|
||||||
.toList();
|
.toList();
|
||||||
PrintPdfClient.DropshipPalletDocument document = new PrintPdfClient.DropshipPalletDocument(
|
return new PrintPdfClient.DropshipPalletDocument(
|
||||||
pallet.palletNo(), inboundCodes, number(pallet.cartonCount()), number(pallet.skuCount()),
|
pallet.palletNo(), inboundCodes, number(pallet.cartonCount()), number(pallet.skuCount()),
|
||||||
pallet.weightKg(), pallet.volumeCbm(), pallet.palletNo(), skuRows);
|
pallet.weightKg(), pallet.volumeCbm(), pallet.palletNo(), skuRows);
|
||||||
PrintPdfClient.DropshipPalletA4PdfRequest request = new PrintPdfClient.DropshipPalletA4PdfRequest(
|
|
||||||
"DROPSHIP_PALLET_A4_V1", new PrintPdfClient.PageSpec(A4_WIDTH_MM, A4_HEIGHT_MM),
|
|
||||||
pallet.palletNo() + "-A4托盘信息单.pdf", List.of(document));
|
|
||||||
try {
|
|
||||||
return requirePdf(printClient.generateDropshipPalletA4Documents(internalToken, requestId, request));
|
|
||||||
} catch (FeignException | NoFallbackAvailableException exception) {
|
|
||||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "打印服务暂不可用,请稍后重试");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int number(Integer value) {
|
private int number(Integer value) {
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Platform dashboard operational metrics
|
||||||
|
version: 1.0.0
|
||||||
|
paths:
|
||||||
|
/api/platform/v1/first-leg/dashboard/operational-metrics:
|
||||||
|
get:
|
||||||
|
summary: 查询首页货柜与清关实时指标
|
||||||
|
description: >-
|
||||||
|
在途柜量按已实际开船且尚未到达海外仓的有效物理柜去重,TEU 按 20*=1、40*=2、45*=2.25
|
||||||
|
折算,未知箱型不计入 TEU;待清关票数按已进入整柜清关且清关未完成的去重订单统计。
|
||||||
|
本接口只返回当前时点事实,不提供历史环比。
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: 查询成功
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/OperationalMetricsEnvelope'
|
||||||
|
'401': {description: 需要登录}
|
||||||
|
'403': {description: 需要货柜列表与报关列表权限}
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
OperationalMetricsEnvelope:
|
||||||
|
type: object
|
||||||
|
required: [code, message, data]
|
||||||
|
properties:
|
||||||
|
code: {type: string, example: '200'}
|
||||||
|
message: {type: string}
|
||||||
|
data: {$ref: '#/components/schemas/OperationalMetrics'}
|
||||||
|
OperationalMetrics:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- inTransitContainerCount
|
||||||
|
- inTransitTeu
|
||||||
|
- unknownContainerTypeCount
|
||||||
|
- pendingCustomsOrderCount
|
||||||
|
properties:
|
||||||
|
inTransitContainerCount:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
description: 已开船未到海外仓的物理柜数
|
||||||
|
inTransitTeu:
|
||||||
|
type: number
|
||||||
|
format: decimal
|
||||||
|
multipleOf: 0.01
|
||||||
|
minimum: 0
|
||||||
|
description: 已知箱型的在途柜 TEU 合计
|
||||||
|
unknownContainerTypeCount:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
description: 未计入 TEU 的未知箱型在途柜数
|
||||||
|
pendingCustomsOrderCount:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
description: 已进入整柜清关且清关未完成的去重订单数
|
||||||
|
asOf:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
nullable: true
|
||||||
|
description: 数据库统计时点
|
||||||
@@ -76,6 +76,14 @@ paths:
|
|||||||
- {$ref: '#/components/parameters/WarehouseId'}
|
- {$ref: '#/components/parameters/WarehouseId'}
|
||||||
responses:
|
responses:
|
||||||
'200': {description: A4 托盘信息单 PDF, content: {application/pdf: {schema: {type: string, format: binary}}}}
|
'200': {description: A4 托盘信息单 PDF, content: {application/pdf: {schema: {type: string, format: binary}}}}
|
||||||
|
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/pallets/print:
|
||||||
|
get:
|
||||||
|
summary: 合并获取本票全部预生成托盘码的多页 A4 PDF
|
||||||
|
description: 每个预生成托盘固定一页,PDA 无需展开托盘列表或逐个下载,最多按本票预计托数生成。
|
||||||
|
x-required-authority: platform:firstleg:pda:view
|
||||||
|
parameters: [{$ref: '#/components/parameters/TaskId'}, {$ref: '#/components/parameters/WarehouseId'}]
|
||||||
|
responses:
|
||||||
|
'200': {description: 多页 A4 托盘信息单 PDF, content: {application/pdf: {schema: {type: string, format: binary}}}}
|
||||||
/api/platform/v1/first-leg/pda-dropship/inbound-orders/{inboundId}/pallets:
|
/api/platform/v1/first-leg/pda-dropship/inbound-orders/{inboundId}/pallets:
|
||||||
get:
|
get:
|
||||||
summary: Admin 查询入仓单权威托盘结果
|
summary: Admin 查询入仓单权威托盘结果
|
||||||
|
|||||||
+10
@@ -1,11 +1,13 @@
|
|||||||
package com.baiyue.firstleg.dashboard;
|
package com.baiyue.firstleg.dashboard;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -30,4 +32,12 @@ class DashboardMetricsContractTest {
|
|||||||
"COUNT(DISTINCT inbound.order_id)", "customs_container.status <> 'COMPLETED'",
|
"COUNT(DISTINCT inbound.order_id)", "customs_container.status <> 'COMPLETED'",
|
||||||
"item.deleted = 0", "inbound.deleted = 0", "LIKE '20%'", "LIKE '40%'", "LIKE '45%'");
|
"item.deleted = 0", "inbound.deleted = 0", "LIKE '20%'", "LIKE '40%'", "LIKE '45%'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test void openApiDocumentsTheCurrentPointInTimeDefinitions() throws Exception {
|
||||||
|
var openApi = new ClassPathResource("openapi/dashboard-metrics-v1.yaml")
|
||||||
|
.getContentAsString(StandardCharsets.UTF_8);
|
||||||
|
assertThat(openApi).contains("/api/platform/v1/first-leg/dashboard/operational-metrics:",
|
||||||
|
"inTransitContainerCount:", "inTransitTeu:", "unknownContainerTypeCount:",
|
||||||
|
"pendingCustomsOrderCount:", "本接口只返回当前时点事实,不提供历史环比");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -69,6 +69,31 @@ class InboundCartonLabelPrintServiceTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void multiplePreGeneratedPalletsAreReturnedInOnePdf() {
|
||||||
|
Pallet first = dropshipPallet("OPEN");
|
||||||
|
Pallet second = new Pallet(90002L, "DP-260911-0002", "OPEN", 0, 0, 0,
|
||||||
|
BigDecimal.ZERO, BigDecimal.ZERO, 1, List.of(), List.of(), null);
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_PDF);
|
||||||
|
when(print.generateDropshipPalletA4Documents(org.mockito.ArgumentMatchers.anyString(),
|
||||||
|
org.mockito.ArgumentMatchers.eq("request-all"), org.mockito.ArgumentMatchers.any()))
|
||||||
|
.thenReturn(new ResponseEntity<>(new byte[] {4, 5, 6}, headers,
|
||||||
|
org.springframework.http.HttpStatus.OK));
|
||||||
|
|
||||||
|
ResponseEntity<byte[]> response = service.generateDropshipPallets(
|
||||||
|
List.of(first, second), "PCHK2608040174", "request-all");
|
||||||
|
|
||||||
|
ArgumentCaptor<PrintPdfClient.DropshipPalletA4PdfRequest> request =
|
||||||
|
ArgumentCaptor.forClass(PrintPdfClient.DropshipPalletA4PdfRequest.class);
|
||||||
|
verify(print).generateDropshipPalletA4Documents(org.mockito.ArgumentMatchers.eq("internal-token"),
|
||||||
|
org.mockito.ArgumentMatchers.eq("request-all"), request.capture());
|
||||||
|
assertThat(request.getValue().documents()).extracting("palletNo")
|
||||||
|
.containsExactly("DP-260911-0001", "DP-260911-0002");
|
||||||
|
assertThat(request.getValue().downloadFileName()).contains("2托");
|
||||||
|
assertThat(response.getBody()).containsExactly(4, 5, 6);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void forwardsStableLabelsAndOnlySafePdfHeaders() {
|
void forwardsStableLabelsAndOnlySafePdfHeaders() {
|
||||||
when(labels.list(10001L, 70001L, List.of(1))).thenReturn(batch());
|
when(labels.list(10001L, 70001L, List.of(1))).thenReturn(batch());
|
||||||
|
|||||||
Reference in New Issue
Block a user