2026-07-07 15:37:56 +08:00
|
|
|
package com.linhelp.order;
|
|
|
|
|
|
2026-07-14 16:04:51 +08:00
|
|
|
import com.linhelp.common.api.PageResponse;
|
2026-07-07 15:37:56 +08:00
|
|
|
import com.linhelp.common.enums.DeliveryMethod;
|
|
|
|
|
import com.linhelp.common.enums.GoodsOrderStatus;
|
2026-07-14 16:04:51 +08:00
|
|
|
import com.linhelp.orderlog.OrderLogRecord;
|
|
|
|
|
import com.linhelp.orderlog.OrderLogService;
|
2026-07-07 15:37:56 +08:00
|
|
|
import com.linhelp.product.ProductService;
|
|
|
|
|
import com.linhelp.product.ProductSkuResponse;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
|
2026-07-14 16:04:51 +08:00
|
|
|
import java.util.ArrayList;
|
2026-07-07 15:37:56 +08:00
|
|
|
import java.util.Collections;
|
2026-07-14 16:04:51 +08:00
|
|
|
import java.util.List;
|
2026-07-07 15:37:56 +08:00
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
|
|
|
|
|
|
|
|
class GoodsOrderServiceTests {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void cannotCreateGoodsOrderWhenSkuStockIsInsufficient() {
|
|
|
|
|
ProductService productService = new ProductService();
|
|
|
|
|
ProductSkuResponse sku = productService.createDemoSku(1L, 1L, 1L, "500g", 990, 2);
|
|
|
|
|
GoodsOrderService goodsOrderService = new GoodsOrderService(productService);
|
|
|
|
|
|
|
|
|
|
CreateGoodsOrderRequest request = new CreateGoodsOrderRequest();
|
|
|
|
|
request.setTenantId(1L);
|
|
|
|
|
request.setCommunityId(1L);
|
|
|
|
|
request.setMerchantId(1L);
|
|
|
|
|
request.setAddressId(1L);
|
|
|
|
|
request.setDeliveryMethod(DeliveryMethod.IMMEDIATE);
|
|
|
|
|
request.setItems(Collections.singletonList(new CreateGoodsOrderItemRequest(1L, sku.getId(), 99)));
|
|
|
|
|
|
2026-07-14 16:04:51 +08:00
|
|
|
assertThatThrownBy(() -> goodsOrderService.create(1L, request));
|
2026-07-07 15:37:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void selfPickupOrderMovesToPendingPickupAfterPreparing() {
|
|
|
|
|
ProductService productService = new ProductService();
|
|
|
|
|
ProductSkuResponse sku = productService.createDemoSku(1L, 1L, 1L, "500g", 990, 5);
|
|
|
|
|
GoodsOrderService goodsOrderService = new GoodsOrderService(productService);
|
|
|
|
|
|
|
|
|
|
CreateGoodsOrderRequest request = new CreateGoodsOrderRequest();
|
|
|
|
|
request.setTenantId(1L);
|
|
|
|
|
request.setCommunityId(1L);
|
|
|
|
|
request.setMerchantId(1L);
|
|
|
|
|
request.setDeliveryMethod(DeliveryMethod.SELF_PICKUP);
|
|
|
|
|
request.setItems(Collections.singletonList(new CreateGoodsOrderItemRequest(1L, sku.getId(), 1)));
|
|
|
|
|
GoodsOrderResponse order = goodsOrderService.create(1L, request);
|
|
|
|
|
|
|
|
|
|
goodsOrderService.confirm(order.getId());
|
|
|
|
|
goodsOrderService.markPrepared(order.getId());
|
|
|
|
|
|
|
|
|
|
assertThat(goodsOrderService.detail(order.getId()).getStatus()).isEqualTo(GoodsOrderStatus.PENDING_PICKUP);
|
|
|
|
|
}
|
2026-07-14 16:04:51 +08:00
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void userCannotViewOrCancelAnotherUsersGoodsOrder() {
|
|
|
|
|
ProductService productService = new ProductService();
|
|
|
|
|
ProductSkuResponse sku = productService.createDemoSku(1L, 1L, 1L, "500g", 990, 5);
|
|
|
|
|
GoodsOrderService goodsOrderService = new GoodsOrderService(productService);
|
|
|
|
|
GoodsOrderResponse order = goodsOrderService.create(1L, deliveryRequest(sku.getId(), 1L));
|
|
|
|
|
|
|
|
|
|
assertThatThrownBy(() -> goodsOrderService.detailMine(2L, order.getId()));
|
|
|
|
|
assertThatThrownBy(() -> goodsOrderService.cancelMine(2L, order.getId()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void adminCannotConfirmGoodsOrderFromAnotherCommunity() {
|
|
|
|
|
ProductService productService = new ProductService();
|
|
|
|
|
ProductSkuResponse sku = productService.createDemoSku(1L, 2L, 1L, "500g", 990, 5);
|
|
|
|
|
GoodsOrderService goodsOrderService = new GoodsOrderService(productService);
|
|
|
|
|
GoodsOrderResponse order = goodsOrderService.create(1L, deliveryRequest(sku.getId(), 2L));
|
|
|
|
|
|
|
|
|
|
assertThatThrownBy(() -> goodsOrderService.confirmAdmin(1L, order.getId()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void adminGoodsOrderPageFiltersAndPaginates() {
|
|
|
|
|
ProductService productService = new ProductService();
|
|
|
|
|
ProductSkuResponse sku = productService.createDemoSku(1L, 1L, 1L, "500g", 990, 10);
|
|
|
|
|
GoodsOrderService goodsOrderService = new GoodsOrderService(productService);
|
|
|
|
|
GoodsOrderResponse first = goodsOrderService.create(1L, deliveryRequest(sku.getId(), 1L));
|
|
|
|
|
GoodsOrderResponse second = goodsOrderService.create(1L, deliveryRequest(sku.getId(), 1L));
|
|
|
|
|
goodsOrderService.create(1L, deliveryRequest(sku.getId(), 1L));
|
|
|
|
|
|
|
|
|
|
goodsOrderService.confirm(first.getId());
|
|
|
|
|
|
|
|
|
|
PageResponse<GoodsOrderResponse> page = goodsOrderService.listAdminPage(1L, GoodsOrderStatus.PENDING_CONFIRM, 1, 1);
|
|
|
|
|
|
|
|
|
|
assertThat(page.getTotal()).isEqualTo(2);
|
|
|
|
|
assertThat(page.getPageNo()).isEqualTo(1);
|
|
|
|
|
assertThat(page.getPageSize()).isEqualTo(1);
|
|
|
|
|
assertThat(page.getRecords()).extracting(GoodsOrderResponse::getId).containsExactly(second.getId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void goodsOrderWritesLogsAndPersistsSnapshots() {
|
|
|
|
|
ProductService productService = new ProductService();
|
|
|
|
|
ProductSkuResponse sku = productService.createDemoSku(1L, 1L, 1L, "500g", 990, 5);
|
|
|
|
|
OrderLogService orderLogService = new OrderLogService();
|
|
|
|
|
RecordingGoodsOrderStore store = new RecordingGoodsOrderStore();
|
|
|
|
|
GoodsOrderService goodsOrderService = new GoodsOrderService(productService, orderLogService, store);
|
|
|
|
|
|
|
|
|
|
GoodsOrderResponse order = goodsOrderService.create(1L, deliveryRequest(sku.getId(), 1L));
|
|
|
|
|
goodsOrderService.confirmAdmin(1L, order.getId(), 9L);
|
|
|
|
|
|
|
|
|
|
List<OrderLogRecord> logs = orderLogService.list("GOODS_ORDER", order.getId());
|
|
|
|
|
assertThat(logs).extracting(OrderLogRecord::getAction).containsExactly("CREATE", "CONFIRM");
|
|
|
|
|
assertThat(logs.get(1).getFromStatus()).isEqualTo("PENDING_CONFIRM");
|
|
|
|
|
assertThat(logs.get(1).getToStatus()).isEqualTo("PREPARING");
|
|
|
|
|
assertThat(logs.get(1).getOperatorId()).isEqualTo(9L);
|
|
|
|
|
assertThat(store.saved).extracting(GoodsOrderResponse::getStatus)
|
|
|
|
|
.containsExactly(GoodsOrderStatus.PENDING_CONFIRM, GoodsOrderStatus.PREPARING);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private CreateGoodsOrderRequest deliveryRequest(Long skuId, Long communityId) {
|
|
|
|
|
CreateGoodsOrderRequest request = new CreateGoodsOrderRequest();
|
|
|
|
|
request.setTenantId(1L);
|
|
|
|
|
request.setCommunityId(communityId);
|
|
|
|
|
request.setMerchantId(1L);
|
|
|
|
|
request.setAddressId(1L);
|
|
|
|
|
request.setDeliveryMethod(DeliveryMethod.IMMEDIATE);
|
|
|
|
|
request.setItems(Collections.singletonList(new CreateGoodsOrderItemRequest(1L, skuId, 1)));
|
|
|
|
|
return request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static class RecordingGoodsOrderStore implements GoodsOrderStore {
|
|
|
|
|
private final List<GoodsOrderResponse> saved = new ArrayList<GoodsOrderResponse>();
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<GoodsOrderResponse> loadAll() {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void save(GoodsOrderResponse order) {
|
|
|
|
|
GoodsOrderResponse snapshot = new GoodsOrderResponse();
|
|
|
|
|
snapshot.setId(order.getId());
|
|
|
|
|
snapshot.setStatus(order.getStatus());
|
|
|
|
|
saved.add(snapshot);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-07-07 15:37:56 +08:00
|
|
|
}
|