package com.zy.asrs.task.kingdee.handler;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
import com.zy.asrs.entity.*;
|
import com.zy.asrs.service.ApiLogService;
|
import com.zy.asrs.service.DocTypeService;
|
import com.zy.asrs.service.OrderService;
|
import com.zy.asrs.service.impl.ErpSecretServiceImpl;
|
import com.zy.asrs.service.impl.OrderDetlPakinServiceImpl;
|
import com.zy.asrs.service.impl.OrderDetlServiceImpl;
|
import com.zy.asrs.task.AbstractHandler;
|
import com.zy.asrs.task.core.ReturnT;
|
import com.zy.asrs.utils.OrderInAndOutUtil;
|
import com.zy.common.utils.HttpHandler;
|
import com.zy.erp.kingdee.enums.KingDeeUtilType;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
|
/**
|
* Created by Monkey D. Luffy on 2023.10.21
|
*/
|
@Slf4j
|
@Service
|
public class SaveOrderSyncHandler extends AbstractHandler<String> {
|
@Value("${erp.address.URL}")
|
private String URL;
|
|
@Value("${erp.address.imPurinbillAdd}")
|
private String imPurinbillAdd;
|
|
@Autowired
|
private OrderService orderService;
|
@Autowired
|
private ApiLogService apiLogService;
|
@Autowired
|
private DocTypeService docTypeService;
|
@Autowired
|
private LoginAuthenticationHandler loginAuthenticationHandler;
|
@Autowired
|
private ErpSecretServiceImpl erpSecretService;
|
@Autowired
|
private OrderDetlPakinServiceImpl orderDetlPakinService;
|
@Autowired
|
private OrderDetlServiceImpl orderDetlService;
|
|
@Value("${erp.login.accountId}")
|
private String accountId;
|
@Value("${erp.login.xAcfwIdentity}")
|
private String xAcfwIdentity;
|
String path;
|
@Transactional
|
public ReturnT<String> start(Order order) {
|
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
|
|
// 获取 Token
|
ErpSecret erpSecret = erpSecretService.selectOne(new EntityWrapper<ErpSecret>().eq("account_id", accountId));
|
|
// 获取 DocType
|
DocType docType = docTypeService.selectById(order.getDocType());
|
if (docType == null) return SUCCESS;
|
|
// 获取 KingDee 类型
|
KingDeeUtilType kingDeeUtilType = KingDeeUtilType.get(docType.getDocName());
|
|
// 构建请求参数
|
JSONObject add = buildRequestParams(order, kingDeeUtilType, sdf1, sdf2);
|
if (add == null) return FAIL.setMsg("请求参数构建失败");
|
|
// 发送请求并处理响应
|
return sendRequestAndProcessResponse(order, erpSecret, add);
|
}
|
|
private JSONObject buildRequestParams(Order order, KingDeeUtilType kingDeeUtilType, SimpleDateFormat sdf1, SimpleDateFormat sdf2) {
|
List<OrderDetl> orderDetlList = orderDetlService.selectList(new EntityWrapper<OrderDetl>().eq("order_no",order.getOrderNo()));
|
|
switch (kingDeeUtilType.formId) {
|
case "PUR_RECEIVEBIll": // 进仓通知单
|
path = imPurinbillAdd;
|
JSONArray billentryLkArray = new JSONArray();
|
JSONArray billentryArray = new JSONArray(); // 用于存储 billentry 对象
|
String suppCode = null; // 供应商
|
String boxType2 = null; // 货主/货源
|
|
// 遍历订单详情
|
for (OrderDetl orderDetl : orderDetlList) {
|
suppCode = orderDetl.getSuppCode();
|
boxType2 = orderDetl.getBoxType2();
|
if (orderDetl.getQty() == 0) {
|
continue;
|
}
|
|
// 创建 billentry_lk 对象
|
JSONObject billentryLk = new JSONObject()
|
.fluentPut("id", Long.parseLong(orderDetl.getThreeCode()))
|
.fluentPut("seq", orderDetl.getLineNumber())
|
.fluentPut("billentry_lk_stableid", 677270092232273922L)
|
.fluentPut("billentry_lk_sbillid", Long.parseLong(order.getItemName())) // 主单ID
|
.fluentPut("billentry_lk_sid", Long.parseLong(orderDetl.getThreeCode())) // 明细ID
|
.fluentPut("billentry_lk_baseqty_old", orderDetl.getErpAnfme()) // ERP数量
|
.fluentPut("billentry_lk_baseqty", orderDetl.getQty()); // 作业数量
|
billentryLkArray.add(billentryLk);
|
// 创建 billentry 对象,填充缺失的字段
|
JSONObject billentry = new JSONObject()
|
.fluentPut("id", Long.parseLong(orderDetl.getThreeCode()))
|
.fluentPut("warehouse_number", orderDetl.getManu()) // 仓库编号
|
.fluentPut("invstatus_number", "110") // 库存状态
|
.fluentPut("invtype_number", "110") // 库存类型
|
.fluentPut("outinvstatus_number", "110")
|
.fluentPut("linetype_number", "010") // 行号类型
|
.fluentPut("qty", orderDetl.getQty()) // 数量
|
.fluentPut("material_number", orderDetl.getMatnr()) // 物料编号
|
.fluentPut("billentry_lk", billentryLkArray); // 将 billentry_lk 添加到 billentry
|
|
billentryArray.add(billentry);
|
}
|
Date now = new Date();
|
// 生成 INR 相关请求参数
|
return new JSONObject()
|
.fluentPut("data", new JSONArray(Arrays.asList(
|
new JSONObject()
|
.fluentPut("billno", order.getOrderNo())
|
.fluentPut("trdbillno", UUID.randomUUID().toString().replace("-", ""))
|
.fluentPut("billtype_number", "im_PurInBill_STD_BT_S")
|
.fluentPut("biztime", sdf1.format(now))
|
.fluentPut("exratedate", sdf1.format(now))
|
.fluentPut("bizorg_number", boxType2)
|
.fluentPut("biztype_number", "110") // 货主/货源
|
.fluentPut("org_number", boxType2) // 货主/货源
|
.fluentPut("paymode", "CREDIT")
|
.fluentPut("invscheme_number", "110")
|
.fluentPut("billtype_number", "im_PurInBill_STD_BT_S")
|
.fluentPut("supplier_number", suppCode) // 供应商编号
|
.fluentPut("billno", order.getOrderNo())
|
.fluentPut("billentry", billentryArray) // 将 billentry 数组添加到请求参数
|
)));
|
|
default:
|
// 默认处理:可以抛出异常或返回空对象
|
throw new IllegalArgumentException("Unsupported formId: " + kingDeeUtilType.formId);
|
}
|
}
|
|
|
private ReturnT<String> sendRequestAndProcessResponse(Order order, ErpSecret erpSecret, JSONObject add) {
|
String response = "";
|
boolean success = false;
|
|
try {
|
// 设置请求头
|
HashMap<String, Object> headers = buildRequestHeaders(erpSecret);
|
|
// 发送请求,将 JSONObject 转换为 String
|
response = new HttpHandler.Builder()
|
.setHeaders(headers)
|
.setUri(URL)
|
.setPath(path)
|
.setJson(add.toJSONString()) // 将 JSONObject 转换为 String
|
.build()
|
.doPost();
|
|
// 解析响应
|
JSONObject jsonResponse = JSON.parseObject(response);
|
|
// 判断是否因为 token 过期 (errorCode = 401)
|
if ("401".equals(jsonResponse.getString("errorCode"))) {
|
log.error("认证失败,尝试重新获取 Token");
|
loginAuthenticationHandler.start(); // 刷新 token
|
// 重新获取新的 token
|
erpSecret = erpSecretService.selectOne(new EntityWrapper<ErpSecret>().eq("account_id", accountId)); // 重新从数据库获取新的 token
|
// 使用新的 token 重试请求
|
headers.put("accesstoken", erpSecret.getAccessToken());
|
response = new HttpHandler.Builder()
|
.setHeaders(headers)
|
.setUri(URL)
|
.setPath(path)
|
.setJson(add.toJSONString()) // 将 JSONObject 转换为 String
|
.build()
|
.doPost();
|
}
|
|
// 解析返回的响应
|
JSONObject data = jsonResponse.getJSONObject("data");
|
String errorCode = jsonResponse.getString("errorCode");
|
boolean status = jsonResponse.getBooleanValue("status");
|
|
// 检查接口调用的整体状态
|
if ("0".equals(errorCode) && status) {
|
// 获取成功与失败的数量
|
int successCount = data.getInteger("successCount");
|
int failCount = data.getInteger("failCount");
|
|
if (failCount == 0) {
|
success = true;
|
log.info("接口调用成功,成功的操作数量: {}", successCount);
|
// 获取返回的单据号和ID
|
JSONArray resultArray = data.getJSONArray("result");
|
for (int i = 0; i < resultArray.size(); i++) {
|
JSONObject resultItem = resultArray.getJSONObject(i);
|
String billNo = resultItem.getString("number"); // 获取返回的单据号
|
String billId = resultItem.getString("id"); // 获取返回的ID
|
|
// 判断返回的单据号与订单号是否一致
|
if (billNo != null && billNo.equals(order.getOrderNo())) {
|
// 如果一致,设置订单的 number
|
order.setNumber(billId);
|
log.info("订单号 {} 与返回的单据号匹配,设置订单 ID 为 {}", order.getOrderNo(), billId);
|
}
|
}
|
} else {
|
log.error("接口调用失败,失败的操作数量: {}", failCount);
|
// 如果有失败的单据,遍历 result 数组查看失败的详细信息
|
JSONArray resultArray = data.getJSONArray("result");
|
for (int i = 0; i < resultArray.size(); i++) {
|
JSONObject resultItem = resultArray.getJSONObject(i);
|
if (!resultItem.getBoolean("billStatus")) {
|
// 单据处理失败,记录错误信息
|
String billNo = resultItem.getString("billno");
|
JSONArray errors = resultItem.getJSONArray("errors");
|
log.error("单据号: {}, 错误信息: {}", billNo, errors);
|
}
|
}
|
}
|
order.setSettle(10L); // 更新状态为 "已上报"
|
orderService.updateById(order);
|
} else {
|
log.error("接口调用失败,错误信息: {}", jsonResponse.getString("message"));
|
}
|
} catch (Exception e) {
|
log.error("请求失败", e);
|
return FAIL.setMsg(e.getMessage());
|
} finally {
|
// 保存接口日志
|
saveApiLog(add, response, success);
|
}
|
|
return success ? SUCCESS : FAIL;
|
}
|
|
|
private HashMap<String, Object> buildRequestHeaders(ErpSecret erpSecret) {
|
HashMap<String, Object> headers = new HashMap<>();
|
headers.put("accesstoken", erpSecret.getAccessToken());
|
headers.put("x-acgw-identity", xAcfwIdentity); // 自定义请求头
|
return headers;
|
}
|
private void saveApiLog(JSONObject add, String response, boolean success) {
|
try {
|
apiLogService.save(
|
"进仓通知单上报新增",
|
URL + path,
|
null,
|
"127.0.0.1",
|
add.toJSONString(),
|
response,
|
success
|
);
|
} catch (Exception e) {
|
log.error("接口日志保存失败", e);
|
}
|
}
|
}
|