feat(lastleg): retain receipt and redispatch history on exceptions
This commit is contained in:
+76
@@ -0,0 +1,76 @@
|
||||
package com.baiyue.lastleg.exceptionorder.service;
|
||||
|
||||
import com.baiyue.lastleg.exceptionorder.dto.ExceptionOrderResponses;
|
||||
import com.baiyue.lastleg.exceptionorder.entity.ExceptionOrder;
|
||||
import com.baiyue.lastleg.exceptionorder.mapper.ExceptionOrderMapper;
|
||||
import com.baiyue.lastleg.exceptionorder.mapper.ExceptionReturnItemMapper;
|
||||
import com.baiyue.lastleg.inventory.mapper.ReturnStockReceiptMapper;
|
||||
import com.baiyue.lastleg.inventory.mapper.ReturnStockReceiptMapper.ReturnHistoryRow;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class ExceptionReturnHistoryTest {
|
||||
private final ExceptionOrderService service = new ExceptionOrderService();
|
||||
private final LocalDateTime time = LocalDateTime.of(2026, 10, 3, 23, 24);
|
||||
|
||||
private List<ExceptionOrderResponses.ReturnReceipt> history(List<ReturnHistoryRow> rows) {
|
||||
return ReflectionTestUtils.invokeMethod(service, "receiptHistory", rows);
|
||||
}
|
||||
private ReturnHistoryRow row(long receipt, String dispatch, long item, String delivery, int quantity) {
|
||||
return new ReturnHistoryRow(receipt, "RSR-" + receipt, 2L, time, item, dispatch, "DEPARTED",
|
||||
quantity, (long) quantity, delivery, delivery == null ? null : "DELIVERED");
|
||||
}
|
||||
@Test void retainsAllBatchesAndMultipleRedispatchesWithoutMultiplyingItemQuantitiesByDeliveryRows() {
|
||||
var result = history(List.of(row(1, "DS-A", 11, "DL-A", 1), row(1, "DS-A", 11, "DL-B", 1),
|
||||
row(1, "DS-B", 12, "DL-C", 1), new ReturnHistoryRow(2L, "RSR-2", 1L, time.plusMinutes(1),
|
||||
null, null, null, null, 0L, null, null)));
|
||||
assertEquals(2, result.size()); assertEquals(2, result.get(0).redispatches().size());
|
||||
var first = result.get(0).redispatches().get(0);
|
||||
assertEquals(1, first.selectedPackages()); assertEquals(1, first.pickedPackages());
|
||||
assertEquals(List.of("DL-A", "DL-B"), first.deliveries().stream().map(ExceptionOrderResponses.RelatedDelivery::deliveryNo).toList());
|
||||
assertEquals(1, result.get(1).receivedPackages()); assertTrue(result.get(1).redispatches().isEmpty());
|
||||
}
|
||||
@Test void sameDispatchAcrossDistinctReceiptBatchesRemainsSeparate() {
|
||||
var result = history(List.of(row(1, "DS-A", 11, "DL-A", 1), row(2, "DS-A", 12, "DL-A", 1)));
|
||||
assertEquals(2, result.size()); assertEquals("RSR-1", result.get(0).receiptNo());
|
||||
assertEquals("RSR-2", result.get(1).receiptNo());
|
||||
assertEquals(1, result.get(0).redispatches().get(0).pickedPackages());
|
||||
}
|
||||
@Test void currentDetailReadsOnlyResolvedCustomerAndExceptionWithoutStateCommands() {
|
||||
var orders = mock(ExceptionOrderMapper.class); var returns = mock(ExceptionReturnItemMapper.class);
|
||||
var receipts = mock(ReturnStockReceiptMapper.class);
|
||||
ReflectionTestUtils.setField(service, "exceptionOrders", orders);
|
||||
ReflectionTestUtils.setField(service, "returnItems", returns);
|
||||
ReflectionTestUtils.setField(service, "returnReceipts", receipts);
|
||||
var order = new ExceptionOrder(); order.setId(10L); order.setCustomerId("C");
|
||||
order.setExceptionNo("EX-10"); order.setExceptionType("RETURN"); order.setStatus("COMPLETED");
|
||||
when(orders.findByNo("C", "EX-10")).thenReturn(order);
|
||||
when(returns.findByException("C", 10L)).thenReturn(List.of());
|
||||
when(receipts.history("C", 10L)).thenReturn(List.of(row(1, "DS-A", 11, "DL-A", 2)));
|
||||
var result = service.detail("C", "EX-10");
|
||||
assertEquals("COMPLETED", result.order().status()); assertTrue(result.order().allowedActions().isEmpty());
|
||||
assertEquals(2, result.returnReceipts().get(0).receivedPackages());
|
||||
verify(receipts).history("C", 10L); verify(orders, never()).updateById(any(ExceptionOrder.class));
|
||||
assertThrows(ResponseStatusException.class, () -> service.detail("OTHER", "EX-10"));
|
||||
verify(receipts, never()).history(eq("OTHER"), any());
|
||||
}
|
||||
@Test void historyQueryKeepsConsumedReceiptsAndFiltersDeliveryByCustomerAndItemDestination() throws Exception {
|
||||
String sql = String.join(" ", ReturnStockReceiptMapper.class.getMethod("history", String.class, Long.class)
|
||||
.getAnnotation(org.apache.ibatis.annotations.Select.class).value());
|
||||
assertTrue(sql.contains("r.exception_order_id=#{exceptionId}"));
|
||||
assertTrue(sql.contains("BINARY r.customer_id=BINARY #{customerId}"));
|
||||
assertTrue(sql.contains("BINARY delivery.delivery_group_key=BINARY CASE"));
|
||||
assertTrue(sql.contains("WHEN di.destination_type='PRIVATE'"));
|
||||
assertTrue(sql.contains("a.return_receipt_id=r.id"));
|
||||
assertFalse(sql.contains("available_packages")); assertFalse(sql.contains("ll_order o"));
|
||||
}
|
||||
@Test void receiptBusinessNumberAndPositiveReceivedQuantityCannotBeGuessed() {
|
||||
assertThrows(ResponseStatusException.class, () -> history(List.of(new ReturnHistoryRow(1L, null, 2L, time,
|
||||
null, null, null, null, 0L, null, null))));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user