feat: 更新项目订单导出和批量查询功能
- 修改 `VueProjectOrderInfoController` 中的导出方法,调用 `exportMcpList` 代替 `exportList` - 在 `IProjectOrderInfoService` 接口中添加 `exportMcpList` 方法 - 在 `ProjectInfo` 实体类中添加 `orderCode` 属性 - 在 `OmsInventoryInnerMapper` 和 `InventoryInfoMapper` 中添加按 `orderCodeList` 和 `innerCodeList` 查询的方法 - 在 `ProjectInfoMapper` 中添加按 `orderCodeList` 查询的方法 - 扩展 `ProjectOrderInfoToolProvider` 类,添加相关依赖和服务,并更新处理逻辑dev_1.0.2
parent
9e8edf01b8
commit
5eec808514
|
|
@ -152,7 +152,7 @@ public class VueProjectOrderInfoController extends BaseController {
|
|||
@PostMapping("/export")
|
||||
public AjaxResult export(@RequestBody ProjectOrderInfo projectOrderInfo) {
|
||||
// 在Vue前端,通常是先调用这个接口生成文件,拿到文件名,然后再通过/common/download接口下载
|
||||
String fileName = projectOrderInfoService.exportList(projectOrderInfo);
|
||||
String fileName = projectOrderInfoService.exportMcpList(projectOrderInfo);
|
||||
return AjaxResult.success(fileName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,5 +79,6 @@ public class OmsInventoryInner extends BaseEntity {
|
|||
private BigDecimal taxTotal;
|
||||
private Long itemId;
|
||||
private List<String> productTypeList;
|
||||
private List<String> orderCodeList;
|
||||
private List<InventoryInfo> inventoryInfoList;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public class ProjectInfo extends BaseEntity
|
|||
/** */
|
||||
private Long id;
|
||||
private String ids;
|
||||
private String orderCode;
|
||||
|
||||
/** 项目编码 */
|
||||
@Excel(name = "项目编号")
|
||||
|
|
|
|||
|
|
@ -1,217 +1,217 @@
|
|||
package com.ruoyi.sip.llm.tools;
|
||||
|
||||
import com.ruoyi.sip.domain.InventoryInfo;
|
||||
import com.ruoyi.sip.domain.InventoryOuter;
|
||||
import com.ruoyi.sip.domain.ProductInfo;
|
||||
import com.ruoyi.sip.llm.tools.support.AbstractMcpToolProvider;
|
||||
import com.ruoyi.sip.service.IInventoryInfoService;
|
||||
import com.ruoyi.sip.service.IInventoryOuterService;
|
||||
import com.ruoyi.sip.service.IProductInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class OutboundOrderInventoryInfoToolProvider extends AbstractMcpToolProvider {
|
||||
|
||||
@Autowired
|
||||
private IInventoryInfoService inventoryInfoService;
|
||||
|
||||
@Autowired
|
||||
private IInventoryOuterService inventoryOuterService;
|
||||
|
||||
@Autowired
|
||||
private IProductInfoService productInfoService;
|
||||
|
||||
@Override
|
||||
protected String getToolName() {
|
||||
return "outbound_order_inventory_info";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getToolDescription() {
|
||||
return "Batch query barcode and price details by outbound order codes.";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> buildInputSchema() {
|
||||
Map<String, Object> outerCodeListProperty = new LinkedHashMap<>();
|
||||
outerCodeListProperty.put("type", "array");
|
||||
outerCodeListProperty.put("description", "Outbound order code list.");
|
||||
outerCodeListProperty.put("items", stringProperty("Outbound order code"));
|
||||
outerCodeListProperty.put("minItems", 1);
|
||||
|
||||
Map<String, Object> properties = new LinkedHashMap<>();
|
||||
properties.put("outer_code_list", outerCodeListProperty);
|
||||
return objectSchema(properties, "outer_code_list");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object handle(Map<String, Object> params) {
|
||||
List<String> outerCodeList = getStringList(params, "outer_code_list");
|
||||
if (outerCodeList.isEmpty()) {
|
||||
throw new RuntimeException("outer_code_list is required");
|
||||
}
|
||||
|
||||
List<InventoryOuter> inventoryOuters = loadInventoryOuters(outerCodeList);
|
||||
Map<String, String> productNameMap = loadProductNameMap(inventoryOuters);
|
||||
Map<String, List<InventoryInfo>> inventoryInfoMap = loadInventoryInfoMap(outerCodeList);
|
||||
|
||||
List<Map<String, Object>> items = new ArrayList<>();
|
||||
for (InventoryOuter inventoryOuter : inventoryOuters) {
|
||||
items.add(toOutboundOrderItem(inventoryOuter, productNameMap, inventoryInfoMap));
|
||||
}
|
||||
|
||||
Map<String, Object> query = new LinkedHashMap<>();
|
||||
query.put("outer_code_list", outerCodeList);
|
||||
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("total", items.size());
|
||||
data.put("items", items);
|
||||
|
||||
Map<String, Object> metadata = new LinkedHashMap<>();
|
||||
metadata.put("tool", getToolName());
|
||||
metadata.put("description", "Batch query outbound-order barcode details from oms_inventory_info.");
|
||||
metadata.put("query_fields", mapOf(
|
||||
"outer_code_list", "Outbound order code list"
|
||||
));
|
||||
metadata.put("data_fields", mapOf(
|
||||
"total", "Matched outbound orders count",
|
||||
"items", "Outbound order detail list"
|
||||
));
|
||||
metadata.put("item_fields", mapOf(
|
||||
"outboundOrderCode", "Outbound order code",
|
||||
"orderCode", "Order code",
|
||||
"productCode", "Product code",
|
||||
"productName", "Product name",
|
||||
"quantity", "Outbound quantity",
|
||||
"inventoryCount", "Barcode detail count",
|
||||
"inventoryInfos", "Barcode detail list"
|
||||
));
|
||||
metadata.put("inventory_info_fields", mapOf(
|
||||
"productSn", "Barcode / serial number",
|
||||
"innerPrice", "Inner price",
|
||||
"outerPrice", "Outer price",
|
||||
"taxRate", "Tax rate"
|
||||
));
|
||||
|
||||
return response(metadata, query, data);
|
||||
}
|
||||
|
||||
private List<InventoryOuter> loadInventoryOuters(List<String> outerCodeList) {
|
||||
InventoryOuter query = new InventoryOuter();
|
||||
query.setOuterCodeList(outerCodeList);
|
||||
List<InventoryOuter> inventoryOuters = inventoryOuterService.selectInventoryOuterList(query);
|
||||
if (inventoryOuters == null || inventoryOuters.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Map<String, InventoryOuter> outerMap = inventoryOuters.stream().collect(Collectors.toMap(
|
||||
InventoryOuter::getOuterCode,
|
||||
item -> item,
|
||||
(first, second) -> first,
|
||||
LinkedHashMap::new
|
||||
));
|
||||
|
||||
List<InventoryOuter> ordered = new ArrayList<>();
|
||||
for (String outerCode : outerCodeList) {
|
||||
InventoryOuter inventoryOuter = outerMap.get(outerCode);
|
||||
if (inventoryOuter != null) {
|
||||
ordered.add(inventoryOuter);
|
||||
}
|
||||
}
|
||||
return ordered;
|
||||
}
|
||||
|
||||
private Map<String, String> loadProductNameMap(List<InventoryOuter> inventoryOuters) {
|
||||
if (inventoryOuters == null || inventoryOuters.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Set<String> productCodes = inventoryOuters.stream()
|
||||
.map(InventoryOuter::getProductCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (productCodes.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(new ArrayList<>(productCodes));
|
||||
if (productInfos == null || productInfos.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return productInfos.stream().collect(Collectors.toMap(ProductInfo::getProductCode, ProductInfo::getProductName, (a, b) -> a));
|
||||
}
|
||||
|
||||
private Map<String, List<InventoryInfo>> loadInventoryInfoMap(List<String> outerCodeList) {
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoService.selectInventoryInfoByOuterCodeList(outerCodeList);
|
||||
if (inventoryInfos == null || inventoryInfos.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return inventoryInfos.stream()
|
||||
.filter(item -> !isBlank(item.getOuterCode()))
|
||||
.collect(Collectors.groupingBy(InventoryInfo::getOuterCode, LinkedHashMap::new, Collectors.toList()));
|
||||
}
|
||||
|
||||
private Map<String, Object> toOutboundOrderItem(InventoryOuter inventoryOuter,
|
||||
Map<String, String> productNameMap,
|
||||
Map<String, List<InventoryInfo>> inventoryInfoMap) {
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoMap.get(inventoryOuter.getOuterCode());
|
||||
List<Map<String, Object>> inventoryInfoItems = new ArrayList<>();
|
||||
if (inventoryInfos != null) {
|
||||
for (InventoryInfo inventoryInfo : inventoryInfos) {
|
||||
inventoryInfoItems.add(toInventoryInfoItem(inventoryInfo));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("outboundOrderCode", inventoryOuter.getOuterCode());
|
||||
item.put("orderCode", inventoryOuter.getOrderCode());
|
||||
item.put("productCode", inventoryOuter.getProductCode());
|
||||
item.put("productName", productNameMap.get(inventoryOuter.getProductCode()));
|
||||
item.put("quantity", inventoryOuter.getQuantity());
|
||||
item.put("inventoryCount", inventoryInfoItems.size());
|
||||
item.put("inventoryInfos", inventoryInfoItems);
|
||||
return item;
|
||||
}
|
||||
|
||||
private Map<String, Object> toInventoryInfoItem(InventoryInfo inventoryInfo) {
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("productSn", inventoryInfo.getProductSn());
|
||||
item.put("innerPrice", inventoryInfo.getInnerPrice());
|
||||
item.put("outerPrice", inventoryInfo.getOuterPrice());
|
||||
item.put("taxRate", inventoryInfo.getTaxRate());
|
||||
return item;
|
||||
}
|
||||
|
||||
private List<String> getStringList(Map<String, Object> params, String key) {
|
||||
if (params == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Object value = params.get(key);
|
||||
if (!(value instanceof List)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<?> rawList = (List<?>) value;
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Object raw : rawList) {
|
||||
if (raw == null) {
|
||||
continue;
|
||||
}
|
||||
String item = String.valueOf(raw).trim();
|
||||
if (!item.isEmpty()) {
|
||||
result.add(item);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//package com.ruoyi.sip.llm.tools;
|
||||
//
|
||||
//import com.ruoyi.sip.domain.InventoryInfo;
|
||||
//import com.ruoyi.sip.domain.InventoryOuter;
|
||||
//import com.ruoyi.sip.domain.ProductInfo;
|
||||
//import com.ruoyi.sip.llm.tools.support.AbstractMcpToolProvider;
|
||||
//import com.ruoyi.sip.service.IInventoryInfoService;
|
||||
//import com.ruoyi.sip.service.IInventoryOuterService;
|
||||
//import com.ruoyi.sip.service.IProductInfoService;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.Collections;
|
||||
//import java.util.LinkedHashMap;
|
||||
//import java.util.LinkedHashSet;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//import java.util.Set;
|
||||
//import java.util.stream.Collectors;
|
||||
//
|
||||
//@Component
|
||||
//public class OutboundOrderInventoryInfoToolProvider extends AbstractMcpToolProvider {
|
||||
//
|
||||
// @Autowired
|
||||
// private IInventoryInfoService inventoryInfoService;
|
||||
//
|
||||
// @Autowired
|
||||
// private IInventoryOuterService inventoryOuterService;
|
||||
//
|
||||
// @Autowired
|
||||
// private IProductInfoService productInfoService;
|
||||
//
|
||||
// @Override
|
||||
// protected String getToolName() {
|
||||
// return "outbound_order_inventory_info";
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected String getToolDescription() {
|
||||
// return "Batch query barcode and price details by outbound order codes.";
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected Map<String, Object> buildInputSchema() {
|
||||
// Map<String, Object> outerCodeListProperty = new LinkedHashMap<>();
|
||||
// outerCodeListProperty.put("type", "array");
|
||||
// outerCodeListProperty.put("description", "Outbound order code list.");
|
||||
// outerCodeListProperty.put("items", stringProperty("Outbound order code"));
|
||||
// outerCodeListProperty.put("minItems", 1);
|
||||
//
|
||||
// Map<String, Object> properties = new LinkedHashMap<>();
|
||||
// properties.put("outer_code_list", outerCodeListProperty);
|
||||
// return objectSchema(properties, "outer_code_list");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected Object handle(Map<String, Object> params) {
|
||||
// List<String> outerCodeList = getStringList(params, "outer_code_list");
|
||||
// if (outerCodeList.isEmpty()) {
|
||||
// throw new RuntimeException("outer_code_list is required");
|
||||
// }
|
||||
//
|
||||
// List<InventoryOuter> inventoryOuters = loadInventoryOuters(outerCodeList);
|
||||
// Map<String, String> productNameMap = loadProductNameMap(inventoryOuters);
|
||||
// Map<String, List<InventoryInfo>> inventoryInfoMap = loadInventoryInfoMap(outerCodeList);
|
||||
//
|
||||
// List<Map<String, Object>> items = new ArrayList<>();
|
||||
// for (InventoryOuter inventoryOuter : inventoryOuters) {
|
||||
// items.add(toOutboundOrderItem(inventoryOuter, productNameMap, inventoryInfoMap));
|
||||
// }
|
||||
//
|
||||
// Map<String, Object> query = new LinkedHashMap<>();
|
||||
// query.put("outer_code_list", outerCodeList);
|
||||
//
|
||||
// Map<String, Object> data = new LinkedHashMap<>();
|
||||
// data.put("total", items.size());
|
||||
// data.put("items", items);
|
||||
//
|
||||
// Map<String, Object> metadata = new LinkedHashMap<>();
|
||||
// metadata.put("tool", getToolName());
|
||||
// metadata.put("description", "Batch query outbound-order barcode details from oms_inventory_info.");
|
||||
// metadata.put("query_fields", mapOf(
|
||||
// "outer_code_list", "Outbound order code list"
|
||||
// ));
|
||||
// metadata.put("data_fields", mapOf(
|
||||
// "total", "Matched outbound orders count",
|
||||
// "items", "Outbound order detail list"
|
||||
// ));
|
||||
// metadata.put("item_fields", mapOf(
|
||||
// "outboundOrderCode", "Outbound order code",
|
||||
// "orderCode", "Order code",
|
||||
// "productCode", "Product code",
|
||||
// "productName", "Product name",
|
||||
// "quantity", "Outbound quantity",
|
||||
// "inventoryCount", "Barcode detail count",
|
||||
// "inventoryInfos", "Barcode detail list"
|
||||
// ));
|
||||
// metadata.put("inventory_info_fields", mapOf(
|
||||
// "productSn", "Barcode / serial number",
|
||||
// "innerPrice", "Inner price",
|
||||
// "outerPrice", "Outer price",
|
||||
// "taxRate", "Tax rate"
|
||||
// ));
|
||||
//
|
||||
// return response(metadata, query, data);
|
||||
// }
|
||||
//
|
||||
// private List<InventoryOuter> loadInventoryOuters(List<String> outerCodeList) {
|
||||
// InventoryOuter query = new InventoryOuter();
|
||||
// query.setOuterCodeList(outerCodeList);
|
||||
// List<InventoryOuter> inventoryOuters = inventoryOuterService.selectInventoryOuterList(query);
|
||||
// if (inventoryOuters == null || inventoryOuters.isEmpty()) {
|
||||
// return Collections.emptyList();
|
||||
// }
|
||||
//
|
||||
// Map<String, InventoryOuter> outerMap = inventoryOuters.stream().collect(Collectors.toMap(
|
||||
// InventoryOuter::getOuterCode,
|
||||
// item -> item,
|
||||
// (first, second) -> first,
|
||||
// LinkedHashMap::new
|
||||
// ));
|
||||
//
|
||||
// List<InventoryOuter> ordered = new ArrayList<>();
|
||||
// for (String outerCode : outerCodeList) {
|
||||
// InventoryOuter inventoryOuter = outerMap.get(outerCode);
|
||||
// if (inventoryOuter != null) {
|
||||
// ordered.add(inventoryOuter);
|
||||
// }
|
||||
// }
|
||||
// return ordered;
|
||||
// }
|
||||
//
|
||||
// private Map<String, String> loadProductNameMap(List<InventoryOuter> inventoryOuters) {
|
||||
// if (inventoryOuters == null || inventoryOuters.isEmpty()) {
|
||||
// return Collections.emptyMap();
|
||||
// }
|
||||
//
|
||||
// Set<String> productCodes = inventoryOuters.stream()
|
||||
// .map(InventoryOuter::getProductCode)
|
||||
// .filter(code -> !isBlank(code))
|
||||
// .collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
// if (productCodes.isEmpty()) {
|
||||
// return Collections.emptyMap();
|
||||
// }
|
||||
//
|
||||
// List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(new ArrayList<>(productCodes));
|
||||
// if (productInfos == null || productInfos.isEmpty()) {
|
||||
// return Collections.emptyMap();
|
||||
// }
|
||||
// return productInfos.stream().collect(Collectors.toMap(ProductInfo::getProductCode, ProductInfo::getProductName, (a, b) -> a));
|
||||
// }
|
||||
//
|
||||
// private Map<String, List<InventoryInfo>> loadInventoryInfoMap(List<String> outerCodeList) {
|
||||
// List<InventoryInfo> inventoryInfos = inventoryInfoService.selectInventoryInfoByOuterCodeList(outerCodeList);
|
||||
// if (inventoryInfos == null || inventoryInfos.isEmpty()) {
|
||||
// return Collections.emptyMap();
|
||||
// }
|
||||
// return inventoryInfos.stream()
|
||||
// .filter(item -> !isBlank(item.getOuterCode()))
|
||||
// .collect(Collectors.groupingBy(InventoryInfo::getOuterCode, LinkedHashMap::new, Collectors.toList()));
|
||||
// }
|
||||
//
|
||||
// private Map<String, Object> toOutboundOrderItem(InventoryOuter inventoryOuter,
|
||||
// Map<String, String> productNameMap,
|
||||
// Map<String, List<InventoryInfo>> inventoryInfoMap) {
|
||||
// List<InventoryInfo> inventoryInfos = inventoryInfoMap.get(inventoryOuter.getOuterCode());
|
||||
// List<Map<String, Object>> inventoryInfoItems = new ArrayList<>();
|
||||
// if (inventoryInfos != null) {
|
||||
// for (InventoryInfo inventoryInfo : inventoryInfos) {
|
||||
// inventoryInfoItems.add(toInventoryInfoItem(inventoryInfo));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Map<String, Object> item = new LinkedHashMap<>();
|
||||
// item.put("outboundOrderCode", inventoryOuter.getOuterCode());
|
||||
// item.put("orderCode", inventoryOuter.getOrderCode());
|
||||
// item.put("productCode", inventoryOuter.getProductCode());
|
||||
// item.put("productName", productNameMap.get(inventoryOuter.getProductCode()));
|
||||
// item.put("quantity", inventoryOuter.getQuantity());
|
||||
// item.put("inventoryCount", inventoryInfoItems.size());
|
||||
// item.put("inventoryInfos", inventoryInfoItems);
|
||||
// return item;
|
||||
// }
|
||||
//
|
||||
// private Map<String, Object> toInventoryInfoItem(InventoryInfo inventoryInfo) {
|
||||
// Map<String, Object> item = new LinkedHashMap<>();
|
||||
// item.put("productSn", inventoryInfo.getProductSn());
|
||||
// item.put("innerPrice", inventoryInfo.getInnerPrice());
|
||||
// item.put("outerPrice", inventoryInfo.getOuterPrice());
|
||||
// item.put("taxRate", inventoryInfo.getTaxRate());
|
||||
// return item;
|
||||
// }
|
||||
//
|
||||
// private List<String> getStringList(Map<String, Object> params, String key) {
|
||||
// if (params == null) {
|
||||
// return Collections.emptyList();
|
||||
// }
|
||||
// Object value = params.get(key);
|
||||
// if (!(value instanceof List)) {
|
||||
// return Collections.emptyList();
|
||||
// }
|
||||
//
|
||||
// List<?> rawList = (List<?>) value;
|
||||
// List<String> result = new ArrayList<>();
|
||||
// for (Object raw : rawList) {
|
||||
// if (raw == null) {
|
||||
// continue;
|
||||
// }
|
||||
// String item = String.valueOf(raw).trim();
|
||||
// if (!item.isEmpty()) {
|
||||
// result.add(item);
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,33 @@
|
|||
package com.ruoyi.sip.llm.tools;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.DictUtils;
|
||||
import com.ruoyi.sip.domain.InventoryInfo;
|
||||
import com.ruoyi.sip.domain.InventoryOuter;
|
||||
import com.ruoyi.sip.domain.ProductInfo;
|
||||
import com.ruoyi.sip.domain.OmsInventoryInner;
|
||||
import com.ruoyi.sip.domain.OmsPurchaseOrderItem;
|
||||
import com.ruoyi.sip.domain.OmsReceivableBill;
|
||||
import com.ruoyi.sip.domain.ProjectInfo;
|
||||
import com.ruoyi.sip.domain.ProjectOrderInfo;
|
||||
import com.ruoyi.sip.domain.ProjectProductInfo;
|
||||
import com.ruoyi.sip.llm.tools.support.AbstractMcpToolProvider;
|
||||
import com.ruoyi.sip.mapper.InventoryInfoMapper;
|
||||
import com.ruoyi.sip.mapper.OmsInventoryInnerMapper;
|
||||
import com.ruoyi.sip.mapper.OmsPurchaseOrderMapper;
|
||||
import com.ruoyi.sip.mapper.ProjectInfoMapper;
|
||||
import com.ruoyi.sip.service.IInventoryInfoService;
|
||||
import com.ruoyi.sip.service.IInventoryOuterService;
|
||||
import com.ruoyi.sip.service.IProductInfoService;
|
||||
import com.ruoyi.sip.service.IOmsReceivableBillService;
|
||||
import com.ruoyi.sip.service.IProjectOrderInfoService;
|
||||
import com.ruoyi.sip.service.IProjectProductInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
|
|
@ -25,58 +40,37 @@ import java.util.stream.Collectors;
|
|||
@Component
|
||||
public class ProjectOrderInfoToolProvider extends AbstractMcpToolProvider {
|
||||
|
||||
private static final List<String> FIXED_ITEM_KEYS = Arrays.asList(
|
||||
"projectCode",
|
||||
"orderDate",
|
||||
"orderEffectiveDate",
|
||||
"requiredDeliveryDate",
|
||||
"orderCode",
|
||||
"projectName",
|
||||
"agentName",
|
||||
"ownerName",
|
||||
"orderChannel",
|
||||
"supplierName",
|
||||
"customerName",
|
||||
"bgName",
|
||||
"industryType",
|
||||
"projectPartnerName",
|
||||
"businessContactName",
|
||||
"businessContactPhone",
|
||||
"currencyType",
|
||||
"partnerName",
|
||||
"partnerLevel",
|
||||
"partnerContactName",
|
||||
"partnerContactPhone",
|
||||
"executionDeadline",
|
||||
"archiveTime",
|
||||
"wssQuantity",
|
||||
"wssAmount",
|
||||
"wssTaxRate",
|
||||
"wspQuantity",
|
||||
"wspAmount",
|
||||
"wspTaxRate",
|
||||
"lsQuantity",
|
||||
"lsAmount",
|
||||
"lsTaxRate"
|
||||
);
|
||||
|
||||
private static final List<String> TAIL_ITEM_KEYS = Arrays.asList(
|
||||
"shipmentAmount",
|
||||
"totalAmount",
|
||||
"maintenanceAmount",
|
||||
"softwareSubtotal",
|
||||
"hardwareSubtotal",
|
||||
"serviceSubtotal"
|
||||
);
|
||||
private static final String INDUSTRY_TYPE_DICT_TYPE = "bg_hysy";
|
||||
private static final String INDUSTRY_TYPE_YYS_DICT_TYPE = "bg_yys";
|
||||
private static final String PROJECT_STAGE_DICT_TYPE = "project_stage";
|
||||
private static final String NOT_DELIVERED_TEXT = "未发货完成";
|
||||
|
||||
@Autowired
|
||||
private IProjectOrderInfoService projectOrderInfoService;
|
||||
|
||||
@Autowired
|
||||
private IProjectProductInfoService projectProductInfoService;
|
||||
|
||||
@Autowired
|
||||
private IInventoryOuterService inventoryOuterService;
|
||||
|
||||
@Autowired
|
||||
private IProductInfoService productInfoService;
|
||||
private IInventoryInfoService inventoryInfoService;
|
||||
|
||||
@Autowired
|
||||
private InventoryInfoMapper inventoryInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private OmsInventoryInnerMapper omsInventoryInnerMapper;
|
||||
|
||||
@Autowired
|
||||
private OmsPurchaseOrderMapper omsPurchaseOrderMapper;
|
||||
|
||||
@Autowired
|
||||
private ProjectInfoMapper projectInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private IOmsReceivableBillService omsReceivableBillService;
|
||||
|
||||
@Override
|
||||
protected String getToolName() {
|
||||
|
|
@ -108,156 +102,569 @@ public class ProjectOrderInfoToolProvider extends AbstractMcpToolProvider {
|
|||
queryCondition.setCreateTimeStart(parseDateTime(createTimeStart));
|
||||
queryCondition.setCreateTimeEnd(parseDateTime(createTimeEnd));
|
||||
|
||||
List<Map<String, Object>> exportRows = projectOrderInfoService.listExportData(queryCondition);
|
||||
Map<String, List<Map<String, Object>>> outboundOrderMap = loadOutboundOrderMap(exportRows);
|
||||
|
||||
List<Map<String, Object>> items = new ArrayList<>();
|
||||
for (Map<String, Object> exportRow : exportRows) {
|
||||
items.add(attachExtraInfo(exportRow, outboundOrderMap));
|
||||
List<Map<String, Object>> items = listItems(queryCondition);
|
||||
if (CollUtil.isEmpty(items)) {
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("total", 0);
|
||||
data.put("items", Collections.emptyList());
|
||||
return response(buildMetadata(), mapOf(
|
||||
"create_time_start", createTimeStart,
|
||||
"create_time_end", createTimeEnd
|
||||
), data);
|
||||
}
|
||||
|
||||
Map<String, Object> query = mapOf(
|
||||
"create_time_start", createTimeStart,
|
||||
"create_time_end", createTimeEnd
|
||||
);
|
||||
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("total", items.size());
|
||||
data.put("items", items);
|
||||
|
||||
Map<String, Object> metadata = new LinkedHashMap<>();
|
||||
metadata.put("tool", getToolName());
|
||||
metadata.put("description", "根据创建时间范围查询项目订单信息,data.items 使用英文驼峰字段返回");
|
||||
metadata.put("query_fields", mapOf(
|
||||
"create_time_start", "创建时间范围开始,包含边界",
|
||||
"create_time_end", "创建时间范围结束,包含边界"
|
||||
));
|
||||
metadata.put("data_fields", mapOf(
|
||||
"total", "命中的项目订单数量",
|
||||
"items", "项目订单列表,字段键已统一为英文驼峰"
|
||||
));
|
||||
metadata.put("item_fields", buildItemFieldMetadata());
|
||||
metadata.put("dynamic_field_rules", mapOf(
|
||||
"details", "产品明细列表",
|
||||
"outboundOrders", "出库单列表"
|
||||
));
|
||||
metadata.put("detail_fields", mapOf(
|
||||
"productCode", "产品编码",
|
||||
"model", "型号",
|
||||
"quantity", "数量",
|
||||
"amount", "金额",
|
||||
"taxRate", "税率"
|
||||
));
|
||||
metadata.put("outbound_order_fields", mapOf(
|
||||
"outboundOrderCode", "出库单号",
|
||||
"productCode", "产品编码",
|
||||
"productName", "产品名称",
|
||||
"quantity", "数量"
|
||||
));
|
||||
|
||||
return response(metadata, query, data);
|
||||
return response(buildMetadata(), mapOf(
|
||||
"create_time_start", createTimeStart,
|
||||
"create_time_end", createTimeEnd
|
||||
), data);
|
||||
}
|
||||
|
||||
private Map<String, Object> attachExtraInfo(Map<String, Object> exportRow,
|
||||
Map<String, List<Map<String, Object>>> outboundOrderMap) {
|
||||
Map<String, Object> result = toCamelCaseItem(exportRow);
|
||||
String orderCode = stringValue(exportRow.get("_order_code"));
|
||||
List<Map<String, Object>> outboundOrders = outboundOrderMap.get(orderCode);
|
||||
result.put("outboundOrders", outboundOrders == null ? Collections.emptyList() : outboundOrders);
|
||||
return result;
|
||||
public List<Map<String, Object>> listItems(ProjectOrderInfo queryCondition) {
|
||||
if (queryCondition == null) {
|
||||
queryCondition = new ProjectOrderInfo();
|
||||
}
|
||||
List<ProjectOrderInfo> orderInfos = projectOrderInfoService.selectProjectOrderInfoList(queryCondition);
|
||||
if (CollUtil.isEmpty(orderInfos)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> orderCodes = orderInfos.stream()
|
||||
.map(ProjectOrderInfo::getOrderCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, List<ProjectProductInfo>> productMap = loadProductMap(orderInfos);
|
||||
PurchaseTaxRateContext purchaseTaxRateContext = loadPurchaseTaxRateContext(orderCodes);
|
||||
Map<String, Map<String, ProductShipmentSummary>> shipmentSummaryMap = loadShipmentSummaryMap(orderCodes, purchaseTaxRateContext);
|
||||
Map<String, Map<String, ProductCostSummary>> serviceCostMap = loadServiceCostMap(purchaseTaxRateContext);
|
||||
Map<String, ReceivableSummary> receivableSummaryMap = loadReceivableSummaryMap(orderInfos);
|
||||
Map<String, ProjectInfo> projectInfoMap = loadProjectInfoMap(orderCodes);
|
||||
|
||||
List<Map<String, Object>> items = new ArrayList<>();
|
||||
for (ProjectOrderInfo orderInfo : orderInfos) {
|
||||
items.add(buildItem(orderInfo, productMap, shipmentSummaryMap, serviceCostMap, receivableSummaryMap, projectInfoMap));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private Map<String, Object> toCamelCaseItem(Map<String, Object> exportRow) {
|
||||
List<Object> values = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : exportRow.entrySet()) {
|
||||
if ("_order_code".equals(entry.getKey()) || "_project_id".equals(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
values.add(entry.getValue());
|
||||
private Map<String, Object> buildItem(ProjectOrderInfo orderInfo,
|
||||
Map<Long, List<ProjectProductInfo>> productMap,
|
||||
Map<String, Map<String, ProductShipmentSummary>> shipmentSummaryMap,
|
||||
Map<String, Map<String, ProductCostSummary>> serviceCostMap,
|
||||
Map<String, ReceivableSummary> receivableSummaryMap,
|
||||
Map<String, ProjectInfo> projectInfoMap) {
|
||||
List<ProjectProductInfo> productInfos = productMap.getOrDefault(orderInfo.getProjectId(), Collections.emptyList());
|
||||
List<ProjectProductInfo> softwareList = filterByType(productInfos, "1");
|
||||
List<ProjectProductInfo> hardwareList = filterByType(productInfos, "2");
|
||||
List<ProjectProductInfo> serviceList = filterByType(productInfos, "3");
|
||||
|
||||
Map<String, ProductShipmentSummary> orderShipmentMap = shipmentSummaryMap.getOrDefault(orderInfo.getOrderCode(), Collections.emptyMap());
|
||||
ReceivableSummary receivableSummary = receivableSummaryMap.getOrDefault(orderInfo.getOrderCode(), new ReceivableSummary());
|
||||
ProjectInfo projectInfo = projectInfoMap.get(orderInfo.getOrderCode());
|
||||
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("projectStage", getProjectStage(projectInfo));
|
||||
item.put("orderDate", formatDate(orderInfo.getEstimatedOrderTime()));
|
||||
item.put("orderEffectiveDate", formatDate(orderInfo.getApproveTime()));
|
||||
item.put("requiredDeliveryDate", formatDate(orderInfo.getDeliveryTime()));
|
||||
item.put("contractCode", orderInfo.getOrderCode());
|
||||
item.put("projectName", orderInfo.getProjectName());
|
||||
item.put("agentName", orderInfo.getAgentName());
|
||||
item.put("orderStatus", DictUtils.getDictLabel("order_status", orderInfo.getOrderStatus()));
|
||||
item.put("ownerName", orderInfo.getDutyName());
|
||||
item.put("orderChannel", getOrderChannelName(orderInfo.getOrderChannel()));
|
||||
item.put("supplierName", orderInfo.getSupplier());
|
||||
item.put("customerName", orderInfo.getCustomerName());
|
||||
item.put("bgName", DictUtils.getDictLabel("bg_type", orderInfo.getBgProperty()));
|
||||
item.put("industryType", getIndustryTypeName(orderInfo));
|
||||
item.put("constructionType", "");
|
||||
item.put("projectPartnerName", orderInfo.getProjectPartnerName());
|
||||
item.put("businessContactName", orderInfo.getBusinessPerson());
|
||||
item.put("businessContactPhone", orderInfo.getBusinessPhone());
|
||||
item.put("currencyType", DictUtils.getDictLabel("currency_type", orderInfo.getCurrencyType()));
|
||||
item.put("partnerName", orderInfo.getPartnerName());
|
||||
item.put("partnerLevel", DictUtils.getDictLabel("identify_level", orderInfo.getLevel()));
|
||||
item.put("partnerContactName", orderInfo.getPartnerUserName());
|
||||
item.put("partnerContactPhone", orderInfo.getPartnerPhone());
|
||||
item.put("executionDeadline", formatDate(orderInfo.getOrderEndTime()));
|
||||
item.put("archiveTime", formatDateTime(orderInfo.getApproveTime()));
|
||||
|
||||
ProductGroupSummary softwareSummary = appendProductFields(item, "software", softwareList,
|
||||
orderShipmentMap, Collections.emptyMap(), true);
|
||||
ProductGroupSummary hardwareSummary = appendProductFields(item, "hardware", hardwareList,
|
||||
orderShipmentMap, Collections.emptyMap(), true);
|
||||
ProductGroupSummary serviceSummary = appendProductFields(item, "service", serviceList,
|
||||
Collections.emptyMap(), serviceCostMap.getOrDefault(orderInfo.getOrderCode(), Collections.emptyMap()), false);
|
||||
|
||||
BigDecimal orderAmountWithTax = defaultValue(orderInfo.getShipmentAmount());
|
||||
BigDecimal discountAmountWithTax = softwareSummary.salesWithTax
|
||||
.add(hardwareSummary.salesWithTax)
|
||||
.add(serviceSummary.salesWithTax);
|
||||
BigDecimal discountAmountWithoutTax = softwareSummary.salesWithoutTax
|
||||
.add(hardwareSummary.salesWithoutTax)
|
||||
.add(serviceSummary.salesWithoutTax);
|
||||
boolean allDelivered = softwareSummary.allDelivered && hardwareSummary.allDelivered && serviceSummary.allDelivered;
|
||||
BigDecimal costWithTax = softwareSummary.costWithTax.add(hardwareSummary.costWithTax).add(serviceSummary.costWithTax);
|
||||
BigDecimal costWithoutTax = softwareSummary.costWithoutTax.add(hardwareSummary.costWithoutTax).add(serviceSummary.costWithoutTax);
|
||||
|
||||
item.put("orderAmountWithTax", orderAmountWithTax);
|
||||
item.put("discountedOrderAmountWithTax", discountAmountWithTax);
|
||||
item.put("discountedOrderAmountWithoutTax", discountAmountWithoutTax);
|
||||
item.put("costTotalWithTax", allDelivered ? costWithTax : NOT_DELIVERED_TEXT);
|
||||
item.put("costTotalWithoutTax", allDelivered ? costWithoutTax : NOT_DELIVERED_TEXT);
|
||||
|
||||
if (allDelivered) {
|
||||
BigDecimal grossProfit = discountAmountWithoutTax.subtract(costWithoutTax);
|
||||
item.put("grossProfit", grossProfit);
|
||||
item.put("grossProfitRate", percentage(grossProfit, costWithoutTax));
|
||||
} else {
|
||||
item.put("grossProfit", NOT_DELIVERED_TEXT);
|
||||
item.put("grossProfitRate", NOT_DELIVERED_TEXT);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
int fixedCount = Math.min(FIXED_ITEM_KEYS.size(), values.size());
|
||||
for (int i = 0; i < fixedCount; i++) {
|
||||
result.put(FIXED_ITEM_KEYS.get(i), values.get(i));
|
||||
}
|
||||
|
||||
int detailStart = fixedCount;
|
||||
int detailEnd = Math.max(detailStart, values.size() - TAIL_ITEM_KEYS.size());
|
||||
List<Map<String, Object>> details = new ArrayList<>();
|
||||
for (int i = detailStart; i + 4 < detailEnd; i += 5) {
|
||||
Map<String, Object> detail = new LinkedHashMap<>();
|
||||
detail.put("productCode", values.get(i));
|
||||
detail.put("model", values.get(i + 1));
|
||||
detail.put("quantity", values.get(i + 2));
|
||||
detail.put("amount", values.get(i + 3));
|
||||
detail.put("taxRate", values.get(i + 4));
|
||||
if (!isEmptyDetail(detail)) {
|
||||
details.add(detail);
|
||||
}
|
||||
}
|
||||
result.put("details", details);
|
||||
|
||||
int tailStart = Math.max(detailEnd, values.size() - TAIL_ITEM_KEYS.size());
|
||||
for (int i = 0; i < TAIL_ITEM_KEYS.size() && tailStart + i < values.size(); i++) {
|
||||
result.put(TAIL_ITEM_KEYS.get(i), values.get(tailStart + i));
|
||||
}
|
||||
return result;
|
||||
item.put("deliveryTime", collectDeliveryTimes(orderShipmentMap));
|
||||
item.put("expectedReceiptAmount", receivableSummary.totalPriceWithTax);
|
||||
item.put("receivedAmount", receivableSummary.receivedAmount);
|
||||
item.put("isCharged", isCharged(orderInfo.getChargeStatus()));
|
||||
return item;
|
||||
}
|
||||
|
||||
private Map<String, List<Map<String, Object>>> loadOutboundOrderMap(List<Map<String, Object>> exportRows) {
|
||||
if (exportRows == null || exportRows.isEmpty()) {
|
||||
private Map<Long, List<ProjectProductInfo>> loadProductMap(List<ProjectOrderInfo> orderInfos) {
|
||||
List<Long> projectIds = orderInfos.stream()
|
||||
.map(ProjectOrderInfo::getProjectId)
|
||||
.filter(id -> id != null)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(projectIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<ProjectProductInfo> productInfos = projectProductInfoService.selectProjectProductInfoListByProjectId(projectIds);
|
||||
if (CollUtil.isEmpty(productInfos)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return productInfos.stream().collect(Collectors.groupingBy(ProjectProductInfo::getProjectId, LinkedHashMap::new, Collectors.toList()));
|
||||
}
|
||||
|
||||
Set<String> orderCodes = exportRows.stream()
|
||||
.map(row -> stringValue(row.get("_order_code")))
|
||||
.filter(code -> !isBlank(code))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (orderCodes.isEmpty()) {
|
||||
private Map<String, Map<String, ProductShipmentSummary>> loadShipmentSummaryMap(List<String> orderCodes,
|
||||
PurchaseTaxRateContext purchaseTaxRateContext) {
|
||||
if (CollUtil.isEmpty(orderCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
InventoryOuter query = new InventoryOuter();
|
||||
query.setOrderCodeList(new ArrayList<>(orderCodes));
|
||||
query.setOrderCodeList(orderCodes);
|
||||
List<InventoryOuter> inventoryOuters = inventoryOuterService.selectInventoryOuterList(query);
|
||||
if (inventoryOuters == null || inventoryOuters.isEmpty()) {
|
||||
if (CollUtil.isEmpty(inventoryOuters)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Set<String> productCodes = inventoryOuters.stream()
|
||||
.map(InventoryOuter::getProductCode)
|
||||
List<String> outerCodes = inventoryOuters.stream()
|
||||
.map(InventoryOuter::getOuterCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
Map<String, String> productNameMap = loadProductNameMap(productCodes);
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<String, List<InventoryInfo>> inventoryInfoMap = Collections.emptyMap();
|
||||
if (CollUtil.isNotEmpty(outerCodes)) {
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoService.selectInventoryInfoByOuterCodeList(outerCodes);
|
||||
if (CollUtil.isNotEmpty(inventoryInfos)) {
|
||||
inventoryInfoMap = inventoryInfos.stream()
|
||||
.filter(item -> !isBlank(item.getOuterCode()))
|
||||
.collect(Collectors.groupingBy(InventoryInfo::getOuterCode, LinkedHashMap::new, Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, List<Map<String, Object>>> result = new LinkedHashMap<>();
|
||||
Map<String, Map<String, ProductShipmentSummary>> result = new LinkedHashMap<>();
|
||||
for (InventoryOuter inventoryOuter : inventoryOuters) {
|
||||
String orderCode = inventoryOuter.getOrderCode();
|
||||
if (isBlank(orderCode)) {
|
||||
if (isBlank(inventoryOuter.getOrderCode()) || isBlank(inventoryOuter.getProductCode())) {
|
||||
continue;
|
||||
}
|
||||
result.computeIfAbsent(orderCode, key -> new ArrayList<>())
|
||||
.add(toOutboundOrderItem(inventoryOuter, productNameMap));
|
||||
Map<String, ProductShipmentSummary> productMap = result.computeIfAbsent(inventoryOuter.getOrderCode(), key -> new LinkedHashMap<>());
|
||||
ProductShipmentSummary summary = productMap.computeIfAbsent(inventoryOuter.getProductCode(), key -> new ProductShipmentSummary());
|
||||
summary.quantity = summary.quantity.add(BigDecimal.valueOf(inventoryOuter.getQuantity() == null ? 0L : inventoryOuter.getQuantity()));
|
||||
if (inventoryOuter.getDeliveryTime() != null) {
|
||||
summary.deliveryTimes.add(inventoryOuter.getDeliveryTime());
|
||||
}
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoMap.getOrDefault(inventoryOuter.getOuterCode(), Collections.emptyList());
|
||||
for (InventoryInfo inventoryInfo : inventoryInfos) {
|
||||
BigDecimal innerPrice = defaultValue(inventoryInfo.getInnerPrice());
|
||||
summary.costWithTax = summary.costWithTax.add(innerPrice);
|
||||
summary.costWithoutTax = summary.costWithoutTax.add(toInventoryAmountWithoutTax(
|
||||
innerPrice,
|
||||
purchaseTaxRateContext.resolveTaxRate(inventoryInfo.getInnerCode(), inventoryInfo.getProductCode())
|
||||
));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Object> toOutboundOrderItem(InventoryOuter inventoryOuter, Map<String, String> productNameMap) {
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("outboundOrderCode", inventoryOuter.getOuterCode());
|
||||
item.put("productCode", inventoryOuter.getProductCode());
|
||||
item.put("productName", productNameMap.get(inventoryOuter.getProductCode()));
|
||||
item.put("quantity", inventoryOuter.getQuantity());
|
||||
return item;
|
||||
}
|
||||
|
||||
private Map<String, String> loadProductNameMap(Set<String> productCodes) {
|
||||
if (productCodes == null || productCodes.isEmpty()) {
|
||||
private Map<String, Map<String, ProductCostSummary>> loadServiceCostMap(PurchaseTaxRateContext purchaseTaxRateContext) {
|
||||
List<OmsInventoryInner> inventoryInners = purchaseTaxRateContext.listInventoryInnersByProductType("3");
|
||||
if (CollUtil.isEmpty(inventoryInners)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(new ArrayList<>(productCodes));
|
||||
return productInfos.stream().collect(Collectors.toMap(ProductInfo::getProductCode, ProductInfo::getProductName, (a, b) -> a));
|
||||
|
||||
List<String> innerCodes = inventoryInners.stream()
|
||||
.map(OmsInventoryInner::getInnerCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<String, List<InventoryInfo>> innerInventoryInfoMap = Collections.emptyMap();
|
||||
if (CollUtil.isNotEmpty(innerCodes)) {
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoMapper.selectInventoryInfoByInnerCodeList(innerCodes);
|
||||
if (CollUtil.isNotEmpty(inventoryInfos)) {
|
||||
innerInventoryInfoMap = inventoryInfos.stream()
|
||||
.filter(item -> !isBlank(item.getInnerCode()))
|
||||
.collect(Collectors.groupingBy(InventoryInfo::getInnerCode, LinkedHashMap::new, Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Map<String, ProductCostSummary>> result = new LinkedHashMap<>();
|
||||
for (OmsInventoryInner inventoryInner : inventoryInners) {
|
||||
if (isBlank(inventoryInner.getOrderCode()) || isBlank(inventoryInner.getProductCode())) {
|
||||
continue;
|
||||
}
|
||||
List<InventoryInfo> inventoryInfos = innerInventoryInfoMap.getOrDefault(inventoryInner.getInnerCode(), Collections.emptyList());
|
||||
Map<String, ProductCostSummary> productMap = result.computeIfAbsent(inventoryInner.getOrderCode(), key -> new LinkedHashMap<>());
|
||||
ProductCostSummary summary = productMap.computeIfAbsent(inventoryInner.getProductCode(), key -> new ProductCostSummary());
|
||||
summary.costWithTax = summary.costWithTax.add(resolveServiceCostWithTax(inventoryInner, inventoryInfos));
|
||||
summary.costWithoutTax = summary.costWithoutTax.add(
|
||||
resolveServiceCostWithoutTax(inventoryInner, inventoryInfos, purchaseTaxRateContext)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private BigDecimal resolveServiceCostWithTax(OmsInventoryInner inventoryInner, List<InventoryInfo> inventoryInfos) {
|
||||
if (inventoryInner.getTotalAmount() != null) {
|
||||
return inventoryInner.getTotalAmount();
|
||||
}
|
||||
if (CollUtil.isEmpty(inventoryInfos)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return inventoryInfos.stream()
|
||||
.map(InventoryInfo::getInnerPrice)
|
||||
.filter(value -> value != null)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
private BigDecimal resolveServiceCostWithoutTax(OmsInventoryInner inventoryInner,
|
||||
List<InventoryInfo> inventoryInfos,
|
||||
PurchaseTaxRateContext purchaseTaxRateContext) {
|
||||
BigDecimal taxRate = purchaseTaxRateContext.resolveTaxRate(inventoryInner.getInnerCode(), inventoryInner.getProductCode());
|
||||
if (CollUtil.isNotEmpty(inventoryInfos)) {
|
||||
BigDecimal total = BigDecimal.ZERO;
|
||||
for (InventoryInfo inventoryInfo : inventoryInfos) {
|
||||
BigDecimal innerPrice = defaultValue(inventoryInfo.getInnerPrice());
|
||||
total = total.add(toInventoryAmountWithoutTax(innerPrice, taxRate));
|
||||
}
|
||||
if (total.compareTo(BigDecimal.ZERO) > 0 || inventoryInner.getTotalAmount() == null) {
|
||||
return total;
|
||||
}
|
||||
}
|
||||
return toInventoryAmountWithoutTax(defaultValue(inventoryInner.getTotalAmount()), taxRate);
|
||||
}
|
||||
|
||||
private Map<String, ReceivableSummary> loadReceivableSummaryMap(List<ProjectOrderInfo> orderInfos) {
|
||||
List<String> orderCodes = orderInfos.stream()
|
||||
.map(ProjectOrderInfo::getOrderCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(orderCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
OmsReceivableBill query = new OmsReceivableBill();
|
||||
query.setOrderCodeList(orderCodes);
|
||||
List<OmsReceivableBill> receivableBills = omsReceivableBillService.selectOmsReceivableBillList(query);
|
||||
if (CollUtil.isEmpty(receivableBills)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<String, ReceivableSummary> result = new LinkedHashMap<>();
|
||||
for (OmsReceivableBill receivableBill : receivableBills) {
|
||||
if (isBlank(receivableBill.getOrderCode())) {
|
||||
continue;
|
||||
}
|
||||
ReceivableSummary summary = result.computeIfAbsent(receivableBill.getOrderCode(), key -> new ReceivableSummary());
|
||||
summary.totalPriceWithTax = summary.totalPriceWithTax.add(defaultValue(receivableBill.getTotalPriceWithTax()));
|
||||
summary.receivedAmount = summary.receivedAmount.add(defaultValue(receivableBill.getReceivedAmount()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, ProjectInfo> loadProjectInfoMap(List<String> orderCodes) {
|
||||
if (CollUtil.isEmpty(orderCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
List<ProjectInfo> projectInfos = projectInfoMapper.selectProjectInfoByOrderCodeList(orderCodes);
|
||||
if (CollUtil.isEmpty(projectInfos)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, ProjectInfo> result = new LinkedHashMap<>();
|
||||
for (ProjectInfo projectInfo : projectInfos) {
|
||||
if (projectInfo == null || isBlank(projectInfo.getOrderCode()) || result.containsKey(projectInfo.getOrderCode())) {
|
||||
continue;
|
||||
}
|
||||
result.put(projectInfo.getOrderCode(), projectInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private PurchaseTaxRateContext loadPurchaseTaxRateContext(List<String> orderCodes) {
|
||||
if (CollUtil.isEmpty(orderCodes)) {
|
||||
return new PurchaseTaxRateContext(Collections.emptyMap(), Collections.emptyList(), Collections.emptyMap());
|
||||
}
|
||||
InventoryOuter outerQuery = new InventoryOuter();
|
||||
outerQuery.setOrderCodeList(orderCodes);
|
||||
List<InventoryOuter> inventoryOuters = inventoryOuterService.selectInventoryOuterList(outerQuery);
|
||||
|
||||
List<String> shippedInnerCodes = Collections.emptyList();
|
||||
if (CollUtil.isNotEmpty(inventoryOuters)) {
|
||||
List<String> outerCodes = inventoryOuters.stream()
|
||||
.map(InventoryOuter::getOuterCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(outerCodes)) {
|
||||
List<InventoryInfo> shippedInventoryInfos = inventoryInfoService.selectInventoryInfoByOuterCodeList(outerCodes);
|
||||
if (CollUtil.isNotEmpty(shippedInventoryInfos)) {
|
||||
shippedInnerCodes = shippedInventoryInfos.stream()
|
||||
.map(InventoryInfo::getInnerCode)
|
||||
.filter(code -> !isBlank(code))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<OmsInventoryInner> inventoryInners = new ArrayList<>();
|
||||
if (CollUtil.isNotEmpty(shippedInnerCodes)) {
|
||||
inventoryInners.addAll(omsInventoryInnerMapper.selectOmsInventoryInnerByInnerCodeList(shippedInnerCodes));
|
||||
}
|
||||
List<OmsInventoryInner> serviceInventoryInners = omsInventoryInnerMapper.selectOmsInventoryInnerByOrderCodeList(orderCodes);
|
||||
if (CollUtil.isNotEmpty(serviceInventoryInners)) {
|
||||
serviceInventoryInners.stream()
|
||||
.filter(item -> "3".equals(item.getProductType()))
|
||||
.forEach(inventoryInners::add);
|
||||
}
|
||||
if (CollUtil.isEmpty(inventoryInners)) {
|
||||
return new PurchaseTaxRateContext(Collections.emptyMap(), Collections.emptyList(), Collections.emptyMap());
|
||||
}
|
||||
Map<String, OmsInventoryInner> innerCodeMap = new LinkedHashMap<>();
|
||||
List<OmsInventoryInner> uniqueInventoryInners = new ArrayList<>();
|
||||
for (OmsInventoryInner inventoryInner : inventoryInners) {
|
||||
if (inventoryInner == null || isBlank(inventoryInner.getInnerCode()) || innerCodeMap.containsKey(inventoryInner.getInnerCode())) {
|
||||
continue;
|
||||
}
|
||||
innerCodeMap.put(inventoryInner.getInnerCode(), inventoryInner);
|
||||
uniqueInventoryInners.add(inventoryInner);
|
||||
}
|
||||
List<String> purchaseNos = uniqueInventoryInners.stream()
|
||||
.map(OmsInventoryInner::getPurchaseNo)
|
||||
.filter(code -> !isBlank(code))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<String, Map<String, BigDecimal>> purchaseTaxRateMap = Collections.emptyMap();
|
||||
if (CollUtil.isNotEmpty(purchaseNos)) {
|
||||
List<OmsPurchaseOrderItem> purchaseOrderItems = omsPurchaseOrderMapper.listItemByCodeList(purchaseNos);
|
||||
if (CollUtil.isNotEmpty(purchaseOrderItems)) {
|
||||
purchaseTaxRateMap = new LinkedHashMap<>();
|
||||
for (OmsPurchaseOrderItem purchaseOrderItem : purchaseOrderItems) {
|
||||
if (isBlank(purchaseOrderItem.getPurchaseNo()) || isBlank(purchaseOrderItem.getProductCode())) {
|
||||
continue;
|
||||
}
|
||||
Map<String, BigDecimal> productTaxRateMap = purchaseTaxRateMap.computeIfAbsent(
|
||||
purchaseOrderItem.getPurchaseNo(),
|
||||
key -> new LinkedHashMap<>()
|
||||
);
|
||||
BigDecimal currentTaxRate = productTaxRateMap.get(purchaseOrderItem.getProductCode());
|
||||
BigDecimal candidateTaxRate = purchaseOrderItem.getTaxRate();
|
||||
if (candidateTaxRate != null && (currentTaxRate == null || currentTaxRate.compareTo(BigDecimal.ZERO) == 0)) {
|
||||
productTaxRateMap.put(purchaseOrderItem.getProductCode(), candidateTaxRate);
|
||||
} else if (currentTaxRate == null) {
|
||||
productTaxRateMap.put(purchaseOrderItem.getProductCode(), BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PurchaseTaxRateContext(innerCodeMap, uniqueInventoryInners, purchaseTaxRateMap);
|
||||
}
|
||||
|
||||
private ProductGroupSummary appendProductFields(Map<String, Object> item,
|
||||
String prefix,
|
||||
List<ProjectProductInfo> productInfos,
|
||||
Map<String, ProductShipmentSummary> shipmentMap,
|
||||
Map<String, ProductCostSummary> serviceCostMap,
|
||||
boolean shipmentRequired) {
|
||||
ProductGroupSummary summary = new ProductGroupSummary();
|
||||
if (CollUtil.isEmpty(productInfos)) {
|
||||
return summary;
|
||||
}
|
||||
for (int i = 0; i < productInfos.size(); i++) {
|
||||
int index = i + 1;
|
||||
ProjectProductInfo productInfo = productInfos.get(i);
|
||||
ProductCostDisplay costDisplay = shipmentRequired
|
||||
? buildShipmentProductCostDisplay(productInfo, shipmentMap.get(productInfo.getProductBomCode()))
|
||||
: buildServiceProductCostDisplay(serviceCostMap.get(productInfo.getProductBomCode()));
|
||||
|
||||
item.put(prefix + "Code" + index, productInfo.getProductBomCode());
|
||||
item.put(prefix + "Level2Type" + index, productInfo.getLevel2Type());
|
||||
item.put(prefix + "Model" + index, productInfo.getModel());
|
||||
item.put(prefix + "Quantity" + index, productInfo.getQuantity());
|
||||
item.put(prefix + "SalesAmount" + index, defaultValue(productInfo.getAllPrice()));
|
||||
item.put(prefix + "CostAmount" + index, costDisplay.displayValue);
|
||||
item.put(prefix + "TaxRate" + index, productInfo.getTaxRate());
|
||||
|
||||
summary.salesWithTax = summary.salesWithTax.add(defaultValue(productInfo.getAllPrice()));
|
||||
summary.salesWithoutTax = summary.salesWithoutTax.add(toOrderAmountWithoutTax(defaultValue(productInfo.getAllPrice()), productInfo.getTaxRate()));
|
||||
if (costDisplay.delivered) {
|
||||
summary.costWithTax = summary.costWithTax.add(costDisplay.costWithTax);
|
||||
summary.costWithoutTax = summary.costWithoutTax.add(costDisplay.costWithoutTax);
|
||||
} else {
|
||||
summary.allDelivered = false;
|
||||
}
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
|
||||
private ProductCostDisplay buildShipmentProductCostDisplay(ProjectProductInfo productInfo, ProductShipmentSummary shipmentSummary) {
|
||||
ProductCostDisplay display = new ProductCostDisplay();
|
||||
BigDecimal requiredQuantity = BigDecimal.valueOf(productInfo.getQuantity() == null ? 0L : productInfo.getQuantity());
|
||||
BigDecimal shippedQuantity = shipmentSummary == null ? BigDecimal.ZERO : shipmentSummary.quantity;
|
||||
if (requiredQuantity.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
display.delivered = true;
|
||||
display.displayValue = BigDecimal.ZERO;
|
||||
return display;
|
||||
}
|
||||
if (shipmentSummary == null || shippedQuantity.compareTo(requiredQuantity) < 0) {
|
||||
display.delivered = false;
|
||||
display.displayValue = NOT_DELIVERED_TEXT;
|
||||
return display;
|
||||
}
|
||||
display.delivered = true;
|
||||
display.costWithTax = shipmentSummary.costWithTax;
|
||||
display.costWithoutTax = shipmentSummary.costWithoutTax;
|
||||
display.displayValue = shipmentSummary.costWithTax;
|
||||
return display;
|
||||
}
|
||||
|
||||
private ProductCostDisplay buildServiceProductCostDisplay(ProductCostSummary serviceCostSummary) {
|
||||
ProductCostDisplay display = new ProductCostDisplay();
|
||||
display.delivered = true;
|
||||
if (serviceCostSummary == null) {
|
||||
display.displayValue = BigDecimal.ZERO;
|
||||
return display;
|
||||
}
|
||||
display.costWithTax = serviceCostSummary.costWithTax;
|
||||
display.costWithoutTax = serviceCostSummary.costWithoutTax;
|
||||
display.displayValue = serviceCostSummary.costWithTax;
|
||||
return display;
|
||||
}
|
||||
|
||||
private List<ProjectProductInfo> filterByType(List<ProjectProductInfo> productInfos, String type) {
|
||||
if (CollUtil.isEmpty(productInfos)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return productInfos.stream()
|
||||
.filter(item -> type.equals(item.getType()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String collectDeliveryTimes(Map<String, ProductShipmentSummary> shipmentMap) {
|
||||
if (shipmentMap == null || shipmentMap.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
Set<String> dates = new LinkedHashSet<>();
|
||||
for (ProductShipmentSummary summary : shipmentMap.values()) {
|
||||
for (Date deliveryTime : summary.deliveryTimes) {
|
||||
dates.add(formatDate(deliveryTime));
|
||||
}
|
||||
}
|
||||
return String.join(", ", dates);
|
||||
}
|
||||
|
||||
private String getProjectStage(ProjectInfo projectInfo) {
|
||||
if (projectInfo == null) {
|
||||
return "";
|
||||
}
|
||||
return DictUtils.getDictLabel(PROJECT_STAGE_DICT_TYPE, projectInfo.getProjectStage());
|
||||
}
|
||||
|
||||
private String getIndustryTypeName(ProjectOrderInfo orderInfo) {
|
||||
if ("YYS".equals(orderInfo.getBgProperty())) {
|
||||
return DictUtils.getDictLabel(INDUSTRY_TYPE_YYS_DICT_TYPE, orderInfo.getIndustryType());
|
||||
}
|
||||
return DictUtils.getDictLabel(INDUSTRY_TYPE_DICT_TYPE, orderInfo.getIndustryType());
|
||||
}
|
||||
|
||||
private String getOrderChannelName(String orderChannel) {
|
||||
if (isBlank(orderChannel)) {
|
||||
return "";
|
||||
}
|
||||
if (ProjectOrderInfo.OrderChannelEnum.TOTAL_GENERATION.getCode().equals(orderChannel)) {
|
||||
return "总代";
|
||||
}
|
||||
if (ProjectOrderInfo.OrderChannelEnum.DIRECT_SIGNING.getCode().equals(orderChannel)) {
|
||||
return "直签";
|
||||
}
|
||||
return orderChannel;
|
||||
}
|
||||
|
||||
private String isCharged(String chargeStatus) {
|
||||
return "2".equals(chargeStatus) || "3".equals(chargeStatus) ? "是" : "否";
|
||||
}
|
||||
|
||||
private BigDecimal toOrderAmountWithoutTax(BigDecimal amountWithTax, BigDecimal taxRate) {
|
||||
BigDecimal rate = normalizePercentTaxRate(taxRate);
|
||||
return amountWithTax.divide(BigDecimal.ONE.add(rate), 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal toInventoryAmountWithoutTax(BigDecimal amountWithTax, BigDecimal taxRate) {
|
||||
BigDecimal rate = normalizeDecimalTaxRate(taxRate);
|
||||
return amountWithTax.divide(BigDecimal.ONE.add(rate), 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal normalizePercentTaxRate(BigDecimal taxRate) {
|
||||
if (taxRate == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
if (taxRate.compareTo(BigDecimal.ONE) > 0) {
|
||||
return taxRate.divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP);
|
||||
}
|
||||
return taxRate;
|
||||
}
|
||||
|
||||
private BigDecimal normalizeDecimalTaxRate(BigDecimal taxRate) {
|
||||
if (taxRate == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return taxRate.compareTo(BigDecimal.ONE) > 0
|
||||
? taxRate.divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP)
|
||||
: taxRate;
|
||||
}
|
||||
|
||||
private BigDecimal percentage(BigDecimal numerator, BigDecimal denominator) {
|
||||
if (denominator == null || denominator.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return numerator.divide(denominator, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
|
||||
}
|
||||
|
||||
private BigDecimal defaultValue(BigDecimal value) {
|
||||
return value == null ? BigDecimal.ZERO : value;
|
||||
}
|
||||
|
||||
private String formatDate(Date value) {
|
||||
return value == null ? "" : DateUtil.format(value, "yyyy-MM-dd");
|
||||
}
|
||||
|
||||
private String formatDateTime(Date value) {
|
||||
return value == null ? "" : DateUtil.format(value, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
private Date parseDateTime(String value) {
|
||||
|
|
@ -280,64 +687,138 @@ public class ProjectOrderInfoToolProvider extends AbstractMcpToolProvider {
|
|||
}
|
||||
}
|
||||
|
||||
private String stringValue(Object value) {
|
||||
return value == null ? null : String.valueOf(value);
|
||||
}
|
||||
|
||||
private boolean isEmptyDetail(Map<String, Object> detail) {
|
||||
if (detail == null || detail.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (Object value : detail.values()) {
|
||||
if (value != null && !isBlank(String.valueOf(value))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
private Map<String, Object> buildMetadata() {
|
||||
Map<String, Object> metadata = new LinkedHashMap<>();
|
||||
metadata.put("tool", getToolName());
|
||||
metadata.put("description", "根据创建时间范围查询项目订单信息,data.items 使用英文驼峰字段返回。");
|
||||
metadata.put("query_fields", mapOf(
|
||||
"create_time_start", "创建时间范围开始,包含边界",
|
||||
"create_time_end", "创建时间范围结束,包含边界"
|
||||
));
|
||||
metadata.put("data_fields", mapOf(
|
||||
"total", "命中的项目订单数量",
|
||||
"items", "项目订单列表"
|
||||
));
|
||||
metadata.put("item_fields", buildItemFieldMetadata());
|
||||
metadata.put("dynamic_field_rules", mapOf(
|
||||
"softwareCodeX", "软件产品第 X 行编码,对应 softwareLevel2TypeX/softwareModelX/softwareQuantityX/softwareSalesAmountX/softwareCostAmountX/softwareTaxRateX",
|
||||
"hardwareCodeX", "硬件产品第 X 行编码,对应 hardwareLevel2TypeX/hardwareModelX/hardwareQuantityX/hardwareSalesAmountX/hardwareCostAmountX/hardwareTaxRateX",
|
||||
"serviceCodeX", "服务产品第 X 行编码,对应 serviceLevel2TypeX/serviceModelX/serviceQuantityX/serviceSalesAmountX/serviceCostAmountX/serviceTaxRateX",
|
||||
"cost_rule", "软件和硬件未发货完成时成本字段返回“未发货完成”;服务默认视为已完成;订单不含税成本为各产品按各自税率换算后求和"
|
||||
));
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private Map<String, Object> buildItemFieldMetadata() {
|
||||
Map<String, Object> metadata = new LinkedHashMap<>();
|
||||
metadata.put("projectCode", "项目编号");
|
||||
metadata.put("projectStage", "项目阶段");
|
||||
metadata.put("orderDate", "下单时间");
|
||||
metadata.put("orderEffectiveDate", "订单生效时间");
|
||||
metadata.put("requiredDeliveryDate", "要求到货时间");
|
||||
metadata.put("orderCode", "合同或订单编号");
|
||||
metadata.put("contractCode", "合同编号");
|
||||
metadata.put("projectName", "项目名称");
|
||||
metadata.put("agentName", "代表处");
|
||||
metadata.put("orderStatus", "订单状态");
|
||||
metadata.put("ownerName", "汇智责任人");
|
||||
metadata.put("orderChannel", "下单通路");
|
||||
metadata.put("supplierName", "供货商");
|
||||
metadata.put("customerName", "最终客户");
|
||||
metadata.put("bgName", "BG");
|
||||
metadata.put("industryType", "行业");
|
||||
metadata.put("constructionType", "建设类型(预留)");
|
||||
metadata.put("projectPartnerName", "运作方");
|
||||
metadata.put("businessContactName", "进货商接口人");
|
||||
metadata.put("businessContactPhone", "进货商接口人联系方式");
|
||||
metadata.put("businessContactPhone", "联系方式");
|
||||
metadata.put("currencyType", "币种");
|
||||
metadata.put("partnerName", "进货商");
|
||||
metadata.put("partnerLevel", "进货商类型");
|
||||
metadata.put("partnerContactName", "进货商联系人");
|
||||
metadata.put("partnerContactPhone", "进货商联系方式");
|
||||
metadata.put("partnerContactPhone", "联系方式");
|
||||
metadata.put("executionDeadline", "执行单截至时间");
|
||||
metadata.put("archiveTime", "归档时间");
|
||||
metadata.put("wssQuantity", "WS 瘦授权软件数量");
|
||||
metadata.put("wssAmount", "WS 瘦授权软件金额");
|
||||
metadata.put("wssTaxRate", "WS 瘦授权软件税率");
|
||||
metadata.put("wspQuantity", "WS 胖授权软件数量");
|
||||
metadata.put("wspAmount", "WS 胖授权软件金额");
|
||||
metadata.put("wspTaxRate", "WS 胖授权软件税率");
|
||||
metadata.put("lsQuantity", "LS 软件数量");
|
||||
metadata.put("lsAmount", "LS 软件金额");
|
||||
metadata.put("lsTaxRate", "LS 软件税率");
|
||||
metadata.put("details", "产品明细列表");
|
||||
metadata.put("shipmentAmount", "总发货金额");
|
||||
metadata.put("totalAmount", "总价合计");
|
||||
metadata.put("maintenanceAmount", "维保金额");
|
||||
metadata.put("softwareSubtotal", "软件折后小计");
|
||||
metadata.put("hardwareSubtotal", "硬件折后小计");
|
||||
metadata.put("serviceSubtotal", "服务折后小计");
|
||||
metadata.put("outboundOrders", "出库单列表");
|
||||
metadata.put("orderAmountWithTax", "订单金额(含税)");
|
||||
metadata.put("discountedOrderAmountWithTax", "订单折后金额(含税)");
|
||||
metadata.put("discountedOrderAmountWithoutTax", "订单折后总金额(不含税)");
|
||||
metadata.put("costTotalWithTax", "成本总计(含税)");
|
||||
metadata.put("costTotalWithoutTax", "成本总计(不含税)");
|
||||
metadata.put("grossProfit", "整单毛利");
|
||||
metadata.put("grossProfitRate", "整单毛利率");
|
||||
metadata.put("deliveryTime", "发货时间");
|
||||
metadata.put("expectedReceiptAmount", "预计收款金额(元)");
|
||||
metadata.put("receivedAmount", "已收金额");
|
||||
metadata.put("isCharged", "是否计收");
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private static class ProductShipmentSummary {
|
||||
private BigDecimal quantity = BigDecimal.ZERO;
|
||||
private BigDecimal costWithTax = BigDecimal.ZERO;
|
||||
private BigDecimal costWithoutTax = BigDecimal.ZERO;
|
||||
private final List<Date> deliveryTimes = new ArrayList<>();
|
||||
}
|
||||
|
||||
private static class ProductCostDisplay {
|
||||
private boolean delivered;
|
||||
private BigDecimal costWithTax = BigDecimal.ZERO;
|
||||
private BigDecimal costWithoutTax = BigDecimal.ZERO;
|
||||
private Object displayValue;
|
||||
}
|
||||
|
||||
private static class ProductCostSummary {
|
||||
private BigDecimal costWithTax = BigDecimal.ZERO;
|
||||
private BigDecimal costWithoutTax = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
private static class PurchaseTaxRateContext {
|
||||
private final Map<String, OmsInventoryInner> innerCodeMap;
|
||||
private final List<OmsInventoryInner> inventoryInners;
|
||||
private final Map<String, Map<String, BigDecimal>> purchaseTaxRateMap;
|
||||
|
||||
private PurchaseTaxRateContext(Map<String, OmsInventoryInner> innerCodeMap,
|
||||
List<OmsInventoryInner> inventoryInners,
|
||||
Map<String, Map<String, BigDecimal>> purchaseTaxRateMap) {
|
||||
this.innerCodeMap = innerCodeMap;
|
||||
this.inventoryInners = inventoryInners;
|
||||
this.purchaseTaxRateMap = purchaseTaxRateMap;
|
||||
}
|
||||
|
||||
private BigDecimal resolveTaxRate(String innerCode, String productCode) {
|
||||
if (isEmpty(innerCode) || isEmpty(productCode)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
OmsInventoryInner inventoryInner = innerCodeMap.get(innerCode);
|
||||
if (inventoryInner == null || isEmpty(inventoryInner.getPurchaseNo())) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return purchaseTaxRateMap
|
||||
.getOrDefault(inventoryInner.getPurchaseNo(), Collections.emptyMap())
|
||||
.getOrDefault(productCode, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private List<OmsInventoryInner> listInventoryInnersByProductType(String productType) {
|
||||
if (isEmpty(productType)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return inventoryInners.stream()
|
||||
.filter(item -> productType.equals(item.getProductType()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean isEmpty(String value) {
|
||||
return value == null || value.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ProductGroupSummary {
|
||||
private boolean allDelivered = true;
|
||||
private BigDecimal salesWithTax = BigDecimal.ZERO;
|
||||
private BigDecimal salesWithoutTax = BigDecimal.ZERO;
|
||||
private BigDecimal costWithTax = BigDecimal.ZERO;
|
||||
private BigDecimal costWithoutTax = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
private static class ReceivableSummary {
|
||||
private BigDecimal totalPriceWithTax = BigDecimal.ZERO;
|
||||
private BigDecimal receivedAmount = BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,4 +81,6 @@ public interface InventoryInfoMapper
|
|||
List<InventoryInfo> selectInventoryInfoByOrderCode(List<String> strings);
|
||||
|
||||
List<InventoryInfo> selectInventoryInfoByOuterCodeList(List<String> outerCodeList);
|
||||
|
||||
List<InventoryInfo> selectInventoryInfoByInnerCodeList(List<String> innerCodeList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,4 +64,8 @@ public interface OmsInventoryInnerMapper
|
|||
List<String> checkDelete(String[] ids);
|
||||
|
||||
List<OmsInventoryInner> listById(String[] idArray);
|
||||
|
||||
List<OmsInventoryInner> selectOmsInventoryInnerByOrderCodeList(List<String> orderCodeList);
|
||||
|
||||
List<OmsInventoryInner> selectOmsInventoryInnerByInnerCodeList(List<String> innerCodeList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,4 +74,6 @@ public interface ProjectInfoMapper
|
|||
void updateCustomerCodeByCode(@Param("oldValue") String oldValue, @Param("newValue")String newValue);
|
||||
|
||||
ProjectInfo selectProjectInfoByOrderCode(String orderCode);
|
||||
|
||||
List<ProjectInfo> selectProjectInfoByOrderCodeList(List<String> orderCodeList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public interface IProjectOrderInfoService
|
|||
List< ProjectOrderInfo> selectProjectOrderInfoByProjectId(List<Long> projectId);
|
||||
|
||||
String exportList(ProjectOrderInfo projectOrderInfo);
|
||||
String exportMcpList(ProjectOrderInfo projectOrderInfo);
|
||||
List<java.util.Map<String, Object>> listExportData(ProjectOrderInfo projectOrderInfo);
|
||||
|
||||
List<StatisticsDetailDto> listHomePageData(HomepageQueryDto dto);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import com.ruoyi.sip.dto.HomepageQueryDto;
|
|||
import com.ruoyi.sip.dto.OrderExcelNumStaticsDto;
|
||||
import com.ruoyi.sip.dto.StatisticsDetailDto;
|
||||
import com.ruoyi.sip.flowable.service.IBuApproveConfigService;
|
||||
import com.ruoyi.sip.llm.tools.ProjectOrderInfoToolProvider;
|
||||
import com.ruoyi.sip.mapper.OmsStockInfoMapper;
|
||||
import com.ruoyi.sip.mapper.ProjectInfoMapper;
|
||||
import com.ruoyi.sip.service.*;
|
||||
|
|
@ -116,6 +117,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
private static final List<String> LS_LIST = Arrays.asList("3130A6LD");
|
||||
private static final List<String> ONE_STOR_LIST = Arrays.asList("3130A4NA", "3130A4N9", "3130A4N5");
|
||||
private static final List<String> N_VIDIA_LIST = Arrays.asList("0504A14F", "0504A14G", "0504A1JX");
|
||||
private Boolean useMcpExportExcelFormat = Boolean.TRUE;
|
||||
private static final List<String> FILE_INFO_LIST = Arrays.asList( "(请上传商务折扣审批邮件信息).pdf/.jpg/.png","(请上传未盖章合同信息).pdf/.jpg/.png", "(补充附件).zip/.rar/.jpg/.png","(请上传已盖章合同信息).pdf/.jpg/.png");
|
||||
@Autowired
|
||||
private TaskService taskService;
|
||||
|
|
@ -141,6 +143,10 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
@Autowired
|
||||
@Lazy
|
||||
private IBuApproveConfigService approveConfigService;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private ProjectOrderInfoToolProvider projectOrderInfoToolProvider;
|
||||
/**
|
||||
* 查询订单管理
|
||||
*
|
||||
|
|
@ -538,6 +544,9 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
@DataScope(deptAlias = "t5", userAlias = "t5")
|
||||
public String exportList(ProjectOrderInfo projectOrderInfo) {
|
||||
try {
|
||||
if (Boolean.TRUE.equals(useMcpExportExcelFormat)) {
|
||||
return exportMcpList(projectOrderInfo);
|
||||
}
|
||||
// 获取项目信息列表
|
||||
List<ProjectOrderInfo> projectInfos = this.selectProjectOrderInfoList(projectOrderInfo);
|
||||
|
||||
|
|
@ -563,6 +572,9 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
@Override
|
||||
@DataScope(deptAlias = "t5", userAlias = "t5")
|
||||
public List<Map<String, Object>> listExportData(ProjectOrderInfo projectOrderInfo) {
|
||||
if (Boolean.TRUE.equals(useMcpExportExcelFormat)) {
|
||||
return buildMcpExportItems(projectOrderInfo);
|
||||
}
|
||||
List<ProjectOrderInfo> projectInfos = this.selectProjectOrderInfoList(projectOrderInfo);
|
||||
if (CollUtil.isEmpty(projectInfos)) {
|
||||
return Collections.emptyList();
|
||||
|
|
@ -592,6 +604,279 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataScope(deptAlias = "t5", userAlias = "t5")
|
||||
public String exportMcpList(ProjectOrderInfo projectOrderInfo) {
|
||||
List<Map<String, Object>> items = buildMcpExportItems(projectOrderInfo);
|
||||
List<String> fieldNames = buildMcpExportFieldNames(items);
|
||||
List<List<String>> header = buildMcpExcelHeader(fieldNames);
|
||||
List<List<Object>> data = buildMcpExcelData(items, fieldNames);
|
||||
return writeExcelToFile(header, data);
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> buildMcpExportItems(ProjectOrderInfo projectOrderInfo) {
|
||||
return projectOrderInfoToolProvider.listItems(projectOrderInfo);
|
||||
}
|
||||
|
||||
private List<String> buildMcpExportFieldNames(List<Map<String, Object>> items) {
|
||||
int maxSoftware = extractMcpDynamicMaxIndex(items, "softwareCode");
|
||||
int maxHardware = extractMcpDynamicMaxIndex(items, "hardwareCode");
|
||||
int maxService = extractMcpDynamicMaxIndex(items, "serviceCode");
|
||||
|
||||
List<String> fieldNames = new ArrayList<>();
|
||||
Collections.addAll(fieldNames,
|
||||
"projectStage",
|
||||
"orderDate",
|
||||
"orderEffectiveDate",
|
||||
"requiredDeliveryDate",
|
||||
"contractCode",
|
||||
"projectName",
|
||||
"agentName",
|
||||
"orderStatus",
|
||||
"ownerName",
|
||||
"orderChannel",
|
||||
"supplierName",
|
||||
"customerName",
|
||||
"bgName",
|
||||
"industryType",
|
||||
"constructionType",
|
||||
"projectPartnerName",
|
||||
"businessContactName",
|
||||
"businessContactPhone",
|
||||
"currencyType",
|
||||
"partnerName",
|
||||
"partnerLevel",
|
||||
"partnerContactName",
|
||||
"partnerContactPhone",
|
||||
"executionDeadline",
|
||||
"archiveTime"
|
||||
);
|
||||
addMcpDynamicFieldNames(fieldNames, "software", maxSoftware);
|
||||
addMcpDynamicFieldNames(fieldNames, "hardware", maxHardware);
|
||||
addMcpDynamicFieldNames(fieldNames, "service", maxService);
|
||||
Collections.addAll(fieldNames,
|
||||
"orderAmountWithTax",
|
||||
"discountedOrderAmountWithTax",
|
||||
"discountedOrderAmountWithoutTax",
|
||||
"costTotalWithTax",
|
||||
"costTotalWithoutTax",
|
||||
"grossProfit",
|
||||
"grossProfitRate",
|
||||
"deliveryTime",
|
||||
"expectedReceiptAmount",
|
||||
"receivedAmount",
|
||||
"isCharged"
|
||||
);
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
private int extractMcpDynamicMaxIndex(List<Map<String, Object>> items, String codePrefix) {
|
||||
int maxIndex = 0;
|
||||
for (Map<String, Object> item : items) {
|
||||
for (String key : item.keySet()) {
|
||||
if (!key.startsWith(codePrefix)) {
|
||||
continue;
|
||||
}
|
||||
String suffix = key.substring(codePrefix.length());
|
||||
if (StringUtils.isNumeric(suffix)) {
|
||||
maxIndex = Math.max(maxIndex, Integer.parseInt(suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxIndex;
|
||||
}
|
||||
|
||||
private void addMcpDynamicFieldNames(List<String> fieldNames, String prefix, int count) {
|
||||
for (int i = 1; i <= count; i++) {
|
||||
fieldNames.add(prefix + "Code" + i);
|
||||
fieldNames.add(prefix + "Level2Type" + i);
|
||||
fieldNames.add(prefix + "Model" + i);
|
||||
fieldNames.add(prefix + "Quantity" + i);
|
||||
fieldNames.add(prefix + "SalesAmount" + i);
|
||||
fieldNames.add(prefix + "CostAmount" + i);
|
||||
fieldNames.add(prefix + "TaxRate" + i);
|
||||
}
|
||||
}
|
||||
|
||||
private List<List<String>> buildMcpExcelHeader(List<String> fieldNames) {
|
||||
return fieldNames.stream()
|
||||
.map(this::toMcpHeaderLabel)
|
||||
.map(Collections::singletonList)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<List<Object>> buildMcpExcelData(List<Map<String, Object>> items, List<String> fieldNames) {
|
||||
List<List<Object>> data = new ArrayList<>();
|
||||
for (Map<String, Object> item : items) {
|
||||
List<Object> row = new ArrayList<>();
|
||||
for (String fieldName : fieldNames) {
|
||||
row.add(resolveMcpExportCellValue(item, fieldName));
|
||||
}
|
||||
data.add(row);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private Object resolveMcpExportCellValue(Map<String, Object> item, String fieldName) {
|
||||
Object value = item.getOrDefault(fieldName, "");
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
if (fieldName.startsWith("softwareLevel2Type")) {
|
||||
return resolveDictLabelOrValue("product_type_1", value);
|
||||
}
|
||||
if (fieldName.startsWith("hardwareLevel2Type")) {
|
||||
return resolveDictLabelOrValue("product_type_2", value);
|
||||
}
|
||||
if (fieldName.startsWith("serviceLevel2Type")) {
|
||||
return resolveDictLabelOrValue("product_type_3", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private Object resolveDictLabelOrValue(String dictType, Object value) {
|
||||
String rawValue = String.valueOf(value);
|
||||
String label = DictUtils.getDictLabel(dictType, rawValue);
|
||||
return StringUtils.isEmpty(label) ? rawValue : label;
|
||||
}
|
||||
|
||||
private String toMcpHeaderLabel(String fieldName) {
|
||||
switch (fieldName) {
|
||||
case "projectStage":
|
||||
return "项目阶段";
|
||||
case "orderDate":
|
||||
return "下单时间";
|
||||
case "orderEffectiveDate":
|
||||
return "订单生效时间";
|
||||
case "requiredDeliveryDate":
|
||||
return "要求到货时间";
|
||||
case "contractCode":
|
||||
return "合同编号";
|
||||
case "projectName":
|
||||
return "项目名称";
|
||||
case "agentName":
|
||||
return "代表处";
|
||||
case "orderStatus":
|
||||
return "订单状态";
|
||||
case "ownerName":
|
||||
return "汇智责任人";
|
||||
case "orderChannel":
|
||||
return "下单通路";
|
||||
case "supplierName":
|
||||
return "供货商";
|
||||
case "customerName":
|
||||
return "最终客户";
|
||||
case "bgName":
|
||||
return "BG";
|
||||
case "industryType":
|
||||
return "行业";
|
||||
case "constructionType":
|
||||
return "建设类型";
|
||||
case "projectPartnerName":
|
||||
return "运作方";
|
||||
case "businessContactName":
|
||||
return "进货商接口人";
|
||||
case "businessContactPhone":
|
||||
return "联系方式";
|
||||
case "currencyType":
|
||||
return "币种";
|
||||
case "partnerName":
|
||||
return "进货商";
|
||||
case "partnerLevel":
|
||||
return "进货商类型";
|
||||
case "partnerContactName":
|
||||
return "进货商联系人";
|
||||
case "partnerContactPhone":
|
||||
return "联系方式";
|
||||
case "executionDeadline":
|
||||
return "执行单截至时间";
|
||||
case "archiveTime":
|
||||
return "归档时间";
|
||||
case "orderAmountWithTax":
|
||||
return "订单金额(含税)";
|
||||
case "discountedOrderAmountWithTax":
|
||||
return "订单折后金额(含税)";
|
||||
case "discountedOrderAmountWithoutTax":
|
||||
return "订单折后总金额(不含税)";
|
||||
case "costTotalWithTax":
|
||||
return "成本总计(含税)";
|
||||
case "costTotalWithoutTax":
|
||||
return "成本总计(不含税)";
|
||||
case "grossProfit":
|
||||
return "整单毛利";
|
||||
case "grossProfitRate":
|
||||
return "整单毛利率";
|
||||
case "deliveryTime":
|
||||
return "发货时间";
|
||||
case "expectedReceiptAmount":
|
||||
return "预计收款金额(元)";
|
||||
case "receivedAmount":
|
||||
return "已收金额";
|
||||
case "isCharged":
|
||||
return "是否计收";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
String dynamicLabel = toMcpDynamicHeaderLabel(fieldName, "software", "软件");
|
||||
if (StringUtils.isNotEmpty(dynamicLabel)) {
|
||||
return dynamicLabel;
|
||||
}
|
||||
dynamicLabel = toMcpDynamicHeaderLabel(fieldName, "hardware", "硬件");
|
||||
if (StringUtils.isNotEmpty(dynamicLabel)) {
|
||||
return dynamicLabel;
|
||||
}
|
||||
dynamicLabel = toMcpDynamicHeaderLabel(fieldName, "service", "服务");
|
||||
if (StringUtils.isNotEmpty(dynamicLabel)) {
|
||||
return dynamicLabel;
|
||||
}
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
private String toMcpDynamicHeaderLabel(String fieldName, String prefix, String labelPrefix) {
|
||||
if (!fieldName.startsWith(prefix)) {
|
||||
return "";
|
||||
}
|
||||
String suffix = fieldName.substring(prefix.length());
|
||||
if (suffix.startsWith("Code")) {
|
||||
return labelPrefix + "编码" + suffix.substring("Code".length());
|
||||
}
|
||||
if (suffix.startsWith("Level2Type")) {
|
||||
return labelPrefix + "二级类型" + suffix.substring("Level2Type".length());
|
||||
}
|
||||
if (suffix.startsWith("Model")) {
|
||||
return labelPrefix + "型号" + suffix.substring("Model".length());
|
||||
}
|
||||
if (suffix.startsWith("Quantity")) {
|
||||
if ("hardware".equals(prefix)) {
|
||||
return "终端数量" + suffix.substring("Quantity".length());
|
||||
}
|
||||
return labelPrefix + "数量" + suffix.substring("Quantity".length());
|
||||
}
|
||||
if (suffix.startsWith("SalesAmount")) {
|
||||
if ("software".equals(prefix)) {
|
||||
return "软件销售金额小计" + suffix.substring("SalesAmount".length());
|
||||
}
|
||||
if ("hardware".equals(prefix)) {
|
||||
return "硬件金额小计" + suffix.substring("SalesAmount".length());
|
||||
}
|
||||
if ("service".equals(prefix)) {
|
||||
return "服务金额小计" + suffix.substring("SalesAmount".length());
|
||||
}
|
||||
return labelPrefix + "销售金额小计" + suffix.substring("SalesAmount".length());
|
||||
}
|
||||
if (suffix.startsWith("CostAmount")) {
|
||||
if ("service".equals(prefix)) {
|
||||
return "服务成本小计" + suffix.substring("CostAmount".length());
|
||||
}
|
||||
return labelPrefix + "成本金额小计" + suffix.substring("CostAmount".length());
|
||||
}
|
||||
if (suffix.startsWith("TaxRate")) {
|
||||
return labelPrefix + "税率" + suffix.substring("TaxRate".length());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StatisticsDetailDto> listHomePageData(HomepageQueryDto dto) {
|
||||
SysUser sysUser = ShiroUtils.getSysUser();
|
||||
|
|
|
|||
|
|
@ -118,6 +118,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="selectInventoryInfoByInnerCodeList" resultType="com.ruoyi.sip.domain.InventoryInfo">
|
||||
<include refid="selectInventoryInfoVo"/>
|
||||
where t1.inner_code in
|
||||
<foreach item="item" index="index" collection="list" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertInventoryInfo" parameterType="InventoryInfo" useGeneratedKeys="true" keyProperty="id">
|
||||
|
|
|
|||
|
|
@ -100,6 +100,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="selectOmsInventoryInnerByOrderCodeList" resultMap="OmsInventoryInnerResult">
|
||||
<include refid="selectOmsInventoryInnerVo"/>
|
||||
where t1.order_code in
|
||||
<foreach item="item" collection="list" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="selectOmsInventoryInnerByInnerCodeList" resultMap="OmsInventoryInnerResult">
|
||||
<include refid="selectOmsInventoryInnerVo"/>
|
||||
where t1.inner_code in
|
||||
<foreach item="item" collection="list" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertOmsInventoryInner" parameterType="OmsInventoryInner" useGeneratedKeys="true" keyProperty="id">
|
||||
|
|
@ -179,4 +193,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -251,6 +251,71 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<include refid="selectRelationProjectInfoVo"/>
|
||||
where t1.id in (select project_id from project_order_info where order_code = #{orderCode})
|
||||
</select>
|
||||
<select id="selectProjectInfoByOrderCodeList" resultType="com.ruoyi.sip.domain.ProjectInfo">
|
||||
select t1.id,
|
||||
t1.project_code,
|
||||
t1.project_name,
|
||||
t1.bg_property,
|
||||
t1.customer_code,
|
||||
t1.customer_name,
|
||||
t1.industry_type,
|
||||
t1.agent_code,
|
||||
t1.project_stage,
|
||||
t1.project_grasp_degree,
|
||||
t1.hz_support_user,
|
||||
t1.operate_institution,
|
||||
t1.partner_code,
|
||||
t1.partner_name,
|
||||
t1.contact_way,
|
||||
t1.estimated_amount,
|
||||
t1.currency_type,
|
||||
t1.estimated_order_time,
|
||||
t1.estimated_deliver_time,
|
||||
t1.competitor,
|
||||
t1.country_product,
|
||||
t1.server_configuration,
|
||||
t1.key_problem,
|
||||
t1.project_desc,
|
||||
t1.create_by,
|
||||
t1.create_time,
|
||||
t1.update_by,
|
||||
t1.update_time,
|
||||
t1.joint_trial,
|
||||
t1.software_info,
|
||||
t1.hardware_info,
|
||||
t1.terminal_peripheral,
|
||||
t1.management_version,
|
||||
t1.desktop_vm_os_version,
|
||||
t1.vm_spec_quantity,
|
||||
t1.joint_trial_result,
|
||||
t1.file_id,
|
||||
t1.quotation_id,
|
||||
t1.customer_user_name,
|
||||
t1.customer_phone,
|
||||
t1.partner_user_name,
|
||||
t1.h3c_person,
|
||||
t1.poc,
|
||||
t1.h3c_phone,
|
||||
t2.agent_name,
|
||||
t2.contact_email,
|
||||
t2.contact_phone,
|
||||
t2.contact_person,
|
||||
t3.user_name as hz_support_user_name,
|
||||
t5.level,
|
||||
t5.contact_email as partner_email,
|
||||
t6.system_user_id as partner_system_user_id,
|
||||
t7.order_code as orderCode
|
||||
from project_info t1
|
||||
left join agent_info t2 on t1.agent_code = t2.agent_code
|
||||
left join sys_user t3 on t1.hz_support_user = t3.user_id
|
||||
left join partner_info t5 on t1.partner_code = t5.partner_code
|
||||
left join partner_info t6 on t1.partner_code = t6.partner_code
|
||||
inner join project_order_info t7 on t1.id = t7.project_id
|
||||
where t7.order_code in
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<insert id="insertProjectInfo" parameterType="ProjectInfo" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into project_info
|
||||
|
|
@ -417,4 +482,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
|
|
|||
Loading…
Reference in New Issue