
13 changed files with 694 additions and 16 deletions
@ -0,0 +1,16 @@ |
|||||
|
package com.yxt.anrui.buscenter.api.bussalesorderreturnveh; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @description: |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2025/4/3 |
||||
|
**/ |
||||
|
@Data |
||||
|
public class ReturnPushVo { |
||||
|
|
||||
|
private String billNo; |
||||
|
|
||||
|
private String materialCode; |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
package com.yxt.anrui.fin.api.kingdee.push; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import com.yxt.common.core.dto.Dto; |
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import javax.validation.constraints.NotBlank; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @description: |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2025/3/31 |
||||
|
**/ |
||||
|
@Data |
||||
|
public class SalOutStockPushSalReturnStock { |
||||
|
|
||||
|
private List<SalesReturnDetailDto> stockDtoList; |
||||
|
|
||||
|
@Data |
||||
|
public static class SalesReturnDetailDto implements Dto { |
||||
|
|
||||
|
private static final long serialVersionUID = -7455578363694683720L; |
||||
|
@NotBlank |
||||
|
@JsonProperty("FMaterialId") |
||||
|
private String FMaterialId; |
||||
|
|
||||
|
@NotBlank |
||||
|
@JsonProperty("FEntryId") // 修正字段名:分录内码
|
||||
|
private String FEntryId; // 原始出库单分录内码
|
||||
|
|
||||
|
@ApiModelProperty("销售出库单单据编码") |
||||
|
private String billNo; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,67 @@ |
|||||
|
package com.yxt.anrui.fin.biz.kingdee.push; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* @description: 下推所需参数 |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2025/4/3 |
||||
|
**/ |
||||
|
@Data |
||||
|
public class KingdeePushRequest { |
||||
|
|
||||
|
/** |
||||
|
* 1.formid:业务对象表单Id,字符串类型(必录) |
||||
|
* 2.data:Json格式数据(详情参考Json格式数据)(必录) |
||||
|
* 2.1.Ids:单据内码集合,字符串类型,格式:"Id1,Id2,..."(使用内码时必录) |
||||
|
* 2.2.Numbers:单据编码集合,数组类型,格式:[No1,No2,...](使用编码时必录) |
||||
|
* 2.3.EntryIds:分录内码集合,逗号分隔(分录下推时必录),注(按分录下推时,单据内码和编码不需要填,否则按整单下推) |
||||
|
* 2.4.RuleId:转换规则内码,字符串类型(未启用默认转换规则时,则必录) |
||||
|
* 2.5.TargetBillTypeId:目标单据类型内码,字符串类型(非必录) |
||||
|
* 2.6.TargetOrgId:目标组织内码,整型(非必录) |
||||
|
* 2.7.TargetFormId:目标单据FormId,字符串类型,(启用默认转换规则时,则必录) |
||||
|
* 2.8.IsEnableDefaultRule:是否启用默认转换规则,布尔类型,默认false(非必录) |
||||
|
* 2.9.CustomParams:自定义参数,字典类型,格式:"{key1:value1,key2:value2,...}"(非必录) ,注(传到转换插件的操作选项中,平台不会解析里面的值) |
||||
|
* <p> |
||||
|
* 二、Json格式数据: |
||||
|
* {\"Ids\":\"\",\"Numbers\":[],\"EntryIds\":\"\",\"RuleId\":\"\",\"TargetBillTypeId\":\"\",\"TargetOrgId\":\"0\",\"TargetFormId\":\"\",\"IsEnableDefaultRule\":\"false\",\"CustomParams\":{}} |
||||
|
*/ |
||||
|
@JsonProperty("formId") |
||||
|
private String formId; |
||||
|
|
||||
|
@JsonProperty("data") |
||||
|
private PushData data = new PushData(); |
||||
|
|
||||
|
@Data |
||||
|
public static class PushData { |
||||
|
@JsonProperty("Ids") |
||||
|
private String ids = ""; |
||||
|
|
||||
|
@JsonProperty("Numbers") |
||||
|
private List<String> numbers = new ArrayList<>(); |
||||
|
|
||||
|
@JsonProperty("EntryIds") |
||||
|
private String entryIds = ""; |
||||
|
|
||||
|
@JsonProperty("RuleId") |
||||
|
private String ruleId; |
||||
|
@JsonProperty("TargetBillTypeId") |
||||
|
private String TargetBillTypeId = ""; |
||||
|
@JsonProperty("TargetOrgId") |
||||
|
private String TargetOrgId = "0"; |
||||
|
@JsonProperty("TargetFormId") |
||||
|
private String TargetFormId; |
||||
|
@JsonProperty("IsDraftWhenSaveFail") |
||||
|
private String IsDraftWhenSaveFail = "false"; |
||||
|
@JsonProperty("IsEnableDefaultRule") |
||||
|
private String IsEnableDefaultRule = "false"; |
||||
|
@JsonProperty("CustomParams") |
||||
|
private Map<String, Object> CustomParams = new HashMap<>(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
package com.yxt.anrui.fin.biz.kingdee.push; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSONArray; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.yxt.anrui.fin.api.kingdee.push.SalOutStockPushSalReturnStock; |
||||
|
import com.yxt.common.core.result.ResultBean; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @description: 销售出库单下推到销售退货单测试 |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2025/4/2 |
||||
|
**/ |
||||
|
@RestController |
||||
|
@RequestMapping("/pushreturn") |
||||
|
public class PushReturnRest { |
||||
|
|
||||
|
@Autowired |
||||
|
private PushReturnService pushReturnService; |
||||
|
@Autowired |
||||
|
private PushReturnService2 pushReturnService2; |
||||
|
|
||||
|
@GetMapping("getReturnStock") |
||||
|
public ResultBean<String> getReturnStock() throws Exception { |
||||
|
SalOutStockPushSalReturnStock salOutStockPushSalReturnStock = new SalOutStockPushSalReturnStock(); |
||||
|
List<SalOutStockPushSalReturnStock.SalesReturnDetailDto> detailDtoList = new ArrayList<>(); |
||||
|
SalOutStockPushSalReturnStock.SalesReturnDetailDto salesReturnDetailDto = new SalOutStockPushSalReturnStock.SalesReturnDetailDto(); |
||||
|
salesReturnDetailDto.setBillNo("XSCKD1012025030023"); |
||||
|
salesReturnDetailDto.setFMaterialId("SR011469"); |
||||
|
detailDtoList.add(salesReturnDetailDto); |
||||
|
salesReturnDetailDto = new SalOutStockPushSalReturnStock.SalesReturnDetailDto(); |
||||
|
salesReturnDetailDto.setBillNo("XSCKD1012025030022"); |
||||
|
salesReturnDetailDto.setFMaterialId("SR011471"); |
||||
|
detailDtoList.add(salesReturnDetailDto); |
||||
|
salOutStockPushSalReturnStock.setStockDtoList(detailDtoList); |
||||
|
return pushReturnService2.getReturnStock(salOutStockPushSalReturnStock); |
||||
|
} |
||||
|
|
||||
|
@GetMapping("getReturnStockEntry") |
||||
|
public JSONArray getReturnStockEntry() throws Exception { |
||||
|
String billNo = "XSTHD001987"; |
||||
|
JSONArray getSalReturnStockEntrys = pushReturnService2.getSalReturnStockEntrys(billNo); |
||||
|
return getSalReturnStockEntrys; |
||||
|
} |
||||
|
} |
@ -0,0 +1,158 @@ |
|||||
|
package com.yxt.anrui.fin.biz.kingdee.push; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.alibaba.fastjson.JSONArray; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.yxt.anrui.fin.api.kingdee.KingDeeBillId; |
||||
|
import com.yxt.anrui.fin.api.kingdee.KingDeeBillUrl; |
||||
|
import com.yxt.anrui.fin.api.kingdee.push.Push; |
||||
|
import com.yxt.anrui.fin.api.kingdee.push.SalOutStockPushSalReturnStock; |
||||
|
import com.yxt.anrui.fin.biz.kingdee.FinKingDeeService; |
||||
|
import com.yxt.common.base.utils.StringUtils; |
||||
|
import com.yxt.common.core.result.ResultBean; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.*; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* @description: 每个销售出库单推送一个销售退货单 |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2025/3/31 |
||||
|
**/ |
||||
|
@Service |
||||
|
public class PushReturnService extends FinKingDeeService { |
||||
|
|
||||
|
|
||||
|
public ResultBean<String> getReturnStock(SalOutStockPushSalReturnStock salOutStockPushSalReturnStock) throws Exception { |
||||
|
ResultBean<String> rb = ResultBean.fireFail(); |
||||
|
Map<String, List<SalOutStockPushSalReturnStock.SalesReturnDetailDto>> groupedByBillNo = salOutStockPushSalReturnStock.getStockDtoList() |
||||
|
.stream() |
||||
|
.collect(Collectors.groupingBy(SalOutStockPushSalReturnStock.SalesReturnDetailDto::getBillNo)); |
||||
|
// 3. 循环处理每个出库单
|
||||
|
for (Map.Entry<String, List<SalOutStockPushSalReturnStock.SalesReturnDetailDto>> entry : groupedByBillNo.entrySet()) { |
||||
|
String billNo = entry.getKey(); |
||||
|
List<SalOutStockPushSalReturnStock.SalesReturnDetailDto> details = entry.getValue(); |
||||
|
String[] materialIds = details.stream() |
||||
|
.map(SalOutStockPushSalReturnStock.SalesReturnDetailDto::getFMaterialId) |
||||
|
.toArray(String[]::new); |
||||
|
|
||||
|
|
||||
|
// 构建下推请求
|
||||
|
Push push = new Push(); |
||||
|
push.setFormid(KingDeeBillId.SAL_OUTSTOCK.getID()); |
||||
|
push.setRuleId("OutStock-SalReturnStock"); |
||||
|
push.setTargetFormId(KingDeeBillId.SAL_RETURNSTOCK.getID()); |
||||
|
push.setEntryIds(String.join(",", materialIds)); |
||||
|
push.setNumbers(billNo); |
||||
|
String kingDeeData = createKingDeeDate(push, billNo); |
||||
|
//业务表的主表数据集合
|
||||
|
try { |
||||
|
ResultBean<String> resultBeans = accessKingDeeInterface(KingDeeBillId.SAL_RETURNSTOCK.getID(), |
||||
|
kingDeeData, KingDeeBillUrl.PUSH_URL.getURL()); |
||||
|
if (!resultBeans.getSuccess()) { |
||||
|
log.info("下推失败!"); |
||||
|
return rb.setMsg("下推失败!"); |
||||
|
} |
||||
|
String data = resultBeans.getData(); |
||||
|
/* ResultBean<String> submit = submit(KingDeeBillId.SAL_RETURNSTOCK.getID(), data); |
||||
|
if (!submit.getSuccess()) { |
||||
|
return rb.setCode(KingDeeCode.SUBMIT.getCode()).setMsg(KingDeeCode.SUBMIT.getMsg()); |
||||
|
}*/ |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
return rb.success(); |
||||
|
} |
||||
|
|
||||
|
private String createKingDeeDate(Push push, String billNo) throws Exception { |
||||
|
JSONArray outStockEntryS = getSalOutStockEntrys(billNo); |
||||
|
String entryIds = push.getEntryIds(); |
||||
|
String[] split = entryIds.split(","); |
||||
|
if (split.length > outStockEntryS.size()) { |
||||
|
return ""; |
||||
|
} |
||||
|
String kingDeeData = ""; |
||||
|
if (split.length == outStockEntryS.size()) {//物料数量相等 说明是整单下推退货单
|
||||
|
kingDeeData = PushCastToKingDeeBillFields.getKingDeeData(push, true); |
||||
|
} else { |
||||
|
String sb = getEntryIds(outStockEntryS, split); |
||||
|
if (sb.length() == 0) { |
||||
|
return ""; |
||||
|
} |
||||
|
entryIds = sb; |
||||
|
log.info("substring:{}", entryIds); |
||||
|
push.setEntryIds(entryIds); |
||||
|
kingDeeData = PushCastToKingDeeBillFields.getKingDeeData(push, false); |
||||
|
} |
||||
|
return kingDeeData; |
||||
|
} |
||||
|
|
||||
|
private String getEntryIds(JSONArray outStockEntryS, String[] materialIds) { |
||||
|
Set<String> materialIdSet = Arrays.stream(materialIds) |
||||
|
.map(String::trim) |
||||
|
.filter(StringUtils::isNotBlank) |
||||
|
.collect(Collectors.toSet()); |
||||
|
|
||||
|
if (materialIdSet.isEmpty()) { |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
// 2. 提取匹配的EntryIds
|
||||
|
return extractPairs(outStockEntryS).stream() |
||||
|
.filter(pair -> pair.containsKey("Value") && pair.get("Value") != null) |
||||
|
.filter(pair -> materialIdSet.contains(pair.get("Value").toString().trim())) |
||||
|
.map(pair -> pair.get("Id").toString()) |
||||
|
.filter(Objects::nonNull) |
||||
|
.collect(Collectors.joining(",")); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 从JSON数组提取ID和物料ID对 |
||||
|
* |
||||
|
* @param array JSON数组 |
||||
|
* @return 包含ID和物料ID对的列表 |
||||
|
*/ |
||||
|
public List<Map<String, String>> extractPairs(JSONArray array) { |
||||
|
ArrayList<Map<String, String>> strs = new ArrayList<>(); |
||||
|
for (int i = 0; i < array.size(); i++) {//解析查询的入库单返回的数据
|
||||
|
JSONObject o = (JSONObject) array.get(i); |
||||
|
|
||||
|
JSONObject materialId = (JSONObject) o.get("MaterialID"); |
||||
|
JSONArray Names = (JSONArray) materialId.get("Name"); |
||||
|
JSONObject Name = (JSONObject) Names.get(0); |
||||
|
String Value = (String) Name.get("Value"); |
||||
|
int Id = (int) o.get("Id"); |
||||
|
log.info("Value:{}", Value); |
||||
|
log.info("Id:{}", Id); |
||||
|
Map<String, String> map = new HashMap<>(); |
||||
|
map.put("Value", Value); |
||||
|
map.put("Id", Id + ""); |
||||
|
strs.add(map); |
||||
|
} |
||||
|
return strs; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private JSONArray getSalOutStockEntrys(String billNo) throws Exception { |
||||
|
String stk = getGetKDForNumbers(KingDeeBillId.SAL_OUTSTOCK.getID(), billNo); |
||||
|
ResultBean<String> resultBean = accessKingDeeInterface(KingDeeBillId.SAL_OUTSTOCK.getID(), |
||||
|
stk, KingDeeBillUrl.VIEW_URL.getURL()); |
||||
|
log.info("stk:{}", stk); |
||||
|
log.info("resultBean:{}", resultBean); |
||||
|
String data = resultBean.getData(); |
||||
|
JSONObject jsonObject = JSONObject.parseObject(data); |
||||
|
JSONObject result = (JSONObject) jsonObject.get("Result"); |
||||
|
log.info("result:{}", result); |
||||
|
JSONObject result2 = (JSONObject) result.get("Result"); |
||||
|
log.info("result2:{}", result2); |
||||
|
|
||||
|
JSONArray outStockEntryS = (JSONArray) result2.get("SAL_OUTSTOCKENTRY"); |
||||
|
log.info("outStockEntryS:{}", outStockEntryS); |
||||
|
log.info("size:{}", outStockEntryS.size()); |
||||
|
return outStockEntryS; |
||||
|
} |
||||
|
} |
@ -0,0 +1,271 @@ |
|||||
|
package com.yxt.anrui.fin.biz.kingdee.push; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSONArray; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.yxt.anrui.fin.api.kingdee.KingDeeBillId; |
||||
|
import com.yxt.anrui.fin.api.kingdee.KingDeeBillUrl; |
||||
|
import com.yxt.anrui.fin.api.kingdee.KingDeeCode; |
||||
|
import com.yxt.anrui.fin.api.kingdee.push.Push; |
||||
|
import com.yxt.anrui.fin.api.kingdee.push.SalOutStockPushSalReturnStock; |
||||
|
import com.yxt.anrui.fin.biz.kingdee.FinKingDeeService; |
||||
|
import com.yxt.common.base.utils.StringUtils; |
||||
|
import com.yxt.common.core.result.ResultBean; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.*; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* @description: 同一个客户的多个销售出库单推送一个销售退货单 |
||||
|
* @author: dimengzhe |
||||
|
* @date: 2025/4/2 |
||||
|
**/ |
||||
|
@Service |
||||
|
public class PushReturnService2 extends FinKingDeeService { |
||||
|
|
||||
|
public ResultBean<String> getReturnStock(SalOutStockPushSalReturnStock salOutStockPushSalReturnStock) throws Exception { |
||||
|
ResultBean<String> rb = ResultBean.fireFail(); |
||||
|
|
||||
|
// 1. 收集所有物料ID和出库单号
|
||||
|
List<SalOutStockPushSalReturnStock.SalesReturnDetailDto> allDetails = salOutStockPushSalReturnStock.getStockDtoList(); |
||||
|
|
||||
|
// 2. 获取所有出库单号(去重)
|
||||
|
Set<String> billNos = allDetails.stream() |
||||
|
.map(SalOutStockPushSalReturnStock.SalesReturnDetailDto::getBillNo) |
||||
|
.collect(Collectors.toSet()); |
||||
|
|
||||
|
// 3. 获取所有出库单的Entry信息
|
||||
|
Map<String, String[]> map = getBillNoToEntriesMap(billNos, allDetails); |
||||
|
|
||||
|
String entryIds = getEntryIds(billNos, map); |
||||
|
|
||||
|
// 5. 构建下推请求
|
||||
|
Push push = new Push(); |
||||
|
push.setFormid(KingDeeBillId.SAL_OUTSTOCK.getID()); |
||||
|
push.setRuleId("OutStock-SalReturnStock"); |
||||
|
push.setTargetFormId(KingDeeBillId.SAL_RETURNSTOCK.getID()); |
||||
|
push.setNumbers(String.join(",", billNos)); // 设置多个出库单号
|
||||
|
push.setEntryIds(String.join(",", entryIds)); // 设置原始分录内码
|
||||
|
|
||||
|
// 6. 创建金蝶数据
|
||||
|
String kingDeeData = PushCastToKingDeeBillFields.getKingDeeData2(push, false); |
||||
|
if (kingDeeData == null || kingDeeData.isEmpty()) { |
||||
|
log.error("创建金蝶数据失败,billNos: {}", billNos); |
||||
|
return rb.setMsg("创建金蝶数据失败"); |
||||
|
} |
||||
|
|
||||
|
// 7. 调用金蝶接口
|
||||
|
try { |
||||
|
ResultBean<String> resultBeans = accessKingDeeInterface( |
||||
|
KingDeeBillId.SAL_RETURNSTOCK.getID(), |
||||
|
kingDeeData, |
||||
|
KingDeeBillUrl.PUSH_URL.getURL()); |
||||
|
|
||||
|
if (!resultBeans.getSuccess()) { |
||||
|
log.error("下推失败! billNos: {}, 错误信息: {}", billNos, resultBeans.getMsg()); |
||||
|
return rb.setMsg("下推失败: " + resultBeans.getMsg()); |
||||
|
} |
||||
|
|
||||
|
String data = resultBeans.getData(); |
||||
|
// 1. 使用安全解析方式
|
||||
|
JSONObject jsonObject = JSONObject.parseObject(data); |
||||
|
// 2. 安全获取ID(带完整异常处理)
|
||||
|
int id = Optional.ofNullable(jsonObject.getJSONObject("Result")) |
||||
|
.map(result -> result.getJSONObject("ResponseStatus")) |
||||
|
.map(response -> response.getJSONArray("SuccessEntitys")) |
||||
|
.filter(array -> !array.isEmpty()) |
||||
|
.map(array -> array.getJSONObject(0)) |
||||
|
.map(entity -> entity.getInteger("Id")) |
||||
|
.orElseThrow(() -> new Exception("无法从金蝶响应中获取有效ID")); |
||||
|
|
||||
|
// 3. 记录关键日志
|
||||
|
log.info("成功解析金蝶响应 | 单据ID: {}", id); |
||||
|
if (log.isDebugEnabled()) { |
||||
|
log.debug("完整响应数据: {}", StringUtils.abbreviate(data, 200)); |
||||
|
} |
||||
|
|
||||
|
// 4. 提交操作
|
||||
|
ResultBean<String> submitResult = submit(KingDeeBillId.SAL_RETURNSTOCK.getID(), String.valueOf(id)); |
||||
|
if (!submitResult.getSuccess()) { |
||||
|
log.warn("单据提交失败 | 单据ID: {}, 错误: {}", id, submitResult.getMsg()); |
||||
|
return rb.setCode(KingDeeCode.SUBMIT.getCode()) |
||||
|
.setData(submitResult.getData()); |
||||
|
} |
||||
|
|
||||
|
// 5. 审核操作(使用解析后的ID而非原始data)
|
||||
|
ResultBean<String> auditResult = audit(KingDeeBillId.SAL_RETURNSTOCK.getID(), String.valueOf(id)); |
||||
|
if (!auditResult.getSuccess()) { |
||||
|
log.warn("单据审核失败 | 单据ID: {}, 错误: {}", id, auditResult.getMsg()); |
||||
|
return rb.setCode(KingDeeCode.AUDIT.getCode()) |
||||
|
.setData(auditResult.getData()); |
||||
|
} |
||||
|
|
||||
|
log.info("单据处理成功 | 单据ID: {}", id); |
||||
|
return resultBeans; |
||||
|
} catch (Exception e) { |
||||
|
log.error("调用金蝶接口异常", e); |
||||
|
throw e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据出库单号和物料ID映射获取Entry IDs |
||||
|
* |
||||
|
* @param billNos 出库单号集合 |
||||
|
* @param map 出库单号到物料ID数组的映射 |
||||
|
* @return 包含所有匹配Entry IDs的StringBuilder |
||||
|
*/ |
||||
|
private String getEntryIds(Set<String> billNos, Map<String, String[]> map) { |
||||
|
List<String> allEntryIds = new ArrayList<>(); |
||||
|
for (String billNo : billNos) { |
||||
|
// 1. 预处理物料IDs
|
||||
|
Set<String> materialIdSet = new HashSet<>(); |
||||
|
String[] materialIds = map.getOrDefault(billNo, new String[0]); |
||||
|
for (String materialId : materialIds) { |
||||
|
if (materialId != null && StringUtils.isNotBlank(materialId)) { |
||||
|
materialIdSet.add(materialId.trim()); |
||||
|
} |
||||
|
} |
||||
|
// 2. 查询分录信息
|
||||
|
try { |
||||
|
JSONArray outStockEntryS = getSalOutStockEntrys(billNo); |
||||
|
List<Map<String, String>> extractPairs = extractPairs(outStockEntryS); |
||||
|
List<String> matchedEntryIds = new ArrayList<>(); |
||||
|
for (int i = 0; i < extractPairs.size(); i++) { |
||||
|
Map<String, String> pair = extractPairs.get(i); |
||||
|
if (!pair.containsKey("Value") || pair.get("Value") == null) { |
||||
|
continue; // 跳过无效条目
|
||||
|
} |
||||
|
|
||||
|
String value = pair.get("Value").toString().trim(); |
||||
|
if (materialIdSet.contains(value)) { |
||||
|
Object id = pair.get("Id"); |
||||
|
if (id != null) { |
||||
|
matchedEntryIds.add(id.toString()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
if (!matchedEntryIds.isEmpty()) { |
||||
|
allEntryIds.add(String.join(",", matchedEntryIds)); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("获取出库单分录信息失败,billNo: {}", billNo, e); |
||||
|
} |
||||
|
} |
||||
|
return String.join(",", allEntryIds); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 从JSON数组提取ID和物料ID对 |
||||
|
* |
||||
|
* @param array JSON数组 |
||||
|
* @return 包含ID和物料ID对的列表 |
||||
|
*/ |
||||
|
public List<Map<String, String>> extractPairs(JSONArray array) { |
||||
|
ArrayList<Map<String, String>> strs = new ArrayList<>(); |
||||
|
for (int i = 0; i < array.size(); i++) {//解析查询的入库单返回的数据
|
||||
|
JSONObject o = (JSONObject) array.get(i); |
||||
|
|
||||
|
JSONObject materialId = (JSONObject) o.get("MaterialID"); |
||||
|
JSONArray Names = (JSONArray) materialId.get("Name"); |
||||
|
JSONObject Name = (JSONObject) Names.get(0); |
||||
|
String Value = (String) Name.get("Value"); |
||||
|
int Id = (int) o.get("Id"); |
||||
|
log.info("Value:{}", Value); |
||||
|
log.info("Id:{}", Id); |
||||
|
Map<String, String> map = new HashMap<>(); |
||||
|
map.put("Value", Value); |
||||
|
map.put("Id", Id + ""); |
||||
|
strs.add(map); |
||||
|
} |
||||
|
return strs; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 根据出库单号(billNo)获取对应的物料ID数组(materialIds) |
||||
|
* |
||||
|
* @param billNos 出库单号集合 |
||||
|
* @param allDetails 所有明细数据 |
||||
|
* @return Map<String, String [ ]> 其中key是出库单号,value是该出库单对应的物料ID数组 |
||||
|
*/ |
||||
|
private Map<String, String[]> getBillNoToEntriesMap(Set<String> billNos, |
||||
|
List<SalOutStockPushSalReturnStock.SalesReturnDetailDto> allDetails) { |
||||
|
|
||||
|
// 1. 按出库单号分组明细数据
|
||||
|
Map<String, List<SalOutStockPushSalReturnStock.SalesReturnDetailDto>> groupedByBillNo = allDetails.stream() |
||||
|
.collect(Collectors.groupingBy(SalOutStockPushSalReturnStock.SalesReturnDetailDto::getBillNo)); |
||||
|
|
||||
|
// 2. 转换为Map<String, String[]>格式
|
||||
|
Map<String, String[]> result = new HashMap<>(); |
||||
|
|
||||
|
for (Map.Entry<String, List<SalOutStockPushSalReturnStock.SalesReturnDetailDto>> entry : groupedByBillNo.entrySet()) { |
||||
|
String billNo = entry.getKey(); |
||||
|
List<SalOutStockPushSalReturnStock.SalesReturnDetailDto> details = entry.getValue(); |
||||
|
|
||||
|
// 提取物料ID数组
|
||||
|
String[] materialIds = details.stream() |
||||
|
.map(SalOutStockPushSalReturnStock.SalesReturnDetailDto::getFMaterialId) |
||||
|
.toArray(String[]::new); |
||||
|
|
||||
|
result.put(billNo, materialIds); |
||||
|
} |
||||
|
|
||||
|
// 3. 确保所有billNos都有对应的entry(即使为空数组)
|
||||
|
for (String billNo : billNos) { |
||||
|
result.putIfAbsent(billNo, new String[0]); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取出库单分录信息 |
||||
|
*/ |
||||
|
private JSONArray getSalOutStockEntrys(String billNo) throws Exception { |
||||
|
String stk = getGetKDForNumbers(KingDeeBillId.SAL_OUTSTOCK.getID(), billNo); |
||||
|
ResultBean<String> resultBean = accessKingDeeInterface( |
||||
|
KingDeeBillId.SAL_OUTSTOCK.getID(), |
||||
|
stk, |
||||
|
KingDeeBillUrl.VIEW_URL.getURL()); |
||||
|
|
||||
|
if (!resultBean.getSuccess()) { |
||||
|
log.error("获取出库单分录信息失败,billNo: {}, 错误: {}", billNo, resultBean.getMsg()); |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
JSONObject jsonObject = JSONObject.parseObject(resultBean.getData()); |
||||
|
JSONObject result = jsonObject.getJSONObject("Result"); |
||||
|
JSONObject result2 = result.getJSONObject("Result"); |
||||
|
return result2.getJSONArray("SAL_OUTSTOCKENTRY"); |
||||
|
} catch (Exception e) { |
||||
|
log.error("解析出库单分录信息异常,billNo: {}", billNo, e); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public JSONArray getSalReturnStockEntrys(String billNo) throws Exception { |
||||
|
String stk = getGetKDForNumbers(KingDeeBillId.SAL_RETURNSTOCK.getID(), billNo); |
||||
|
ResultBean<String> resultBean = accessKingDeeInterface( |
||||
|
KingDeeBillId.SAL_RETURNSTOCK.getID(), |
||||
|
stk, |
||||
|
KingDeeBillUrl.VIEW_URL.getURL()); |
||||
|
|
||||
|
if (!resultBean.getSuccess()) { |
||||
|
log.error("获取出库单分录信息失败,billNo: {}, 错误: {}", billNo, resultBean.getMsg()); |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
JSONObject jsonObject = JSONObject.parseObject(resultBean.getData()); |
||||
|
JSONObject result = jsonObject.getJSONObject("Result"); |
||||
|
JSONObject result2 = result.getJSONObject("Result"); |
||||
|
return result2.getJSONArray("SAL_RETURNSTOCKENTRY"); |
||||
|
} catch (Exception e) { |
||||
|
log.error("解析出库单分录信息异常,billNo: {}", billNo, e); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue