mirror of https://github.com/jeecgboot/jeecg-boot
Merge pull request #127 from LQYBill/feat/clientInvoicingOptimization
Feat/client invoicing optimizationpull/8040/head
commit
47a9149549
|
@ -222,24 +222,23 @@ public class PurchaseOrderController {
|
||||||
platformOrderService.removePurchaseInvoiceNumber(purchaseOrder.getInvoiceNumber(), purchaseOrder.getClientId());
|
platformOrderService.removePurchaseInvoiceNumber(purchaseOrder.getInvoiceNumber(), purchaseOrder.getClientId());
|
||||||
List<PlatformOrder> platformOrders = platformOrderService.selectByPlatformOrderIds(platformOrderIds);
|
List<PlatformOrder> platformOrders = platformOrderService.selectByPlatformOrderIds(platformOrderIds);
|
||||||
log.info("Platform orders found for attribution : {}", platformOrders.stream().map(PlatformOrder::getPlatformOrderId).collect(Collectors.toList()));
|
log.info("Platform orders found for attribution : {}", platformOrders.stream().map(PlatformOrder::getPlatformOrderId).collect(Collectors.toList()));
|
||||||
Map<String, List<String>> platformOrderIdUpdateMap = new HashMap<>();
|
Map<String, Responses> responsesMappedByReason = new HashMap<>();
|
||||||
|
Responses platformOrderIdUpdateResponse = new Responses();
|
||||||
if(!platformOrders.isEmpty()) {
|
if(!platformOrders.isEmpty()) {
|
||||||
for(PlatformOrder po : platformOrders) {
|
for(PlatformOrder po : platformOrders) {
|
||||||
po.setPurchaseInvoiceNumber(purchaseOrder.getInvoiceNumber());
|
po.setPurchaseInvoiceNumber(purchaseOrder.getInvoiceNumber());
|
||||||
platformOrderIds.remove(po.getPlatformOrderId());
|
platformOrderIds.remove(po.getPlatformOrderId());
|
||||||
if(platformOrderIdUpdateMap.get("success") != null)
|
platformOrderIdUpdateResponse.addSuccess(po.getPlatformOrderId());
|
||||||
platformOrderIdUpdateMap.get("success").add(po.getPlatformOrderId());
|
|
||||||
else
|
|
||||||
platformOrderIdUpdateMap.put("success", new ArrayList<>(Collections.singletonList(po.getPlatformOrderId())));
|
|
||||||
}
|
}
|
||||||
platformOrderService.updateBatchById(platformOrders);
|
platformOrderService.updateBatchById(platformOrders);
|
||||||
}
|
}
|
||||||
if(!platformOrderIds.isEmpty()) {
|
if(!platformOrderIds.isEmpty()) {
|
||||||
log.error("Platform orders not found: {}", platformOrderIds);
|
log.error("Platform orders not found: {}", platformOrderIds);
|
||||||
platformOrderIdUpdateMap.put("fail", platformOrderIds);
|
platformOrderIdUpdateResponse.getFailures().addAll(platformOrderIds);
|
||||||
}
|
}
|
||||||
purchaseOrderService.updateById(purchaseOrder);
|
purchaseOrderService.updateById(purchaseOrder);
|
||||||
return Result.OK("sys.api.entryEditSuccess", platformOrderIdUpdateMap);
|
responsesMappedByReason.put("Platform Order IDs Update / 平台订单号码更新 : " + purchaseOrder.getInvoiceNumber(), platformOrderIdUpdateResponse);
|
||||||
|
return Result.OK("sys.api.entryEditSuccess", responsesMappedByReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,7 +11,6 @@ import freemarker.template.TemplateException;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.jeecg.common.api.dto.message.TemplateMessageDTO;
|
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
import org.jeecg.common.system.query.QueryGenerator;
|
||||||
|
@ -626,18 +625,53 @@ public class InvoiceController {
|
||||||
@RequestParam("type") String type
|
@RequestParam("type") String type
|
||||||
) throws IOException, UserException {
|
) throws IOException, UserException {
|
||||||
log.info("Request for downloading invoice detail by client and period : \nclient : {} \nshops : {}\nstart date : {}\nend date : {}\ntype : {}", clientId, shopIds, startDate, endDate, type);
|
log.info("Request for downloading invoice detail by client and period : \nclient : {} \nshops : {}\nstart date : {}\nend date : {}\ntype : {}", clientId, shopIds, startDate, endDate, type);
|
||||||
List<FactureDetail> invoiceDetails = shippingInvoiceService.getInvoiceDetailByShopsAndPeriod(shopIds, startDate, endDate, type);
|
boolean isEmployee = securityService.checkIsEmployee();
|
||||||
Client client = clientService.getById(clientId);
|
Client client = clientService.getById(clientId);
|
||||||
|
Client currentClient;
|
||||||
|
if(client == null) {
|
||||||
|
log.error("Client {} not found", clientId);
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
if (!isEmployee) {
|
||||||
|
currentClient = clientService.getCurrentClient();
|
||||||
|
if (currentClient == null) {
|
||||||
|
log.error("Client is not registered as a user : {}", clientId);
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
if(!clientId.equals(currentClient.getId())) {
|
||||||
|
log.error("Client {} is not authorized to download invoice detail for client {}", currentClient.getInternalCode(), client.getInternalCode());
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<FactureDetail> invoiceDetails = shippingInvoiceService.getInvoiceDetailByShopsAndPeriod(shopIds, startDate, endDate, type);
|
||||||
String period = startDate + "-" + endDate;
|
String period = startDate + "-" + endDate;
|
||||||
return shippingInvoiceService.exportToExcel(invoiceDetails, Collections.emptyList(), Collections.emptyList(), period, client.getInvoiceEntity(), client.getInternalCode());
|
return shippingInvoiceService.exportToExcel(invoiceDetails, Collections.emptyList(), Collections.emptyList(), period, client.getInvoiceEntity(), client.getInternalCode());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only downloads the inventory of skus that are in the invoice
|
||||||
|
* Whereas downloadInventory downloads the inventory of a list of skus for the client
|
||||||
|
* @param invoiceCode
|
||||||
|
* @param internalCode
|
||||||
|
* @param invoiceEntity
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
@GetMapping(value = "/downloadInvoiceInventory")
|
@GetMapping(value = "/downloadInvoiceInventory")
|
||||||
public byte[] downloadInvoiceInventory(@RequestParam("invoiceCode") String invoiceCode, @RequestParam("internalCode") String internalCode, @RequestParam("invoiceEntity") String invoiceEntity) throws IOException {
|
public byte[] downloadInvoiceInventory(@RequestParam("invoiceCode") String invoiceCode, @RequestParam("internalCode") String internalCode, @RequestParam("invoiceEntity") String invoiceEntity) throws IOException {
|
||||||
InvoiceMetaData metaData = new InvoiceMetaData("", invoiceCode, internalCode, invoiceEntity, "");
|
InvoiceMetaData metaData = new InvoiceMetaData("", invoiceCode, internalCode, invoiceEntity, "");
|
||||||
List<SkuOrderPage> skuOrderPages = skuService.getInventoryByInvoiceNumber(metaData.getInvoiceCode());
|
List<SkuOrderPage> skuOrderPages = skuService.getInventoryByInvoiceNumber(metaData.getInvoiceCode());
|
||||||
return shippingInvoiceService.exportPurchaseInventoryToExcel(skuOrderPages, metaData);
|
return shippingInvoiceService.exportPurchaseInventoryToExcel(skuOrderPages, metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the inventory of skus for the client
|
||||||
|
* @param invoiceCode
|
||||||
|
* @param internalCode
|
||||||
|
* @param invoiceEntity
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
@GetMapping(value = "/downloadInventory")
|
@GetMapping(value = "/downloadInventory")
|
||||||
public byte[] downloadInventory(@RequestParam("invoiceCode") String invoiceCode, @RequestParam("internalCode") String internalCode, @RequestParam("invoiceEntity") String invoiceEntity) throws IOException {
|
public byte[] downloadInventory(@RequestParam("invoiceCode") String invoiceCode, @RequestParam("internalCode") String internalCode, @RequestParam("invoiceEntity") String invoiceEntity) throws IOException {
|
||||||
InvoiceMetaData metaData = new InvoiceMetaData("", invoiceCode, internalCode, invoiceEntity, "");
|
InvoiceMetaData metaData = new InvoiceMetaData("", invoiceCode, internalCode, invoiceEntity, "");
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
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 UnpairedSkuListStream 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 UnpairedSkuListStream(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.AutomaticallyCreated)) {
|
||||||
|
res.add(firstElement);
|
||||||
|
}
|
||||||
|
while (hasNext()) {
|
||||||
|
SkuData nextSku = next();
|
||||||
|
if(nextSku.getStatus().equals(SkuStatus.AutomaticallyCreated)) {
|
||||||
|
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);
|
||||||
|
log.info("Raw response: {}", response.getData());
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,19 +8,23 @@ import java.util.function.Function;
|
||||||
|
|
||||||
public class AddPurchaseOrderRequestBody implements RequestBody {
|
public class AddPurchaseOrderRequestBody implements RequestBody {
|
||||||
private String providerName;
|
private String providerName;
|
||||||
private String employeeName;
|
private final String employeeName;
|
||||||
private String content;
|
private final String content;
|
||||||
private List<SkuStockData> stockData;
|
private final List<SkuStockData> stockData;
|
||||||
|
|
||||||
private final static String DEFAULT_WAREHOUSE_NAME = "SZBA宝安仓";
|
private final static String DEFAULT_WAREHOUSE_NAME = "SZBA宝安仓";
|
||||||
|
private final static String TEMPORARY_PROVIDER_NAME = "临时供货商";
|
||||||
|
|
||||||
public AddPurchaseOrderRequestBody(String employeeName, String providerName, String content, List<SkuStockData> stockData) {
|
public AddPurchaseOrderRequestBody(String employeeName, String providerName, String content, List<SkuStockData> stockData) {
|
||||||
this.stockData = stockData;
|
this.stockData = stockData;
|
||||||
this.providerName = providerName;
|
setProviderName(providerName);
|
||||||
this.employeeName = employeeName;
|
this.employeeName = employeeName;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProviderName(String providerName) {
|
||||||
|
this.providerName = providerName == null || providerName.isEmpty() ? TEMPORARY_PROVIDER_NAME : providerName;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public String api() {
|
public String api() {
|
||||||
return "pur-do-add-purchase";
|
return "pur-do-add-purchase";
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
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.modules.business.domain.api.mabang.doSearchSkuListNew.*;
|
||||||
|
import org.quartz.Job;
|
||||||
|
import org.quartz.JobDataMap;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class MabangUnpairedSkuJob implements Job {
|
||||||
|
@Override
|
||||||
|
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
JobDataMap jobDataMap = context.getMergedJobDataMap();
|
||||||
|
List<String> skuList = new ArrayList<>();
|
||||||
|
String parameter = ((String) jobDataMap.get("parameter"));
|
||||||
|
if (parameter != null) {
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = new JSONObject(parameter);
|
||||||
|
if (!jsonObject.isNull("skus")) {
|
||||||
|
for (int i = 0; i < jsonObject.getJSONArray("skus").length(); i++) {
|
||||||
|
skuList.add(jsonObject.getJSONArray("skus").getString(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
log.error("Error while parsing parameter as JSON, falling back to default parameters.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(skuList.isEmpty()) {
|
||||||
|
log.error("No skus provided, exiting job.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkuListRequestBody body = new SkuListRequestBody();
|
||||||
|
body.setStockSkuList(String.join(",", skuList));
|
||||||
|
SkuListRawStream rawStream = new SkuListRawStream(body);
|
||||||
|
UnpairedSkuListStream stream = new UnpairedSkuListStream(rawStream);
|
||||||
|
List<SkuData> skusFromMabang = stream.all();
|
||||||
|
// System.out.println("skus from mabang : " + skusFromMabang);
|
||||||
|
}
|
||||||
|
}
|
|
@ -715,6 +715,7 @@
|
||||||
) AS shipping_available,
|
) AS shipping_available,
|
||||||
MIN(
|
MIN(
|
||||||
CASE
|
CASE
|
||||||
|
WHEN poc.id IS NULL OR sku.id IS NULL THEN -1
|
||||||
WHEN po.purchase_invoice_number IS NULL AND stats.price_count = 0 THEN -1
|
WHEN po.purchase_invoice_number IS NULL AND stats.price_count = 0 THEN -1
|
||||||
WHEN po.purchase_invoice_number IS NOT NULL AND pur.paid_amount > 0.00 THEN 2
|
WHEN po.purchase_invoice_number IS NOT NULL AND pur.paid_amount > 0.00 THEN 2
|
||||||
WHEN po.purchase_invoice_number IS NOT NULL AND pur.paid_amount = 0.00 THEN 1
|
WHEN po.purchase_invoice_number IS NOT NULL AND pur.paid_amount = 0.00 THEN 1
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
JOIN client c ON s.owner_id = c.id
|
JOIN client c ON s.owner_id = c.id
|
||||||
JOIN client_category cc ON c.client_category_id = cc.id
|
JOIN client_category cc ON c.client_category_id = cc.id
|
||||||
WHERE po.erp_status IN (1,2)
|
WHERE po.erp_status IN (1,2)
|
||||||
AND cc.name = 'self-service'
|
AND cc.name IN ('self-service', 'confirmed')
|
||||||
AND po.order_time >= #{start}
|
AND po.order_time >= #{start}
|
||||||
ORDER BY po.order_time
|
ORDER BY po.order_time
|
||||||
),
|
),
|
||||||
|
|
|
@ -85,6 +85,8 @@ public class PlatformOrderShippingInvoiceService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IShopService shopService;
|
private IShopService shopService;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private ISkuService skuService;
|
||||||
|
@Autowired
|
||||||
CountryService countryService;
|
CountryService countryService;
|
||||||
@Autowired
|
@Autowired
|
||||||
IPurchaseOrderService purchaseOrderService;
|
IPurchaseOrderService purchaseOrderService;
|
||||||
|
@ -791,6 +793,10 @@ public class PlatformOrderShippingInvoiceService {
|
||||||
log.info("File asked is of type invoice detail");
|
log.info("File asked is of type invoice detail");
|
||||||
pathList = getPath(INVOICE_DETAIL_DIR, invoiceNumber);
|
pathList = getPath(INVOICE_DETAIL_DIR, invoiceNumber);
|
||||||
}
|
}
|
||||||
|
if(filetype.equals("inventory")) {
|
||||||
|
log.info("File asked is of type inventory");
|
||||||
|
pathList = getPath(PURCHASE_INVENTORY_DIR, invoiceNumber);
|
||||||
|
}
|
||||||
if(pathList.isEmpty()) {
|
if(pathList.isEmpty()) {
|
||||||
log.error("NO INVOICE FILE FOUND : " + invoiceNumber);
|
log.error("NO INVOICE FILE FOUND : " + invoiceNumber);
|
||||||
log.info("Generating a new invoice file ...");
|
log.info("Generating a new invoice file ...");
|
||||||
|
@ -803,6 +809,11 @@ public class PlatformOrderShippingInvoiceService {
|
||||||
List<ExtraFeeResult> extraFees = extraFeeService.findByInvoiceNumber(invoiceNumber);
|
List<ExtraFeeResult> extraFees = extraFeeService.findByInvoiceNumber(invoiceNumber);
|
||||||
exportToExcel(details, refunds, extraFees, invoiceNumber, client.getInvoiceEntity(), client.getInternalCode());
|
exportToExcel(details, refunds, extraFees, invoiceNumber, client.getInvoiceEntity(), client.getInternalCode());
|
||||||
pathList = getPath(INVOICE_DETAIL_DIR, invoiceNumber);
|
pathList = getPath(INVOICE_DETAIL_DIR, invoiceNumber);
|
||||||
|
} else if (filetype.equals("inventory")) {
|
||||||
|
InvoiceMetaData metaData = purchaseOrderService.getMetaDataFromInvoiceNumbers(invoiceNumber);
|
||||||
|
List<SkuOrderPage> skuOrderPages = skuService.getInventoryByInvoiceNumber(metaData.getInvoiceCode());
|
||||||
|
exportPurchaseInventoryToExcel(skuOrderPages, metaData);
|
||||||
|
pathList = getPath(PURCHASE_INVENTORY_DIR, invoiceNumber);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "ERROR";
|
return "ERROR";
|
||||||
|
|
Loading…
Reference in New Issue