新增条码解析,同步服务更新

master
anthonyywj2 3 years ago
parent 812041adbd
commit dded95a77c

@ -368,6 +368,14 @@
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>

@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@RestController
@ -132,6 +133,9 @@ public class BussinessChangeTypeController {
}
if (bussinessTypeEntity != null) {
bussinessChangeTypeService.updateBusChangeType(bussinessTypeEntity);
BussinessLocalTypeEntity bussinessLocalTypeEntity = bussinessLocalTypeService.findBTByAction(bussinessTypeEntity.getAction());
bussinessLocalTypeEntity.setUpdateTime(new Date());
bussinessLocalTypeService.updateBusLocalType(bussinessLocalTypeEntity);
} else {
ResultVOUtils.error(999, "参数错误");
}

@ -199,6 +199,8 @@ public class SpsSyncDownloadService {
BussinessLocalTypeService bussinessLocalTypeService;
@Resource
BussinessOriginTypeService bussinessOriginTypeService;
@Resource
private BussinessChangeTypeService bussinessChangeTypeService;
public BaseResponse findBusType(SpsSyncDataRequest spsSyncDataRequest) {
@ -216,14 +218,19 @@ public class SpsSyncDownloadService {
BeanUtils.copyProperties(spsSyncDataRequest, bussinessLocalTypeFilterRequest);
List<BussinessLocalTypeEntity> bussinessLocalTypeEntities = bussinessLocalTypeService.filterAllList(bussinessLocalTypeFilterRequest);
List<BussinessChangeTypeEntity> allBussinessChanges = new ArrayList<>();
List<SpsBusLoclTypeResponse> spsBusLoclTypeResponses = new ArrayList<>();
bussinessLocalTypeEntities.forEach(bussinessTypeEntity -> {
SpsBusLoclTypeResponse busLoclTypeResponse = new SpsBusLoclTypeResponse();
BeanUtils.copyProperties(bussinessTypeEntity, busLoclTypeResponse);
spsBusLoclTypeResponses.add(busLoclTypeResponse);
});
List<BussinessChangeTypeEntity> bussinessChangeTypeEntities = bussinessChangeTypeService.findByAction(bussinessTypeEntity.getAction());
allBussinessChanges.addAll(bussinessChangeTypeEntities);
});
spsSyncBusResponse.setBussinessLocalTypeEntities(spsBusLoclTypeResponses);
spsSyncBusResponse.setBussinessChangeTypeEntities(allBussinessChanges);
}
if (syncDataSetEntity.isTypeThird()) {
BussinessOriginTypeFilterRequest bussinessOriginTypeFilterRequest = new BussinessOriginTypeFilterRequest();

@ -21,6 +21,7 @@ import com.glxp.sale.admin.res.basic.SpsSyncBusResponse;
import com.glxp.sale.admin.res.basic.SpsSyncDataResponse;
import com.glxp.sale.admin.res.basic.SpsSyncOrderResponse;
import com.glxp.sale.admin.service.basic.BasicUnitMaintainService;
import com.glxp.sale.admin.service.basic.BussinessChangeTypeService;
import com.glxp.sale.admin.service.basic.UdiRelevanceService;
import com.glxp.sale.admin.service.info.CompanyProductRelevanceService;
import com.glxp.sale.admin.service.inout.OrderService;
@ -60,6 +61,8 @@ public class SpsSyncUploadController {
WarehouseUserDao warehouseUserDao;
@Resource
WarehouseBussinessTypeDao warehouseBussinessTypeDao;
@Resource
BussinessChangeTypeService bussinessChangeTypeService;
@PostMapping("sps/sync/basic/upload")
public BaseResponse findProductInfo(@RequestBody SpsSyncDataResponse syncDataResponse) {
@ -292,16 +295,20 @@ public class SpsSyncUploadController {
try {
List<SpsBusLoclTypeResponse> spsBusLoclTypeResponses = syncDataResponse.getBussinessLocalTypeEntities();
List<BussinessLocalTypeEntity> bussinessLocalTypeEntities = new ArrayList<>();
BussinessLocalTypeDao mapper = batchSession.getMapper(BussinessLocalTypeDao.class);
spsBusLoclTypeResponses.forEach(spsBusLoclTypeResponse ->
{
BussinessLocalTypeEntity bussinessLocalTypeEntity = new BussinessLocalTypeEntity();
BeanUtils.copyProperties(spsBusLoclTypeResponse, bussinessLocalTypeEntity);
bussinessLocalTypeEntities.add(bussinessLocalTypeEntity);
bussinessLocalTypeEntity.setUpdateTime(null);
bussinessChangeTypeService.deleteByAction(spsBusLoclTypeResponse.getAction());
mapper.insertBussinessType(bussinessLocalTypeEntity);
});
BussinessLocalTypeDao mapper = batchSession.getMapper(BussinessLocalTypeDao.class);
for (BussinessLocalTypeEntity bussinessTypeEntity : bussinessLocalTypeEntities) {
bussinessTypeEntity.setUpdateTime(null);
mapper.insertBussinessType(bussinessTypeEntity);
List<BussinessChangeTypeEntity> bussinessChangeTypeEntities = syncDataResponse.getBussinessChangeTypeEntities();
if (CollUtil.isNotEmpty(bussinessChangeTypeEntities)) {
for (BussinessChangeTypeEntity bussinessChangeTypeEntity : bussinessChangeTypeEntities) {
bussinessChangeTypeService.insertBusChangeTypee(bussinessChangeTypeEntity);
}
}
batchSession.commit();
} catch (Exception e) {

@ -364,7 +364,7 @@ public class OrderController {
String supplementOrderNo = orderNo;
supplementOrder.setOriginUllageSupNo(orderEntity.getId());
supplementOrder.setId(supplementOrderNo);
supplementOrder.setStatus(ConstantStatus.ORDER_STATUS_PROCESS);
supplementOrder.setStatus(ConstantStatus.ORDER_STATUS_ADDITIONAL);
supplementOrder.setExportStatus(0); //设置导出状态为未导出

@ -1,5 +1,6 @@
package com.glxp.sale.admin.controller.inout;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.glxp.sale.admin.annotation.AuthRuleAnnotation;
@ -90,6 +91,19 @@ public class StockOrderDetailController {
}
List<StockOrderDetailEntity> stockOrderDetailEntityList
= stockOrderDetailService.filterStockOrderDetail(stockOrderDetailFilterRequest);
// if (CollUtil.isNotEmpty(stockOrderDetailEntityList)) {
//
// for (StockOrderDetailEntity stockOrderDetailEntity : stockOrderDetailEntityList) {
// UdiRelevanceResponse udiInfoEntity = udiRelevanceService.selectGroupById(stockOrderDetailEntity.getProductId());
// stockOrderDetailEntity.setAllowNoBatch(udiInfoEntity.isAllowNoBatch());
// stockOrderDetailEntity.setAllowNoBatch(udiInfoEntity.isAllowNoBatch());
// stockOrderDetailEntity.setAllowNoBatch(udiInfoEntity.isAllowNoBatch());
// }
//
// }
PageInfo<StockOrderDetailEntity> pageInfo;
pageInfo = new PageInfo<>(stockOrderDetailEntityList);
PageSimpleResponse<StockOrderDetailEntity> pageSimpleResponse = new PageSimpleResponse<>();
@ -289,7 +303,7 @@ public class StockOrderDetailController {
stockOrderDetailEntity.setYlqxzcrbarmc(udiInfoEntity.getYlqxzcrbarmc());
stockOrderDetailEntity.setZczbhhzbapzbh(udiInfoEntity.getZczbhhzbapzbh());
stockOrderDetailEntity.setAllowNoBatch(udiInfoEntity.isAllowNoBatch());
if(StrUtil.isNotEmpty(udiInfoEntity.getPrice())){
if (StrUtil.isNotEmpty(udiInfoEntity.getPrice())) {
stockOrderDetailEntity.setPrice(new BigDecimal(udiInfoEntity.getPrice()));
}
if (stockOrderIdsRequest.getUdiEntity() != null) {

@ -27,5 +27,6 @@ public class SpsBusLoclTypeResponse {
private String prefix;
private String localPrefix;
private boolean preIn;
private boolean changeEnable;
}

@ -36,5 +36,7 @@ public class StockOrderDetailEntity {
private String invoiceDate;
private String manufactory;
private boolean allowNoBatch;
private boolean allowNoExpire;
private boolean allowNoProduct;
}

@ -1,10 +1,7 @@
package com.glxp.sale.admin.res.basic;
import com.glxp.sale.admin.entity.auth.AuthAdmin;
import com.glxp.sale.admin.entity.basic.BussinessLocalTypeEntity;
import com.glxp.sale.admin.entity.basic.BussinessOriginTypeEntity;
import com.glxp.sale.admin.entity.basic.BussinessTypeEntity;
import com.glxp.sale.admin.entity.basic.SpsBusLoclTypeResponse;
import com.glxp.sale.admin.entity.basic.*;
import lombok.Data;
import java.util.List;
@ -15,6 +12,7 @@ public class SpsSyncBusResponse {
private List<BussinessTypeEntity> bussinessTypeEntities;
private List<BussinessOriginTypeEntity> bussinessOriginTypeEntities;
private List<SpsBusLoclTypeResponse> bussinessLocalTypeEntities;
private List<BussinessChangeTypeEntity> bussinessChangeTypeEntities;
}

@ -19,6 +19,8 @@ public interface BussinessLocalTypeService {
List<BussinessLocalTypeEntity> filterLeftJoin(BussinessLocalTypeFilterRequest bussinessTypeFilterRequest);
BussinessLocalTypeEntity findByAction(String action);
BussinessLocalTypeEntity findBTByAction(String action);
BussinessLocalTypeEntity findBTByName(String name);

@ -1,5 +1,6 @@
package com.glxp.sale.admin.service.basic.impl;
import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageHelper;
import com.glxp.sale.admin.dao.basic.BussinessLocalTypeDao;
import com.glxp.sale.admin.entity.basic.BussinessLocalTypeEntity;
@ -75,6 +76,17 @@ public class BussinessLocalTypeServiceImpl implements BussinessLocalTypeService
return data;
}
@Override
public BussinessLocalTypeEntity findByAction(String action) {
BussinessLocalTypeFilterRequest bussinessLocalTypeFilterRequest = new BussinessLocalTypeFilterRequest();
bussinessLocalTypeFilterRequest.setAction(action);
List<BussinessLocalTypeEntity> data = bussinessLocalTypeDao.filterAllList(bussinessLocalTypeFilterRequest);
if (CollUtil.isNotEmpty(data)) {
data.get(0);
}
return null;
}
@Override
public BussinessLocalTypeEntity findBTByAction(String action) {
BussinessLocalTypeFilterRequest bussinessTypeFilterRequest = new BussinessLocalTypeFilterRequest();

@ -586,7 +586,7 @@ public class IoTransInoutService {
return;
}
} else if (orderEntity.getFromType().intValue() == ConstantStatus.FROM_UDIWMS) {
if (!bussinessTypeEntity.isSecCheckUdiwms()) {
if (!bussinessTypeEntity.isCheckUdiwms()) {
unCheckFinish(orderEntity, warehouseEntityList);
return;
}

@ -1,9 +1,16 @@
package com.glxp.sale.admin.util;
import cn.hutool.core.util.StrUtil;
import com.glxp.sale.admin.entity.basic.UdiInfoEntity;
import com.glxp.sale.admin.entity.inout.WarehouseEntity;
import com.glxp.sale.admin.entity.udid.UdiEntity;
import com.glxp.sale.admin.util.gs1.AI;
import com.glxp.sale.admin.util.gs1.AIs;
import com.glxp.sale.admin.util.gs1.Gs1128Decoder;
import com.glxp.sale.admin.util.gs1.Gs1128Engine;
import java.util.Map;
/**
* @author
@ -25,7 +32,7 @@ public class FilterUdiUtils {
return null;
}
public static UdiEntity getGS1Udi(String data) {
public static UdiEntity getGS1UdiOld(String data) {
String batchNo = "";
String produceDate = "";
String expireDate = "";
@ -50,8 +57,8 @@ public class FilterUdiUtils {
} else {
serialNo = null;
}
}else{
if (last.length() >= 10 && last.substring(8, 10).equals("21")){
} else {
if (last.length() >= 10 && last.substring(8, 10).equals("21")) {
serialNo = last.substring(10);
}
}
@ -64,8 +71,8 @@ public class FilterUdiUtils {
} else {
serialNo = null;
}
}else {
if (last.length() >= 10 && last.substring(8, 10).equals("21")){
} else {
if (last.length() >= 10 && last.substring(8, 10).equals("21")) {
serialNo = last.substring(10);
}
}
@ -90,7 +97,7 @@ public class FilterUdiUtils {
batchNo = data.substring(34, data.length());
}
}else if (data.length() >= 34 && data.substring(32, 34).equals("21")) {
} else if (data.length() >= 34 && data.substring(32, 34).equals("21")) {
serialNo = data.substring(34, data.length());
}
} else if (data.length() >= 26 && data.substring(24, 26).equals("10")) {
@ -164,6 +171,32 @@ public class FilterUdiUtils {
return udiEntity;
}
public static UdiEntity getGS1Udi(String data) {
Gs1128Engine engine = new Gs1128Engine();
Gs1128Decoder decoder = engine.decoder();
Map<AI, String> result = decoder.decode("]C1" + data);
UdiEntity udiEntity = new UdiEntity();
for (Map.Entry<AI, String> entry : result.entrySet()) {
if (entry.getKey() == AIs.GTIN) {
udiEntity.setUdi(entry.getValue());
} else if (entry.getKey() == AIs.BATCH_LOT) {
udiEntity.setBatchNo(entry.getValue());
} else if (entry.getKey() == AIs.EXPIRY) {
udiEntity.setExpireDate(entry.getValue());
} else if (entry.getKey() == AIs.PROD_DATE) {
udiEntity.setProduceDate(entry.getValue());
} else if (entry.getKey() == AIs.SERIAL) {
udiEntity.setSerialNo(entry.getValue());
}
}
if (StrUtil.isEmpty(udiEntity.getUdi())) {
return null;
} else
return udiEntity;
}
public static UdiEntity getZGCUdi(String data) {
String batchNo = "";
String produceDate = "";

@ -0,0 +1,14 @@
package com.glxp.sale.admin.util.gs1;
/**
* @author guilherme.pacheco
*/
public interface AI {
String getCode();
String getDescription();
String getFormat();
}

@ -0,0 +1,112 @@
package com.glxp.sale.admin.util.gs1;
/**
* @author guilherme.pacheco
*/
public enum AIs implements AI {
SSCC("00", "Serial Shipping Container Code", "n2+n18"),
GTIN("01", "GTIN-14", "n2+n14"),
CONTENT("02", "Number of containers", "n2+n14"),
BATCH_LOT("10", "Batch Number", "n2+an..20"),
PROD_DATE("11", "Production Date", "n2+n6"),
DUE_DATE("12", "Production Date", "n2+n6"),
PACK_DATE("13", "Packaging Date", "n2+n6"),
BEST_BEFORE("15", "Sell by Date (Quality Control) ", "n2+n6"),
EXPIRY("17", "Expiration Date", "n2+n6"),
VARIANT("20", "Product Variant", "n2+n2"),
SERIAL("21", "Serial Number", "n2+an..20"),
INTERNAL("91", "Company Internal Information", "n2+an..30"),
ADDITIONAL_ID("240", "Additional Product Identification", "n3+an..30"),
CUSTOMER_PART("241", "Customer Part Number", "n3+an..30"),
VARIATION_NUMBER("242", "242 Made-to-Order variation no", "n2+n..30"),
SECONDARY_SERIAL("250", "Secondary Serial Number", "n3+an..30"),
REF_TO_SOURCE("251", "Reference to source entity", "n3+an..30"),
DOC_ID("253", "Global Document Type Identifier", "n3+n13+n..17"),
GLN_EXTENSION("254", "GLN extension component ", "n3+an..20"),
VAR_COUNT("30", "Quantity Each", "n2+n..8"),
NET_WEIGHT("310n", "Product Net Weight in kg", "n4+n6"),
LENGTH("311n", "Product Length/1st Dimension, in meters", "n4+n6"),
WIDTH("312n", "Product Width/Diameter/2nd Dimension, in meters", "n4+n6"),
HEIGHT("313n", "Product Depth/Thickness/3rd Dimension, in meters", "n4+n6"),
AREA("314n", "Product Area, in square meters", "n4+n6"),
NET_VOLUME_LITERS("315n", " Product Volume, in liters", "n4+n6"),
NET_VOLUME_CUBICS("316n", " product Volume, in cubic meters", "n4+n6"),
NET_WEIGHT_POUNDS("320n", "Product Net Weight, in pounds", "n4+n6"),
LENGTH_INCHES("321n", "Product Length/1st Dimension, in inches", "n4+n6"),
LENGTH_PES("322n", "Product Length/1st Dimension, in feet", "n4+n6"),
LENGTH_YARDS("323n", "Product Length/1st Dimension, in yards", "n4+n6"),
WIDTH_INCHES("324n", "Product Width/Diameter/2nd Dimension, in inches", "n4+n6"),
WIDTH_FEET("325n", "Product Width/Diameter/2nd Dimension, in feet", "n4+n6"),
WIDTH_YARDS("326n", "Product Width/Diameter/2nd Dimension, in yards", "n4+n6"),
HEIGHT_INCHES("327n", "Product Depth/Thickness/3rd Dimension, in inches", "n4+n6"),
HEIGHT_FEET("328n", "Product Depth/Thickness/3rd Dimension, in feet", "n4+n6"),
HEIGHT_YARDS("329n", "Product Depth/Thickness/3rd Dimension, in yards", "n4+n6"),
PRODUCT_AREA_INCHES("350n", "Product Area (Square Inches)", "n4+n6"),
PRODUCT_AREA_FEET("351n", "Product Area (Square Feet)", "n4+n6"),
PRODUCT_AREA_YARDS("352n", "Product Area (Square Yards)", "n4+n6"),
CONTAINER_AREA_INCHES("353n", "Container Area (Square Inches) ", "n4+n6"),
CONTAINER_AREA_FEET("354n", "Container Area (Square Feet) ", "n4+n6"),
CONTAINER_AREA_YARDS("355n", "Container Area (Square Yards) ", "n4+n6"),
NET_WEIGHT_OUNCES("356n", "Net Weight (Troy Ounces)", "n4+n6"),
PRODUCT_VOLUME_QUARTS("360n", " Product Volume (Quarts)", "n4+n6"),
PRODUCT_VOLUME_GALLONS("361n", " Product Volume (Gallons)", "n4+n6"),
CONTAINER_VOLUME_QUARTS("362n", " Container Gross Volume (Quarts)", "n4+n6"),
CONTAINER_VOLUME_GALLONS("363n", " Container Gross Volume (Gallons)", "n4+n6"),
PRODUCT_VOLUME_INCHES("364n", " Product Volume (Cubic Inches)", "n4+n6"),
PRODUCT_VOLUME_FEET("365n", " Product Volume (Cubic Feet)", "n4+n6"),
PRODUCT_VOLUME_YARDS("366n", " Product Volume (Cubic Yards)", "n4+n6"),
CONTAINER_VOLUME_INCHES("367n", " Container Gross Volume (Cubic Inches)", "n4+n6"),
CONTAINER_VOLUME_FEET("368n", " Container Gross Volume (Cubic Feet)", "n4+n6"),
CONTAINER_VOLUME_YARDS("369n", " Container Gross Volume (Cubic Yards)", "n4+n6"),
COUNT("37", " Number of Units Contained", "n2+n..8"),
ORDER_NUMBER("400", "Customer Purchase Order Number", "n3+an..30"),
SHIP_TO_DELIVER_TO_LOCATION_CODE("410", "Ship To/Deliver To Location Code (EAN13 or DUNS code)", "n3+n13"),
BILL_TO_INVOICEE_TO_LOCATION_CODE("411", "Bill To/Invoice Location Code (EAN13 or DUNS code)", "n3+n13"),
PURCHASE_FROM_LOCATION_CODE("412", "Purchase From Location Code (EAN13 or DUNS code)", "n3+n13"),
SHIP_TO_DELIVER_TO_POSTALCODE("420", "Ship To/Deliver To Postal Code (Single Postal Authority)", "n3+an..9"),
SHIP_TO_DELIVER_TO_MULTI_POSTALCODE("421", "Ship To/Deliver To Postal Code (Multiple Postal Authority)",
"n3+n3+an..9"),
ORIGIN("422", "Country orign", "n3+n3"),
COUNTRY_INITIAL_PROCESS("423", "County initial processing", "n3+n3+n..12"),
COUNTRY_PROCESS("424", "County processing", "n3+n3"),
COUNTRY_DISASSEMBLY("425", "Country disassembly", "n3+n3"),
COUNTRY_FULL_PROCESS("426", "Country pull processing", "n3+n3"),
ROLL_PRODUCTS("8001", "Roll Products Width/Length/Core Diameter", "n4+n14"),
ESN("8002", "Electronic Serial Number (ESN) for Cellular Phone", "n4+an..20"),
UPC_EAN_RETURNABLE_ASSET("8003", "UPC/EAN Number and Serial Number of Returnable Asset", "n4+an..30"),
UPC_EAN_SERIAL_IDENTIFICATION("8004", "UPC/EAN Serial Identification", "n4+an..30"),
PRICE_UNIT_MEASURE("8005", "Price per Unit of Measure", "n4+n6"),
;
private final String code;
private final String description;
private final String format;
private AIs(String code, String description, String format) {
this.code = code;
this.description = description;
this.format = format;
}
@Override
public String getCode() {
return code;
}
@Override
public String getDescription() {
return description;
}
@Override
public String getFormat() {
return format;
}
@Override
public String toString() {
return description;
}
}

@ -0,0 +1,32 @@
package com.glxp.sale.admin.util.gs1;
/**
* @author guilherme.pacheco
*/
public final class AiFactory {
private AiFactory() {
super();
}
public static AI create(String code, String description, String format) {
return new AI() {
@Override
public String getFormat() {
return format;
}
@Override
public String getDescription() {
return description;
}
@Override
public String getCode() {
return code;
}
};
}
}

@ -0,0 +1,71 @@
package com.glxp.sale.admin.util.gs1;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
/**
* @author guilherme.pacheco
*/
final class Format {
private static final String JOIN_SYMBOL = "+";
private final List<Session> sessions;
public Format(List<Session> sessions) {
this.sessions = Validate.notEmpty(sessions);
}
public Format(Session... sessions) {
this(Arrays.asList(sessions));
}
public Session getIdentifier() {
return sessions.get(0);
}
public List<Session> getDataSessions() {
return sessions.subList(1, sessions.size());
}
@Override
public String toString() {
return sessions.stream().map(String::valueOf).collect(Collectors.joining(JOIN_SYMBOL));
}
public boolean isValid(String value) {
if (StringUtils.isBlank(value)) {
return false;
}
if (!validLength(value)) {
return false;
}
return validate(value);
}
private boolean validate(String value) {
return getDataSessions().stream().allMatch(s -> s.getType().isValid(Gs1128Utils.value(s, value)));
}
private boolean validLength(String value) {
return isVaried() ? value.length() <= getLength() : value.length() == getLength();
}
public int getLength() {
return getDataSessions().stream().mapToInt(Session::getLength).sum();
}
public boolean isVaried() {
return getDataSessions().stream().anyMatch(Session::isVaried);
}
public static Format valueOf(String value) {
String[] split = StringUtils.split(value, JOIN_SYMBOL);
List<Session> list = Arrays.stream(split).map(Session::valueOf).collect(Collectors.toList());
return new Format(list);
}
}

@ -0,0 +1,61 @@
package com.glxp.sale.admin.util.gs1;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.WeakHashMap;
import java.util.function.Function;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
/**
* @author guilherme.pacheco
*/
public final class Gs1128Decoder {
private final Collection<AI> ais;
Gs1128Decoder(Collection<AI> ais) {
this.ais = ais;
}
public Map<AI, String> decode(final String barcode) {
validateBarcode(barcode);
String barcodeValue = StringUtils.remove(barcode, Gs1128Utils.PREFIX);
return extract(barcodeValue);
}
private Map<AI, String> extract(String barcode) {
final Iterator<Character> iterator = Gs1128Utils.iterator(barcode);
final Map<AI, String> result = new WeakHashMap<>(4);
StringBuilder builder = new StringBuilder();
while (iterator.hasNext()) {
builder.append(iterator.next());
Optional<Map<AI, String>> mapAi = mapAi(iterator, builder.toString());
if (mapAi.isPresent()) {
result.putAll(mapAi.get());
builder = new StringBuilder();
}
}
return result;
}
private Optional<Map<AI, String>> mapAi(Iterator<Character> iterator, String builder) {
return ais.stream().filter(v -> v.getCode().equals(builder)).findFirst().map(aiValue(iterator));
}
private Function<AI, Map<AI, String>> aiValue(Iterator<Character> iterator) {
return ai -> {
String value = Gs1128Utils.value(ai, iterator);
return Map.of(ai, value);
};
}
private void validateBarcode(String barcode) {
Validate.notBlank(barcode, "Barcode cannot be blank");
Validate.isTrue(StringUtils.startsWith(barcode, Gs1128Utils.PREFIX), "Barcode must start with prefix Gs1-128 \"]C1\"");
}
}

@ -0,0 +1,33 @@
package com.glxp.sale.admin.util.gs1;
import java.util.Collection;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
/**
* @author guilherme.pacheco
*/
public final class Gs1128Encoder {
Gs1128Encoder() {
super();
}
public String encode(Collection<Segment> segments) {
Validate.notEmpty(segments);
String barcode = joinSegments(segments);
return checkBarcode(barcode);
}
private String checkBarcode(String barcode) {
return StringUtils.removeEnd(barcode, String.valueOf(Gs1128Utils.END_AI_VARIED));
}
private String joinSegments(Collection<Segment> segments) {
String joinValue = segments.stream().map(Segment::encode).collect(Collectors.joining());
return Gs1128Utils.PREFIX.concat(joinValue);
}
}

@ -0,0 +1,35 @@
package com.glxp.sale.admin.util.gs1;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
/**
* @author guilherme.pacheco
*/
public final class Gs1128Engine {
private final Set<AI> aisRegistred = new HashSet<>();
public Gs1128Engine() {
aisRegistred.addAll(EnumSet.allOf(AIs.class));
}
public void registerAi(AI ai) {
aisRegistred.add(ai);
}
public Set<AI> getAisRegistred() {
return Collections.unmodifiableSet(aisRegistred);
}
public Gs1128Encoder encoder() {
return new Gs1128Encoder();
}
public Gs1128Decoder decoder() {
return new Gs1128Decoder(aisRegistred);
}
}

@ -0,0 +1,59 @@
package com.glxp.sale.admin.util.gs1;
import java.util.Iterator;
/**
* @author guilherme.pacheco
*/
final class Gs1128Utils {
public static final String PREFIX = "]C1";
public static final char END_AI_VARIED = (char) 29;
private Gs1128Utils() {
super();
}
public static Iterator<Character> iterator(String value) {
return value.chars().mapToObj(c -> (char) c).iterator();
}
public static String value(AI ai, Iterator<Character> iterator) {
Format format = Format.valueOf(ai.getFormat());
if (format.isVaried()) {
return variedValue(iterator);
} else {
return fixedValue(format.getLength(), iterator);
}
}
public static String value(Session session, String value) {
Iterator<Character> iterator = iterator(value);
if (session.isVaried()) {
return variedValue(iterator);
} else {
return fixedValue(session.getLength(), iterator);
}
}
private static String fixedValue(int size, Iterator<Character> iterator) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < size; i++) {
builder.append(iterator.next());
}
return builder.toString();
}
private static String variedValue(Iterator<Character> iterator) {
StringBuilder builder = new StringBuilder();
while (iterator.hasNext()) {
char value = iterator.next();
if (value == END_AI_VARIED) {
break;
}
builder.append(value);
}
return builder.toString();
}
}

@ -0,0 +1,35 @@
package com.glxp.sale.admin.util.gs1;
import org.apache.commons.lang3.Validate;
/**
* @author guilherme.pacheco
*/
public final class Segment {
private final AI ai;
private final String value;
private final Format format;
public Segment(AI ai, String value) {
this.ai = Validate.notNull(ai, "Invalid AI");
format = Format.valueOf(ai.getFormat());
this.value = validateValue(format, value);
}
private String validateValue(Format format, String value) {
Validate.notBlank(value, "Invalid segment value");
Validate.notNull(format, "Invalid format");
Validate.isTrue(format.isValid(value));
return value;
}
String encode() {
String codeValue = ai.getCode().concat(value);
if (format.isVaried()) {
return codeValue + Gs1128Utils.END_AI_VARIED;
}
return codeValue;
}
}

@ -0,0 +1,69 @@
package com.glxp.sale.admin.util.gs1;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
/**
* @author guilherme.pacheco
*/
final class Session {
private static final String VARIED_CONSTANT = "..";
private final SessionType type;
private final boolean varied;
private final int length;
public Session(SessionType type, int length, boolean varied) {
this.type = Validate.notNull(type);
Validate.isTrue(length > 0, "Session invalid lenght");
this.length = length;
this.varied = varied;
}
public SessionType getType() {
return type;
}
public int getLength() {
return length;
}
public boolean isVaried() {
return varied;
}
public static Session valueOf(String value) {
Validate.notBlank(value, "Session cannot be blank");
SessionType type = sessionType(value);
String strLength = value.substring(type.length());
boolean varied = strLength.startsWith(VARIED_CONSTANT);
int length = createLength(strLength, varied);
return new Session(type, length, varied);
}
private static SessionType sessionType(String value) {
return SessionType.valueByPrefix(value).orElseThrow(() -> new IllegalArgumentException("Invalid session type"));
}
private static Integer createLength(String strLength, boolean varied) {
try {
if (varied) {
String lengthValue = StringUtils.substringAfter(strLength, VARIED_CONSTANT);
return Integer.parseInt(lengthValue);
}
return Integer.valueOf(strLength);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException(String.format("Invalid length: '%s'", strLength), ex);
}
}
@Override
public String toString() {
return new StringBuilder(type.getSymbol())
.append(varied ? VARIED_CONSTANT : StringUtils.EMPTY)
.append(length)
.toString();
}
}

@ -0,0 +1,49 @@
package com.glxp.sale.admin.util.gs1;
import java.util.EnumSet;
import java.util.Optional;
import java.util.function.Predicate;
import org.apache.commons.lang3.StringUtils;
/**
* @author guilherme.pacheco
*/
enum SessionType {
ALPHANUMERIC("an", v -> Character.isAlphabetic(v) || Character.isDigit(v)),
ALPHABETIC("a", v -> Character.isAlphabetic(v)),
NUMERIC("n", v -> Character.isDigit(v));
private final String symbol;
private final Predicate<Character> validator;
private SessionType(String symbol, Predicate<Character> validator) {
this.symbol = symbol;
this.validator = validator;
}
public boolean isValid(String value) {
if (StringUtils.isBlank(value)) {
return false;
}
return value.chars().mapToObj(c -> (char) c).allMatch(validator::test);
}
public String getSymbol() {
return symbol;
}
public int length() {
return symbol.length();
}
public static Optional<SessionType> valueByPrefix(String value) {
if (StringUtils.isBlank(value)) {
return Optional.empty();
}
return EnumSet.allOf(SessionType.class).stream()
.filter(v -> StringUtils.startsWithIgnoreCase(value, v.symbol))
.findFirst();
}
}

@ -221,7 +221,7 @@
AND productIdFk = #{productIdFk}
</if>
<if test="batchNo != '' and batchNo != null and batchNo!='empty'">
AND inv_product.batchNo like concat('%',#{batchNo},'%')
AND inv_prein_product_detail.batchNo like concat('%',#{batchNo},'%')
</if>
<if test="batchNo == 'empty'">
AND batchNo is NULL

Loading…
Cancel
Save