feat: fix order list, invoice number in order on mabang

pull/8523/head
Gauthier LO 2025-05-12 15:06:14 +02:00
parent 12fa98eabf
commit c8cfc8fb2d
14 changed files with 262 additions and 158 deletions

View File

@ -323,7 +323,7 @@ public interface CommonConstant {
String X_MiniFlowExclusionFieldMode = "X-Miniflowexclusionfieldmode";
/**===============================================================================================*/
String TOKEN_IS_INVALID_MSG = "Token失效请重新登录!";
String TOKEN_IS_INVALID_MSG = "Your session has expired, please log in again";
String X_FORWARDED_SCHEME = "X-Forwarded-Scheme";

View File

@ -79,6 +79,8 @@ public class PurchaseOrderController {
@Autowired
private IShippingInvoiceService shippingInvoiceService;
@Autowired private IProviderMabangService providerMabangService;
@Autowired
private IPlatformOrderMabangService platformOrderMabangService;
private static final Integer DEFAULT_NUMBER_OF_THREADS = 2;
private static final Integer MABANG_API_RATE_LIMIT_PER_MINUTE = 10;
@ -625,7 +627,7 @@ public class PurchaseOrderController {
} else {
log.info("Updating order erp status to 2 in Mabang");
List<String> platformOrderIds = platformOrderService.getPlatformOrderIdsByInvoiceNumbers(invoiceNumbers);
Response<List<UpdateResult>, List<UpdateResult>> updateResponse = providerMabangService.updateOrderStatusToPreparing(platformOrderIds);
Response<List<UpdateResult>, List<UpdateResult>> updateResponse = platformOrderMabangService.updateOrderStatusToPreparing(platformOrderIds);
Responses updateOrderStatusResponse = new Responses();
if(updateResponse.getStatus() == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
String errMsg = updateResponse.getError().get(0).getReason();
@ -634,10 +636,10 @@ public class PurchaseOrderController {
}
else {
List<String> updateOrderStatusSuccess = updateResponse.getData().stream()
.map(UpdateResult::getPlatformOrderId)
.map(UpdateResult::getPlatformOrderNumber)
.collect(Collectors.toList());
List<String> updateOrderStatusFailure = updateResponse.getError().stream()
.map(UpdateResult::getPlatformOrderId)
.map(UpdateResult::getPlatformOrderNumber)
.collect(Collectors.toList());
log.info("Update order errors : {}", updateResponse.getError());
updateOrderStatusResponse.getSuccesses().addAll(updateOrderStatusSuccess);

View File

@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.CaseFormat;
import com.google.common.collect.Lists;
import freemarker.template.Template;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -15,12 +14,7 @@ import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuData;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuListRawStream;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuListRequestBody;
import org.jeecg.modules.business.domain.api.mabang.doSearchSkuListNew.SkuUpdateListStream;
import org.jeecg.modules.business.entity.*;
import org.jeecg.modules.business.model.SkuDocument;
import org.jeecg.modules.business.mongoService.SkuMongoService;
import org.jeecg.modules.business.service.*;
import org.jeecg.modules.business.vo.*;
@ -622,70 +616,11 @@ public class SkuController {
public Result<?> compareClientSkuWithMabang(@RequestParam(name="clientId") String clientId,
@RequestParam(name="erpStatuses[]") List<String> erpStatuses) {
Map<String, Sku> clientSkus = skuService.listInUninvoicedOrders(clientId, erpStatuses);
List<String> skuIds = new ArrayList<>(clientSkus.keySet());
List<SkuDocument> clientSkuDocs = new ArrayList<>();
for(String skuId: skuIds) {
List<SkuDocument> skus = skuMongoService.findBySkuId(skuId);
if(skus.isEmpty()) {
skuMongoService.migrateOneSku(clientSkus.get(skuId));
skus = skuMongoService.findBySkuId(skuId);
}
SkuDocument sku = skus.get(0);
clientSkuDocs.add(sku);
}
List<List<String>> erpCodePartition = Lists.partition(clientSkuDocs, 50)
.stream()
.map(skus -> skus.stream().map(SkuDocument::getErpCode).collect(Collectors.toList()))
.collect(Collectors.toList());
List<SkuData> skusFromMabang = new ArrayList<>();
for(List<String> partition : erpCodePartition) {
SkuListRequestBody body = new SkuListRequestBody();
body.setStockSkuList(String.join(",", partition));
SkuListRawStream rawStream = new SkuListRawStream(body);
SkuUpdateListStream stream = new SkuUpdateListStream(rawStream);
skusFromMabang.addAll(stream.all());
}
List<String> desyncedSkus = new ArrayList<>();
List<String> syncedSkus = new ArrayList<>();
for(SkuDocument sku : clientSkuDocs) {
SkuData skuData = skusFromMabang.stream().filter(s -> s.getErpCode().equals(sku.getErpCode()))
.findFirst().orElse(null);
if(skuData != null) {
boolean isDesynced = false;
BigDecimal mabangPrice = skuData.getSalePrice().setScale(2, RoundingMode.HALF_UP); // because price from mabang has 4 decimal places, so Objects.equals will always return false
if(skuData.getWeight() == null && sku.getLatestSkuWeight() != null) {
log.info("sku {} doesn't have a weight on Mabang but has one in Mongo", skuData.getErpCode());
isDesynced = true;
}
if (sku.getLatestSkuWeight() != null && !Objects.equals(skuData.getWeight(), sku.getLatestSkuWeight().getWeight())) {
log.info("sku {} has a different weight on Mabang and in Mongo : mabang :{}; mongo :{}", skuData.getErpCode() ,skuData.getWeight(), sku.getLatestSkuWeight().getWeight());
isDesynced = true;
}
if(skuData.getSalePrice() == null && sku.getLatestSkuPrice() != null) {
log.info("sku {} doesn't have a price on Mabang but has one in mongo", skuData.getErpCode());
isDesynced = true;
}
if(sku.getLatestSkuPrice() != null && !Objects.equals(mabangPrice, sku.getLatestSkuPrice().getPrice())) {
log.info("sku {} has a different price on Mabang and in Mongo : mabang :{}; mongo :{}", skuData.getErpCode() ,skuData.getSalePrice(), sku.getLatestSkuPrice().getPrice());
isDesynced = true;
}
if(isDesynced)
desyncedSkus.add(skuData.getErpCode());
else
syncedSkus.add(skuData.getErpCode());
} else {
desyncedSkus.add(sku.getErpCode());
}
}
if(!desyncedSkus.isEmpty()) {
log.info("Desynced skus : {}", desyncedSkus);
skuService.setIsSynced(desyncedSkus, false);
}
if(!syncedSkus.isEmpty()) {
log.info("Synced skus : {}", syncedSkus);
skuService.setIsSynced(syncedSkus, true);
if(clientSkus.isEmpty()) {
log.info("No skus to compare");
return Result.OK();
}
skuListMabangService.compareClientSkusWithMabang(clientSkus);
return Result.OK();
}

View File

@ -15,7 +15,6 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.business.controller.UserException;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.OrderStatus;
import org.jeecg.modules.business.domain.purchase.invoice.PurchaseInvoiceEntry;
import org.jeecg.modules.business.entity.*;
import org.jeecg.modules.business.mapper.ExchangeRatesMapper;
@ -54,6 +53,7 @@ import java.util.stream.Collectors;
import static org.jeecg.common.util.SqlInjectionUtil.specialFilterContentForDictSql;
import static org.jeecg.modules.business.entity.Invoice.InvoiceType.*;
import static org.jeecg.modules.business.entity.Invoice.InvoicingMethod.*;
import static org.jeecg.modules.business.entity.Task.TaskCode.SI_G;
import static org.jeecg.modules.business.entity.TaskHistory.TaskStatus.*;
import static org.jeecg.modules.business.vo.PlatformOrderFront.*;
@ -117,6 +117,8 @@ public class InvoiceController {
@Autowired
private ICreditService creditService;
@Autowired
private IPlatformOrderMabangService platformOrderMabangService;
@Autowired
Environment env;
@Value("${jeecg.path.shippingInvoiceDir}")
@ -246,10 +248,20 @@ public class InvoiceController {
@PostMapping(value = "/makeComplete")
public Result<?> makeCompleteShippingInvoice(@RequestBody ShippingInvoiceParam param) {
try {
String method = param.getErpStatuses().toString().equals("[3]") ? "post" : param.getErpStatuses().toString().equals("[1, 2]") ? "pre-shipping" : "all";
JSONObject response = new JSONObject();
String method = param.getErpStatuses().toString().equals("[3]") ? POSTSHIPPING.getMethod() : param.getErpStatuses().toString().equals("[1, 2]") ? PRESHIPPING.getMethod() : ALL.getMethod();
InvoiceMetaData metaData = shippingInvoiceService.makeCompleteInvoicePostShipping(param, method);
balanceService.updateBalance(param.clientID(), metaData.getInvoiceCode(), COMPLETE.name());
return Result.OK(metaData);
if(method.equals(PRESHIPPING.getMethod())) {
ResponsesWithMsg<String> mabangResponses = platformOrderMabangService.editOrdersRemark(metaData.getInvoiceCode());
response.put("metaData", metaData);
response.put("mabangResponses", mabangResponses);
return Result.OK(response);
}
response.put("metaData", metaData);
return Result.OK(response);
} catch (UserException e) {
return Result.error(e.getMessage());
} catch (IOException | ParseException e) {
@ -320,6 +332,7 @@ public class InvoiceController {
public Result<?> makeManualPurchaseInvoice(@RequestBody ShippingInvoiceOrderParam param) {
InvoiceMetaData metaData;
try {
JSONObject response = new JSONObject();
List<SkuQuantity> skuQuantities = skuService.getSkuQuantitiesFromOrderIds(param.orderIds());
if(skuQuantities.isEmpty()) {
return Result.error("Nothing to invoice.");
@ -353,7 +366,14 @@ public class InvoiceController {
emailService.sendSimpleMessage(destEmail, subject, htmlBody, session);
log.info("Mail sent successfully");
}
return Result.OK(metaData);
if(param.getType().equals(PRESHIPPING.getMethod())) {
ResponsesWithMsg<String> mabangResponses = platformOrderMabangService.editOrdersRemark(metaData.getInvoiceCode());
response.put("metaData", metaData);
response.put("mabangResponses", mabangResponses);
return Result.OK(response);
}
response.put("metaData", metaData);
return Result.OK(response);
} catch (UserException e) {
return Result.error(e.getMessage());
} catch (IOException e) {
@ -376,6 +396,7 @@ public class InvoiceController {
@PostMapping(value = "/makeManualComplete")
public Result<?> makeManualCompleteInvoice(@RequestBody ShippingInvoiceOrderParam param) {
try {
JSONObject response = new JSONObject();
InvoiceMetaData metaData = shippingInvoiceService.makeCompleteInvoice(param);
String clientCategory = clientCategoryService.getClientCategoryByClientId(param.clientID());
if(clientCategory.equals(ClientCategory.CategoryName.CONFIRMED.getName()) || clientCategory.equals(ClientCategory.CategoryName.VIP.getName())) {
@ -402,7 +423,14 @@ public class InvoiceController {
emailService.sendSimpleMessage(destEmail, subject, htmlBody, session);
log.info("Mail sent successfully");
}
return Result.OK(metaData);
if(param.getType().equals(PRESHIPPING.getMethod())) {
ResponsesWithMsg<String> mabangResponses = platformOrderMabangService.editOrdersRemark(metaData.getInvoiceCode());
response.put("metaData", metaData);
response.put("mabangResponses", mabangResponses);
return Result.OK(response);
}
response.put("metaData", metaData);
return Result.OK(response);
} catch (UserException e) {
return Result.error(e.getMessage());
} catch (IOException | ParseException e) {

View File

@ -36,6 +36,7 @@ import java.util.stream.Collectors;
import static cn.hutool.core.date.DateTime.now;
import static java.util.stream.Collectors.*;
import static org.jeecg.modules.business.entity.Invoice.InvoiceType.*;
import static org.jeecg.modules.business.entity.Invoice.InvoicingMethod.*;
@Slf4j
@Component
@ -132,11 +133,11 @@ public class ShippingInvoiceFactory {
List<ExtraFeeResult> extraFees = extraFeeService.findNotInvoicedByShops(shopIds);
log.info("Orders to be invoiced: {}", uninvoicedOrderToContent);
String subject;
if(type.equals("shipping"))
if(type.equals(POSTSHIPPING.getMethod()))
subject = String.format("Shipping fees from %s to %s", start, end);
else if(type.equals("pre-shipping"))
else if(type.equals(PRESHIPPING.getMethod()))
subject = String.format("Pre-Shipping fees, order time from %s to %s", start, end);
else if(type.equals("all"))
else if(type.equals(ALL.getMethod()))
subject = String.format("Shipping fees, order time from %s to %s", start, end);
else
throw new UserException("Couldn't create shipping invoice of unknown type.");
@ -180,11 +181,11 @@ public class ShippingInvoiceFactory {
String subject;
if(shippingMethod.equals("shipping"))
subject = String.format("Purchase and Shipping fees from %s to %s", start, end);
else if(shippingMethod.equals("post"))
else if(shippingMethod.equals(POSTSHIPPING.getMethod()))
subject = String.format("Purchase and post-Shipping fees from %s to %s", start, end);
else if (shippingMethod.equals("pre-shipping"))
else if (shippingMethod.equals(PRESHIPPING.getMethod()))
subject = String.format("Purchase and pre-Shipping fees, order time from %s to %s", start, end);
else if(shippingMethod.equals("all"))
else if(shippingMethod.equals(ALL.getMethod()))
subject = String.format("Purchase and Shipping fees, order time from %s to %s", start, end);
else throw new UserException("Couldn't create complete invoice for unknown shipping method");
if(balance != null)

View File

@ -684,6 +684,8 @@
</select>
<select id="fetchUninvoicedOrdersByShopForClientFullSQL" resultType="org.jeecg.modules.business.vo.PlatformOrderFront">
-- sku_stats counts the number of weights and prices for each sku
-- this is used to determine if an order is available for shipping or purchase invoicing
WITH sku_stats AS (
SELECT
sku.id AS sku_id,
@ -694,7 +696,7 @@
LEFT JOIN sku_price sp ON sku.id = sp.sku_id
GROUP BY sku.id
),
uninvoiced_orders AS (
uninvoiced_orders AS (
SELECT
po.id AS id,
s.name AS shop_id,
@ -769,7 +771,19 @@
</foreach>
GROUP BY po.id, po.platform_order_number, po.product_available, po.virtual_product_available, po.purchase_invoice_number
)
SELECT *, COUNT(*) OVER() AS total_count
SELECT *,
COUNT(*) OVER() AS total_count,
CASE
WHEN EXISTS (
SELECT 1
FROM platform_order_content poc
JOIN sku s ON poc.sku_id = s.id
WHERE poc.platform_order_id = uninvoiced_orders.id
AND s.is_synced = 0
AND poc.erp_status &lt;&gt; 5
) THEN 1
ELSE 0
END as has_desynced_sku
FROM uninvoiced_orders
WHERE
product_available IN
@ -965,7 +979,7 @@
<select id="getPlatformOrderIdsByInvoiceNumber" resultType="java.lang.String">
SELECT platform_order_id
FROM platform_order
WHERE shipping_invoice_number = #{invoiceNumber};
WHERE shipping_invoice_number = #{invoiceNumber} OR purchase_invoice_number = #{invoiceNumber};
</select>
<select id="countPlatformOrders" resultType="org.jeecg.modules.business.vo.OrderKpi">
WITH processedByUser AS (
@ -1283,9 +1297,7 @@
<select id="countListByClientAndShops" resultType="java.lang.Integer">
SELECT count(po.id)
FROM platform_order po
JOIN platform_order_content poc ON po.id = poc.platform_order_id
JOIN sku s ON poc.sku_id = s.id
JOIN logistic_channel lc ON po.logistic_channel_name = lc.zh_name
JOIN logistic_channel lc ON po.logistic_channel_name = lc.zh_name
WHERE po.erp_status IN
<foreach collection="erpStatuses" separator="," open="(" close=")" index="index" item="erpStatus">
#{erpStatus}
@ -1308,6 +1320,7 @@
<if test="erpStatuses.size > 1">
AND po.order_time BETWEEN #{start} AND #{end}
</if>
AND po.shipping_invoice_number IS NULL
</select>
<select id="listByClientAndShops" resultType="org.jeecg.modules.business.vo.PlatformOrderFront">
WITH orders AS (

View File

@ -5,7 +5,9 @@ import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.Order;
import org.jeecg.modules.business.domain.api.mabang.getorderlist.OrderListRequestBody;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.UpdateResult;
import org.jeecg.modules.business.vo.PlatformOrderOperation;
import org.jeecg.modules.business.vo.Response;
import org.jeecg.modules.business.vo.Responses;
import org.jeecg.modules.business.vo.ResponsesWithMsg;
@ -47,4 +49,8 @@ public interface IPlatformOrderMabangService extends IService<Order> {
JSONObject syncOrdersFromMabang(List<String> platformOrderIds) throws JSONException;
ResponsesWithMsg<String> editOrdersRemark(String invoiceNumber);
ResponsesWithMsg<String> deleteOrderRemark(String invoiceNumber);
Response<List<UpdateResult>, List<UpdateResult>> updateOrderStatusToPreparing(List<String> platformOrderIds);
}

View File

@ -1,10 +1,8 @@
package org.jeecg.modules.business.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.UpdateResult;
import org.jeecg.modules.business.domain.api.mabang.purDoGetProvider.ProviderData;
import org.jeecg.modules.business.vo.InvoiceMetaData;
import org.jeecg.modules.business.vo.Response;
import org.jeecg.modules.business.vo.Responses;
import java.time.LocalDateTime;
@ -23,6 +21,4 @@ public interface IProviderMabangService extends IService<ProviderData> {
Responses addPurchaseOrderToMabang(Map<String, Integer> skuQuantities, InvoiceMetaData metaData, AtomicReference<Map<String, LocalDateTime>> providersHistory);
Responses deletePurchaseOrderFromMabang(List<String> groupIds);
Response<List<UpdateResult>, List<UpdateResult>> updateOrderStatusToPreparing(List<String> platformOrderIds);
}

View File

@ -47,4 +47,6 @@ public interface ISkuListMabangService extends IService<SkuData> {
List<SkuOrderPage> unpairedSkus(String shopId, Integer pageNo, Integer pageSize, String column, String order);
int countUnpairedSkus(String shopId);
void compareClientSkusWithMabang(Map<String, Sku> clientSkus);
}

View File

@ -46,6 +46,7 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static org.jeecg.modules.business.entity.Invoice.InvoiceType.*;
import static org.jeecg.modules.business.entity.Invoice.InvoicingMethod.*;
@Service
@Slf4j
@ -284,7 +285,7 @@ public class PlatformOrderShippingInvoiceService {
public InvoiceMetaData makeCompleteInvoicePostShipping(ShippingInvoiceParam param, String method, String ... user) throws UserException, ParseException, IOException, MessagingException {
String username = user.length > 0 ? user[0] : ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getUsername();
List<PlatformOrder> platformOrderList;
if(method.equals("post")) {
if(method.equals(POSTSHIPPING.getMethod())) {
//On récupère les commandes entre 2 dates d'expédition avec un status 3
platformOrderList = platformOrderMapper.fetchUninvoicedShippedOrderIDInShops(param.getStart(), param.getEnd(), param.shopIDs(), param.getWarehouses());
} else {
@ -644,7 +645,7 @@ public class PlatformOrderShippingInvoiceService {
balanceService.updateBalance(entry.getKey(), metaData.getInvoiceCode(), SHIPPING.name());
}
else {
metaData = makeCompleteInvoicePostShipping(param, "post");
metaData = makeCompleteInvoicePostShipping(param, POSTSHIPPING.getMethod());
if(client.getClientCategoryId().equals(clientCategoryService.getIdByCode(CategoryName.VIP.getName()))
|| client.getClientCategoryId().equals(clientCategoryService.getIdByCode(CategoryName.CONFIRMED.getName())))
balanceService.updateBalance(entry.getKey(), metaData.getInvoiceCode(), COMPLETE.name());
@ -701,7 +702,7 @@ public class PlatformOrderShippingInvoiceService {
balanceService.updateBalance(clientId, metaData.getInvoiceCode(), SHIPPING.name());
}
else {
metaData = makeCompleteInvoicePostShipping(param, "pre-shipping", "system");
metaData = makeCompleteInvoicePostShipping(param, PRESHIPPING.getMethod(), "system");
balanceService.updateBalance(clientId, metaData.getInvoiceCode(), COMPLETE.name());
}
platformOrderMapper.updateErpStatusByCode(metaData.getInvoiceCode(), 2);

View File

@ -31,6 +31,8 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> impl
@Autowired
private IPlatformOrderContentService platformOrderContentService;
@Autowired
private IPlatformOrderMabangService platformOrderMabangService;
@Autowired
private IPlatformOrderService platformOrderService;
@Autowired
private IPurchaseOrderService purchaseOrderService;
@ -83,6 +85,7 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> impl
shippingInvoiceService.deleteAttachmentFile(po.getInventoryDocumentString());
if (po.getPaymentDocumentString() != null && !po.getPaymentDocumentString().isEmpty())
shippingInvoiceService.deleteAttachmentFile(po.getPaymentDocumentString());
platformOrderMabangService.deleteOrderRemark(invoiceNumber);
platformOrderService.removePurchaseInvoiceNumber(invoiceNumber, clientId);
purchaseOrderService.cancelInvoice(id);
}
@ -119,6 +122,7 @@ public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> impl
if(purchase.getPaymentDocumentString() != null && !purchase.getPaymentDocumentString().isEmpty())
shippingInvoiceService.deleteAttachmentFile(purchase.getPaymentDocumentString());
platformOrderContentService.cancelInvoice(invoiceNumber, clientId);
platformOrderMabangService.deleteOrderRemark(invoiceNumber);
platformOrderService.removePurchaseInvoiceNumber(invoiceNumber, clientId);
platformOrderService.cancelInvoice(invoiceNumber, clientId);
purchaseOrderService.cancelInvoice(purchase.getId());

View File

@ -3,6 +3,7 @@ package org.jeecg.modules.business.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.apache.shiro.SecurityUtils;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
@ -12,12 +13,17 @@ import org.jeecg.modules.business.domain.api.mabang.getorderlist.*;
import org.jeecg.modules.business.domain.api.mabang.orderDoOrderAbnormal.OrderSuspendRequest;
import org.jeecg.modules.business.domain.api.mabang.orderDoOrderAbnormal.OrderSuspendRequestBody;
import org.jeecg.modules.business.domain.api.mabang.orderDoOrderAbnormal.OrderSuspendResponse;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.OrderUpdateOrderNewOrderRequest;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.OrderUpdateOrderNewOrderRequestBody;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.OrderUpdateOrderNewOrderResponse;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.UpdateResult;
import org.jeecg.modules.business.domain.job.ThrottlingExecutorService;
import org.jeecg.modules.business.entity.PlatformOrder;
import org.jeecg.modules.business.mapper.PlatformOrderMabangMapper;
import org.jeecg.modules.business.service.IPlatformOrderMabangService;
import org.jeecg.modules.business.service.IPlatformOrderService;
import org.jeecg.modules.business.vo.PlatformOrderOperation;
import org.jeecg.modules.business.vo.Response;
import org.jeecg.modules.business.vo.Responses;
import org.jeecg.modules.business.vo.ResponsesWithMsg;
import org.springframework.beans.factory.annotation.Autowired;
@ -55,7 +61,6 @@ public class PlatformOrderMabangServiceImpl extends ServiceImpl<PlatformOrderMab
private static final Integer DEFAULT_NUMBER_OF_THREADS = 2;
private static final Integer MABANG_API_RATE_LIMIT_PER_MINUTE = 10;
private static final Pattern INVOICE_NUMBER_REMARK_PATTERN = Pattern.compile("^([0-9]{4}-[0-9]{2}-[1278][0-9]{3})?(.*)$");
@Override
@Transactional
@ -387,28 +392,18 @@ public class PlatformOrderMabangServiceImpl extends ServiceImpl<PlatformOrderMab
public ResponsesWithMsg<String> editOrdersRemark(String invoiceNumber) {
ResponsesWithMsg<String> responses = new ResponsesWithMsg<>();
List<String> platformOrderIds = platformOrderService.getPlatformOrderIdsByInvoiceNumber(invoiceNumber);
log.info("Editing orders remark with invoice number {} for platform order ids {}", invoiceNumber, platformOrderIds);
ExecutorService executor = ThrottlingExecutorService.createExecutorService(DEFAULT_NUMBER_OF_THREADS,
MABANG_API_RATE_LIMIT_PER_MINUTE, TimeUnit.MINUTES);
List<OrderListRequestBody> Ordersrequests = new ArrayList<>();
List<OrderListRequestBody> OrderRequests = new ArrayList<>();
List<List<String>> orderIdsPartition = Lists.partition(platformOrderIds, 10);
for (List<String> platformOrderIdList : orderIdsPartition) {
Ordersrequests.add(new OrderListRequestBody().setPlatformOrderIds(platformOrderIdList));
OrderRequests.add(new OrderListRequestBody().setPlatformOrderIds(platformOrderIdList));
}
List<Order> ordersFromMabang = getOrdersFromMabang(Ordersrequests, executor);
List<Order> ordersFromMabang = getOrdersFromMabang(OrderRequests, executor);
List<EditRemarkRequestBody> editRemarkRequests = new ArrayList<>();
for(Order order: ordersFromMabang) {
String orderRemark = order.getRemark();
StringBuilder remark = new StringBuilder();
remark.append(invoiceNumber);
Matcher invoiceMatcher = INVOICE_NUMBER_REMARK_PATTERN.matcher(order.getRemark());
// TODO : do we override the invoice number if one is present ? Ask
if (orderRemark != null && !orderRemark.isEmpty()) {
if(invoiceMatcher.matches() && !invoiceMatcher.group(2).isEmpty()) {
log.info("Order {} has remark {}", order.getPlatformOrderId(), invoiceMatcher.group(2));
remark.append(invoiceMatcher.group(2));
}
}
editRemarkRequests.add(new EditRemarkRequestBody(order.getPlatformOrderId(), remark.toString()));
editRemarkRequests.add(new EditRemarkRequestBody(order.getPlatformOrderId(), order.getRemark()+ " " + invoiceNumber));
}
List<CompletableFuture<Boolean>> editRemarkFutures = editRemarkRequests.stream()
.map(request -> CompletableFuture.supplyAsync(() -> {
@ -434,5 +429,93 @@ public class PlatformOrderMabangServiceImpl extends ServiceImpl<PlatformOrderMab
log.info("{}/{} order remarks updated successfully.", nbSuccesses, editRemarkRequests.size());
return responses;
}
@Override
public ResponsesWithMsg<String> deleteOrderRemark(String invoiceNumber) {
ResponsesWithMsg<String> responses = new ResponsesWithMsg<>();
List<String> orderIds = platformOrderService.getPlatformOrderIdsByInvoiceNumber(invoiceNumber);
log.info("Removing orders remark with invoice number {} for platform order ids {}", invoiceNumber, orderIds);
ExecutorService executor = ThrottlingExecutorService.createExecutorService(DEFAULT_NUMBER_OF_THREADS,
MABANG_API_RATE_LIMIT_PER_MINUTE, TimeUnit.MINUTES);
List<OrderListRequestBody> OrderRequests = new ArrayList<>();
List<List<String>> orderIdsPartition = Lists.partition(orderIds, 10);
for (List<String> platformOrderIdList : orderIdsPartition) {
OrderRequests.add(new OrderListRequestBody().setPlatformOrderIds(platformOrderIdList));
}
List<Order> ordersFromMabang = getOrdersFromMabang(OrderRequests, executor);
List<EditRemarkRequestBody> removeRemarkRequests = new ArrayList<>();
for(Order order: ordersFromMabang) {
Matcher invoiceRemarkMatcher = Pattern.compile("^(.*)("+ invoiceNumber +")(.*)$").matcher(order.getRemark());
if(invoiceRemarkMatcher.matches() && !invoiceRemarkMatcher.group(2).isEmpty()) {
log.info("Invoice number {} found in order remark {}", invoiceNumber, order.getPlatformOrderId());
String orderRemark1 = invoiceRemarkMatcher.group(1);
String orderRemark2 = invoiceRemarkMatcher.group(3);
removeRemarkRequests.add(new EditRemarkRequestBody(order.getPlatformOrderId(), orderRemark1.trim() + " " +orderRemark2.trim()));
} else {
log.info("Invoice number {} not found in order remark {}", invoiceNumber, order.getPlatformOrderId());
}
}
List<CompletableFuture<Boolean>> editRemarkFutures = removeRemarkRequests.stream()
.map(request -> CompletableFuture.supplyAsync(() -> {
boolean success = false;
try {
EditRemarkRequest removeRemarkRequest = new EditRemarkRequest(request);
ChangeOrderResponse response = removeRemarkRequest.send();
success = response.success();
if (success) {
responses.addSuccess(request.getPlatformOrderId());
} else {
responses.addFailure(request.getPlatformOrderId(), response.getMessage());
}
} catch (RuntimeException e) {
log.error("Error removing order remark {} : {}", request.getPlatformOrderId(), e.getMessage());
responses.addFailure(request.getPlatformOrderId(), e.getMessage());
}
return success;
}, executor))
.collect(Collectors.toList());
List<Boolean> results = editRemarkFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
long nbSuccesses = results.stream().filter(b -> b).count();
log.info("{}/{} order remarks removed successfully.", nbSuccesses, removeRemarkRequests.size());
return responses;
}
@Override
public Response<List<UpdateResult>, List<UpdateResult>> updateOrderStatusToPreparing(List<String> platformOrderIds) {
Response<List<UpdateResult>, List<UpdateResult>> updateResponse = new Response<>();
updateResponse.setData(new ArrayList<>());
updateResponse.setError(new ArrayList<>());
List<List<String>> orderPartitions = Lists.partition(platformOrderIds, 50);
ExecutorService throttlingExecutorService = ThrottlingExecutorService.createExecutorService(DEFAULT_NUMBER_OF_THREADS,
MABANG_API_RATE_LIMIT_PER_MINUTE, TimeUnit.MINUTES);
List<CompletableFuture<Boolean>> updateOrderFutures = orderPartitions.stream()
.map(platformOrderIdList -> CompletableFuture.supplyAsync(() -> {
log.info("Updating order status on Mabang for PlatformOrderIds : {}", platformOrderIdList);
OrderUpdateOrderNewOrderRequestBody body = new OrderUpdateOrderNewOrderRequestBody(platformOrderIdList);
OrderUpdateOrderNewOrderRequest request = new OrderUpdateOrderNewOrderRequest(body);
OrderUpdateOrderNewOrderResponse response = request.send();
if(!response.success()) {
log.error("Failed to update order status on Mabang. PlatformOrderIds : {} - Reason : {}", platformOrderIdList, response.getMessage());
UpdateResult error = new UpdateResult();
error.setReason(response.getMessage());
updateResponse.setError(Collections.singletonList(error));
updateResponse.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
return false;
} else {
updateResponse.getData().addAll(response.getSuccessOrders());
updateResponse.getError().addAll(response.getOrdersNotFound());
updateResponse.setStatus(!response.getOrdersNotFound().isEmpty() ? HttpStatus.SC_NOT_FOUND : HttpStatus.SC_OK);
return true;
}
}, throttlingExecutorService)).collect(Collectors.toList());
List<Boolean> results = updateOrderFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
long nbSuccesses = results.stream().filter(b -> b).count();
log.info("{}/{} platform orders status updated successfully on Mabang. PlatformOrderIds : {}", nbSuccesses, platformOrderIds.size(), platformOrderIds);
return updateResponse;
}
}

View File

@ -1,16 +1,10 @@
package org.jeecg.modules.business.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
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.orderUpdateOrderNewOrder.OrderUpdateOrderNewOrderRequest;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.OrderUpdateOrderNewOrderRequestBody;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.OrderUpdateOrderNewOrderResponse;
import org.jeecg.modules.business.domain.api.mabang.orderUpdateOrderNewOrder.UpdateResult;
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;
@ -26,7 +20,6 @@ import org.jeecg.modules.business.service.IProviderMabangService;
import org.jeecg.modules.business.service.IProviderService;
import org.jeecg.modules.business.service.IPurchaseOrderService;
import org.jeecg.modules.business.vo.InvoiceMetaData;
import org.jeecg.modules.business.vo.Response;
import org.jeecg.modules.business.vo.Responses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -243,42 +236,4 @@ public class ProviderMabangServiceImpl extends ServiceImpl<ProviderMabangMapper,
log.info("{}/{} purchase orders deleted successfully from Mabang. GroupIds : {}", nbSuccesses, groupIds.size(), groupIds);
return groupIdsDeleteResult;
}
@Override
public Response<List<UpdateResult>, List<UpdateResult>> updateOrderStatusToPreparing(List<String> platformOrderIds) {
Response<List<UpdateResult>, List<UpdateResult>> updateResponse = new Response<>();
updateResponse.setData(new ArrayList<>());
updateResponse.setError(new ArrayList<>());
List<List<String>> platformOrderIdsPartition = Lists.partition(platformOrderIds, 50);
ExecutorService throttlingExecutorService = ThrottlingExecutorService.createExecutorService(DEFAULT_NUMBER_OF_THREADS,
MABANG_API_RATE_LIMIT_PER_MINUTE, TimeUnit.MINUTES);
List<CompletableFuture<Boolean>> updateOrderFutures = platformOrderIdsPartition.stream()
.map(platformOrderIdList -> CompletableFuture.supplyAsync(() -> {
log.info("Updating order status on Mabang for PlatformOrderIds : {}", platformOrderIdList);
OrderUpdateOrderNewOrderRequestBody body = new OrderUpdateOrderNewOrderRequestBody(platformOrderIdList);
OrderUpdateOrderNewOrderRequest request = new OrderUpdateOrderNewOrderRequest(body);
OrderUpdateOrderNewOrderResponse response = request.send();
if(!response.success()) {
log.error("Failed to update order status on Mabang. PlatformOrderIds : {} - Reason : {}", platformOrderIdList, response.getMessage());
UpdateResult error = new UpdateResult();
error.setReason(response.getMessage());
updateResponse.setError(Collections.singletonList(error));
updateResponse.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
return false;
} else {
updateResponse.getData().addAll(response.getSuccessOrders());
updateResponse.getError().addAll(response.getOrdersNotFound());
updateResponse.setStatus(!response.getOrdersNotFound().isEmpty() ? HttpStatus.SC_NOT_FOUND : HttpStatus.SC_OK);
return true;
}
}, throttlingExecutorService)).collect(Collectors.toList());
List<Boolean> results = updateOrderFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
long nbSuccesses = results.stream().filter(b -> b).count();
log.info("{}/{} platform orders status updated successfully on Mabang. PlatformOrderIds : {}", nbSuccesses, platformOrderIds.size(), platformOrderIds);
return updateResponse;
}
}

View File

@ -20,6 +20,7 @@ import org.jeecg.modules.business.domain.api.mabang.stockGetStockQuantity.SkuSto
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.model.SkuDocument;
import org.jeecg.modules.business.mongoService.SkuMongoService;
import org.jeecg.modules.business.service.*;
import org.jeecg.modules.business.vo.ResponsesWithMsg;
@ -35,6 +36,8 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@ -838,4 +841,79 @@ public class SkuListMabangServiceImpl extends ServiceImpl<SkuListMabangMapper, S
public int countUnpairedSkus(String shopId) {
return skuService.countUnpairedSkus(shopId);
}
@Override
public void compareClientSkusWithMabang(Map<String, Sku> clientSkus) {
List<String> skuIds = new ArrayList<>(clientSkus.keySet());
List<SkuDocument> clientSkuDocs = new ArrayList<>();
for(String skuId: skuIds) {
List<SkuDocument> skus = skuMongoService.findBySkuId(skuId);
if(skus.isEmpty()) {
skuMongoService.migrateOneSku(clientSkus.get(skuId));
skus = skuMongoService.findBySkuId(skuId);
}
SkuDocument sku = skus.get(0);
clientSkuDocs.add(sku);
}
List<List<String>> erpCodePartition = Lists.partition(clientSkuDocs, 50)
.stream()
.map(skus -> skus.stream().map(SkuDocument::getErpCode).collect(Collectors.toList()))
.collect(Collectors.toList());
List<SkuData> skusFromMabang = new ArrayList<>();
for(List<String> partition : erpCodePartition) {
SkuListRequestBody body = new SkuListRequestBody();
body.setStockSkuList(String.join(",", partition));
SkuListRawStream rawStream = new SkuListRawStream(body);
SkuUpdateListStream stream = new SkuUpdateListStream(rawStream);
skusFromMabang.addAll(stream.all());
}
List<String> desyncedSkus = new ArrayList<>();
List<String> syncedSkus = new ArrayList<>();
for(SkuDocument sku : clientSkuDocs) {
SkuData skuData = skusFromMabang.stream().filter(s -> s.getErpCode().equals(sku.getErpCode()))
.findFirst().orElse(null);
if(skuData != null) {
boolean isDesynced = false;
BigDecimal mabangPrice = skuData.getSalePrice().setScale(2, RoundingMode.HALF_UP); // because price from mabang has 4 decimal places, so Objects.equals will always return false
int weightInRemark = -1;
Matcher saleRemarkMatcher = saleRemarkPattern.matcher(skuData.getSaleRemark());
if(saleRemarkMatcher.matches() && !saleRemarkMatcher.group(1).isEmpty()) {
String saleRemark = saleRemarkMatcher.group(1);
weightInRemark = (int) ceil(Double.parseDouble(saleRemark));
}
if(weightInRemark == -1 && sku.getLatestSkuWeight() != null) {
log.info("sku {} doesn't have a weight on Mabang but has one in Mongo", skuData.getErpCode());
isDesynced = true;
}
if (sku.getLatestSkuWeight() != null && !Objects.equals(weightInRemark, sku.getLatestSkuWeight().getWeight())) {
log.info("sku {} has a different weight on Mabang and in Mongo : mabang :{}; mongo :{}", skuData.getErpCode() ,weightInRemark, sku.getLatestSkuWeight().getWeight());
isDesynced = true;
}
if(skuData.getSalePrice() == null && sku.getLatestSkuPrice() != null) {
log.info("sku {} doesn't have a price on Mabang but has one in mongo", skuData.getErpCode());
isDesynced = true;
}
if(sku.getLatestSkuPrice() != null && !Objects.equals(mabangPrice, sku.getLatestSkuPrice().getPrice())) {
log.info("sku {} has a different price on Mabang and in Mongo : mabang :{}; mongo :{}", skuData.getErpCode() ,skuData.getSalePrice(), sku.getLatestSkuPrice().getPrice());
isDesynced = true;
}
if(isDesynced)
desyncedSkus.add(skuData.getErpCode());
else
syncedSkus.add(skuData.getErpCode());
} else {
desyncedSkus.add(sku.getErpCode());
}
}
if(!desyncedSkus.isEmpty()) {
log.info("Desynced skus : {}", desyncedSkus);
skuService.setIsSynced(desyncedSkus, false);
}
if(!syncedSkus.isEmpty()) {
log.info("Synced skus : {}", syncedSkus);
skuService.setIsSynced(syncedSkus, true);
}
}
}