fix(lastleg): trace return carton sources and generate scannable labels

This commit is contained in:
2026-09-12 16:16:38 +08:00
parent e467d60e8f
commit f26e4b2972
13 changed files with 204 additions and 5 deletions
@@ -0,0 +1,36 @@
package com.baiyue.lastleg.returnreceipt.service;
import com.google.zxing.common.BitArray;
import com.google.zxing.oned.Code128Reader;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.util.regex.Pattern;
import static org.assertj.core.api.Assertions.assertThat;
class ReturnCartonBarcodeTest {
@ParameterizedTest
@ValueSource(strings = {"RC-WH-20260912-480898", "RC-WH-20260912-274178", "RC-1", "RC-MERGED"})
void decodesTheActualRenderedSvgBarsToTheExactCartonMark(String mark) throws Exception {
String svg = ReturnCartonBarcode.svg(mark);
var viewBox = Pattern.compile("viewBox=\"0 0 (\\d+) 50\"").matcher(svg);
assertThat(viewBox.find()).isTrue();
int width = Integer.parseInt(viewBox.group(1));
BitArray scanline = new BitArray(width);
var bars = Pattern.compile("<rect x=\"(\\d+)\" y=\"0\" width=\"(\\d+)\" height=\"50\" fill=\"black\"/>").matcher(svg);
int firstBar = width;
int lastBar = 0;
while (bars.find()) {
int start = Integer.parseInt(bars.group(1));
int end = start + Integer.parseInt(bars.group(2));
firstBar = Math.min(firstBar, start);
lastBar = Math.max(lastBar, end);
scanline.setRange(start, end);
}
assertThat(firstBar).isGreaterThanOrEqualTo(10);
assertThat(width - lastBar).isGreaterThanOrEqualTo(10);
assertThat(new Code128Reader().decodeRow(0, scanline, null).getText()).isEqualTo(mark);
assertThat(svg).doesNotContain("background", "repeating-linear-gradient");
}
}
@@ -0,0 +1,32 @@
package com.baiyue.lastleg.returnreceipt.service;
import com.baiyue.lastleg.returnreceipt.dto.ReturnInventoryRequests;
import com.baiyue.lastleg.returnreceipt.mapper.ReturnInventoryCartonMapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.junit.jupiter.api.Test;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
class ReturnCartonQueryTest {
@Test
void bothQueriesUseExactCustomerScopeAndSkuExistenceWithoutAnOuterJoin() throws Exception {
var query = new ReturnInventoryRequests.Query(2, 1, "42", "SKU", "RC", "AVAILABLE", "RT");
for (String name : new String[]{"merchantCount", "merchantPage"}) {
var method = java.util.Arrays.stream(ReturnInventoryCartonMapper.class.getMethods())
.filter(candidate -> candidate.getName().equals(name)).findFirst().orElseThrow();
String script = String.join(" ", method.getAnnotation(Select.class).value());
var source = new XMLLanguageDriver().createSqlSource(new Configuration(), script, Map.class);
var bound = source.getBoundSql(Map.of("customerId", "10001", "query", query, "offset", 1L));
String sql = bound.getSql().replaceAll("\\s+", " ");
assertThat(sql).contains("WHERE c.customer_id=?", "AND EXISTS(SELECT 1 FROM ll_return_inventory_carton_item");
assertThat(sql).doesNotContain("customer_id LIKE", " JOIN ");
assertThat(bound.getParameterMappings().get(0).getProperty()).isEqualTo("customerId");
if (name.equals("merchantPage")) assertThat(sql).contains("ORDER BY c.created_at DESC,c.id DESC LIMIT ?,?");
else assertThat(sql).startsWith("SELECT COUNT(*) FROM ll_return_inventory_carton");
}
}
}
@@ -59,6 +59,41 @@ class ReturnInventoryServiceTest {
ReflectionTestUtils.setField(service, "receiptMapper", receipts);
}
@Test
void printableLabelUsesBusinessNumbersAndShowsMissingDimensionsWithoutNullOrInternalIds() {
ReturnInventoryCarton carton = new ReturnInventoryCarton();
carton.setId(31L);
carton.setCartonMark("RC-WH-20260912-480898");
carton.setCustomerId("2098676663424974850");
carton.setOverseasWarehouseId("193000000000200003");
carton.setSourceReturnNo("RT-1");
carton.setSourceBatchNo("RB-1,RB-2");
carton.setTotalQuantity(2L);
carton.setSkuTypes(1);
when(cartons.findCustomerMark(carton.getCustomerId(), carton.getCartonMark())).thenReturn(carton);
when(cartonItems.listCarton(31L)).thenReturn(List.of(item(41L, "SKU-A", 2L)));
String html = service.label(carton.getCustomerId(), carton.getCartonMark()).printableHtml();
assertThat(html).contains("<svg", "RT-1", "RB-1,RB-2", "—", "box-sizing:border-box");
assertThat(html).doesNotContain("repeating-linear-gradient", "null", carton.getCustomerId(), carton.getOverseasWarehouseId());
}
@Test
void cartonPageCountsPhysicalCartonsAndKeepsTheAuthenticatedCustomerScope() {
var query = new ReturnInventoryRequests.Query(2, 1, "42", "SKU", null, "AVAILABLE", "RT-1");
ReturnInventoryCarton carton = new ReturnInventoryCarton();
carton.setCartonMark("RC-SECOND");
carton.setSkuTypes(2);
carton.setTotalQuantity(5L);
when(cartons.merchantCount("10001", query)).thenReturn(2L);
when(cartons.merchantPage("10001", query, 1L)).thenReturn(List.of(carton));
var result = service.cartonPage("10001", query);
assertThat(result.total()).isEqualTo(2);
assertThat(result.records()).hasSize(1);
assertThat(result.records().get(0).skuTypes()).isEqualTo(2);
assertThat(result.records().get(0).totalQuantity()).isEqualTo(5);
verify(cartons).merchantPage("10001", query, 1L);
}
@Test
void receiptCartonKeepsTheSourceReturnNumber() {
ReturnOrder order = completedOrder();
@@ -85,6 +120,8 @@ class ReturnInventoryServiceTest {
source.setCustomerId("10001");
source.setOverseasWarehouseId("42");
source.setCartonMark("RC-SOURCE");
source.setSourceBatchNo("RB-1");
source.setSourceReturnNo("RT-1");
source.setStatus(ReturnInventoryService.AVAILABLE);
source.setSkuTypes(2);
source.setTotalQuantity(4L);
@@ -109,6 +146,10 @@ class ReturnInventoryServiceTest {
verify(balances).adjustCartonQuantity("10001", "42", "SKU-B", 1L);
assertThat(source.getTotalQuantity()).isEqualTo(2L);
assertThat(source.getStatus()).isEqualTo(ReturnInventoryService.AVAILABLE);
ArgumentCaptor<ReturnInventoryCarton> target = ArgumentCaptor.forClass(ReturnInventoryCarton.class);
verify(cartons).insert(target.capture());
assertThat(target.getValue().getSourceBatchNo()).isEqualTo("RB-1");
assertThat(target.getValue().getSourceReturnNo()).isEqualTo("RT-1");
}
private ReturnOrder completedOrder() {