From 7a15481e2db0244cd97a5f6c8a9767c16aac34ca Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Fri, 28 Aug 2026 17:28:39 +0800 Subject: [PATCH] fix(firstleg): resolve merchant customs plan lookup --- .../mapper/ContainerCustomsMapper.java | 2 +- .../ContainerCustomsMapperContractTest.java | 9 ++++++ .../ContainerCustomsServiceTest.java | 32 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/firstleg/src/main/java/com/baiyue/firstleg/customs/container/mapper/ContainerCustomsMapper.java b/firstleg/src/main/java/com/baiyue/firstleg/customs/container/mapper/ContainerCustomsMapper.java index bf185e24a..3854af353 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/customs/container/mapper/ContainerCustomsMapper.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/customs/container/mapper/ContainerCustomsMapper.java @@ -27,7 +27,7 @@ public interface ContainerCustomsMapper { JOIN fl_loading_plan_item item ON item.loading_plan_id=p.id AND item.deleted=0 JOIN fl_inbound_order i ON i.id=item.inbound_id AND i.tenant_id=item.account_id AND i.deleted=0 WHERE p.plan_status='COMPLETED' AND i.tenant_id=#{tenantId} AND i.order_id=#{orderId} AND i.tax_mode='TAX_REFUND' - ORDER BY p.completed_at DESC,p.id DESC LIMIT 1 + ORDER BY COALESCE(p.confirmed_at,p.updated_at) DESC,p.id DESC LIMIT 1 """) Long completedPlanForOrder(@Param("tenantId") long tenantId, @Param("orderId") long orderId); diff --git a/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsMapperContractTest.java b/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsMapperContractTest.java index 7c4e1c85b..0c29d018b 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsMapperContractTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsMapperContractTest.java @@ -7,6 +7,15 @@ import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class ContainerCustomsMapperContractTest { + @Test void merchantOrderUsesCompletedTaxRefundPlanWithRealCompletionTimestamp() throws Exception { + String value=sql("completedPlanForOrder",long.class,long.class); + assertThat(value) + .contains("p.plan_status='COMPLETED'", "i.tenant_id=#{tenantId}", "i.order_id=#{orderId}", + "i.tax_mode='TAX_REFUND'") + .contains("ORDER BY COALESCE(p.confirmed_at,p.updated_at) DESC,p.id DESC") + .doesNotContain("p.completed_at"); + } + @Test void actualCompletedLoadingItemsAndTaxModeAreTheOnlyTicketFacts() throws Exception { String plan=sql("planInbounds",long.class); assertThat(plan).contains("fl_loading_plan_item","fl_inbound_order","p.id=#{planId}","item.deleted=0"); diff --git a/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsServiceTest.java b/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsServiceTest.java index 69fcedc11..718d52b78 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsServiceTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/customs/container/ContainerCustomsServiceTest.java @@ -1,5 +1,6 @@ package com.baiyue.firstleg.customs.container; +import com.baiyue.common.core.api.ResultCode; import com.baiyue.common.core.exception.BizException; import com.baiyue.firstleg.customs.container.dto.ContainerCustomsDtos.ActionRequest; import com.baiyue.firstleg.customs.container.mapper.ContainerCustomsMapper; @@ -13,6 +14,7 @@ import org.springframework.mock.web.MockMultipartFile; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.*; @@ -24,6 +26,31 @@ class ContainerCustomsServiceTest { @InjectMocks ContainerCustomsService service; @BeforeEach void setUp(){MockitoAnnotations.openMocks(this);} + @Test void merchantOwnBuyOrderIsNotFound(){ + assertMerchantOrderNotFound(7L,31L); + } + + @Test void merchantCrossCustomerOrderIsNotFound(){ + assertMerchantOrderNotFound(8L,21L); + } + + @Test void merchantUncompletedOrderIsNotFound(){ + assertMerchantOrderNotFound(7L,22L); + } + + @Test void merchantCompletedTaxRefundOrderReturnsContainerView(){ + var row=new ContainerCustomsMapper.InboundRow(9L,"LP9",8L,"COMPLETED","CAB","C",11L,21L,"O","I",7L,"客户","TAX_REFUND"); + when(mapper.completedPlanForOrder(7L,21L)).thenReturn(9L); + when(mapper.planInbounds(9L)).thenReturn(List.of(row)); + when(mapper.container(9L)).thenReturn(container(ContainerCustomsService.READY,2)); + + var view=service.merchantOrderView(7L,21L); + + assertThat(view.loadingPlanId()).isEqualTo(9L); + assertThat(view.taxRefundCount()).isEqualTo(1); + assertThat(view.inbounds()).extracting(value->value.orderId()).containsExactly(21L); + } + @Test void startFailsClosedWhenAnyRefundInboundHasNoActiveDocumentCoverage(){ var row=new ContainerCustomsMapper.InboundRow(9L,"LP9",8L,"COMPLETED","CAB","C",11L,21L,"O","I",7L,"客户","TAX_REFUND"); var container=new ContainerCustomsMapper.ContainerRow(1L,9L,8L,ContainerCustomsService.READY,null,null,null,null,null,null,null,null,2); @@ -88,4 +115,9 @@ class ContainerCustomsServiceTest { private static ContainerCustomsMapper.DocumentRow document(long id){return new ContainerCustomsMapper.DocumentRow(id,2L,7L,10L,"source.bin","a".repeat(64),"application/octet-stream",1L,"ACTIVE",5L,java.time.LocalDateTime.now(),1,java.time.LocalDateTime.now(),1);} private static ContainerCustomsMapper.ContainerRow container(String status,int version){return new ContainerCustomsMapper.ContainerRow(2L,9L,8L,status,null,null,null,null,null,null,null,null,version);} + private void assertMerchantOrderNotFound(long tenantId,long orderId){ + assertThatThrownBy(()->service.merchantOrderView(tenantId,orderId)) + .isInstanceOfSatisfying(BizException.class, + error->assertThat(error.getResultCode()).isEqualTo(ResultCode.NOT_FOUND)); + } }