fix(lastleg): trace return carton sources and generate scannable labels
This commit is contained in:
+36
@@ -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");
|
||||
}
|
||||
}
|
||||
+32
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user