mirror of https://github.com/jeecgboot/jeecg-boot
feat:add SKU order workflow with export and place order by Excel
parent
2bb112f952
commit
29dd6316da
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.business.controller.admin;
|
package org.jeecg.modules.business.controller.admin;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
@ -9,6 +10,9 @@ import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||||
|
@ -19,10 +23,13 @@ import org.jeecg.modules.business.entity.*;
|
||||||
import org.jeecg.modules.business.mongoService.SkuMongoService;
|
import org.jeecg.modules.business.mongoService.SkuMongoService;
|
||||||
import org.jeecg.modules.business.service.*;
|
import org.jeecg.modules.business.service.*;
|
||||||
import org.jeecg.modules.business.vo.*;
|
import org.jeecg.modules.business.vo.*;
|
||||||
|
import org.jeecgframework.poi.excel.ExcelExportUtil;
|
||||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||||
|
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||||
|
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -37,12 +44,15 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||||
import javax.mail.Authenticator;
|
import javax.mail.Authenticator;
|
||||||
import javax.mail.PasswordAuthentication;
|
import javax.mail.PasswordAuthentication;
|
||||||
import javax.mail.Session;
|
import javax.mail.Session;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -377,30 +387,30 @@ public class SkuController {
|
||||||
|
|
||||||
@GetMapping("/listWithFilters")
|
@GetMapping("/listWithFilters")
|
||||||
public Result<?> listWithFilters(@RequestParam(name = "clientId", required = false) String clientId,
|
public Result<?> listWithFilters(@RequestParam(name = "clientId", required = false) String clientId,
|
||||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
@RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize,
|
@RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize,
|
||||||
@RequestParam(name = "column", defaultValue = "erp_code") String column,
|
@RequestParam(name = "column", defaultValue = "erp_code") String column,
|
||||||
@RequestParam(name = "order", defaultValue = "ASC") String order,
|
@RequestParam(name = "order", defaultValue = "ASC") String order,
|
||||||
@RequestParam(name = "erpCodes", required = false) String erpCodes,
|
@RequestParam(name = "erpCodes", required = false) String erpCodes,
|
||||||
@RequestParam(name = "zhNames", required = false) String zhNames,
|
@RequestParam(name = "zhNames", required = false) String zhNames,
|
||||||
@RequestParam(name = "enNames", required = false) String enNames,
|
@RequestParam(name = "enNames", required = false) String enNames,
|
||||||
ServletRequest servletRequest) {
|
ServletRequest servletRequest) {
|
||||||
if(!securityService.checkIsEmployee()) {
|
if (!securityService.checkIsEmployee()) {
|
||||||
Client client = clientService.getCurrentClient();
|
Client client = clientService.getCurrentClient();
|
||||||
// Here we don't explicitly tell the user that they are not allowed to access this endpoint for security measure.
|
// Here we don't explicitly tell the user that they are not allowed to access this endpoint for security measure.
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
return Result.error(HttpStatus.SC_NOT_FOUND, "Profile not found");
|
return Result.error(HttpStatus.SC_NOT_FOUND, "Profile not found");
|
||||||
}
|
}
|
||||||
if( clientId == null) {
|
if (clientId == null) {
|
||||||
return Result.error(HttpStatus.SC_BAD_REQUEST, "Bad request");
|
return Result.error(HttpStatus.SC_BAD_REQUEST, "Bad request");
|
||||||
}
|
}
|
||||||
if(!client.getId().equals(clientId)) {
|
if (!client.getId().equals(clientId)) {
|
||||||
return Result.error(HttpStatus.SC_NOT_FOUND, "Client not found");
|
return Result.error(HttpStatus.SC_NOT_FOUND, "Client not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String parsedColumn = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, column.replace("_dictText", ""));
|
String parsedColumn = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, column.replace("_dictText", ""));
|
||||||
String parsedOrder = order.toUpperCase();
|
String parsedOrder = order.toUpperCase();
|
||||||
if(!parsedOrder.equals("ASC") && !parsedOrder.equals("DESC")) {
|
if (!parsedOrder.equals("ASC") && !parsedOrder.equals("DESC")) {
|
||||||
return Result.error("Error 400 Bad Request");
|
return Result.error("Error 400 Bad Request");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -410,20 +420,19 @@ public class SkuController {
|
||||||
}
|
}
|
||||||
List<SkuOrderPage> skuOrdersPage;
|
List<SkuOrderPage> skuOrdersPage;
|
||||||
int total;
|
int total;
|
||||||
if(erpCodes != null || zhNames != null || enNames != null) {
|
if (erpCodes != null || zhNames != null || enNames != null) {
|
||||||
List<String> erpCodeList = erpCodes == null ? null : Arrays.asList(erpCodes.split(","));
|
List<String> erpCodeList = erpCodes == null ? null : Arrays.asList(erpCodes.split(","));
|
||||||
List<String> zhNameList = zhNames == null ? null : Arrays.asList(zhNames.split(","));
|
List<String> zhNameList = zhNames == null ? null : Arrays.asList(zhNames.split(","));
|
||||||
List<String> enNameList = enNames == null ? null : Arrays.asList(enNames.split(","));
|
List<String> enNameList = enNames == null ? null : Arrays.asList(enNames.split(","));
|
||||||
if(clientId != null) {
|
if (clientId != null) {
|
||||||
total = skuService.countAllClientSkusWithFilters(clientId, erpCodeList, zhNameList, enNameList);
|
total = skuService.countAllClientSkusWithFilters(clientId, erpCodeList, zhNameList, enNameList);
|
||||||
skuOrdersPage = skuService.fetchSkusByClientWithFilters(clientId, pageNo, pageSize, parsedColumn, parsedOrder, erpCodeList, zhNameList, enNameList);
|
skuOrdersPage = skuService.fetchSkusByClientWithFilters(clientId, pageNo, pageSize, parsedColumn, parsedOrder, erpCodeList, zhNameList, enNameList);
|
||||||
} else {
|
} else {
|
||||||
total = skuService.countAllSkuWeightsWithFilters(erpCodeList, zhNameList, enNameList);
|
total = skuService.countAllSkuWeightsWithFilters(erpCodeList, zhNameList, enNameList);
|
||||||
skuOrdersPage = skuService.fetchSkuWeightsWithFilters(pageNo, pageSize, parsedColumn, parsedOrder, erpCodeList, zhNameList, enNameList);
|
skuOrdersPage = skuService.fetchSkuWeightsWithFilters(pageNo, pageSize, parsedColumn, parsedOrder, erpCodeList, zhNameList, enNameList);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (clientId != null) {
|
||||||
if(clientId != null) {
|
|
||||||
total = skuService.countAllClientSkus(clientId);
|
total = skuService.countAllClientSkus(clientId);
|
||||||
skuOrdersPage = skuService.fetchSkusByClient(clientId, pageNo, pageSize, parsedColumn, parsedOrder);
|
skuOrdersPage = skuService.fetchSkusByClient(clientId, pageNo, pageSize, parsedColumn, parsedOrder);
|
||||||
} else {
|
} else {
|
||||||
|
@ -480,6 +489,7 @@ public class SkuController {
|
||||||
page.setTotal(total);
|
page.setTotal(total);
|
||||||
return Result.OK(page);
|
return Result.OK(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/listAllSelectableSkuIds")
|
@GetMapping("/listAllSelectableSkuIds")
|
||||||
public Result<?> listAllSelectableSkuIds(@RequestParam(name = "clientId") String clientId,
|
public Result<?> listAllSelectableSkuIds(@RequestParam(name = "clientId") String clientId,
|
||||||
@RequestParam(name = "erpCodes", required = false) String erpCodes,
|
@RequestParam(name = "erpCodes", required = false) String erpCodes,
|
||||||
|
@ -487,7 +497,7 @@ public class SkuController {
|
||||||
@RequestParam(name = "enNames", required = false) String enNames
|
@RequestParam(name = "enNames", required = false) String enNames
|
||||||
) {
|
) {
|
||||||
List<SkuOrderPage> selectableSkuIds;
|
List<SkuOrderPage> selectableSkuIds;
|
||||||
if(erpCodes != null || zhNames != null || enNames != null) {
|
if (erpCodes != null || zhNames != null || enNames != null) {
|
||||||
List<String> erpCodeList = erpCodes == null ? null : Arrays.asList(erpCodes.split(","));
|
List<String> erpCodeList = erpCodes == null ? null : Arrays.asList(erpCodes.split(","));
|
||||||
List<String> zhNameList = zhNames == null ? null : Arrays.asList(zhNames.split(","));
|
List<String> zhNameList = zhNames == null ? null : Arrays.asList(zhNames.split(","));
|
||||||
List<String> enNameList = enNames == null ? null : Arrays.asList(enNames.split(","));
|
List<String> enNameList = enNames == null ? null : Arrays.asList(enNames.split(","));
|
||||||
|
@ -497,10 +507,11 @@ public class SkuController {
|
||||||
}
|
}
|
||||||
return Result.OK(selectableSkuIds);
|
return Result.OK(selectableSkuIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/searchExistingSkuByKeywords")
|
@GetMapping("/searchExistingSkuByKeywords")
|
||||||
public Result<?> searchExistingSkuByKeywords(@RequestParam("keywords") String keywords) {
|
public Result<?> searchExistingSkuByKeywords(@RequestParam("keywords") String keywords) {
|
||||||
String parsedKeywords = keywords.trim().replaceAll("[{}=$]", "");
|
String parsedKeywords = keywords.trim().replaceAll("[{}=$]", "");
|
||||||
if(parsedKeywords.isEmpty()) {
|
if (parsedKeywords.isEmpty()) {
|
||||||
return Result.OK(new ArrayList<>());
|
return Result.OK(new ArrayList<>());
|
||||||
}
|
}
|
||||||
return Result.OK(skuMongoService.textSearch(parsedKeywords));
|
return Result.OK(skuMongoService.textSearch(parsedKeywords));
|
||||||
|
@ -510,7 +521,7 @@ public class SkuController {
|
||||||
public Result<?> createMabangSku(@RequestBody List<SkuOrderPage> skuList) {
|
public Result<?> createMabangSku(@RequestBody List<SkuOrderPage> skuList) {
|
||||||
log.info("Request to create {} new skus in Mabang", skuList.size());
|
log.info("Request to create {} new skus in Mabang", skuList.size());
|
||||||
skuList.forEach(sku -> {
|
skuList.forEach(sku -> {
|
||||||
if(sku.getShippingDiscount() == null) {
|
if (sku.getShippingDiscount() == null) {
|
||||||
sku.setShippingDiscount(BigDecimal.ZERO);
|
sku.setShippingDiscount(BigDecimal.ZERO);
|
||||||
} else {
|
} else {
|
||||||
BigDecimal oldValue = sku.getShippingDiscount().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
BigDecimal oldValue = sku.getShippingDiscount().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||||
|
@ -526,7 +537,7 @@ public class SkuController {
|
||||||
List<NewSkuPage> skuList = parseSkuList(params);
|
List<NewSkuPage> skuList = parseSkuList(params);
|
||||||
log.info("Exporting new skus to excel ...");
|
log.info("Exporting new skus to excel ...");
|
||||||
skuList.forEach(sku -> {
|
skuList.forEach(sku -> {
|
||||||
if(sku.getShippingDiscount() == null) {
|
if (sku.getShippingDiscount() == null) {
|
||||||
sku.setShippingDiscount(BigDecimal.ONE);
|
sku.setShippingDiscount(BigDecimal.ONE);
|
||||||
} else {
|
} else {
|
||||||
BigDecimal oldValue = sku.getShippingDiscount().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
BigDecimal oldValue = sku.getShippingDiscount().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||||
|
@ -641,7 +652,7 @@ public class SkuController {
|
||||||
@RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize,
|
@RequestParam(name = "pageSize", defaultValue = "50") Integer pageSize,
|
||||||
@RequestParam(name = "skus[]", required = false) List<String> skuNames
|
@RequestParam(name = "skus[]", required = false) List<String> skuNames
|
||||||
) {
|
) {
|
||||||
if(skuNames == null)
|
if (skuNames == null)
|
||||||
skuNames = new ArrayList<>();
|
skuNames = new ArrayList<>();
|
||||||
String shopId = shopService.getIdByCode(shopCode);
|
String shopId = shopService.getIdByCode(shopCode);
|
||||||
if (shopId == null) return Result.error(404, "Shop not found");
|
if (shopId == null) return Result.error(404, "Shop not found");
|
||||||
|
@ -651,17 +662,17 @@ public class SkuController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/latestSkuCounter")
|
@GetMapping(value = "/latestSkuCounter")
|
||||||
public Result<?> latestSkuCounter(@RequestParam(name= "userCode") String userCode,
|
public Result<?> latestSkuCounter(@RequestParam(name = "userCode") String userCode,
|
||||||
@RequestParam(name= "clientCode") String clientCode,
|
@RequestParam(name = "clientCode") String clientCode,
|
||||||
@RequestParam(name= "date") String date) {
|
@RequestParam(name = "date") String date) {
|
||||||
return Result.OK(skuService.latestSkuCounter(userCode, clientCode, date));
|
return Result.OK(skuService.latestSkuCounter(userCode, clientCode, date));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/compare")
|
@GetMapping(value = "/compare")
|
||||||
public Result<?> compareClientSkuWithMabang(@RequestParam(name="clientId") String clientId,
|
public Result<?> compareClientSkuWithMabang(@RequestParam(name = "clientId") String clientId,
|
||||||
@RequestParam(name="erpStatuses[]") List<String> erpStatuses) {
|
@RequestParam(name = "erpStatuses[]") List<String> erpStatuses) {
|
||||||
Map<String, Sku> clientSkus = skuService.listInUninvoicedOrders(clientId, erpStatuses);
|
Map<String, Sku> clientSkus = skuService.listInUninvoicedOrders(clientId, erpStatuses);
|
||||||
if(clientSkus.isEmpty()) {
|
if (clientSkus.isEmpty()) {
|
||||||
log.info("No skus to compare");
|
log.info("No skus to compare");
|
||||||
return Result.OK();
|
return Result.OK();
|
||||||
}
|
}
|
||||||
|
@ -669,4 +680,64 @@ public class SkuController {
|
||||||
|
|
||||||
return Result.OK();
|
return Result.OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/skuOrderExport")
|
||||||
|
public void SkuOrderExport(HttpServletResponse response,
|
||||||
|
@RequestParam String clientId) throws IOException {
|
||||||
|
List<SkuOrderPage> skuList = skuService.listSkuOrdersByClient(clientId);
|
||||||
|
String clientCode = clientService.getById(clientId).getInternalCode();
|
||||||
|
String exportDate = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
|
||||||
|
ExportParams exportParams = new ExportParams("SKU Orders" + " - " + clientCode + " - " + exportDate, "SKU Orders");
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
List<ExcelExportEntity> entityList = new ArrayList<>();
|
||||||
|
entityList.add(new ExcelExportEntity("SKU", "erpCode"));
|
||||||
|
entityList.add(new ExcelExportEntity("Nom Anglais", "enName"));
|
||||||
|
entityList.add(new ExcelExportEntity("Nom Chinois", "zhName"));
|
||||||
|
entityList.add(new ExcelExportEntity("Stock Dispo", "availableAmount"));
|
||||||
|
entityList.add(new ExcelExportEntity("Achat WIA en cours", "purchasingAmount"));
|
||||||
|
entityList.add(new ExcelExportEntity("Cde shopify en cours", "qtyInOrdersNotShipped"));
|
||||||
|
entityList.add(new ExcelExportEntity("Stock " + (new SimpleDateFormat("dd/MM").format(new Date())), "stock"));
|
||||||
|
entityList.add(new ExcelExportEntity("Quantité à acheter", "qtyToBuy"));
|
||||||
|
entityList.add(new ExcelExportEntity("Ventes 7j", "salesLastWeek"));
|
||||||
|
entityList.add(new ExcelExportEntity("Ventes 28j", "salesFourWeeks"));
|
||||||
|
entityList.add(new ExcelExportEntity("Ventes 42j", "salesSixWeeks"));
|
||||||
|
entityList.add(new ExcelExportEntity("SKU Price", "skuPrice"));
|
||||||
|
|
||||||
|
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||||
|
for (SkuOrderPage sku : skuList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("erpCode", sku.getErpCode());
|
||||||
|
map.put("enName", sku.getEnName());
|
||||||
|
map.put("zhName", sku.getZhName());
|
||||||
|
map.put("availableAmount", sku.getAvailableAmount());
|
||||||
|
map.put("purchasingAmount", sku.getPurchasingAmount());
|
||||||
|
map.put("qtyInOrdersNotShipped", sku.getQtyInOrdersNotShipped());
|
||||||
|
map.put("stock", sku.getStock());
|
||||||
|
map.put("qtyToBuy", sku.getQtyToBuy());
|
||||||
|
map.put("salesLastWeek", sku.getSalesLastWeek());
|
||||||
|
map.put("salesFourWeeks", sku.getSalesFourWeeks());
|
||||||
|
map.put("salesSixWeeks", sku.getSalesSixWeeks());
|
||||||
|
map.put("skuPrice", sku.getSkuPrice());
|
||||||
|
dataList.add(map);
|
||||||
|
}
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, dataList);
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
if (sheet.getPhysicalNumberOfRows() > 0) {
|
||||||
|
Row headerRow = sheet.getRow(0);
|
||||||
|
if (headerRow != null) {
|
||||||
|
int cellCount = headerRow.getPhysicalNumberOfCells();
|
||||||
|
for (int i = 0; i < cellCount; i++) {
|
||||||
|
sheet.autoSizeColumn(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("SKU Orders_" + clientCode + "_" + exportDate + ".xlsx", "UTF-8"));
|
||||||
|
try (ServletOutputStream out = response.getOutputStream()) {
|
||||||
|
workbook.write(out);
|
||||||
|
out.flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||||
|
|
||||||
import javax.mail.Authenticator;
|
import javax.mail.Authenticator;
|
||||||
|
@ -462,6 +463,43 @@ public class InvoiceController {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@PostMapping("/createOrderByExcel")
|
||||||
|
public Result<?> createOrderByExcel(@RequestParam("file") MultipartFile file) {
|
||||||
|
boolean isEmployee = securityService.checkIsEmployee();
|
||||||
|
Client client = null;
|
||||||
|
if (!isEmployee) {
|
||||||
|
client = clientService.getCurrentClient();
|
||||||
|
if (client == null) {
|
||||||
|
return Result.error(HttpStatus.SC_NOT_FOUND, "Client not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//get the excel data
|
||||||
|
List<Map<String, Object>> skuList = skuService.parseExcelToSkuList(file);
|
||||||
|
// if not employee, filter out skus that are not from the client
|
||||||
|
if (!isEmployee) {
|
||||||
|
Iterator<Map<String, Object>> iterator = skuList.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map<String, Object> sku = iterator.next();
|
||||||
|
String erpCode = (String) sku.get("erpCode");
|
||||||
|
if (erpCode == null || erpCode.isEmpty()) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String skuId = skuService.getIdFromErpCode(erpCode);
|
||||||
|
if (skuId == null) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String skuClientId = clientSkuService.getClientIdFromSkuId(skuId);
|
||||||
|
if (!client.getId().equals(skuClientId)) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("SKU list after filtering: {}", skuList);
|
||||||
|
return Result.OK(skuList);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/preShipping/orderTime")
|
@GetMapping(value = "/preShipping/orderTime")
|
||||||
public Result<?> getValidOrderTimePeriod(@RequestParam("shopIds[]") List<String> shopIDs, @RequestParam("erpStatuses[]") List<Integer> erpStatuses) {
|
public Result<?> getValidOrderTimePeriod(@RequestParam("shopIds[]") List<String> shopIDs, @RequestParam("erpStatuses[]") List<Integer> erpStatuses) {
|
||||||
log.info("Request for valid order time period for shops: {} and erpStatuses : {}", shopIDs.toString(), erpStatuses.toString());
|
log.info("Request for valid order time period for shops: {} and erpStatuses : {}", shopIDs.toString(), erpStatuses.toString());
|
||||||
|
|
|
@ -62,6 +62,7 @@ public interface SkuMapper extends BaseMapper<Sku> {
|
||||||
List<SkuOrderPage> fetchSkuWeightsWithFilters(@Param("offset") Integer offset, @Param("size") Integer pageSize, @Param("column") String column, @Param("order") String order, @Param("erpCodes") String erpCodesRegex, @Param("zhNames") String zhNamesRegex, @Param("enNames") String enNamesRegex);
|
List<SkuOrderPage> fetchSkuWeightsWithFilters(@Param("offset") Integer offset, @Param("size") Integer pageSize, @Param("column") String column, @Param("order") String order, @Param("erpCodes") String erpCodesRegex, @Param("zhNames") String zhNamesRegex, @Param("enNames") String enNamesRegex);
|
||||||
List<SkuOrderPage> fetchAllSkuWeightsWithFilters(@Param("offset") Integer offset, @Param("size") Integer pageSize, @Param("column") String column, @Param("order") String order, @Param("erpCodes") String erpCodesRegex, @Param("zhNames") String zhNamesRegex, @Param("enNames") String enNamesRegex);
|
List<SkuOrderPage> fetchAllSkuWeightsWithFilters(@Param("offset") Integer offset, @Param("size") Integer pageSize, @Param("column") String column, @Param("order") String order, @Param("erpCodes") String erpCodesRegex, @Param("zhNames") String zhNamesRegex, @Param("enNames") String enNamesRegex);
|
||||||
List<SkuOrderPage> fetchSkusByClientWithFilters(@Param("clientId") String clientId, @Param("offset") Integer offset, @Param("size") Integer pageSize, @Param("column") String column, @Param("order") String order, @Param("erpCodes") String erpCodesRegex, @Param("zhNames") String zhNamesRegex, @Param("enNames") String enNamesRegex);
|
List<SkuOrderPage> fetchSkusByClientWithFilters(@Param("clientId") String clientId, @Param("offset") Integer offset, @Param("size") Integer pageSize, @Param("column") String column, @Param("order") String order, @Param("erpCodes") String erpCodesRegex, @Param("zhNames") String zhNamesRegex, @Param("enNames") String enNamesRegex);
|
||||||
|
List<SkuOrderPage> listSkuOrdersByClient(@Param("clientId") String clientId);
|
||||||
|
|
||||||
List<SkuOrderPage> listSelectableSkuIdsWithFilters(@Param("clientId") String clientId, @Param("erpCodes") String erpCodeList, @Param("zhNames") String zhNameList, @Param("enNames") String enNameList);
|
List<SkuOrderPage> listSelectableSkuIdsWithFilters(@Param("clientId") String clientId, @Param("erpCodes") String erpCodeList, @Param("zhNames") String zhNameList, @Param("enNames") String enNameList);
|
||||||
List<SkuOrderPage> listSelectableSkuIds(@Param("clientId") String clientId);
|
List<SkuOrderPage> listSelectableSkuIds(@Param("clientId") String clientId);
|
||||||
|
|
|
@ -450,6 +450,58 @@
|
||||||
</if>
|
</if>
|
||||||
;
|
;
|
||||||
</select>
|
</select>
|
||||||
|
<select id="listSkuOrdersByClient" resultType="org.jeecg.modules.business.vo.SkuOrderPage">
|
||||||
|
WITH qtyInOrdersNotShippedCTE AS (
|
||||||
|
SELECT sku_id AS ID, SUM(quantity) AS quantity
|
||||||
|
FROM platform_order_content poc
|
||||||
|
JOIN platform_order po ON poc.platform_order_id = po.id
|
||||||
|
JOIN shop s ON po.shop_id = s.id
|
||||||
|
JOIN client c ON s.owner_id = c.id
|
||||||
|
WHERE c.id = #{clientId}
|
||||||
|
AND po.erp_status IN ('1','2')
|
||||||
|
AND po.can_send = 1
|
||||||
|
AND poc.erp_status IN ('1','2')
|
||||||
|
GROUP BY sku_id
|
||||||
|
), latest_exchange_rate AS (
|
||||||
|
SELECT rate
|
||||||
|
FROM exchange_rates
|
||||||
|
WHERE original_currency = 'EUR' AND target_currency = 'RMB'
|
||||||
|
ORDER BY create_time DESC LIMIT 1
|
||||||
|
), rmb_id AS (
|
||||||
|
SELECT id FROM currency WHERE code = 'RMB'
|
||||||
|
)
|
||||||
|
SELECT s.id,
|
||||||
|
s.erp_code,
|
||||||
|
s.en_name,
|
||||||
|
s.zh_name,
|
||||||
|
s.purchasing_amount,
|
||||||
|
s.available_amount,
|
||||||
|
qtyInOrdersNotShippedCTE.quantity AS qtyInOrdersNotShipped,
|
||||||
|
s.available_amount + s.purchasing_amount - COALESCE(qtyInOrdersNotShippedCTE.quantity, 0) AS stock,
|
||||||
|
s.image_source,
|
||||||
|
s.service_fee,
|
||||||
|
IF(sp.currency_id = (SELECT id FROM rmb_id),
|
||||||
|
ROUND(sp.price / (SELECT rate FROM latest_exchange_rate), 2),
|
||||||
|
sp.price) AS sku_price,
|
||||||
|
sp.threshold AS discount_moq,
|
||||||
|
IF(sp.currency_id = (SELECT id FROM rmb_id),
|
||||||
|
ROUND(sp.discounted_price / (SELECT rate FROM latest_exchange_rate), 2),
|
||||||
|
sp.discounted_price) AS discounted_price,
|
||||||
|
s7.quantity AS sales_last_week,
|
||||||
|
s28.quantity AS sales_four_weeks,
|
||||||
|
s42.quantity AS sales_six_weeks
|
||||||
|
FROM sku s
|
||||||
|
JOIN client_sku ON s.id = client_sku.sku_id
|
||||||
|
LEFT JOIN sku_current_price sp ON s.id = sp.sku_id
|
||||||
|
LEFT JOIN sales_28 s28 ON s.id = s28.sku_id
|
||||||
|
LEFT JOIN sales_42 s42 ON s.id = s42.sku_id
|
||||||
|
LEFT JOIN sales_7 s7 ON s.id = s7.sku_id
|
||||||
|
LEFT JOIN qtyInOrdersNotShippedCTE ON s.id = qtyInOrdersNotShippedCTE.ID
|
||||||
|
WHERE client_sku.client_id = #{clientId}
|
||||||
|
AND s.status = 3
|
||||||
|
ORDER BY stock ASC
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="listSelectableSkuIds" resultType="org.jeecg.modules.business.vo.SkuOrderPage">
|
<select id="listSelectableSkuIds" resultType="org.jeecg.modules.business.vo.SkuOrderPage">
|
||||||
WITH qtyInOrdersNotShippedCTE AS (
|
WITH qtyInOrdersNotShippedCTE AS (
|
||||||
SELECT sku_id as ID, SUM(quantity) AS quantity
|
SELECT sku_id as ID, SUM(quantity) AS quantity
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.jeecg.modules.business.controller.UserException;
|
||||||
import org.jeecg.modules.business.entity.*;
|
import org.jeecg.modules.business.entity.*;
|
||||||
import org.jeecg.modules.business.vo.*;
|
import org.jeecg.modules.business.vo.*;
|
||||||
import org.jeecg.modules.business.vo.inventory.InventoryRecord;
|
import org.jeecg.modules.business.vo.inventory.InventoryRecord;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -98,6 +99,7 @@ public interface ISkuService extends IService<Sku> {
|
||||||
|
|
||||||
Integer countAllClientSkus(String clientId);
|
Integer countAllClientSkus(String clientId);
|
||||||
List<SkuOrderPage> fetchSkusByClient(String clientId, Integer pageNo, Integer pageSize, String column, String order);
|
List<SkuOrderPage> fetchSkusByClient(String clientId, Integer pageNo, Integer pageSize, String column, String order);
|
||||||
|
List<SkuOrderPage> listSkuOrdersByClient(String clientId);
|
||||||
|
|
||||||
Integer countAllSkuWeightsWithFilters(List<String> erpCodeList, List<String> zhNameList, List<String> enNameList);
|
Integer countAllSkuWeightsWithFilters(List<String> erpCodeList, List<String> zhNameList, List<String> enNameList);
|
||||||
|
|
||||||
|
@ -134,4 +136,6 @@ public interface ISkuService extends IService<Sku> {
|
||||||
int latestSkuCounter(String userCode, String clientCode, String date);
|
int latestSkuCounter(String userCode, String clientCode, String date);
|
||||||
|
|
||||||
void setIsSynced(List<String> erpCodes, boolean isSynced);
|
void setIsSynced(List<String> erpCodes, boolean isSynced);
|
||||||
|
|
||||||
|
List<Map<String, Object>> parseExcelToSkuList(MultipartFile file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.jeecg.modules.business.service.impl;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
import org.jeecg.modules.business.controller.UserException;
|
import org.jeecg.modules.business.controller.UserException;
|
||||||
|
@ -19,6 +20,7 @@ import org.jeecg.modules.business.vo.inventory.InventoryRecord;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
@ -427,6 +429,10 @@ public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku> implements ISkuS
|
||||||
return skuMapper.fetchSkusByClient(clientId, offset, pageSize, column, order);
|
return skuMapper.fetchSkusByClient(clientId, offset, pageSize, column, order);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public List<SkuOrderPage> listSkuOrdersByClient(String clientID){
|
||||||
|
return skuMapper.listSkuOrdersByClient(clientID);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public Integer countAllSkuWeightsWithFilters(List<String> erpCodes, List<String> zhNames, List<String> enNames) {
|
public Integer countAllSkuWeightsWithFilters(List<String> erpCodes, List<String> zhNames, List<String> enNames) {
|
||||||
StringBuilder erpCodesRegex= new StringBuilder(), zhNamesRegex = new StringBuilder(), enNamesRegex = new StringBuilder();
|
StringBuilder erpCodesRegex= new StringBuilder(), zhNamesRegex = new StringBuilder(), enNamesRegex = new StringBuilder();
|
||||||
if(erpCodes != null){
|
if(erpCodes != null){
|
||||||
|
@ -710,4 +716,80 @@ public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku> implements ISkuS
|
||||||
public void setIsSynced(List<String> erpCodes, boolean isSynced) {
|
public void setIsSynced(List<String> erpCodes, boolean isSynced) {
|
||||||
skuMapper.setIsSynced(erpCodes, isSynced);
|
skuMapper.setIsSynced(erpCodes, isSynced);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> parseExcelToSkuList(MultipartFile file) {
|
||||||
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
|
try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
int headerRowIndex = -1;
|
||||||
|
Map<String, Integer> colMap = new HashMap<>();
|
||||||
|
// find header row with required columns
|
||||||
|
for (int i = 0; i <= 5; i++) {
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if (row == null) continue;
|
||||||
|
for (int j = 0; j < row.getLastCellNum(); j++) {
|
||||||
|
Cell cell = row.getCell(j);
|
||||||
|
if (cell == null || cell.getCellType() != CellType.STRING) continue;
|
||||||
|
String val = cell.getStringCellValue().trim().toLowerCase();
|
||||||
|
if (val.equals("sku")) colMap.put("erpCode", j);
|
||||||
|
else if (val.contains("anglais")) colMap.put("enName", j);
|
||||||
|
else if (val.contains("chinois")) colMap.put("zhName", j);
|
||||||
|
else if (val.contains("stock dispo")) colMap.put("stock", j);
|
||||||
|
else if (val.contains("wia")) colMap.put("purchaseWIA", j);
|
||||||
|
else if (val.contains("shopify")) colMap.put("shopifyOrder", j);
|
||||||
|
else if (val.contains("stock") && val.matches(".*\\d{2}/\\d{2}.*")) colMap.put("stockDate", j);
|
||||||
|
else if (val.contains("quantité") || val.contains("quantity")) colMap.put("quantity", j);
|
||||||
|
else if (val.contains("ventes 7")) colMap.put("sales7d", j);
|
||||||
|
else if (val.contains("ventes 28")) colMap.put("sales28d", j);
|
||||||
|
else if (val.contains("ventes 42")) colMap.put("sales42d", j);
|
||||||
|
else if (val.contains("price")) colMap.put("skuPrice", j);
|
||||||
|
}
|
||||||
|
if (!colMap.isEmpty()) {
|
||||||
|
headerRowIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (headerRowIndex == -1 || !colMap.containsKey("erpCode") || !colMap.containsKey("quantity")) {
|
||||||
|
throw new RuntimeException("Missing required columns: SKU and Quantity");
|
||||||
|
}
|
||||||
|
// parse data rows
|
||||||
|
for (int i = headerRowIndex + 1; i <= sheet.getLastRowNum(); i++) {
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if (row == null) continue;
|
||||||
|
Map<String, Object> sku = new HashMap<>();
|
||||||
|
for (Map.Entry<String, Integer> entry : colMap.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
int col = entry.getValue();
|
||||||
|
Cell cell = row.getCell(col);
|
||||||
|
if (cell == null) continue;
|
||||||
|
Object value = null;
|
||||||
|
if (cell.getCellType() == CellType.NUMERIC) {
|
||||||
|
value = key.equals("erpCode")
|
||||||
|
? new BigDecimal(cell.getNumericCellValue()).toPlainString().trim()
|
||||||
|
: cell.getNumericCellValue();
|
||||||
|
} else {
|
||||||
|
String str = cell.toString().trim();
|
||||||
|
if (Arrays.asList("quantity", "sales7d", "sales28d", "sales42d", "skuPrice", "stock", "purchaseWIA", "shopifyOrder", "stockDate").contains(key)) {
|
||||||
|
try {
|
||||||
|
value = Double.parseDouble(str);
|
||||||
|
} catch (NumberFormatException ignored) {}
|
||||||
|
} else {
|
||||||
|
value = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sku.put(key, value);
|
||||||
|
}
|
||||||
|
// Only add SKUs with positive quantity and positive price
|
||||||
|
Object qtyObj = sku.get("quantity");
|
||||||
|
if (qtyObj instanceof Number && ((Number) qtyObj).doubleValue() > 0) {
|
||||||
|
result.add(sku);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.info("Parsed Excel SKU list: {}", result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Excel parsing failed", e);
|
||||||
|
throw new RuntimeException("Excel parsing error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -85,6 +85,12 @@ public class SkuOrderPage {
|
||||||
@Excel(name = "stock", width = 15)
|
@Excel(name = "stock", width = 15)
|
||||||
@ApiModelProperty(value = "stock")
|
@ApiModelProperty(value = "stock")
|
||||||
private Integer stock;
|
private Integer stock;
|
||||||
|
/**
|
||||||
|
* 用户要采购的数量
|
||||||
|
*/
|
||||||
|
@Excel(name = "qty à acheter", width = 15)
|
||||||
|
@ApiModelProperty("用户要采购的数量")
|
||||||
|
private Integer qtyToBuy = 0;
|
||||||
/**
|
/**
|
||||||
* 图片链接
|
* 图片链接
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue