feature : Sku purchase order Mabang API

pull/6221/head
Gauthier LO 2024-02-20 15:19:07 +01:00
parent 26d3c61c08
commit faa3636c3d
42 changed files with 1924 additions and 11 deletions

3
.gitattributes vendored
View File

@ -3,3 +3,6 @@
*.html linguist-language=Java
*.vue linguist-language=Java
*.sql linguist-language=Java
*.java filter=javaignore
*.yml filter=ymlignore

View File

@ -126,5 +126,7 @@ public class LoginUser {
/**设备id uniapp推送用*/
private String clientId;
/**Mabang username*/
private String mabangUsername;
}

View File

@ -0,0 +1,162 @@
package org.jeecg.modules.business.controller.admin;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.business.entity.Provider;
import org.jeecg.modules.business.service.IProviderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;
/**
* @Description: provider
* @Author: jeecg-boot
* @Date: 2024-02-14
* @Version: V1.0
*/
@Api(tags="provider")
@RestController
@RequestMapping("/business/provider")
@Slf4j
public class ProviderController extends JeecgController<Provider, IProviderService> {
@Autowired
private IProviderService providerService;
/**
*
*
* @param provider
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "provider-分页列表查询")
@ApiOperation(value="provider-分页列表查询", notes="provider-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<Provider>> queryPageList(Provider provider,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<Provider> queryWrapper = QueryGenerator.initQueryWrapper(provider, req.getParameterMap());
Page<Provider> page = new Page<Provider>(pageNo, pageSize);
IPage<Provider> pageList = providerService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
*
*
* @param provider
* @return
*/
@AutoLog(value = "provider-添加")
@ApiOperation(value="provider-添加", notes="provider-添加")
@RequiresPermissions("business:provider:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody Provider provider) {
providerService.save(provider);
return Result.OK("添加成功!");
}
/**
*
*
* @param provider
* @return
*/
@AutoLog(value = "provider-编辑")
@ApiOperation(value="provider-编辑", notes="provider-编辑")
@RequiresPermissions("business:provider:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody Provider provider) {
providerService.updateById(provider);
return Result.OK("编辑成功!");
}
/**
* id
*
* @param id
* @return
*/
@AutoLog(value = "provider-通过id删除")
@ApiOperation(value="provider-通过id删除", notes="provider-通过id删除")
@RequiresPermissions("business:provider:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
providerService.removeById(id);
return Result.OK("删除成功!");
}
/**
*
*
* @param ids
* @return
*/
@AutoLog(value = "provider-批量删除")
@ApiOperation(value="provider-批量删除", notes="provider-批量删除")
@RequiresPermissions("business:provider:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.providerService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* id
*
* @param id
* @return
*/
//@AutoLog(value = "provider-通过id查询")
@ApiOperation(value="provider-通过id查询", notes="provider-通过id查询")
@GetMapping(value = "/queryById")
public Result<Provider> queryById(@RequestParam(name="id",required=true) String id) {
Provider provider = providerService.getById(id);
if(provider==null) {
return Result.error("未找到对应数据");
}
return Result.OK(provider);
}
/**
* excel
*
* @param request
* @param provider
*/
@RequiresPermissions("business:provider:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, Provider provider) {
return super.exportXls(request, provider, Provider.class, "provider");
}
/**
* excel
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("business:provider:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, Provider.class);
}
}

View File

@ -25,6 +25,7 @@ import org.jeecg.modules.business.mapper.PlatformOrderContentMapper;
import org.jeecg.modules.business.mapper.PlatformOrderMapper;
import org.jeecg.modules.business.mapper.PurchaseOrderContentMapper;
import org.jeecg.modules.business.service.*;
import org.jeecg.modules.business.service.impl.ProviderMabangServiceImpl;
import org.jeecg.modules.business.vo.*;
import org.jeecg.modules.quartz.entity.QuartzJob;
import org.jeecg.modules.quartz.service.IQuartzJobService;
@ -90,6 +91,8 @@ public class InvoiceController {
@Autowired
private IProductService productService;
@Autowired
private ProviderMabangServiceImpl providerMabangService;
@Autowired
private IPurchaseOrderService purchaseOrderService;
@Autowired
private PurchaseOrderContentMapper purchaseOrderContentMapper;
@ -127,7 +130,6 @@ public class InvoiceController {
private final String SECTION_START = "<section><ul>";
private final String SECTION_END = "</ul></section>";
@GetMapping(value = "/shopsByClient")
public Result<List<Shop>> getShopsByClient(@RequestParam("clientID") String clientID) {
log.info("Request for shop by client {}", clientID);
@ -421,7 +423,7 @@ public class InvoiceController {
@PostMapping("/makeManualSkuPurchaseInvoice")
public Result<?> createOrder(@RequestBody Map<String, Integer> payload) {
InvoiceMetaData metaData;
List<SkuQuantity> skuQuantities = new ArrayList<>();
List<SkuQuantity> skuQuantities = new ArrayList<>();
for(Map.Entry<String, Integer> entry : payload.entrySet()) {
String skuId = skuService.getIdFromErpCode(entry.getKey());
skuQuantities.add(new SkuQuantity(skuId, entry.getValue()));
@ -429,6 +431,7 @@ public class InvoiceController {
try {
String purchaseId = purchaseOrderService.addPurchase(skuQuantities);
metaData = purchaseOrderService.makeInvoice(purchaseId);
providerMabangService.addPurchaseOrderToMabang(payload, metaData);
return Result.OK(metaData);
} catch (UserException e) {
return Result.error(e.getMessage());

View File

@ -44,6 +44,9 @@ public class SkuData {
private BigDecimal salePrice;
@JSONField(name="declareValue")
private BigDecimal declareValue;
/**最新采购价*/
@JSONField(name="purchasePrice")
private BigDecimal purchasePrice;
/**
* if stockPicture is empty, we use it
*/

View File

@ -0,0 +1,31 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
public enum DateType {
UPDATE(1, "updateTime"),
CREATE(2, "timeCreated");
private final int code;
private final String text;
DateType(int code, String text) {
this.code = code;
this.text = text;
}
public String getCode() {
return String.valueOf(code);
}
public String text() {
return text;
}
public static DateType fromCode(Integer code) {
for (DateType dateType : DateType.values()) {
if (dateType.code == code) {
return dateType;
}
}
return null;
}
}

View File

@ -0,0 +1,109 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
@Data
@TableName("sku")
public class SkuData {
/**
* Primary key
*/
@JSONField(deserialize = false)
@TableId(type = IdType.ASSIGN_ID)
private String id = IdWorker.getIdStr();
@JSONField(name="id")
private Integer stockSkuId;
@JSONField(name="timeCreated")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String createdTime;
@JSONField(name="stockSku")
private String erpCode;
@JSONField(name="nameCN")
private String nameCN;
@JSONField(name="nameEN")
private String nameEN;
/**
* 1.; 2.; 3.; 4.; 5.
*/
@JSONField(name="status")
private Integer status;
@JSONField(name="originalSku")
private String originalSku;
@JSONField(name="salePrice")
private BigDecimal salePrice;
@JSONField(name="declareValue")
private BigDecimal declareValue;
/**最新采购价*/
@JSONField(name="purchasePrice")
private BigDecimal purchasePrice;
/**默认供应商名称,接口参数传showProvider才返回*/
@JSONField(name="provider")
private String provider;
/**
* if stockPicture is empty, we use it
*/
@JSONField(name="stockPicture")
private String stockPicture;
/**
* else we use salePicture
*/
@JSONField(name="salePicture")
private String salePicture;
/**
* length, width and height are used in computing volume of item, but volume is now an obsolete field
*/
@JSONField(name="length")
private String length;
@JSONField(name="width")
private String width;
@JSONField(name="height")
private String height;
@JSONField(name="weight")
private Double weight;
/**
* saleRemark contains the weight
*/
@JSONField(name="saleRemark")
private String saleRemark;
/**
* :1;2
*/
@JSONField(name="hasBattery")
private Integer hasBattery;
/**
* :1:;2:
*/
@JSONField(name="magnetic")
private Integer magnetic ;
public SkuStatus getStatus() {
return SkuStatus.fromCode(this.status);
}
public String toString() {
return "ID : " + this.id +
"\nStockSkuId : " + this.stockSkuId +
"\nStockSku : " + this.erpCode +
"\nStatus : " + this.status +
"\nEn name : " + this.nameEN +
"\nZh name : " + this.nameCN +
"\nDeclared Value : " + this.declareValue +
"\nSale Price : " + this.salePrice +
"\nSale Remark (weight): " + this.saleRemark +
"\nStock Picture : " + this.stockPicture +
"\nsale Picture : " + this.salePicture +
"\nBattery : " + this.hasBattery +
"\nMagnetic : " + this.magnetic
;
}
}

View File

@ -0,0 +1,80 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.NetworkDataStream;
import java.util.NoSuchElementException;
/**
* This stream control reception of the response of the mabang order list API
*/
@Slf4j
public class SkuListRawStream implements NetworkDataStream<SkuListResponse> {
/**
* Instance's current request.
*/
private final SkuListRequestBody toSend;
/**
* Response of last request.
*/
private SkuListResponse currentResponse;
private boolean began;
public SkuListRawStream(SkuListRequestBody firstBody) {
this.toSend = firstBody;
this.currentResponse = null;
began = false;
}
@Override
public SkuListResponse attempt() {
log.info("Begin the first request");
this.currentResponse = new SkuListRequest(toSend).send();
if (currentResponse.getData().isEmpty()) {
return null;
}
began = true;
toSend.nextPage();
return currentResponse;
}
/**
* Check whether there are still order left, network communication is done here.
*
* @return true if there are, otherwise false.
*/
@Override
public boolean hasNext() throws SkuListRequestErrorException {
if (!began) {
throw new IllegalStateException("Calling hasNext before begin");
}
// still has page left, true
if (!currentResponse.getCursor().isEmpty() || currentResponse.getCursor().equals(toSend.getCursor())) {
log.info("page: {}, has next", toSend.getPage());
toSend.setCursor(currentResponse.getCursor());
return true;
}
// no page left, false
log.info("No page left, end");
return false;
}
/**
* Get next Order.
*
* @return next order.
* @throws NoSuchElementException if data is already empty.
* @throws SkuListRequestErrorException if request format is not valid.
*/
@Override
public SkuListResponse next() throws SkuListRequestErrorException {
if (!hasNext())
throw new NoSuchElementException();
log.info("Sending request for page {}/{}.", toSend.getPage(), toSend.getTotalPages());
this.currentResponse = new SkuListRequest(toSend).send();
toSend.nextPage();
return this.currentResponse;
}
}

View File

@ -0,0 +1,32 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.Request;
import org.springframework.http.ResponseEntity;
/**
* This class contains some key information and necessary procedures
* to send a request to mabang "get order list" API, for example: target URL,
* correspondent HTTP method, procedure to generate authorization.
* <p>
* One can use static method {@code sendRequest} to send request with body,
* and then get respective response. Or use instance of this class, see below.
* <p>
* Because data returned by target API is paginated. One can retrieve all data
* by calling next and hasNext.
*/
@Slf4j
public class SkuListRequest extends Request {
public SkuListRequest(SkuListRequestBody body) {
super(body);
}
@Override
public SkuListResponse send() {
ResponseEntity<String> res = rawSend();
return SkuListResponse.parse(JSON.parseObject(res.getBody()));
}
}

View File

@ -0,0 +1,117 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.business.domain.api.mabang.RequestBody;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.function.Function;
@Getter
@Setter
public class SkuListRequestBody implements RequestBody {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private String stockSku = "";
// 50 skus max
private String stockSkuList = "";
private DateType datetimeType;
private LocalDateTime startDate;
private LocalDateTime endDate;
private Integer page = 1;
private Integer total;
private String cursor = "";
private Integer maxRows = 10;
private Integer showVirtualSku = 0;
private Integer showProvider = 0;
private Integer showWarehouse = 0;
private Integer showLabel = 0;
private Integer showAttributes = 0;
private Integer showMachining = 0;
@Override
public String api() {
return "stock-do-search-sku-list-new";
}
@Override
public JSONObject parameters() {
JSONObject json = new JSONObject();
putNonNull(json, "stockSku", stockSku);
putNonNull(json, "stockSkuList", stockSkuList);
putNonNull(json, datetimeType.text() + "Start", startDate, formatter::format);
putNonNull(json, datetimeType.text() + "End", endDate, formatter::format);
putNonNull(json, "cursor", cursor);
putNonNull(json, "maxRows", maxRows);
putNonNull(json, "showVirtualSku", showVirtualSku);
putNonNull(json, "showProvider", showProvider);
putNonNull(json, "showWarehouse", showWarehouse);
putNonNull(json, "showLabel", showLabel);
putNonNull(json, "showAttributes", showAttributes);
return json;
}
void nextPage() {
setPage(this.page + 1);
}
int getPage() {
return page;
}
public SkuListRequestBody setDatetimeType(DateType datetimeType) {
this.datetimeType = datetimeType;
return this;
}
public SkuListRequestBody setStartDate(LocalDateTime startDate) {
this.startDate = startDate;
return this;
}
public SkuListRequestBody setEndDate(LocalDateTime endDate) {
this.endDate = endDate;
return this;
}
public SkuListRequestBody setPage(int page) {
this.page = page;
return this;
}
public SkuListRequestBody setRowsPerPage(int rowsPerPage) {
this.page = rowsPerPage;
return this;
}
public SkuListRequestBody setSkuStockList(String skuStockList) {
this.stockSkuList = skuStockList;
return this;
}
public SkuListRequestBody setShowProvider(int showProvider) {
this.showProvider = showProvider;
return this;
}
public SkuListRequestBody setCursor(String cursor) {
this.cursor = cursor;
return this;
}
public SkuListRequestBody setTotal(int total) {
this.total = total;
return this;
}
public int getTotalPages() {
return (int) Math.ceil((double) total / maxRows);
}
private <E> void putNonNull(JSONObject json, String key, E value) {
if (value != null) {
json.put(key, value);
}
}
private <E, T> void putNonNull(JSONObject json, String key, E value, Function<E, T> mapper) {
if (value != null) {
json.put(key, mapper.apply(value));
}
}
}

View File

@ -0,0 +1,13 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
import java.time.LocalDateTime;
public class SkuListRequestBodys {
public static SkuListRequestBody allSkuOfDateType(LocalDateTime start, LocalDateTime end, DateType dateType) {
return new SkuListRequestBody()
.setDatetimeType(dateType)
.setStartDate(start)
.setEndDate(end);
}
}

View File

@ -0,0 +1,11 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
/**
* This class represents error that is returned by target stock-do-search-sku-list API
* Message will contain error details.
*/
public class SkuListRequestErrorException extends RuntimeException {
public SkuListRequestErrorException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,70 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.Response;
/**
* Immutable object
*/
@Slf4j
@Getter
public class SkuListResponse extends Response {
/**
* Current page
*/
private final String cursor;
/**
* Current page data
*/
private final JSONArray data;
private final JSONObject rawData;
SkuListResponse(Code code, String cursor, JSONArray data, JSONObject rawData) {
super(code);
this.cursor = cursor;
this.data = data;
this.rawData = rawData;
}
/**
* Make an instance by parsing json, it only checks validity of code.
* if json is not valid, return null
*
* @param json the json to parse
* @return Instance
* @throws SkuListRequestErrorException if response code represents error.
*/
public static SkuListResponse parse(JSONObject json) throws SkuListRequestErrorException {
log.debug("Constructing a response by json.");
String code = json.getString("code");
if (code.equals(Code.ERROR.value))
throw new SkuListRequestErrorException(json.getString("message"));
JSONObject data = json.getJSONObject("data");
String cursor = data.getString("nextCursor");
JSONArray realData = data.getJSONArray("data");
if(realData != null) {
log.info("Constructed response: data contained {}", realData.size());
}
else {
log.info("Data is null");
}
return new SkuListResponse(Code.SUCCESS, cursor, realData, json);
}
public JSONObject getRawDate() {
return rawData;
}
@Override
public String toString() {
return "SkuListResponse{" +
", data=" + data +
'}';
}
}

View File

@ -0,0 +1,122 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.NetworkDataStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
/**
* This class provide stream of order.
*/
@Slf4j
public class SkuListStream implements NetworkDataStream<SkuData> {
private final NetworkDataStream<SkuListResponse> rawStream;
private List<SkuData> skus;
private int index;
private boolean began;
/**
* Flag of current data is already empty,
* either currentOrders is null or currentIndex arrives at the end.
* In both case, we should call next() of the rawStream.
*/
private boolean empty;
public SkuListStream(NetworkDataStream<SkuListResponse> rawStream) {
this.rawStream = rawStream;
skus = null;
this.index = 0;
this.empty = true;
this.began = false;
}
@Override
public List<SkuData> all() {
SkuData firstElement = attempt();
if (firstElement == null) {
return Collections.emptyList();
}
ArrayList<SkuData> res = new ArrayList<>();
if (firstElement.getStatus().equals(SkuStatus.Normal)) {
res.add(firstElement);
}
while (hasNext()) {
SkuData nextSku = next();
if(nextSku.getStatus().equals(SkuStatus.Normal)) {
res.add(nextSku);
}
}
return res;
}
@Override
public SkuData attempt() {
began = true;
log.info("Attempting for the first request");
SkuListResponse response = rawStream.attempt();
if (response == null) {
log.info("No response");
return null;
}
if (response.getData().isEmpty()) {
log.info("Response with empty data");
return null;
}
skus = response.getData().toJavaList(SkuData.class);
index = 1;
log.info("Returned the first element");
empty = index >= skus.size();
return skus.get(0);
}
@Override
public boolean hasNext() {
// the first time
if (!began) {
throw new IllegalStateException("Calling hasNext before begin");
}
// Current data is not yet empty
if (index < skus.size()) {
log.debug("Current order list is not empty yet");
return true;
}
/* Current data is empty */
this.empty = true;
log.debug("Current order list is already empty,");
// and raw stream is empty too.
if (!rawStream.hasNext()) {
log.debug("and source stream is empty too, hasNext: false");
return false;
}
// but raw stream not empty.
else {
log.debug("but source stream still has data, hasNext: true");
return true;
}
}
@Override
public SkuData next() {
if (!hasNext()) {
throw new NoSuchElementException("Stream is empty!");
}
if (empty) {
skus = this.rawStream.next().getData().toJavaList(SkuData.class);
empty = false;
index = 0;
}
log.debug("Return data at {}", index);
SkuData res = skus.get(index);
index++;
return res;
}
}

View File

@ -0,0 +1,32 @@
package org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew;
public enum SkuStatus {
//"status": "状态:1.自动创建;2.待开发;3.正常;4.清仓;5.停止销售",
AutomaticallyCreated(1, "自动创建"),
ToBePaired(2, "待开发"),
Normal(3, "正常"),
Liquidation(4, "清仓"),
StoppedSelling(5, "停止销售");
private final int code;
private final String name;
SkuStatus(int code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return String.valueOf(code);
}
public static SkuStatus fromCode(Integer code) {
for (SkuStatus skuStatus : SkuStatus.values()) {
if (skuStatus.code == code) {
return skuStatus;
}
}
return null;
}
}

View File

@ -0,0 +1,15 @@
package org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase;
import org.jeecg.modules.business.domain.api.mabang.Request;
public class AddPurchaseOrderRequest extends Request {
public AddPurchaseOrderRequest(AddPurchaseOrderRequestBody body) {
super(body);
}
@Override
public AddPurchaseOrderResponse send() {
String jsonString = rawSend().getBody();
return AddPurchaseOrderResponse.parse(jsonString);
}
}

View File

@ -0,0 +1,63 @@
package org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.modules.business.domain.api.mabang.RequestBody;
import java.util.List;
import java.util.function.Function;
public class AddPurchaseOrderRequestBody implements RequestBody {
private String providerName;
private String employeeName;
private String content;
private List<SkuStockData> stockData;
private final static String DEFAULT_WAREHOUSE_NAME = "SZBA宝安仓";
public AddPurchaseOrderRequestBody(String employeeName, String providerName, String content, List<SkuStockData> stockData) {
this.stockData = stockData;
this.providerName = providerName;
this.employeeName = employeeName;
this.content = content;
}
@Override
public String api() {
return "pur-do-add-purchase";
}
@Override
public JSONObject parameters() {
JSONObject json = new JSONObject();
putNonNull(json, "warehouseName", DEFAULT_WAREHOUSE_NAME);
putNonNull(json, "providerName", providerName);
putNonNull(json, "employeeName", employeeName);
JSONArray stockDataArray = new JSONArray();
if (!stockData.isEmpty()) {
for (SkuStockData s : stockData) {
JSONObject stockData = new JSONObject();
stockData.put("stockSku", s.getStockSku());
stockData.put("price", s.getPrice());
stockData.put("purchaseNum", s.getPurchaseNum());
stockDataArray.add(stockData);
}
}
json.put("stockList", stockDataArray.toJSONString());
return json;
}
private <E> void putNonNull(JSONObject json, String key, E value) {
if (value != null) {
json.put(key, value);
}
}
private <E, T> void putNonNull(JSONObject json, String key, E value, Function<E, T> mapper) {
if (value != null) {
json.put(key, mapper.apply(value));
}
}
}

View File

@ -0,0 +1,40 @@
package org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import org.jeecg.modules.business.domain.api.mabang.Response;
@Getter
public class AddPurchaseOrderResponse extends Response {
/**采购批次号*/
private final String groupId;
private final String message;
private AddPurchaseOrderResponse(Code status, String message, String groupId) {
super(status);
this.message = message;
this.groupId = groupId;
}
public static AddPurchaseOrderResponse parse(String json) {
JSONObject jsonObject = JSON.parseObject(json);
String code = jsonObject.getString("code");
String message = jsonObject.getString("message");
if (code.equals("200")) {
JSONObject data = jsonObject.getJSONObject("data");
String groupId = data.getString("groupId");
return new AddPurchaseOrderResponse(Code.SUCCESS, message, groupId);
} else {
return new AddPurchaseOrderResponse(Code.ERROR, message, null);
}
}
@Override
public String toString() {
return "AddPurchaseOrderResponse{" +
"message='" + message + '\'' +
", groupId='" + groupId + '\'' +
'}';
}
}

View File

@ -0,0 +1,18 @@
package org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class SkuStockData {
/**库存sku*/
private String stockSku;
/**采购价格*/
private BigDecimal price;
/**采购量*/
private Integer purchaseNum;
/**商品备注*/
private String goodremark;
private String provider;
}

View File

@ -0,0 +1,89 @@
package org.jeecg.modules.business.domain.api.mabang.purDoGetProvider;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("provider")
public class ProviderData {
/**id*/
@JSONField(name = "id")
private java.lang.String id;
/**创建人*/
@JSONField(name = "createTime")
private java.util.Date createTime;
/**供应商编号*/
@JSONField(name = "flag")
private java.lang.Integer flag;
/**供应商名称*/
@JSONField(name = "provider")
private java.lang.String provider;
/**供应商类型: 1 1688 2 淘宝 33 拼多多 38 淘供销 43 淘供销(淘宝天猫) 0 普通 */
@JSONField(name = "providerType")
private java.lang.Integer providerType;
/**供应商链接*/
@JSONField(name = "linkAddress")
private java.lang.String linkAddress;
/**联系QQ*/
@JSONField(name = "contactQq")
private java.lang.String contactQq;
/**联系旺旺*/
@JSONField(name = "contactAliw")
private java.lang.String contactAliw;
/**联系人*/
@JSONField(name = "contactPerson")
private java.lang.String contactPerson;
/**联系电话*/
@JSONField(name = "contactTel")
private java.lang.String contactTel;
/**采购员编号*/
@JSONField(name = "buyerId")
private java.lang.String buyerId;
/**采购员名称*/
@JSONField(name = "buyerName")
private java.lang.String buyerName;
/**付款方式:1到付,2分期付款,3现付,4周结,5月结,6账期支付*/
@JSONField(name = "paymentType")
private java.lang.Integer paymentType;
/**联系地址(省)*/
@JSONField(name = "contactProvince")
private java.lang.String contactProvince;
/**联系地址*/
@JSONField(name = "contactAddress")
private java.lang.String contactAddress;
/**收款人*/
@JSONField(name = "payee")
private java.lang.String payee;
/**收款账号*/
@JSONField(name = "receiveAccount")
private java.lang.String receiveAccount;
/**分销:1是2否*/
@JSONField(name = "isDistribution")
private java.lang.Integer isDistribution;
/**财务编码*/
@JSONField(name = "financialcode")
private java.lang.String financialcode;
public String toString() {
return "ID : " + this.id +
"createTime : " + this.createTime +
"flag : " + this.flag +
"provider : " + this.provider +
"providerType : " + this.providerType +
"linkAddress : " + this.linkAddress +
"contactQq : " + this.contactQq +
"contactAliw : " + this.contactAliw +
"contactPerson : " + this.contactPerson +
"contactTel : " + this.contactTel +
"buyerId : " + this.buyerId +
"buyerName : " + this.buyerName +
"paymentType : " + this.paymentType +
"contactProvince : " + this.contactProvince +
"contactAddress : " + this.contactAddress +
"payee : " + this.payee +
"receiveAccount : " + this.receiveAccount +
"isDistribution : " + this.isDistribution +
"financialcode : " + this.financialcode
;
}
}

View File

@ -0,0 +1,79 @@
package org.jeecg.modules.business.domain.api.mabang.purDoGetProvider;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.NetworkDataStream;
import java.util.NoSuchElementException;
/**
* This stream control reception of the response of the mabang provider list API
*/
@Slf4j
public class ProviderRawStream implements NetworkDataStream<ProviderResponse> {
/**
* Instance's current request.
*/
private final ProviderRequestBody toSend;
/**
* Response of last request.
*/
private ProviderResponse currentResponse;
private boolean began;
public ProviderRawStream(ProviderRequestBody firstBody) {
this.toSend = firstBody;
this.currentResponse = null;
began = false;
}
@Override
public ProviderResponse attempt() {
log.info("Begin the first request");
this.currentResponse = new ProviderRequest(toSend).send();
if (currentResponse.getDataCount() == 0) {
return null;
}
began = true;
toSend.nextPage();
return currentResponse;
}
/**
* Check whether there are still order left, network communication is done here.
*
* @return true if there are, otherwise false.
*/
@Override
public boolean hasNext() throws ProviderRequestErrorException {
if (!began) {
throw new IllegalStateException("Calling hasNext before begin");
}
// still has page left, true
if (toSend.getPage() <= currentResponse.getTotalPage()) {
log.info("page: {}/{}, has next", toSend.getPage(), currentResponse.getTotalPage());
return true;
}
// no page left, false
log.info("No page left, end");
return false;
}
/**
* Get next Order.
*
* @return next order.
* @throws NoSuchElementException if data is already empty.
* @throws ProviderRequestErrorException if request format is not valid.
*/
@Override
public ProviderResponse next() throws ProviderRequestErrorException {
if (!hasNext())
throw new NoSuchElementException();
log.info("Sending request for page {}.", toSend.getPage());
this.currentResponse = new ProviderRequest(toSend).send();
toSend.nextPage();
return this.currentResponse;
}
}

View File

@ -0,0 +1,32 @@
package org.jeecg.modules.business.domain.api.mabang.purDoGetProvider;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.Request;
import org.springframework.http.ResponseEntity;
/**
* This class contains some key information and necessary procedures
* to send a request to mabang "get order list" API, for example: target URL,
* correspondent HTTP method, procedure to generate authorization.
* <p>
* One can use static method {@code sendRequest} to send request with body,
* and then get respective response. Or use instance of this class, see below.
* <p>
* Because data returned by target API is paginated. One can retrieve all data
* by calling next and hasNext.
*/
@Slf4j
public class ProviderRequest extends Request {
public ProviderRequest(ProviderRequestBody body) {
super(body);
}
@Override
public ProviderResponse send() {
ResponseEntity<String> res = rawSend();
return ProviderResponse.parse(JSON.parseObject(res.getBody()));
}
}

View File

@ -0,0 +1,91 @@
package org.jeecg.modules.business.domain.api.mabang.purDoGetProvider;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.modules.business.domain.api.mabang.RequestBody;
import java.util.function.Function;
public class ProviderRequestBody implements RequestBody {
/**
*
*/
private String provider;
private String contactPerson;
private String contactTel;
/**
* :12
*/
private int flag = 1;
/**
* :12
*/
private int isDistribution;
/**
*
*/
private int buyerId;
/**
* :1,2,3,4,5,6
*/
private int paymentType;
/**
* : 1:1688, 2 3
*/
private int providerType;
private int page = 1;
private int rowPerPage = 50;
/**
*
*/
private String financialcode;
@Override
public String api() {
return "pur-do-get-provider";
}
@Override
public JSONObject parameters() {
JSONObject json = new JSONObject();
putNonNull(json, "flag", flag);
putNonNull(json, "provider", provider);
putNonNull(json, "page", page);
putNonNull(json, "rowPerPage", rowPerPage);
return json;
}
void nextPage() {
setPage(this.page + 1);
}
int getPage() {
return page;
}
public ProviderRequestBody setProvider(String provider) {
this.provider = provider;
return this;
}
public ProviderRequestBody setFlag(int flag) {
this.flag = flag;
return this;
}
public ProviderRequestBody setPage(int page) {
this.page = page;
return this;
}
private <E> void putNonNull(JSONObject json, String key, E value) {
if (value != null) {
json.put(key, value);
}
}
private <E, T> void putNonNull(JSONObject json, String key, E value, Function<E, T> mapper) {
if (value != null) {
json.put(key, mapper.apply(value));
}
}
}

View File

@ -0,0 +1,11 @@
package org.jeecg.modules.business.domain.api.mabang.purDoGetProvider;
/**
* This class represents error that is returned by target stock-do-search-sku-list API
* Message will contain error details.
*/
public class ProviderRequestErrorException extends RuntimeException {
public ProviderRequestErrorException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,88 @@
package org.jeecg.modules.business.domain.api.mabang.purDoGetProvider;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.Response;
/**
* Immutable object
*/
@Slf4j
public class ProviderResponse extends Response {
/**
* total page number
*/
@Getter
private final int totalPage;
/**
* rows per page
*/
@Getter
public final int rowsPerPage = 50;
/**
* Total data number
*/
private final int total;
/**
* Current page data
*/
@Getter
private final JSONArray data;
private final JSONObject rawData;
ProviderResponse(Code code, int totalPage, int total, JSONArray data, JSONObject rawData) {
super(code);
this.totalPage = totalPage;
this.total = total;
this.data = data;
this.rawData = rawData;
}
/**
* Make an instance by parsing json, it only checks validity of code.
* if json is not valid, return null
*
* @param json the json to parse
* @return Instance
* @throws ProviderRequestErrorException if response code represents error.
*/
public static ProviderResponse parse(JSONObject json) throws ProviderRequestErrorException {
log.debug("Constructing a response by json.");
String code = json.getString("code");
if (code.equals(Code.ERROR.value))
throw new ProviderRequestErrorException(json.getString("message"));
JSONObject data = json.getJSONObject("data");
System.out.println("data from API request : " + data);
int total = Integer.parseInt(data.getString("count"));
int totalPage = (int)Math.ceil((double) total /50);
JSONArray realData = data.getJSONArray("data");
if(realData != null) {
log.info("Constructed response: data contained {}, total page {}, rows per page {} total data {}", realData.size(), totalPage, 50, total);
}
else {
log.info("Data is null");
}
return new ProviderResponse(Code.SUCCESS, totalPage, total, realData, json);
}
public JSONObject getRawDate() {
return rawData;
}
public int getDataCount() {
return total;
}
@Override
public String toString() {
return "ProviderResponse{" +
"pageCount=" + totalPage +
", rowPerPage=" + rowsPerPage +
", dataCount=" + total +
'}';
}
}

View File

@ -0,0 +1,120 @@
package org.jeecg.modules.business.domain.api.mabang.purDoGetProvider;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.NetworkDataStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
/**
* This class provide stream of order.
*/
@Slf4j
public class ProviderStream implements NetworkDataStream<ProviderData> {
private final ProviderRawStream rawStream;
private List<ProviderData> providers;
private int index;
private boolean began;
/**
* Flag of current data is already empty,
* either currentOrders is null or currentIndex arrives at the end.
* In both case, we should call next() of the rawStream.
*/
private boolean empty;
public ProviderStream(ProviderRawStream rawStream) {
this.rawStream = rawStream;
providers = null;
this.index = 0;
this.empty = true;
this.began = false;
}
@Override
public List<ProviderData> all() {
ProviderData firstElement = attempt();
if (firstElement == null) {
return Collections.emptyList();
}
ArrayList<ProviderData> res = new ArrayList<>();
res.add(firstElement);
System.out.println("firstElement : " + firstElement);
while (hasNext()) {
ProviderData nextProvider = next();
res.add(nextProvider);
}
return res;
}
@Override
public ProviderData attempt() {
began = true;
log.info("Attempting for the first request");
ProviderResponse response = rawStream.attempt();
if (response == null) {
log.info("No response");
return null;
}
if (response.getDataCount() == 0) {
log.info("Response with empty data");
return null;
}
providers = response.getData().toJavaList(ProviderData.class);
index = 1;
log.info("Returned the first element");
empty = index >= providers.size();
return providers.get(0);
}
@Override
public boolean hasNext() {
// the first time
if (!began) {
throw new IllegalStateException("Calling hasNext before begin");
}
// Current data is not yet empty
if (index < providers.size()) {
log.debug("Current order list is not empty yet");
return true;
}
/* Current data is empty */
this.empty = true;
log.debug("Current order list is already empty,");
// and raw stream is empty too.
if (!rawStream.hasNext()) {
log.debug("and source stream is empty too, hasNext: false");
return false;
}
// but raw stream not empty.
else {
log.debug("but source stream still has data, hasNext: true");
return true;
}
}
@Override
public ProviderData next() {
if (!hasNext()) {
throw new NoSuchElementException("Stream is empty!");
}
if (empty) {
providers = this.rawStream.next().getData().toJavaList(ProviderData.class);
empty = false;
index = 0;
}
log.debug("Return data at {}", index);
ProviderData res = providers.get(index);
index++;
return res;
}
}

View File

@ -0,0 +1,67 @@
package org.jeecg.modules.business.domain.job;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.modules.business.domain.api.mabang.purDoGetProvider.*;
import org.jeecg.modules.business.service.IProviderMabangService;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A Job that retrieves all Providers from Mabang
*/
@Slf4j
@Component
public class MabangGetProviderJob implements Job {
@Autowired
private ISysBaseAPI ISysBaseApi;
@Autowired
private IProviderMabangService ProviderMabangService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
int flag = 1; // 1: actif, 2: inactif
JobDataMap jobDataMap = context.getMergedJobDataMap();
String parameter = ((String) jobDataMap.get("parameter"));
if (parameter != null) {
try {
JSONObject jsonObject = new JSONObject(parameter);
if (!jsonObject.isNull("flag")) {
flag = Integer.parseInt(jsonObject.getString("flag"));
}
} catch (JSONException e) {
log.error("Error while parsing parameter as JSON, falling back to default parameters.");
}
}
Map<String, ProviderData> providerDataMap = new HashMap<>();
try {
ProviderRequestBody body = (new ProviderRequestBody()).setFlag(flag);
ProviderRawStream rawStream = new ProviderRawStream(body);
ProviderStream stream = new ProviderStream(rawStream);
// the status is directly filtered in all() method
List<ProviderData> providersFromMabang = stream.all();
providersFromMabang.forEach(providerData -> providerDataMap.put(providerData.getId(), providerData));
log.info("{} providers to be inserted.", providersFromMabang.size());
if (providersFromMabang.size() > 0) {
// we save the skuDatas in DB
ProviderMabangService.saveProviderFromMabang(providersFromMabang);
}
} catch (ProviderRequestErrorException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -7,8 +7,8 @@ import org.codehaus.jettison.json.JSONObject;
import org.jeecg.common.api.dto.message.TemplateMessageDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuList.*;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuList.SkuData;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.*;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuData;
import org.jeecg.modules.business.entity.Sku;
import org.jeecg.modules.business.service.ISkuListMabangService;
import org.jeecg.modules.online.cgform.mapper.OnlCgformFieldMapper;

View File

@ -0,0 +1,147 @@
package org.jeecg.modules.business.entity;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.jeecg.modules.business.domain.api.mabang.purDoGetProvider.ProviderData;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @Description: provider
* @Author: jeecg-boot
* @Date: 2024-02-14
* @Version: V1.0
*/
@Data
@TableName("provider")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="provider对象", description="provider")
public class Provider implements Serializable {
private static final long serialVersionUID = 1L;
/**id*/
@TableId(type = IdType.ASSIGN_UUID)
@ApiModelProperty(value = "id")
private java.lang.String id;
/**创建人*/
@ApiModelProperty(value = "创建人")
private java.lang.String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "创建日期")
private java.util.Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private java.lang.String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "更新日期")
private java.util.Date updateTime;
/**ID from Mabang*/
@Excel(name = "ID from Mabang", width = 15)
@ApiModelProperty(value = "ID from Mabang")
private java.lang.String idMabang;
/**供应商编号*/
@Excel(name = "供应商编号", width = 15)
@ApiModelProperty(value = "供应商编号")
private java.lang.Integer flag;
/**供应商名称*/
@Excel(name = "供应商名称", width = 15)
@ApiModelProperty(value = "供应商名称")
private java.lang.String provider;
/**供应商类型: 1 1688 2 淘宝 33 拼多多 38 淘供销 43 淘供销(淘宝天猫) 0 普通 */
@Excel(name = "供应商类型: 1 1688 2 淘宝 33 拼多多 38 淘供销 43 淘供销(淘宝天猫) 0 普通 ", width = 15)
@ApiModelProperty(value = "供应商类型: 1 1688 2 淘宝 33 拼多多 38 淘供销 43 淘供销(淘宝天猫) 0 普通 ")
private java.lang.Integer providerType;
/**供应商链接*/
@Excel(name = "供应商链接", width = 15)
@ApiModelProperty(value = "供应商链接")
private java.lang.String linkAddress;
/**联系QQ*/
@Excel(name = "联系QQ", width = 15)
@ApiModelProperty(value = "联系QQ")
private java.lang.String contactQq;
/**联系旺旺*/
@Excel(name = "联系旺旺", width = 15)
@ApiModelProperty(value = "联系旺旺")
private java.lang.String contactAliw;
/**联系人*/
@Excel(name = "联系人", width = 15)
@ApiModelProperty(value = "联系人")
private java.lang.String contactPerson;
/**联系电话*/
@Excel(name = "联系电话", width = 15)
@ApiModelProperty(value = "联系电话")
private java.lang.String contactTel;
/**采购员编号*/
@Excel(name = "采购员编号", width = 15)
@ApiModelProperty(value = "采购员编号")
private java.lang.String buyerId;
/**采购员名称*/
@Excel(name = "采购员名称", width = 15)
@ApiModelProperty(value = "采购员名称")
private java.lang.String buyerName;
/**付款方式:1到付,2分期付款,3现付,4周结,5月结,6账期支付*/
@Excel(name = "付款方式:1到付,2分期付款,3现付,4周结,5月结,6账期支付", width = 15)
@ApiModelProperty(value = "付款方式:1到付,2分期付款,3现付,4周结,5月结,6账期支付")
private java.lang.Integer paymentType;
/**联系地址(省)*/
@Excel(name = "联系地址(省)", width = 15)
@ApiModelProperty(value = "联系地址(省)")
private java.lang.String contactProvince;
/**联系地址*/
@Excel(name = "联系地址", width = 15)
@ApiModelProperty(value = "联系地址")
private java.lang.String contactAddress;
/**收款人*/
@Excel(name = "收款人", width = 15)
@ApiModelProperty(value = "收款人")
private java.lang.String payee;
/**收款账号*/
@Excel(name = "收款账号", width = 15)
@ApiModelProperty(value = "收款账号")
private java.lang.String receiveAccount;
/**分销:1是2否*/
@Excel(name = "分销:1是2否", width = 15)
@ApiModelProperty(value = "分销:1是2否")
private java.lang.Integer isDistribution;
/**财务编码*/
@Excel(name = "财务编码", width = 15)
@ApiModelProperty(value = "财务编码")
private java.lang.String financialcode;
public Provider providerFromData(ProviderData data) {
this.createTime = data.getCreateTime();
this.createBy = "Mabang";
this.idMabang = data.getId();
this.flag = data.getFlag();
this.provider = data.getProvider();
this.providerType = data.getProviderType();
this.linkAddress = data.getLinkAddress() == null ? null : data.getLinkAddress().isEmpty() ? null : data.getLinkAddress();
this.contactQq = data.getContactQq() == null ? null : data.getContactQq().isEmpty() ? null : data.getContactQq();
this.contactAliw = data.getContactAliw() == null ? null : data.getContactAliw().isEmpty() ? null : data.getContactAliw();
this.contactPerson = data.getContactPerson() == null ? null : data.getContactPerson().isEmpty() ? null : data.getContactPerson();
this.contactTel = data.getContactTel() == null ? null : data.getContactTel().isEmpty() ? null : data.getContactTel();
this.buyerId = data.getBuyerId() == null ? null : data.getBuyerId().isEmpty() ? null : data.getBuyerId();
this.buyerName = data.getBuyerName() == null ? null : data.getBuyerName().isEmpty() ? null : data.getBuyerName();
this.paymentType = data.getPaymentType();
this.contactProvince = data.getContactProvince() == null ? null : data.getContactProvince().isEmpty() ? null : data.getContactProvince();
this.contactAddress = data.getContactAddress() == null ? null : data.getContactAddress().isEmpty() ? null : data.getContactAddress();
this.payee = data.getPayee() == null ? null : data.getPayee().isEmpty() ? null : data.getPayee();
this.receiveAccount = data.getReceiveAccount() == null ? null : data.getReceiveAccount().isEmpty() ? null : data.getReceiveAccount();
this.isDistribution = data.getIsDistribution();
this.financialcode = data.getFinancialcode() == null ? null : data.getFinancialcode().isEmpty() ? null : data.getFinancialcode();
return this;
}
}

View File

@ -0,0 +1,16 @@
package org.jeecg.modules.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.business.domain.api.mabang.purDoGetProvider.ProviderData;
import org.springframework.stereotype.Repository;
/**
* @Description: provider
* @Author: jeecg-boot
* @Date: 2024-02-14
* @Version: V1.0
*/
@Repository
public interface ProviderMabangMapper extends BaseMapper<ProviderData> {
}

View File

@ -0,0 +1,21 @@
package org.jeecg.modules.business.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.business.entity.Provider;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
/**
* @Description: provider
* @Author: jeecg-boot
* @Date: 2024-02-14
* @Version: V1.0
*/
@Repository
public interface ProviderMapper extends BaseMapper<Provider> {
List<Provider> listByMabangIds(@Param("ids") List<String> ids);
}

View File

@ -2,12 +2,9 @@ package org.jeecg.modules.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.logging.log4j.util.ProcessIdUtil;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuList.SkuData;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuData;
import org.jeecg.modules.business.entity.Product;
import org.jeecg.modules.business.entity.Sku;
import org.jeecg.modules.business.entity.SkuDeclaredValue;
import org.jeecg.modules.business.entity.SkuPrice;
import org.springframework.stereotype.Repository;
import java.util.Collection;

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.business.mapper.ProviderMabangMapper">
</mapper>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.business.mapper.ProviderMapper">
<select id="listByMabangIds" resultType="org.jeecg.modules.business.entity.Provider">
SELECT * FROM provider WHERE id_mabang IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
</mapper>

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.business.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.business.domain.api.mabang.purDoGetProvider.ProviderData;
import org.jeecg.modules.business.vo.InvoiceMetaData;
import java.util.List;
import java.util.Map;
public interface IProviderMabangService extends IService<ProviderData> {
/**
* Save providers to DB from mabang api.
*
* @param providerDataList providers to save.
*/
void saveProviderFromMabang(List<ProviderData> providerDataList);
void addPurchaseOrderToMabang(Map<String, Integer> skuQuantities, InvoiceMetaData metaData);
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.business.service;
import org.jeecg.modules.business.entity.Provider;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @Description: provider
* @Author: jeecg-boot
* @Date: 2024-02-14
* @Version: V1.0
*/
public interface IProviderService extends IService<Provider> {
List<Provider> listByMabangIds(List<String> ids);
}

View File

@ -1,7 +1,7 @@
package org.jeecg.modules.business.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuList.SkuData;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuData;
import org.jeecg.modules.business.entity.Product;
import org.jeecg.modules.business.entity.Sku;

View File

@ -0,0 +1,142 @@
package org.jeecg.modules.business.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.*;
import org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase.AddPurchaseOrderRequest;
import org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase.AddPurchaseOrderRequestBody;
import org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase.AddPurchaseOrderResponse;
import org.jeecg.modules.business.domain.api.mabang.purDoAddPurchase.SkuStockData;
import org.jeecg.modules.business.domain.api.mabang.purDoGetProvider.ProviderData;
import org.jeecg.modules.business.domain.api.mabang.purDoGetProvider.ProviderRequestErrorException;
import org.jeecg.modules.business.entity.Provider;
import org.jeecg.modules.business.mapper.ProviderMabangMapper;
import org.jeecg.modules.business.service.IProviderMabangService;
import org.jeecg.modules.business.service.IProviderService;
import org.jeecg.modules.business.service.ISkuService;
import org.jeecg.modules.business.vo.InvoiceMetaData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Description: provider
* @Author: jeecg-boot
* @Date: 2024-02-14
* @Version: V1.0
*/
@Service
@Slf4j
public class ProviderMabangServiceImpl extends ServiceImpl<ProviderMabangMapper, ProviderData> implements IProviderMabangService {
@Autowired
private IProviderService providerService;
@Autowired
ISkuService skuService;
@Override
public void saveProviderFromMabang(List<ProviderData> providerDataList) {
if(providerDataList.isEmpty()) {
return;
}
List<String> allProviderIds = providerDataList.stream().map(ProviderData::getId).collect(Collectors.toList());
List<Provider> existingProviders = providerService.listByMabangIds(allProviderIds);
List<String> existingProviderIds = existingProviders.stream().map(Provider::getIdMabang).collect(Collectors.toList());
List<String> newProviderIds = allProviderIds.stream().filter(providerId -> !existingProviderIds.contains(providerId)).collect(Collectors.toList());
List<Provider> newProviders = providerDataList.stream().filter(providerData -> newProviderIds.contains(providerData.getId())).map(providerData -> (new Provider()).providerFromData(providerData)).collect(Collectors.toList());
if(!newProviders.isEmpty()) {
providerService.saveBatch(newProviders);
}
}
@Transactional
@Override
public void addPurchaseOrderToMabang(Map<String, Integer> skuQuantities, InvoiceMetaData metaData) {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String mabangUsername = sysUser.getMabangUsername();
String content = metaData.getFilename().substring(0, metaData.getFilename().lastIndexOf("."));
List<String> stockSkuList = new ArrayList<>();
String stockSkus;
log.info("Creating purchase order to Mabang : {} skus", skuQuantities.size());
Map<String, SkuData> skuDataMap = new HashMap<>();
List<SkuData> skuDataList = new ArrayList<>();
log.info("Requesting SKU data from Mabang API.");
for(String stockSku : skuQuantities.keySet()) {
stockSkuList.add(stockSku);
if(stockSkuList.size() == 50) {
stockSkus = String.join(",", stockSkuList);
stockSkuList.clear();
SkuListRequestBody skuListRequestBody = new SkuListRequestBody()
.setSkuStockList(stockSkus)
.setShowProvider(1)
.setDatetimeType(DateType.CREATE)
.setTotal(50);
SkuListRawStream skuListRawStream = new SkuListRawStream(skuListRequestBody);
SkuListStream skuListStream = new SkuListStream(skuListRawStream);
skuDataList.addAll(skuListStream.all());
}
}
if(!stockSkuList.isEmpty()) {
stockSkus = String.join(",", stockSkuList);
SkuListRequestBody skuListRequestBody = new SkuListRequestBody()
.setSkuStockList(stockSkus)
.setShowProvider(1)
.setDatetimeType(DateType.CREATE)
.setTotal(stockSkuList.size());
SkuListRawStream skuListRawStream = new SkuListRawStream(skuListRequestBody);
SkuListStream skuListStream = new SkuListStream(skuListRawStream);
skuDataList.addAll(skuListStream.all());
}
if(skuDataList.isEmpty()) {
throw new SkuListRequestErrorException("Couldn't get SKU data from Mabang API.");
}
for(SkuData skuData : skuDataList) {
skuDataMap.put(skuData.getErpCode(), skuData);
}
List<SkuStockData> skuStockData = new ArrayList<>();
for(Map.Entry<String, SkuData> entry : skuDataMap.entrySet()) {
SkuStockData stockData = new SkuStockData();
stockData.setStockSku(entry.getKey());
stockData.setPrice(entry.getValue().getPurchasePrice());
stockData.setPurchaseNum(skuQuantities.get(entry.getKey()));
stockData.setProvider(entry.getValue().getProvider());
skuStockData.add(stockData);
}
// group by provider
Map<String, List<SkuStockData>> stockProviderMap = new HashMap<>();
for(SkuStockData stockData : skuStockData) {
if(stockProviderMap.containsKey(stockData.getProvider())) {
stockProviderMap.get(stockData.getProvider()).add(stockData);
} else {
List<SkuStockData> stockDataList = new ArrayList<>();
stockDataList.add(stockData);
stockProviderMap.put(stockData.getProvider(), stockDataList);
}
}
log.info("Create {} purchase orders to Mabang.", stockProviderMap.size());
// group id is the response from mabang API
List<String> groupIds = new ArrayList<>();
for(Map.Entry<String, List<SkuStockData>> entry : stockProviderMap.entrySet()) {
String providerName = entry.getKey();
List<SkuStockData> stockDataList = entry.getValue();
AddPurchaseOrderRequestBody body = new AddPurchaseOrderRequestBody(mabangUsername, providerName, content, stockDataList);
AddPurchaseOrderRequest request = new AddPurchaseOrderRequest(body);
AddPurchaseOrderResponse response = request.send();
log.info("Response from Mabang Add purchase API : " + response.toString());
if(!response.success())
throw new ProviderRequestErrorException("Couldn't add purchase order to Mabang.");
groupIds.add(response.getGroupId());
}
log.info("Purchase orders created to Mabang, groupIds : {}", groupIds);
}
}

View File

@ -0,0 +1,27 @@
package org.jeecg.modules.business.service.impl;
import org.jeecg.modules.business.entity.Provider;
import org.jeecg.modules.business.mapper.ProviderMapper;
import org.jeecg.modules.business.service.IProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
/**
* @Description: provider
* @Author: jeecg-boot
* @Date: 2024-02-14
* @Version: V1.0
*/
@Service
public class ProviderServiceImpl extends ServiceImpl<ProviderMapper, Provider> implements IProviderService {
@Autowired
private ProviderMapper providerMapper;
@Override
public List<Provider> listByMabangIds(List<String> ids) {
return providerMapper.listByMabangIds(ids);
}
}

View File

@ -3,8 +3,8 @@ package org.jeecg.modules.business.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuList.SkuData;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuList.SkuListRequestErrorException;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuData;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuListRequestErrorException;
import org.jeecg.modules.business.entity.Product;
import org.jeecg.modules.business.entity.Sku;
import org.jeecg.modules.business.entity.SkuDeclaredValue;

View File

@ -1742,4 +1742,11 @@ public class SysUserController {
sysUserService.editTenantUser(sysUser,tenantId,departs,roles);
return Result.ok("修改成功");
}
@GetMapping(value = "/getMabangUsername")
public Result<?> getMabangUsername() {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if(sysUser.getMabangUsername() == null || sysUser.getMabangUsername().isEmpty())
return Result.error("Mabang username not found");
return Result.ok(sysUser.getMabangUsername());
}
}

View File

@ -187,6 +187,8 @@ public class SysUser implements Serializable {
/**设备id uniapp推送用*/
private String clientId;
/**Mabang username*/
private String mabangUsername;
/**
*