diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java index 8e3c0c903..ac94aae36 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java @@ -222,24 +222,23 @@ public class PurchaseOrderController { platformOrderService.removePurchaseInvoiceNumber(purchaseOrder.getInvoiceNumber(), purchaseOrder.getClientId()); List platformOrders = platformOrderService.selectByPlatformOrderIds(platformOrderIds); log.info("Platform orders found for attribution : {}", platformOrders.stream().map(PlatformOrder::getPlatformOrderId).collect(Collectors.toList())); - Map> platformOrderIdUpdateMap = new HashMap<>(); + Map responsesMappedByReason = new HashMap<>(); + Responses platformOrderIdUpdateResponse = new Responses(); if(!platformOrders.isEmpty()) { for(PlatformOrder po : platformOrders) { po.setPurchaseInvoiceNumber(purchaseOrder.getInvoiceNumber()); platformOrderIds.remove(po.getPlatformOrderId()); - if(platformOrderIdUpdateMap.get("success") != null) - platformOrderIdUpdateMap.get("success").add(po.getPlatformOrderId()); - else - platformOrderIdUpdateMap.put("success", new ArrayList<>(Collections.singletonList(po.getPlatformOrderId()))); + platformOrderIdUpdateResponse.addSuccess(po.getPlatformOrderId()); } platformOrderService.updateBatchById(platformOrders); } if(!platformOrderIds.isEmpty()) { log.error("Platform orders not found: {}", platformOrderIds); - platformOrderIdUpdateMap.put("fail", platformOrderIds); + platformOrderIdUpdateResponse.getFailures().addAll(platformOrderIds); } 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); } /** diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java index c0139b0e9..f3a8ab6ed 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java @@ -11,7 +11,6 @@ import freemarker.template.TemplateException; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; -import org.jeecg.common.api.dto.message.TemplateMessageDTO; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.query.QueryGenerator; @@ -626,18 +625,53 @@ public class InvoiceController { @RequestParam("type") String type ) 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); - List invoiceDetails = shippingInvoiceService.getInvoiceDetailByShopsAndPeriod(shopIds, startDate, endDate, type); + boolean isEmployee = securityService.checkIsEmployee(); 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 invoiceDetails = shippingInvoiceService.getInvoiceDetailByShopsAndPeriod(shopIds, startDate, endDate, type); String period = startDate + "-" + endDate; 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") public byte[] downloadInvoiceInventory(@RequestParam("invoiceCode") String invoiceCode, @RequestParam("internalCode") String internalCode, @RequestParam("invoiceEntity") String invoiceEntity) throws IOException { InvoiceMetaData metaData = new InvoiceMetaData("", invoiceCode, internalCode, invoiceEntity, ""); List skuOrderPages = skuService.getInventoryByInvoiceNumber(metaData.getInvoiceCode()); 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") public byte[] downloadInventory(@RequestParam("invoiceCode") String invoiceCode, @RequestParam("internalCode") String internalCode, @RequestParam("invoiceEntity") String invoiceEntity) throws IOException { InvoiceMetaData metaData = new InvoiceMetaData("", invoiceCode, internalCode, invoiceEntity, ""); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/doSearchSkuListNew/UnpairedSkuListStream.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/doSearchSkuListNew/UnpairedSkuListStream.java new file mode 100644 index 000000000..fc0b3e907 --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/doSearchSkuListNew/UnpairedSkuListStream.java @@ -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 { + + private final NetworkDataStream rawStream; + + private List 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 rawStream) { + this.rawStream = rawStream; + skus = null; + this.index = 0; + this.empty = true; + this.began = false; + } + @Override + public List all() { + SkuData firstElement = attempt(); + if (firstElement == null) { + return Collections.emptyList(); + } + + ArrayList 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; + } +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/purDoAddPurchase/AddPurchaseOrderRequestBody.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/purDoAddPurchase/AddPurchaseOrderRequestBody.java index 6aa0004a4..fdd09b117 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/purDoAddPurchase/AddPurchaseOrderRequestBody.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/api/mabang/purDoAddPurchase/AddPurchaseOrderRequestBody.java @@ -8,19 +8,23 @@ import java.util.function.Function; public class AddPurchaseOrderRequestBody implements RequestBody { private String providerName; - private String employeeName; - private String content; - private List stockData; + private final String employeeName; + private final String content; + private final List stockData; private final static String DEFAULT_WAREHOUSE_NAME = "SZBA宝安仓"; + private final static String TEMPORARY_PROVIDER_NAME = "临时供货商"; public AddPurchaseOrderRequestBody(String employeeName, String providerName, String content, List stockData) { this.stockData = stockData; - this.providerName = providerName; + setProviderName(providerName); this.employeeName = employeeName; this.content = content; } + public void setProviderName(String providerName) { + this.providerName = providerName == null || providerName.isEmpty() ? TEMPORARY_PROVIDER_NAME : providerName; + } @Override public String api() { return "pur-do-add-purchase"; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/MabangUnpairedSkuJob.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/MabangUnpairedSkuJob.java new file mode 100644 index 000000000..9f159806b --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/MabangUnpairedSkuJob.java @@ -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 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 skusFromMabang = stream.all(); +// System.out.println("skus from mabang : " + skusFromMabang); + } +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml index 4e2cde8eb..186241de9 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml @@ -715,6 +715,7 @@ ) AS shipping_available, MIN( 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 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 diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml index 5911990b1..6880e791f 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml @@ -107,7 +107,7 @@ JOIN client c ON s.owner_id = c.id JOIN client_category cc ON c.client_category_id = cc.id WHERE po.erp_status IN (1,2) - AND cc.name = 'self-service' + AND cc.name IN ('self-service', 'confirmed') AND po.order_time >= #{start} ORDER BY po.order_time ), diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java index 2de575fb6..8f3fbabef 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java @@ -85,6 +85,8 @@ public class PlatformOrderShippingInvoiceService { @Autowired private IShopService shopService; @Autowired + private ISkuService skuService; + @Autowired CountryService countryService; @Autowired IPurchaseOrderService purchaseOrderService; @@ -791,6 +793,10 @@ public class PlatformOrderShippingInvoiceService { log.info("File asked is of type invoice detail"); 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()) { log.error("NO INVOICE FILE FOUND : " + invoiceNumber); log.info("Generating a new invoice file ..."); @@ -803,6 +809,11 @@ public class PlatformOrderShippingInvoiceService { List extraFees = extraFeeService.findByInvoiceNumber(invoiceNumber); exportToExcel(details, refunds, extraFees, invoiceNumber, client.getInvoiceEntity(), client.getInternalCode()); pathList = getPath(INVOICE_DETAIL_DIR, invoiceNumber); + } else if (filetype.equals("inventory")) { + InvoiceMetaData metaData = purchaseOrderService.getMetaDataFromInvoiceNumbers(invoiceNumber); + List skuOrderPages = skuService.getInventoryByInvoiceNumber(metaData.getInvoiceCode()); + exportPurchaseInventoryToExcel(skuOrderPages, metaData); + pathList = getPath(PURCHASE_INVENTORY_DIR, invoiceNumber); } else { return "ERROR";