mirror of https://github.com/jeecgboot/jeecg-boot
feat: sku weight update in app and mabang
parent
74e7df9dda
commit
3a6812c6a3
|
@ -1,9 +1,6 @@
|
|||
package org.jeecg.modules.business.controller.admin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -15,6 +12,7 @@ import org.jeecg.modules.business.entity.Sku;
|
|||
import org.jeecg.modules.business.entity.SkuWeight;
|
||||
import org.jeecg.modules.business.mongoService.SkuMongoService;
|
||||
import org.jeecg.modules.business.service.ISecurityService;
|
||||
import org.jeecg.modules.business.service.ISkuListMabangService;
|
||||
import org.jeecg.modules.business.service.ISkuService;
|
||||
import org.jeecg.modules.business.service.ISkuWeightService;
|
||||
|
||||
|
@ -24,6 +22,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.modules.business.vo.Responses;
|
||||
import org.jeecg.modules.business.vo.SkuWeightParam;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -45,6 +44,8 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|||
@RequestMapping("/skuWeight")
|
||||
@Slf4j
|
||||
public class SkuWeightController extends JeecgController<SkuWeight, ISkuWeightService> {
|
||||
@Autowired
|
||||
private ISkuListMabangService skuListMabangService;
|
||||
@Autowired
|
||||
private ISkuService skuService;
|
||||
@Autowired
|
||||
|
@ -164,7 +165,8 @@ public class SkuWeightController extends JeecgController<SkuWeight, ISkuWeightSe
|
|||
}
|
||||
|
||||
/**
|
||||
* Updating weight of multiple SKUs, creates new sku_weight entries with new effective_date and weight.
|
||||
* /!\ Not maintained use updateBatch instead.
|
||||
* Updating weight of a SKU, creates new sku_weight entry with new effective_date and weight.
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
|
@ -188,16 +190,23 @@ public class SkuWeightController extends JeecgController<SkuWeight, ISkuWeightSe
|
|||
skuWeightService.save(skuWeight);
|
||||
return Result.OK("data.invoice.effectiveDate");
|
||||
}
|
||||
/**
|
||||
* Updating weight of multiple SKUs, creates new sku_weight entries with new effective_date and weight.
|
||||
* Updates the weight in Mabang.
|
||||
* Updates the weight in MongoDB.
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
@PostMapping(value = "/updateBatch")
|
||||
public Result<String> updateBatch(@RequestBody SkuWeightParam param) {
|
||||
public Result<?> updateBatch(@RequestBody SkuWeightParam param) {
|
||||
boolean isEmployee = securityService.checkIsEmployee();
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
if(!isEmployee){
|
||||
log.info("User {}, tried to access /skuWeight/updateBatch but is not authorized.", sysUser.getUsername());
|
||||
return Result.error(403,"Forbidden.");
|
||||
}
|
||||
List<SkuWeight> skuWeights = new ArrayList<>();
|
||||
Map<String, SkuWeight> skuWeightsMap = new HashMap<>();
|
||||
for(String skuId : param.getIds()){
|
||||
Sku sku = skuService.getById(skuId);
|
||||
if(sku == null){
|
||||
|
@ -208,10 +217,15 @@ public class SkuWeightController extends JeecgController<SkuWeight, ISkuWeightSe
|
|||
skuWeight.setEffectiveDate(param.getEffectiveDate());
|
||||
skuWeight.setSkuId(skuId);
|
||||
skuWeight.setWeight(param.getWeight());
|
||||
skuWeights.add(skuWeight);
|
||||
skuMongoService.upsertSkuWeight(skuWeight);
|
||||
skuWeightsMap.put(sku.getErpCode(), skuWeight);
|
||||
}
|
||||
List<SkuWeight> skuWeights = new ArrayList<>(skuWeightsMap.values());
|
||||
Responses responses = skuListMabangService.mabangSkuWeightUpdate(skuWeights);
|
||||
List<SkuWeight> skuWeightSuccesses = new ArrayList<>();
|
||||
responses.getSuccesses().forEach(skuErpCode -> skuWeightSuccesses.add(skuWeightsMap.get(skuErpCode)));
|
||||
|
||||
skuWeightSuccesses.forEach(skuWeight -> skuMongoService.upsertSkuWeight(skuWeight));
|
||||
skuWeightService.saveBatch(skuWeights);
|
||||
return Result.OK("data.invoice.effectiveDate");
|
||||
return Result.OK(responses);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class SkuData {
|
|||
@JSONField(name="height")
|
||||
private String height;
|
||||
@JSONField(name="weight")
|
||||
private Double weight;
|
||||
private Integer weight;
|
||||
/**
|
||||
* saleRemark contains the weight
|
||||
*/
|
||||
|
|
|
@ -18,15 +18,16 @@ import org.springframework.http.ResponseEntity;
|
|||
*/
|
||||
@Slf4j
|
||||
public class SkuChangeRequest extends Request {
|
||||
|
||||
private final SkuChangeRequestBody body;
|
||||
public SkuChangeRequest(SkuChangeRequestBody body) {
|
||||
super(body);
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SkuChangeResponse send() {
|
||||
ResponseEntity<String> res = rawSend();
|
||||
return SkuChangeResponse.parse(JSON.parseObject(res.getBody()));
|
||||
return SkuChangeResponse.parse(JSON.parseObject(res.getBody()), body.getStockSku());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,21 +19,12 @@ public class SkuChangeRequestBody implements RequestBody {
|
|||
private String nameEn;
|
||||
private Integer status;
|
||||
private BigDecimal salePrice;
|
||||
private BigDecimal declareValue;
|
||||
private String declareName;
|
||||
private String declareEname;
|
||||
private String warehouse;
|
||||
private String remark;
|
||||
private Integer hasBattery;
|
||||
private Integer magnetic;
|
||||
private Integer powder;
|
||||
private Integer isPaste;
|
||||
private Integer noLiquidCosmetic;
|
||||
private Integer isFlammable;
|
||||
private Integer isKnife;
|
||||
private Integer weight;
|
||||
private Integer isGift;
|
||||
private String supplier;
|
||||
private String supplierLink;
|
||||
|
||||
@Override
|
||||
public String api() {
|
||||
|
@ -48,32 +39,11 @@ public class SkuChangeRequestBody implements RequestBody {
|
|||
putNonNull(json, "nameEN", nameEn);
|
||||
putNonNull(json, "status", status);
|
||||
putNonNull(json, "salePrice", salePrice);
|
||||
putNonNull(json, "declareValue", declareValue);
|
||||
putNonNull(json, "declareName", declareName);
|
||||
putNonNull(json, "declareEname", declareEname);
|
||||
JSONArray warehouseData = new JSONArray();
|
||||
JSONObject warehouse = new JSONObject();
|
||||
warehouse.put("name", this.warehouse);
|
||||
warehouseData.add(warehouse);
|
||||
json.put("warehouseData", warehouseData.toJSONString());
|
||||
putNonNull(json, "weight", remark);
|
||||
putNonNull(json, "weight", weight);
|
||||
putNonNull(json, "saleRemark", remark);
|
||||
putNonNull(json, "hasBattery", hasBattery);
|
||||
putNonNull(json, "magnetic", magnetic);
|
||||
putNonNull(json, "powder", powder);
|
||||
putNonNull(json, "ispaste", isPaste);
|
||||
putNonNull(json, "noLiquidCosmetic", noLiquidCosmetic);
|
||||
putNonNull(json, "is_flammable", isFlammable);
|
||||
putNonNull(json, "is_knife", isKnife);
|
||||
putNonNull(json, "isGift", isGift);
|
||||
putNonNull(json, "autoCreateSupplier", 1);
|
||||
JSONArray supplierData = new JSONArray();
|
||||
JSONObject supplier = new JSONObject();
|
||||
supplier.put("name", this.supplier);
|
||||
supplier.put("productLinkAddress", this.supplierLink);
|
||||
supplier.put("flag", 1);
|
||||
supplierData.add(supplier);
|
||||
json.put("suppliersData", supplierData.toJSONString());
|
||||
return json;
|
||||
}
|
||||
|
||||
|
@ -82,21 +52,11 @@ public class SkuChangeRequestBody implements RequestBody {
|
|||
this.nameCn = data.getNameCN();
|
||||
this.nameEn = data.getNameEN();
|
||||
this.salePrice = data.getSalePrice();
|
||||
this.declareValue = data.getDeclareValue();
|
||||
this.declareName = data.getDeclareNameZh();
|
||||
this.declareEname = data.getDeclareNameEn();
|
||||
this.warehouse = data.getWarehouse();
|
||||
this.remark = data.getSaleRemark();
|
||||
this.hasBattery = data.getHasBattery();
|
||||
this.magnetic = data.getMagnetic();
|
||||
this.powder = data.getPowder();
|
||||
this.isPaste = data.getIsPaste();
|
||||
this.noLiquidCosmetic = data.getNoLiquidCosmetic();
|
||||
this.isFlammable = data.getIsFlammable();
|
||||
this.isKnife = data.getIsKnife();
|
||||
this.weight = data.getWeight();
|
||||
this.isGift = data.getIsGift();
|
||||
this.supplier = data.getSupplier();
|
||||
this.supplierLink = data.getSupplierLink();
|
||||
}
|
||||
|
||||
private <E> void putNonNull(JSONObject json, String key, E value) {
|
||||
|
|
|
@ -35,7 +35,7 @@ public class SkuChangeResponse extends Response {
|
|||
* @return Instance
|
||||
* @throws SkuChangeRequestErrorException if response code represents error.
|
||||
*/
|
||||
public static SkuChangeResponse parse(JSONObject json) throws SkuChangeRequestErrorException {
|
||||
public static SkuChangeResponse parse(JSONObject json, String erpCode) throws SkuChangeRequestErrorException {
|
||||
log.debug("Constructing a response by json.");
|
||||
String code = json.getString("code");
|
||||
if (code.equals(Code.ERROR.value))
|
||||
|
@ -43,21 +43,20 @@ public class SkuChangeResponse extends Response {
|
|||
|
||||
JSONObject data = json.getJSONObject("data");
|
||||
String stockId = data.getString("stockId");
|
||||
String stockSku = data.getString("stockSku");
|
||||
if(data != null) {
|
||||
log.info("Constructed response: data contained {}", data);
|
||||
}
|
||||
else {
|
||||
log.info("Data is null");
|
||||
}
|
||||
return new SkuChangeResponse(Code.SUCCESS, data, stockId, stockSku);
|
||||
return new SkuChangeResponse(Code.SUCCESS, data, stockId, erpCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SkuListResponse{" +
|
||||
return "SkuChangeResponse{" +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.jeecg.modules.business.service;
|
|||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuData;
|
||||
import org.jeecg.modules.business.entity.Sku;
|
||||
import org.jeecg.modules.business.entity.SkuWeight;
|
||||
import org.jeecg.modules.business.vo.Responses;
|
||||
import org.jeecg.modules.business.vo.SkuOrderPage;
|
||||
|
||||
|
@ -38,4 +39,6 @@ public interface ISkuListMabangService extends IService<SkuData> {
|
|||
void updateSkuId();
|
||||
|
||||
void mabangSkuStockUpdate(List<String> erpCodes);
|
||||
|
||||
Responses mabangSkuWeightUpdate(List<SkuWeight> skuWeights);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.jeecg.modules.business.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.google.common.collect.Lists;
|
||||
import freemarker.template.Template;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
|
@ -9,10 +10,14 @@ import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.*;
|
|||
import org.jeecg.modules.business.domain.api.mabang.stockDoAddStock.SkuAddRequest;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockDoAddStock.SkuAddRequestBody;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockDoAddStock.SkuAddResponse;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockDoChangeStock.SkuChangeRequest;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockDoChangeStock.SkuChangeRequestBody;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockDoChangeStock.SkuChangeResponse;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockGetStockQuantity.SkuStockData;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockGetStockQuantity.SkuStockRawStream;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockGetStockQuantity.SkuStockRequestBody;
|
||||
import org.jeecg.modules.business.domain.api.mabang.stockGetStockQuantity.SkuStockStream;
|
||||
import org.jeecg.modules.business.domain.job.ThrottlingExecutorService;
|
||||
import org.jeecg.modules.business.entity.*;
|
||||
import org.jeecg.modules.business.mapper.SkuListMabangMapper;
|
||||
import org.jeecg.modules.business.mongoService.SkuMongoService;
|
||||
|
@ -36,6 +41,7 @@ import java.util.*;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -73,6 +79,7 @@ public class SkuListMabangServiceImpl extends ServiceImpl<SkuListMabangMapper, S
|
|||
Environment env;
|
||||
|
||||
private static final Integer DEFAULT_NUMBER_OF_THREADS = 10;
|
||||
private static final Integer MABANG_API_RATE_LIMIT_PER_MINUTE = 10;
|
||||
|
||||
private final static String DEFAULT_WAREHOUSE_NAME = "SZBA宝安仓";
|
||||
|
||||
|
@ -626,4 +633,95 @@ public class SkuListMabangServiceImpl extends ServiceImpl<SkuListMabangMapper, S
|
|||
skuMongoService.updateStock(sku);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Responses mabangSkuWeightUpdate(List<SkuWeight> skuWeights) {
|
||||
Responses responses = new Responses();
|
||||
List<String> failures = new ArrayList<>();
|
||||
List<Sku> skus = skuService.listByIds(skuWeights.stream()
|
||||
.map(SkuWeight::getSkuId).collect(toList()));
|
||||
|
||||
Map<String, String> remarkMappedByErpCode = new HashMap<>();
|
||||
List<List<String>> skusPartition = Lists.partition(skus.stream().map(Sku::getErpCode).collect(toList()), 50);
|
||||
for(List<String> skuPartition : skusPartition) {
|
||||
SkuListRequestBody body = new SkuListRequestBody();
|
||||
body.setStockSkuList(String.join(",", skuPartition));
|
||||
SkuListRawStream rawStream = new SkuListRawStream(body);
|
||||
SkuUpdateListStream stream = new SkuUpdateListStream(rawStream);
|
||||
List<SkuData> skusFromMabang = stream.all();
|
||||
log.info("{} skus to be updated.", skusFromMabang.size());
|
||||
if (skusFromMabang.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
skusFromMabang.stream()
|
||||
.filter(skuData -> skuData.getSaleRemark() != null)
|
||||
.forEach(skuData -> {
|
||||
String erpCode = skuData.getErpCode();
|
||||
String remark = skuData.getSaleRemark();
|
||||
remarkMappedByErpCode.put(erpCode, remark);
|
||||
});
|
||||
}
|
||||
|
||||
List<SkuData> skuDataList = skuWeights.stream()
|
||||
.map(skuWeight -> {
|
||||
Sku sku = skus.stream()
|
||||
.filter(s -> s.getId().equals(skuWeight.getSkuId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if(null == sku) {
|
||||
log.error("Sku not found : {}", skuWeight.getSkuId());
|
||||
failures.add(skuWeight.getSkuId());
|
||||
return null;
|
||||
}
|
||||
SkuData skuData = new SkuData();
|
||||
skuData.setErpCode(sku.getErpCode());
|
||||
if(remarkMappedByErpCode.containsKey(sku.getErpCode())) {
|
||||
StringBuilder remark = new StringBuilder();
|
||||
remark.append(skuWeight.getWeight());
|
||||
Matcher saleRemarkMatcher = saleRemarkPattern.matcher(remarkMappedByErpCode.get(sku.getErpCode()));
|
||||
if(saleRemarkMatcher.matches() && !saleRemarkMatcher.group(2).isEmpty()) {
|
||||
log.info("Sku {} has remark from Mabang : {}", sku.getErpCode(), saleRemarkMatcher.group(2));
|
||||
String saleRemarkNotWeight = saleRemarkMatcher.group(2);
|
||||
remark.append(saleRemarkNotWeight);
|
||||
}
|
||||
skuData.setSaleRemark(remark.toString());
|
||||
}
|
||||
else {
|
||||
skuData.setSaleRemark(String.valueOf(skuWeight.getWeight()));
|
||||
}
|
||||
skuData.setWeight(skuWeight.getWeight());
|
||||
return skuData;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(toList());
|
||||
|
||||
ExecutorService executor = ThrottlingExecutorService.createExecutorService(DEFAULT_NUMBER_OF_THREADS, MABANG_API_RATE_LIMIT_PER_MINUTE, TimeUnit.MINUTES);
|
||||
List<CompletableFuture<SkuChangeResponse>> futures = skuDataList.stream()
|
||||
.map(skuData -> CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
SkuChangeRequestBody body = new SkuChangeRequestBody(skuData);
|
||||
SkuChangeRequest request = new SkuChangeRequest(body);
|
||||
return request.send();
|
||||
} catch (Exception e) {
|
||||
log.error("Error updating weight for sku {} : {}", skuData.getErpCode(), e.getMessage());
|
||||
return new SkuChangeResponse(Response.Code.ERROR, null, null, skuData.getErpCode());
|
||||
}
|
||||
}, executor))
|
||||
.collect(toList());
|
||||
List<SkuChangeResponse> results = futures.stream().map(CompletableFuture::join).collect(toList());
|
||||
long successCount = results.stream().filter(SkuChangeResponse::success).count();
|
||||
log.info("{}/{} skus updated successfully.", successCount, skuDataList.size());
|
||||
List<String> successes = results.stream()
|
||||
.filter(SkuChangeResponse::success)
|
||||
.map(SkuChangeResponse::getStockSku)
|
||||
.collect(toList());
|
||||
failures.addAll(results.stream()
|
||||
.filter(response -> !response.success())
|
||||
.map(SkuChangeResponse::getStockSku)
|
||||
.collect(toList()));
|
||||
|
||||
responses.setSuccesses(successes);
|
||||
responses.setFailures(failures);
|
||||
return responses;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue