GySaleReturn,GyDelivery及相应工具新增

This commit is contained in:
cyy 2025-12-19 16:42:57 +08:00
parent 28c53f2cb5
commit 5630acb90c
6 changed files with 927 additions and 0 deletions

View File

@ -0,0 +1,123 @@
package tqq9.lc123.cloud.app.api.utils;
import com.fasterxml.jackson.databind.JsonNode;
import tqq9.lc123.cloud.app.api.utils.mapping.GyDeliveryMapping;
import java.util.*;
/**
* delivery 节点全部拍扁
*/
public final class GyDeliverySyncMappingUtil {
/* 1. 缓存key = 全路径value = 值或List<Map> */
private static final Map<String, Object> CACHE = new HashMap<>();
/* 2. 入口 */
public static void parse(JsonNode delivery) {
CACHE.clear();
flatten(null, delivery);
}
/* 3. 统一取值 */
public static Object get(String outerKey) {
String path = GyDeliveryMapping.FIELD_MAP.get(outerKey);
if (path == null) return null;
/* 3.1 整段数组或对象 */
if (isWholeBlock(path)) return CACHE.get(path);
/* 3.2 数组模板details[].field 或 details[1].field */
if (path.contains("[") && path.contains("].")) {
return handleArrayTemplate(path);
}
/* 3.3 普通根字段 */
return CACHE.get(path);
}
/* 4. 拍扁:对象展开;数组既存整段,又明细到 CACHE */
private static void flatten(String parent, JsonNode node) {
if (node.isObject()) {
Iterator<Map.Entry<String, JsonNode>> it = node.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> e = it.next();
flatten(join(parent, e.getKey()), e.getValue());
}
} else if (node.isArray()) {
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < node.size(); i++) {
JsonNode child = node.get(i);
Map<String, Object> row = new LinkedHashMap<>();
Iterator<Map.Entry<String, JsonNode>> it = child.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> f = it.next();
String key = f.getKey();
Object val = convert(f.getValue());
row.put(key, val);
/* 字段别名item_code -> material */
String alias = GyDeliveryMapping.ALIAS_MAP.get(key);
if (alias != null) row.put(alias, val);
}
list.add(row);
/* 明细拍扁details[0].xxx */
String idxKey = parent + "[" + i + "]";
for (Map.Entry<String, Object> entry : row.entrySet()) {
CACHE.put(idxKey + "." + entry.getKey(), entry.getValue());
}
}
CACHE.put(parent, list); // 整段也保留
} else {
CACHE.put(parent, convert(node));
}
}
/* 5. 数组模板处理 */
private static Object handleArrayTemplate(String path) {
int dot = path.indexOf("].");
String listPart = path.substring(0, dot + 1);
String field = path.substring(dot + 2);
String listKey = listPart.substring(0, listPart.indexOf("["));
Object block = CACHE.get(listKey);
if (!(block instanceof List)) return null;
List<Map<String, Object>> list = (List<Map<String, Object>>) block;
String idxPart = listPart.substring(listPart.indexOf("[") + 1, listPart.length() - 1);
/* 5.1 通配details[].field */
if (idxPart.isEmpty()) {
List<Object> res = new ArrayList<>(list.size());
for (Map<String, Object> row : list) {
res.add(row.get(field));
}
return res;
}
/* 5.2 单条details[1].field */
int i = Integer.parseInt(idxPart);
return i < 0 || i >= list.size() ? null : list.get(i).get(field);
}
/* 6. 工具方法 */
private static boolean isWholeBlock(String path) {
return path.equals("details") || path.equals("payments")
|| path.equals("invoices") || path.equals("tags")
|| path.equals("stock_location")
|| path.equals("delivery_statusInfo")
|| path.equals("store_info");
}
private static String join(String parent, String key) {
return parent == null ? key : parent + "." + key;
}
private static Object convert(JsonNode n) {
if (n.isTextual()) return n.asText();
if (n.isNumber()) return n.isFloatingPointNumber() ? n.asDouble() : n.asLong();
if (n.isBoolean()) return n.asBoolean();
return n.asText();
}
}

View File

@ -0,0 +1,122 @@
package tqq9.lc123.cloud.app.api.utils;
import com.fasterxml.jackson.databind.JsonNode;
import tqq9.lc123.cloud.app.api.utils.mapping.GySaleReturnMapping;
import java.util.*;
/**
* delivery 节点全部拍扁
*/
public final class GySaleReturnSyncMappingUtil {
/* 1. 缓存key = 全路径value = 值或List<Map> */
private static final Map<String, Object> CACHE = new HashMap<>();
/* 2. 入口 */
public static void parse(JsonNode delivery) {
CACHE.clear();
flatten(null, delivery);
}
/* 3. 统一取值 */
public static Object get(String outerKey) {
String path = GySaleReturnMapping.FIELD_MAP.get(outerKey);
if (path == null) return null;
/* 3.1 整段数组或对象 */
if (isWholeBlock(path)) return CACHE.get(path);
/* 3.2 数组模板details[].field 或 details[1].field */
if (path.contains("[") && path.contains("].")) {
return handleArrayTemplate(path);
}
/* 3.3 普通根字段 */
return CACHE.get(path);
}
/* 4. 拍扁:对象展开;数组既存整段,又明细到 CACHE */
private static void flatten(String parent, JsonNode node) {
if (node.isObject()) {
Iterator<Map.Entry<String, JsonNode>> it = node.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> e = it.next();
flatten(join(parent, e.getKey()), e.getValue());
}
} else if (node.isArray()) {
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < node.size(); i++) {
JsonNode child = node.get(i);
Map<String, Object> row = new LinkedHashMap<>();
Iterator<Map.Entry<String, JsonNode>> it = child.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> f = it.next();
String key = f.getKey();
Object val = convert(f.getValue());
row.put(key, val);
/* 字段别名item_code -> material */
String alias = GySaleReturnMapping.ALIAS_MAP.get(key);
if (alias != null) row.put(alias, val);
}
list.add(row);
/* 明细拍扁details[0].xxx */
String idxKey = parent + "[" + i + "]";
for (Map.Entry<String, Object> entry : row.entrySet()) {
CACHE.put(idxKey + "." + entry.getKey(), entry.getValue());
}
}
CACHE.put(parent, list); // 整段也保留
} else {
CACHE.put(parent, convert(node));
}
}
/* 5. 数组模板处理 */
private static Object handleArrayTemplate(String path) {
int dot = path.indexOf("].");
String listPart = path.substring(0, dot + 1);
String field = path.substring(dot + 2);
String listKey = listPart.substring(0, listPart.indexOf("["));
Object block = CACHE.get(listKey);
if (!(block instanceof List)) return null;
List<Map<String, Object>> list = (List<Map<String, Object>>) block;
String idxPart = listPart.substring(listPart.indexOf("[") + 1, listPart.length() - 1);
/* 5.1 通配details[].field */
if (idxPart.isEmpty()) {
List<Object> res = new ArrayList<>(list.size());
for (Map<String, Object> row : list) {
res.add(row.get(field));
}
return res;
}
/* 5.2 单条details[1].field */
int i = Integer.parseInt(idxPart);
return i < 0 || i >= list.size() ? null : list.get(i).get(field);
}
/* 6. 工具方法 */
private static boolean isWholeBlock(String path) {
return path.equals("details") || path.equals("payments")
|| path.equals("item_detail_out") || path.equals("refund_codes")
|| path.equals("stock_location")
|| path.equals("tags");
}
private static String join(String parent, String key) {
return parent == null ? key : parent + "." + key;
}
private static Object convert(JsonNode n) {
if (n.isTextual()) return n.asText();
if (n.isNumber()) return n.isFloatingPointNumber() ? n.asDouble() : n.asLong();
if (n.isBoolean()) return n.asBoolean();
return n.asText();
}
}

View File

@ -0,0 +1,42 @@
package tqq9.lc123.cloud.app.api.utils.mapping;
import java.util.HashMap;
import java.util.Map;
public final class GyDeliveryMapping {
public static final Map<String, String> FIELD_MAP = new HashMap<>();
static {
// delivery 主数据
FIELD_MAP.put("tqq9_gyfhdh", "code");//发货单单号
FIELD_MAP.put("tqq9_ptddh", "platform_code");//平台单号
FIELD_MAP.put("customer", "receiver_name");//订货客户-名称
FIELD_MAP.put("tqq9_sjr", "receiver_name");//收件人
FIELD_MAP.put("tqq9_sjrsj", "receiver_mobile");//收件人手机号
FIELD_MAP.put("tqq9_xxdz", "receiver_address");//收件人详细地址
FIELD_MAP.put("tqq9_ck", "warehouse_name");//发货仓库-仓库名称
// details 数组
FIELD_MAP.put("details", "details");
// invoices 数组
FIELD_MAP.put("invoices", "invoices");
// delivery_statusInfo 对象数据
FIELD_MAP.put("isCancel", "delivery_statusInfo.cancel");//发货单状态-是否取消
}
/* 数组内字段别名:真实字段 -> 别名 */
public static final Map<String, String> ALIAS_MAP = new HashMap<>();
static {
// details 数组数据
ALIAS_MAP.put("item_code", "material");//物料-编码
ALIAS_MAP.put("itemUnitName", "unit");//单位-名称
// invoices 数组数据
ALIAS_MAP.put("invoice_title", "tqq9_invoicett");//发票抬头
ALIAS_MAP.put("invoice_type_name", "tqq9_fplx");//发票类型
ALIAS_MAP.put("tex_payer_number", "tqq9_registerno");//纳税人识别号
ALIAS_MAP.put("bank_name", "tqq9_bank");//开户行
ALIAS_MAP.put("bank_account", "tqq9_bankno");//账号
}
private GyDeliveryMapping() {}
}

View File

@ -0,0 +1,26 @@
package tqq9.lc123.cloud.app.api.utils.mapping;
import java.util.HashMap;
import java.util.Map;
public final class GySaleReturnMapping {
public static final Map<String, String> FIELD_MAP = new HashMap<>();
static {
// delivery 主数据
FIELD_MAP.put("tqq9_gythdh", "code");//发货单单号
FIELD_MAP.put("tqq9_ptddh", "platform_code");//平台单号
FIELD_MAP.put("customer", "receiver_name");//订货客户-名称
FIELD_MAP.put("tqq9_lydh", "order_code");//销售订单号
// details 数组
FIELD_MAP.put("details", "details");
}
/* 数组内字段别名:真实字段 -> 别名 */
public static final Map<String, String> ALIAS_MAP = new HashMap<>();
static {
// details 数组数据
ALIAS_MAP.put("item_code", "material");//物料-编码
}
private GySaleReturnMapping() {}
}

View File

@ -0,0 +1,363 @@
package tqq9.lc123.cloud.app.plugin.task;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import kd.bos.coderule.api.CodeRuleInfo;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.botp.runtime.PushArgs;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.service.business.datamodel.DynamicFormModelProxy;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.util.StringUtils;
import kd.sdk.plugin.Plugin;
import tqq9.lc123.cloud.app.api.utils.GyDeliverySyncMappingUtil;
import tqq9.lc123.cloud.app.api.utils.GyOpenApiUtil;
import tqq9.lc123.cloud.app.plugin.utils.BillCloseCancelUtils;
import tqq9.lc123.cloud.app.plugin.utils.BotpParamUtils;
import java.math.BigDecimal;
import java.util.*;
import static tqq9.lc123.cloud.app.plugin.form.result.CloneBill.cloneOperation;
/**
* 后台任务插件
* 定时获取OMS的发货单生成金蝶的发货通知单
*/
public class GyDeliverySyncTask extends AbstractTask implements Plugin {
private static Log logger = LogFactory.getLog(GyDeliverySyncTask.class);
private static String DELIVERNOTICE = "sm_delivernotice";
private static String ADMINORG = "bos_adminorg";
private static String SALOUT = "im_saloutbill";
private static String SALORDER = "sm_salorder";
private static String USER = "bos_user";
private static String BILLTYPE = "bos_billtype";
private static String BIZTYPE = "bd_biztype";
private static String CUSTOMER = "bd_customer";
private static String LINETYPE = "bd_linetype";
private static String MATERIALSALINFO = "bd_materialsalinfo";
private static String MEASUREUNITS = "bd_measureunits";
private static String INVOICEBIZTYPE = "bd_invoicebiztype";
private static String OPERATOR = "bd_operator";
private static String EXRATETABLE = "bd_exratetable";
private static String CURRENCY = "bd_currency";
@Override
public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
Map<String, Object> params = new HashMap<>();
//管易发货单列表接口
params.put("method", "gy.erp.trade.deliverys.get");
Map<String, Object> listObjectMap = GyOpenApiUtil.buildRequestParams(params);
String listGuanyiApi = GyOpenApiUtil.callGuanyiApi(listObjectMap);
JSONObject listRoot = JSON.parseObject(listGuanyiApi);
//管易发货单列表-查询成功
if(listRoot.getBoolean("success")) {
JSONArray deliverys = listRoot.getJSONArray("deliverys");
//遍历逐个拿 code
for (int i = 0; i < deliverys.size(); i++) {
params = new HashMap<>();
//管易发货单详情接口
params.put("method", "gy.erp.trade.deliverys.detail.get");
params.put("code", deliverys.getJSONObject(i).getString("code"));
Map<String, Object> stringObjectMap = GyOpenApiUtil.buildRequestParams(params);
String callGuanyiApi = GyOpenApiUtil.callGuanyiApi(stringObjectMap);
JSONObject callRoot = JSON.parseObject(listGuanyiApi);
//管易发货单详情-查询成功
if(callRoot.getBoolean("success")) {
try {
//解析处理
JsonNode delivery = new ObjectMapper()
.readTree(callGuanyiApi)
.path("delivery");
GyDeliverySyncMappingUtil.parse(delivery);
String api_gyfhdh = (String) GyDeliverySyncMappingUtil.get("tqq9_gyfhdh");
String api_ptddh = (String) GyDeliverySyncMappingUtil.get("tqq9_ptddh");
//判断该发货单是否生成金蝶的发货通知单
QFilter filter_gyfhdh = new QFilter("tqq9_gyfhdh", QCP.equals, api_gyfhdh);//发货单号
QFilter filter_ptddh = new QFilter("tqq9_ptddh", QCP.equals, api_ptddh);//平台单号
DynamicObject deliveryNotice = BusinessDataServiceHelper.loadSingle(DELIVERNOTICE,
"billno,tqq9_gyfhdh,tqq9_ptddh,tqq9_trading,tqq9_interstatus,org.*,tqq9_ck.*",
new QFilter[]{filter_gyfhdh, filter_ptddh});
//获取发货通知单信息
if (deliveryNotice != null) {
Boolean api_isCancel = (Boolean) GyDeliverySyncMappingUtil.get("isCancel");
//发货单状态为取消 更新平台交易状态并拦截发货
if (api_isCancel != null && api_isCancel) {
String billno = deliveryNotice.getString("billno");//发货通知单编码
//拦截发货
Map<String, HashSet<Long>> targetBills = BFTrackerServiceHelper.findTargetBills(DELIVERNOTICE, new Long[]{deliveryNotice.getLong("id")});
//下游存在系统进行提示不允许后续操作
if (null != targetBills && targetBills.size() > 0 && targetBills.containsKey(SALOUT)) {
deliveryNotice.set("tqq9_interstatus","fail");//拦截失败
logger.info(billno+":存在下游单据,不允许拦截");
}
String message = null;
DynamicObject org = deliveryNotice.getDynamicObject("org");//收货组织
if (null != org) {
String number = org.getString("number");
if ("SHLC".equals(number)) {
String warehouseCode = null;
DynamicObject warehouse = deliveryNotice.getDynamicObject("tqq9_ck");//仓库处理状态
if (null != warehouse) {
warehouseCode = warehouse.getString("number");
}
message = BillCloseCancelUtils.wmsCancel("PTCK", warehouseCode, billno, DELIVERNOTICE, "WMS-SH-发货通知单取消", "tqq9_isclose");
}
if (StringUtils.isNotEmpty(message) && message.contains("关闭成功")) {
cloneOperation(deliveryNotice, "发货通知单", DELIVERNOTICE);
//克隆单据操作后原有单据已做删除处理需重新获取发货通知单
deliveryNotice = BusinessDataServiceHelper.loadSingle(DELIVERNOTICE, new QFilter[]{new QFilter("billno", QCP.equals, billno)});
deliveryNotice.set("tqq9_interstatus","sucess");//拦截成功
}else if (StringUtils.isNotEmpty(message)) {
logger.info(billno+":"+message);
deliveryNotice.set("tqq9_interstatus","fail");//拦截失败
}
}
deliveryNotice.set("tqq9_trading","TRADE_FINISHED");//交易关闭
SaveServiceHelper.save(new DynamicObject[]{deliveryNotice});
}
}else{
//通过发货单新增发货通知单
DynamicFormModelProxy modelProxy = new DynamicFormModelProxy(DELIVERNOTICE, UUID.randomUUID().toString(), new HashMap<>());
DynamicObject newDeliveryNotice = (DynamicObject) modelProxy.createNewData();
//默认数据
DynamicObject org = BusinessDataServiceHelper.loadSingle(ADMINORG,
new QFilter[]{new QFilter("number", QCP.equals, "SHLC")});//固定销售组织为SHLC
newDeliveryNotice.set("org",org);//固定销售组织为SHLC
newDeliveryNotice.set("deliverorg",org);//固定发货组织为SHLC
CodeRuleInfo rule = CodeRuleServiceHelper.getCodeRule(DELIVERNOTICE, newDeliveryNotice, null);// 获取本单据的编码规则
String billno = CodeRuleServiceHelper.getNumber(rule, newDeliveryNotice);// 通过编码规则获取单据编号
newDeliveryNotice.set("billno", billno);//单据编码
newDeliveryNotice.set("billstatus","A");//单据状态
DynamicObject operator = BusinessDataServiceHelper.loadSingle(OPERATOR,
new QFilter[]{new QFilter("operatornumber", QCP.equals, "SHKF001")});//默认吴海艳
newDeliveryNotice.set("tqq9_sskf",operator);//业务人员
DynamicObject bd_billtype = BusinessDataServiceHelper.loadSingle(BILLTYPE,
new QFilter[]{new QFilter("number", QCP.equals, "sm_delivernotice_STD_BT_S")});//默认标准销售发货通知单
newDeliveryNotice.set("billtype",bd_billtype);//单据类型
DynamicObject bd_biztype = BusinessDataServiceHelper.loadSingle(BIZTYPE,
new QFilter[]{new QFilter("number", QCP.equals, "210")});//默认物料类销售
newDeliveryNotice.set("biztype",bd_biztype);//业务类型
newDeliveryNotice.set("bizdate",new Date());//通知日期
newDeliveryNotice.set("closestatus","A");//关闭状态-正常
//当前用户
long userId = RequestContext.get().getCurrUserId();
//查询用户所属部门
long deptId = UserServiceHelper.getUserMainOrgId(Long.valueOf(userId));
DynamicObject deptOrg = BusinessDataServiceHelper.loadSingle(ADMINORG,
new QFilter[]{new QFilter("id", QCP.equals, deptId)});
newDeliveryNotice.set("tqq9_dept",deptOrg);//创建人部门
newDeliveryNotice.set("tqq9_ddlx","tmall");//订单类型-默认
newDeliveryNotice.set("tqq9_ddly","天猫订单");//订单来源-默认
newDeliveryNotice.set("exchangerate",1);//汇率-默认
DynamicObject bd_exratetable = BusinessDataServiceHelper.loadSingle(EXRATETABLE,
new QFilter[]{new QFilter("number", QCP.equals, "ERT-01")});//默认
newDeliveryNotice.set("exratetable",bd_exratetable);//汇率表
DynamicObject bd_currency = BusinessDataServiceHelper.loadSingle(CURRENCY,
new QFilter[]{new QFilter("number", QCP.equals, "CNY")});//默认
newDeliveryNotice.set("currency",bd_currency);//本位币
newDeliveryNotice.set("settlecurrency",bd_currency);//结算币
//接口数据
newDeliveryNotice.set("tqq9_gyfhdh",api_gyfhdh);//管易发货单号
newDeliveryNotice.set("tqq9_ptddh",api_ptddh);//平台订单号
newDeliveryNotice.set("tqq9_sjr",GyDeliverySyncMappingUtil.get("tqq9_sjr"));//收件人
newDeliveryNotice.set("tqq9_sjrsj",GyDeliverySyncMappingUtil.get("tqq9_sjrsj"));//收件人手机号
newDeliveryNotice.set("tqq9_xxdz",GyDeliverySyncMappingUtil.get("tqq9_xxdz"));//收件人详细地址
// newDeliveryNotice.set("tqq9_ck",GyDeliverySyncMappingUtil.get("tqq9_sjr"));//发货仓库-仓库名称
String api_customer = (String) GyDeliverySyncMappingUtil.get("customer");//订货客户-名称
//----------------------测试给值 上海励齿--待改动
DynamicObject bd_customer = BusinessDataServiceHelper.loadSingle(CUSTOMER,
new QFilter[]{new QFilter("name", QCP.equals, "上海励齿")});
newDeliveryNotice.set("customer",bd_customer);//订货客户
newDeliveryNotice.set("tqq9_invoicett",bd_customer);//发票抬头
DynamicObject bd_tinviceType = BusinessDataServiceHelper.loadSingle(INVOICEBIZTYPE,
new QFilter[]{new QFilter("number", QCP.equals, "SP00001_S")});
newDeliveryNotice.set("tqq9_fplx", bd_tinviceType);//发票类型
//---------------------测试给值
// 发票信息 invoices
List<Object> invoices = (List<Object>) GyDeliverySyncMappingUtil.get("invoices");
if (invoices != null && !invoices.isEmpty()) {
Object row = invoices.get(0);//单据只有一个发票信息
Map<String, Object> rowMap = (Map<String, Object>) row;
newDeliveryNotice.set("tqq9_invoicett",bd_customer);//发票抬头
String fplxNumber = "";
if("增值普通发票".equals(rowMap.get("tqq9_fplx"))){//发票类型
fplxNumber = "SP00001_S";
}else if("增值专用发票".equals(rowMap.get("tqq9_fplx"))){
fplxNumber = "SP00002_S";
}
DynamicObject bd_inviceType = BusinessDataServiceHelper.loadSingle(INVOICEBIZTYPE,
new QFilter[]{new QFilter("number", QCP.equals, fplxNumber)});
newDeliveryNotice.set("tqq9_fplx", bd_inviceType);//发票类型
newDeliveryNotice.set("tqq9_registerno", rowMap.get("tqq9_registerno"));//纳税人识别号
newDeliveryNotice.set("tqq9_bank",rowMap.get("tqq9_bank"));//开户行
newDeliveryNotice.set("tqq9_bankno",rowMap.get("tqq9_bankno"));//账号
}
// 物料明细 details
DynamicObjectCollection billentry = newDeliveryNotice.getDynamicObjectCollection("billentry");
billentry.clear();
List<Object> details = (List<Object>) GyDeliverySyncMappingUtil.get("details");
if (details != null && !details.isEmpty()) {
for (int j = 0; j < details.size(); j++) {
Object row = details.get(j);
Map<String, Object> rowMap = (Map<String, Object>) row;
//新增分录
DynamicObject newEntry = new DynamicObject(billentry.getDynamicObjectType());
DynamicObject bd_linetype = BusinessDataServiceHelper.loadSingle(LINETYPE,
new QFilter[]{new QFilter("number", QCP.equals, "010")});//默认物资
newEntry.set("linetype", bd_linetype);//行类型
String api_material = (String) rowMap.get("material");//物料-编码
DynamicObject bd_materialsalinfo = BusinessDataServiceHelper.loadSingle(MATERIALSALINFO,
new QFilter[]{new QFilter("masterid.number", QCP.equals, api_material)});//物料查询
newEntry.set("material", bd_materialsalinfo);//物料
if (bd_materialsalinfo!=null) newEntry.set("materialname", bd_materialsalinfo.get("masterid.name"));//物料名称
String api_unit = (String) rowMap.get("unit");//计量单位-编码
DynamicObject bd_measureunits = BusinessDataServiceHelper.loadSingle(MEASUREUNITS,
new QFilter[]{new QFilter("name", QCP.equals, api_unit)});//计量单位查询
newEntry.set("unit", bd_measureunits);//计量单位
newEntry.set("qty", rowMap.get("qty"));//数量
newEntry.set("baseqty", rowMap.get("qty"));//基本数量
newEntry.set("amount", rowMap.get("amount"));//金额
newEntry.set("entrysettleorg", org);//结算组织
newEntry.set("e_deliverorg", org);//发货组织
newEntry.set("salesorg", org);//销售组织
newEntry.set("discounttype", "NULL");//折扣方式
newEntry.set("deliverydate1", new Date());//要货日期
//-----------------测试给值
newEntry.set("associatedqty", 1);//关联数量
newEntry.set("associatedbaseqty", 1);//关联基本数量
newEntry.set("deliverbaseqtyup", 2);//发货上限基本数量>关联基本数量
newEntry.set("isinspect", false);//是否检验
//-----------------测试给值
newEntry.set("ownertype", "bos_org");//货主类型
newEntry.set("rowclosestatus", "A");//行关闭状态
billentry.add(newEntry);
}
}
SaveServiceHelper.save(new DynamicObject[]{newDeliveryNotice});
//发货通知单为审核状态-走标准提交审核操作
StringBuilder message = new StringBuilder();
OperationResult submitResult = OperationServiceHelper.executeOperate("submit", DELIVERNOTICE, new DynamicObject[]{newDeliveryNotice}, OperateOption.create());
if (submitResult.isSuccess()) {
OperationResult auditResult = OperationServiceHelper.executeOperate("audit", DELIVERNOTICE, new DynamicObject[]{newDeliveryNotice}, OperateOption.create());
if (!auditResult.isSuccess()) {
auditResult.getAllErrorOrValidateInfo().forEach((error) -> {
message.append(error.getMessage());
});
logger.info("Gy发货通知单 " + billno + "审核 失败:" + message);
}
}else{
submitResult.getAllErrorOrValidateInfo().forEach((error) -> {
message.append(error.getMessage());
});
logger.info("Gy发货通知单 " + billno + "提交 失败:" + message);
}
}
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
}
//销售出库单全部出库之后由金蝶的销售出库单生成金蝶销售订单
QFilter filter_gyfhdh = new QFilter("tqq9_gyfhdh", QCP.not_equals, "");//发货单号
QFilter filter_ptddh = new QFilter("tqq9_ptddh", QCP.not_equals, "");//平台单号
DynamicObject[] deliveryNotices = BusinessDataServiceHelper.load(DELIVERNOTICE,
"billno,billentry,billentry.qty,billentry.associatedqty",
new QFilter[]{filter_gyfhdh, filter_ptddh});
//遍历查询管易生成的发货通知单
for (DynamicObject deliveryNotice : deliveryNotices) {
//通过关联关系下查判断下游销售出库单是否已存在
Map<String, HashSet<Long>> tarBills = BFTrackerServiceHelper.findTargetBills(DELIVERNOTICE, new Long[]{Long.valueOf(deliveryNotice.getPkValue().toString())});
//返回的Map对象 如果有数据 String 对应的是 目标单据标识 value 对应的目标单ids
Set<Long> saloutId = new HashSet<Long>();
if (tarBills.containsKey(SALOUT)) {
saloutId = tarBills.get(SALOUT);
}
// 销售出库单存在的查询是否已全部出库通过系统自动下推销售订单
if (!saloutId.isEmpty()) {
Long srcSalOutId = saloutId.toArray(new Long[0])[0];
QFilter filter_id = new QFilter("id", QCP.equals, srcSalOutId);
DynamicObject salOutBill = BusinessDataServiceHelper.loadSingle(SALOUT,
new QFilter[]{filter_id});
//查询销售出库单是否全部出库-----根据发货通知单关联数量 关联数量等于发货通知单数量就是全部出库了
boolean allunverify = true;
DynamicObjectCollection billentrys = deliveryNotice.getDynamicObjectCollection("billentry");
for (DynamicObject billentry : billentrys) {
BigDecimal qty = billentry.getBigDecimal("qty");//数量
BigDecimal associatedqty = billentry.getBigDecimal("associatedqty");//关联数量
if (associatedqty.compareTo(qty) != 0) {
//未全部出库
allunverify = false;
}
}
if (allunverify) {
//销售出库单下推销售订单
Map<String, Object> param = new HashMap<>();
List<Long> salOutIds = new ArrayList<>();
salOutIds.add((Long) salOutBill.getPkValue());
String salOutRule = BotpParamUtils.getBotpRuleId(SALOUT, SALORDER, "OMS_销售出库单推发货方销售订单_转换规则");
PushArgs salOutPushArgs = BotpParamUtils.getPushArgs(SALOUT, SALORDER, param, salOutIds, salOutRule);
List<DynamicObject> saleOrders = BotpParamUtils.getDestObject(salOutPushArgs);
DynamicObject saleOrder = null;
//客户付款通知书 仅为保存状态
if (!saleOrders.isEmpty()) {
saleOrder = saleOrders.get(0);
try {
SaveServiceHelper.saveOperate(SALORDER, new DynamicObject[] {saleOrder}, OperateOption.create());
//销售订单为审核状态-走标准提交审核操作
StringBuilder message = new StringBuilder();
OperationResult submitResult = OperationServiceHelper.executeOperate("submit", SALORDER, new DynamicObject[]{saleOrder}, OperateOption.create());
if (submitResult.isSuccess()) {
//需重新查询一遍
saleOrder = BusinessDataServiceHelper.loadSingle(SALORDER,
new QFilter[]{new QFilter("id", QCP.equals, saleOrder.getPkValue())});
OperationResult auditResult = OperationServiceHelper.executeOperate("audit", SALORDER, new DynamicObject[]{saleOrder}, OperateOption.create());
if (!auditResult.isSuccess()) {
auditResult.getAllErrorOrValidateInfo().forEach((error) -> {
message.append(error.getMessage());
});
logger.info("Gy销售订单 " + salOutBill.get("number") + "审核 失败:" + message);
}
}else{
submitResult.getAllErrorOrValidateInfo().forEach((error) -> {
message.append(error.getMessage());
});
logger.info("Gy销售订单 " + salOutBill.get("number") + "提交 失败:" + message);
}
} catch (Exception ee) {
logger.info("Gy处理销售出库单" + salOutBill.get("number") + "下推销售订单出错:" + ee.getMessage());
}
}
}
}
}
}
}

View File

@ -0,0 +1,251 @@
package tqq9.lc123.cloud.app.plugin.task;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import kd.bos.coderule.api.CodeRuleInfo;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.botp.runtime.PushArgs;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.schedule.executor.AbstractTask;
import kd.bos.service.business.datamodel.DynamicFormModelProxy;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.util.StringUtils;
import kd.sdk.plugin.Plugin;
import tqq9.lc123.cloud.app.api.utils.GySaleReturnSyncMappingUtil;
import tqq9.lc123.cloud.app.api.utils.GyOpenApiUtil;
import tqq9.lc123.cloud.app.plugin.utils.BillCloseCancelUtils;
import tqq9.lc123.cloud.app.plugin.utils.BotpParamUtils;
import java.math.BigDecimal;
import java.util.*;
import static tqq9.lc123.cloud.app.plugin.form.result.CloneBill.cloneOperation;
/**
* 后台任务插件
* 定时获取OMS的退货单生成金蝶的销售退货申请单
*/
public class GySaleReturnSyncTask extends AbstractTask implements Plugin {
private static Log logger = LogFactory.getLog(GySaleReturnSyncTask.class);
private static String RETURNAPPLY = "sm_returnapply";
private static String SALOUT = "im_saloutbill";
private static String ADMINORG = "bos_adminorg";
private static String USER = "bos_user";
private static String BILLTYPE = "bos_billtype";
private static String BIZTYPE = "bd_biztype";
private static String CUSTOMER = "bd_customer";
private static String LINETYPE = "bd_linetype";
private static String MATERIALSALINFO = "bd_materialsalinfo";
private static String MEASUREUNITS = "bd_measureunits";
private static String INVOICEBIZTYPE = "bd_invoicebiztype";
private static String OPERATOR = "bd_operator";
private static String EXRATETABLE = "bd_exratetable";
private static String CURRENCY = "bd_currency";
@Override
public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
Map<String, Object> params = new HashMap<>();
//管易退货单列表接口
params.put("method", "gy.erp.trade.return.get");
Map<String, Object> listObjectMap = GyOpenApiUtil.buildRequestParams(params);
String listGuanyiApi = GyOpenApiUtil.callGuanyiApi(listObjectMap);
JSONObject listRoot = JSON.parseObject(listGuanyiApi);
//管易退货单详情接口-查询成功
if(listRoot.getBoolean("success")) {
JSONArray tradeReturns = listRoot.getJSONArray("tradeReturns");
//遍历逐个拿 code
for (int i = 0; i < tradeReturns.size(); i++) {
params = new HashMap<>();
//管易退货单详情接口
params.put("method", "gy.erp.trade.return.detail.get");
params.put("code", tradeReturns.getJSONObject(i).getString("code"));
Map<String, Object> stringObjectMap = GyOpenApiUtil.buildRequestParams(params);
String callGuanyiApi = GyOpenApiUtil.callGuanyiApi(stringObjectMap);
JSONObject callRoot = JSON.parseObject(listGuanyiApi);
//管易退货单详情-查询成功
if(callRoot.getBoolean("success")) {
try {
//解析处理
JsonNode tradeReturn = new ObjectMapper()
.readTree(callGuanyiApi)
.path("tradeReturn");
GySaleReturnSyncMappingUtil.parse(tradeReturn);
String api_gythdh = (String) GySaleReturnSyncMappingUtil.get("tqq9_gythdh");
String api_ptddh = (String) GySaleReturnSyncMappingUtil.get("tqq9_ptddh");
//判断该退货单是否生成金蝶的销售退货申请单
QFilter filter_gythdh = new QFilter("tqq9_gythdh", QCP.equals, api_gythdh);//退货单号
QFilter filter_ptddh = new QFilter("tqq9_ptddh", QCP.equals, api_ptddh);//平台单号
DynamicObject returnApply = BusinessDataServiceHelper.loadSingle(RETURNAPPLY,
"billno,tqq9_gyfhdh,tqq9_ptddh,tqq9_trading,tqq9_interstatus,org.*,tqq9_ck.*",
new QFilter[]{filter_gythdh, filter_ptddh});
//获取销售退货申请单信息
if (returnApply != null) {
Boolean api_isCancel = (Boolean) GySaleReturnSyncMappingUtil.get("isCancel");
//退货单状态为取消 更新平台交易状态并拦截发货
if (api_isCancel != null && api_isCancel) {
String billno = returnApply.getString("billno");//销售退货申请单编码
//拦截发货
Map<String, HashSet<Long>> targetBills = BFTrackerServiceHelper.findTargetBills(RETURNAPPLY, new Long[]{returnApply.getLong("id")});
//下游存在系统进行提示不允许后续操作
if (null != targetBills && targetBills.size() > 0 && targetBills.containsKey(SALOUT)) {
returnApply.set("tqq9_interstatus","fail");//拦截失败
logger.info(billno+":存在下游单据,不允许拦截");
}
String message = null;
DynamicObject org = returnApply.getDynamicObject("org");//收货组织
if (null != org) {
String number = org.getString("number");
if ("SHLC".equals(number)) {
String warehouseCode = null;
DynamicObject warehouse = returnApply.getDynamicObject("tqq9_ck");//仓库处理状态
if (null != warehouse) {
warehouseCode = warehouse.getString("number");
}
message = BillCloseCancelUtils.wmsCancel("PTCK", warehouseCode, billno, RETURNAPPLY, "WMS-SH-销售退货申请单取消", "tqq9_isclose");
}
if (StringUtils.isNotEmpty(message) && message.contains("关闭成功")) {
cloneOperation(returnApply, "销售退货申请单", RETURNAPPLY);
//克隆单据操作后原有单据已做删除处理需重新获取销售退货申请单
returnApply = BusinessDataServiceHelper.loadSingle(RETURNAPPLY, new QFilter[]{new QFilter("billno", QCP.equals, billno)});
returnApply.set("tqq9_interstatus","sucess");//拦截成功
}else if (StringUtils.isNotEmpty(message)) {
logger.info(billno+":"+message);
returnApply.set("tqq9_interstatus","fail");//拦截失败
}
}
returnApply.set("tqq9_trading","TRADE_FINISHED");//交易关闭
SaveServiceHelper.save(new DynamicObject[]{returnApply});
}
}else{
//通过退货单新增销售退货申请单
DynamicFormModelProxy modelProxy = new DynamicFormModelProxy(RETURNAPPLY, UUID.randomUUID().toString(), new HashMap<>());
DynamicObject newreturnApply = (DynamicObject) modelProxy.createNewData();
//默认数据
DynamicObject org = BusinessDataServiceHelper.loadSingle(ADMINORG,
new QFilter[]{new QFilter("number", QCP.equals, "SHLC")});//固定销售组织为SHLC
newreturnApply.set("org",org);//固定销售组织为SHLC
CodeRuleInfo rule = CodeRuleServiceHelper.getCodeRule(RETURNAPPLY, newreturnApply, null);// 获取本单据的编码规则
String billno = CodeRuleServiceHelper.getNumber(rule, newreturnApply);// 通过编码规则获取单据编号
newreturnApply.set("billno", billno);//单据编码
newreturnApply.set("billstatus","A");//单据状态
DynamicObject bd_billtype = BusinessDataServiceHelper.loadSingle(BILLTYPE,
new QFilter[]{new QFilter("number", QCP.equals, "sm_returnapply_BT_S")});//默认标准销售退货申请单
newreturnApply.set("billtype",bd_billtype);//单据类型
DynamicObject bd_biztype = BusinessDataServiceHelper.loadSingle(BIZTYPE,
new QFilter[]{new QFilter("number", QCP.equals, "2101")});//默认物料类销售退货退款
newreturnApply.set("biztype",bd_biztype);//业务类型
newreturnApply.set("tqq9_shsqrq",new Date());//售后申请日期
newreturnApply.set("closestatus","A");//关闭状态-正常
//当前用户
long userId = RequestContext.get().getCurrUserId();
//查询用户所属部门
long deptId = UserServiceHelper.getUserMainOrgId(Long.valueOf(userId));
DynamicObject deptOrg = BusinessDataServiceHelper.loadSingle(ADMINORG,
new QFilter[]{new QFilter("id", QCP.equals, deptId)});
newreturnApply.set("tqq9_dept",deptOrg);//创建人部门
newreturnApply.set("exchangerate",1);//汇率-默认
DynamicObject bd_exratetable = BusinessDataServiceHelper.loadSingle(EXRATETABLE,
new QFilter[]{new QFilter("number", QCP.equals, "ERT-01")});//默认
newreturnApply.set("exratetable",bd_exratetable);//汇率表
DynamicObject bd_currency = BusinessDataServiceHelper.loadSingle(CURRENCY,
new QFilter[]{new QFilter("number", QCP.equals, "CNY")});//默认
newreturnApply.set("currency",bd_currency);//本位币
newreturnApply.set("settlecurrency",bd_currency);//结算币
//接口数据
newreturnApply.set("tqq9_gythdh",api_gythdh);//管易退货单号
newreturnApply.set("tqq9_ptddh",api_ptddh);//平台订单号
newreturnApply.set("tqq9_lydh",GySaleReturnSyncMappingUtil.get("tqq9_lydh"));//销售订单号
String api_customer = (String) GySaleReturnSyncMappingUtil.get("customer");//订货客户-名称
//----------------------测试给值 上海励齿--待改动
DynamicObject bd_customer = BusinessDataServiceHelper.loadSingle(CUSTOMER,
new QFilter[]{new QFilter("name", QCP.equals, "上海励齿")});
newreturnApply.set("customer",bd_customer);//订货客户
newreturnApply.set("tqq9_fptt",bd_customer);//发票抬头
//---------------------测试给值
// 物料明细 details
DynamicObjectCollection billentry = newreturnApply.getDynamicObjectCollection("billentry");
billentry.clear();
List<Object> details = (List<Object>) GySaleReturnSyncMappingUtil.get("details");
if (details != null && !details.isEmpty()) {
for (int j = 0; j < details.size(); j++) {
Object row = details.get(j);
Map<String, Object> rowMap = (Map<String, Object>) row;
//新增分录
DynamicObject newEntry = new DynamicObject(billentry.getDynamicObjectType());
DynamicObject bd_linetype = BusinessDataServiceHelper.loadSingle(LINETYPE,
new QFilter[]{new QFilter("number", QCP.equals, "010")});//默认物资
newEntry.set("linetype", bd_linetype);//行类型
String api_material = (String) rowMap.get("material");//物料-编码
DynamicObject bd_materialsalinfo = BusinessDataServiceHelper.loadSingle(MATERIALSALINFO,
new QFilter[]{new QFilter("masterid.number", QCP.equals, api_material)});//物料查询
newEntry.set("material", bd_materialsalinfo);//物料
if (bd_materialsalinfo!=null) newEntry.set("materialmasterid", bd_materialsalinfo.get("masterid"));//主物料
if (bd_materialsalinfo!=null) newEntry.set("materialname", bd_materialsalinfo.get("masterid.name"));//物料名称
if (bd_materialsalinfo!=null) newEntry.set("unit", bd_materialsalinfo.get("salesunit"));//计量单位
newEntry.set("qty", rowMap.get("qty"));//数量
newEntry.set("baseqty", rowMap.get("qty"));//基本数量
newEntry.set("amount", rowMap.get("amount"));//金额
newEntry.set("price", rowMap.get("price"));//单价
newEntry.set("salesorg", org);//销售组织
newEntry.set("entrysettleorg", org);//结算组织
newEntry.set("entryinvorg", org);//发货组织
newEntry.set("discounttype", "NULL");//折扣方式
newEntry.set("ownertype", "bos_org");//货主类型
newEntry.set("rowclosestatus", "A");//行关闭状态
billentry.add(newEntry);
}
}
SaveServiceHelper.save(new DynamicObject[]{newreturnApply});
//销售退货申请单为审核状态-走标准提交审核操作
StringBuilder message = new StringBuilder();
// OperationResult submitResult = OperationServiceHelper.executeOperate("submit", RETURNAPPLY, new DynamicObject[]{newreturnApply}, OperateOption.create());
// if (submitResult.isSuccess()) {
// OperationResult auditResult = OperationServiceHelper.executeOperate("audit", RETURNAPPLY, new DynamicObject[]{newreturnApply}, OperateOption.create());
// if (!auditResult.isSuccess()) {
// auditResult.getAllErrorOrValidateInfo().forEach((error) -> {
// message.append(error.getMessage());
// });
// logger.info("Gy销售退货申请单 " + billno + "审核 失败:" + message);
// }
// }else{
// submitResult.getAllErrorOrValidateInfo().forEach((error) -> {
// message.append(error.getMessage());
// });
// logger.info("Gy销售退货申请单 " + billno + "提交 失败:" + message);
// }
}
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
}
}
}