From 719ec4e8f6389496f760b3196a242f41992e4ee6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Sun, 20 Sep 2026 16:05:54 +0800
Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E5=AE=A2=E5=95=86=E6=A1=A3?=
=?UTF-8?q?=E6=A1=88=E5=90=8C=E6=AD=A5=E9=87=91=E8=9D=B6=E5=AE=8C=E5=96=84?=
=?UTF-8?q?=EF=BC=9A=E4=BC=99=E4=BC=B4=E7=B1=BB=E5=9E=8B=E6=8C=89=E5=AE=A2?=
=?UTF-8?q?=E5=95=86=E6=80=A7=E8=B4=A8=E5=AD=97=E5=85=B8=E8=A7=A3=E6=9E=90?=
=?UTF-8?q?=E3=80=81=E6=8E=A8=E9=80=81=E9=93=B6=E8=A1=8C/=E8=81=94?=
=?UTF-8?q?=E7=B3=BB=E4=BA=BA=E5=88=86=E5=BD=95=E3=80=81BFI=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE=E6=8A=BD=E5=8F=96BfiProperties?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../common/feign/CustomFeignLogger.java | 14 +-
.../transport/config/BfiProperties.java | 80 ++
.../constant/CustomerBfiConstants.java | 30 +-
.../controller/CustomerArchiveController.java | 10 +
.../impl/CustomerArchiveServiceImpl.java | 51 ++
.../service/impl/CustomerBfiConverter.java | 165 +++-
.../impl/PaymentApplicationServiceImpl.java | 27 +-
.../support/KingdeeApBillSyncSupport.java | 13 +-
.../thirdparty/bfi/constant/BfiConstant.java | 5 +
...业财融合-集成流程图文字版与业务流程梳理.md | 817 ++++++++++++++++++
doc/docs/TMS业财融合方案.docx | Bin 0 -> 4090790 bytes
...Œ步金蝶(A902-1查询回填+A902-2审批推送)技术文档.md | 62 +-
...路业务流程(A102-2保存-A102-4查询-A103-1下推-A103-2回写).md | 334 +++++++
doc/docs/业财融合系统接口文档.xlsx | Bin 0 -> 5646196 bytes
doc/docs/客商填报审核编码规范.xlsx | Bin 0 -> 16145 bytes
doc/nacos/blade-dev.yaml | 14 +-
doc/nacos/blade-prod.yaml | 4 +-
doc/nacos/third-party-api.yaml | 4 +-
18 files changed, 1513 insertions(+), 117 deletions(-)
create mode 100644 blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
create mode 100644 doc/docs/TMS业财融合-集成流程图文字版与业务流程梳理.md
create mode 100644 doc/docs/TMS业财融合方案.docx
create mode 100644 doc/docs/业务流程/2026-09-20-应付单与付款申请同步金蝶全链路业务流程(A102-2保存-A102-4查询-A103-1下推-A103-2回写).md
create mode 100644 doc/docs/业财融合系统接口文档.xlsx
create mode 100644 doc/docs/客商填报审核编码规范.xlsx
diff --git a/blade-common/src/main/java/org/springblade/common/feign/CustomFeignLogger.java b/blade-common/src/main/java/org/springblade/common/feign/CustomFeignLogger.java
index f22a743d..cfbf7724 100644
--- a/blade-common/src/main/java/org/springblade/common/feign/CustomFeignLogger.java
+++ b/blade-common/src/main/java/org/springblade/common/feign/CustomFeignLogger.java
@@ -70,7 +70,7 @@ public class CustomFeignLogger extends Logger {
bodyStr = new String(body, StandardCharsets.UTF_8);
}
- log.info("===> [{}] {} {} | Headers: {} | Body: {}", configKey, method, url, headers, bodyStr);
+ log.info("===> [{}] {} {} | Headers: {} | Body: {}", configKey, method, url, headers, flattenBody(bodyStr));
}
@Override
@@ -94,11 +94,21 @@ public class CustomFeignLogger extends Logger {
bodyStr = new String(bodyData, StandardCharsets.UTF_8);
}
- log.info("<==== [{}] {} | Status: {} | Duration: {}ms | Body: {}", configKey, url, status, millis, bodyStr);
+ log.info("<==== [{}] {} | Status: {} | Duration: {}ms | Body: {}", configKey, url, status, millis, flattenBody(bodyStr));
return response.toBuilder().body(bodyData).build();
}
+ /**
+ * 将报文内容压缩为单行显示(换行、回车、制表符等空白序列替换为单个空格)
+ */
+ private String flattenBody(String bodyStr) {
+ if (bodyStr == null) {
+ return null;
+ }
+ return bodyStr.replaceAll("\\s+", " ").trim();
+ }
+
/**
* 获取Content-Type
*/
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
new file mode 100644
index 00000000..61d1dbef
--- /dev/null
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/config/BfiProperties.java
@@ -0,0 +1,80 @@
+/**
+ * BladeX Commercial License Agreement
+ * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
+ *
+ * Use of this software is governed by the Commercial License Agreement
+ * obtained after purchasing a license from BladeX.
+ *
+ * 1. This software is for development use only under a valid license
+ * from BladeX.
+ *
+ * 2. Redistribution of this software's source code to any third party
+ * without a commercial license is strictly prohibited.
+ *
+ * 3. Licensees may copyright their own code but cannot use segments
+ * from this software for such purposes. Copyright of this software
+ * remains with BladeX.
+ *
+ * Using this software signifies agreement to this License, and the software
+ * must not be used for illegal purposes.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
+ * not liable for any claims arising from secondary or illegal development.
+ *
+ * Author: Chill Zhuang (bladejava@qq.com)
+ */
+package org.springblade.transport.config;
+
+import lombok.Data;
+import org.springblade.thirdparty.bfi.constant.BfiConstant;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 业财融合(BFI)推送金蝶配置属性,统一收口 Nacos 配置 thirdParty.bfi.*:
+ *
+ * srcSys 为客商、付款申请等各业务推送金蝶的公共参数(外部系统编号);
+ * customer、payApply 为各业务专属参数;未配置时使用字段默认值。
+ *
+ * prefix 须为全小写(thirdparty.bfi),Spring 宽松绑定可匹配 Nacos 中的 camelCase 键(thirdParty.payApply.srcSys 等)。
+ *
+ * @author Chill
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "thirdparty.bfi")
+public class BfiProperties {
+
+ /**
+ * 数据来源系统编码(公共):客商、付款申请等推送金蝶时统一使用,默认 WLTMS(运输TMS)
+ */
+ private String srcSys = BfiConstant.DATA_SOURCE_WLTMS;
+
+ /**
+ * 付款申请推送配置(A103-3 付款申请保存)
+ */
+ private PayApply payApply = new PayApply();
+
+ /**
+ * 付款申请推送配置项
+ */
+ @Data
+ public static class PayApply {
+
+ /**
+ * 单据类型编码:ap_payapply_BT_S 付款申请单、ap_payapply_oth_BT_S 其他付款单,默认其他付款单
+ */
+ private String billtype = "ap_payapply_oth_BT_S";
+
+ /**
+ * 汇率表编码,默认 01
+ */
+ private String exratetable = "01";
+
+ /**
+ * 外部单据类型,默认 0KzXs
+ */
+ private String srcType = "0KzXs";
+ }
+
+}
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/CustomerBfiConstants.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/CustomerBfiConstants.java
index 6725a436..712643da 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/CustomerBfiConstants.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/constant/CustomerBfiConstants.java
@@ -25,8 +25,6 @@
*/
package org.springblade.transport.constant;
-import java.util.Map;
-
/**
* 客商档案金蝶(星瀚)协同常量
*
@@ -40,29 +38,25 @@ public class CustomerBfiConstants {
public static final String BIZ_FUNCTION_ALL = "1,2,3,4";
/**
- * 推送金蝶固定值:伙伴类型兜底编码(民营企业),客商性质未命中映射时使用
+ * 客商类型:内部组织(customer_kind 字段值)
*/
- public static final String DEFAULT_PARTNER_TYPE = "6";
+ public static final String CUSTOMER_KIND_INTERNAL = "internal";
+
+ /**
+ * 客商类型:外部客商(customer_kind 字段值)
+ */
+ public static final String CUSTOMER_KIND_EXTERNAL = "external";
+
+ /**
+ * 金蝶伙伴类型编码有效范围上界(BfiCustomerSaveDTO.type 全集 1~17)
+ */
+ public static final int PARTNER_TYPE_MAX = 17;
/**
* 营业期限类型:长期(TMS 表单文本)
*/
public static final String BUSINESS_TERM_LONG = "长期";
- /**
- * 客商性质(nature_of_client 字典 dictKey)→ 金蝶伙伴类型编码
- * 键名以数据库字典 nature_of_client 实际 dictKey 为准核对;未命中走 DEFAULT_PARTNER_TYPE
- */
- public static final Map NATURE_TYPE_MAPPING = Map.of(
- "企业法人", "1",
- "个人", "4",
- "个体工商户", "5",
- "民营企业", "6",
- "国有企业", "8",
- "政府事业单位", "9",
- "其他", "12"
- );
-
private CustomerBfiConstants() {
}
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java
index 3c44fd00..07c55e02 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CustomerArchiveController.java
@@ -193,6 +193,16 @@ public class CustomerArchiveController extends BladeController {
return R.data(customerArchiveService.syncKingdee(id));
}
+ /**
+ * 金蝶客商数据定时同步测试入口:手动触发 syncKingdeeCustomerData 定时任务逻辑,便于联调验证
+ */
+ @PostMapping("/sync-kingdee-data-test")
+ @ApiOperationSupport(order = 13)
+ @Operation(summary = "金蝶客商数据同步测试", description = "手动触发定时任务逻辑:自动推送待推送客商(approved 且 none/failed),并联动已同步客商的金蝶使用状态")
+ public R syncKingdeeCustomerDataTest() {
+ return R.data(customerArchiveService.syncKingdeeCustomerData());
+ }
+
/**
* 评分明细模板
*/
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java
index 96eb5cdd..815ae544 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerArchiveServiceImpl.java
@@ -116,18 +116,69 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class CustomerArchiveServiceImpl extends BaseServiceImpl implements ICustomerArchiveService {
+ /**
+ * 状态:启用
+ */
private static final int STATUS_ENABLED = 1;
+
+ /**
+ * 状态:停用
+ */
private static final int STATUS_DISABLED = 2;
+
+ /**
+ * 准入类型:临时
+ */
private static final String ACCESS_TEMPORARY = "temporary";
+
+ /**
+ * 准入类型:正式
+ */
private static final String ACCESS_FORMAL = "formal";
+
+ /**
+ * 审批状态:草稿
+ */
private static final String APPROVAL_DRAFT = "draft";
+
+ /**
+ * 审批状态:审核中
+ */
private static final String APPROVAL_REVIEWING = "reviewing";
+
+ /**
+ * 审批状态:审批通过
+ */
private static final String APPROVAL_APPROVED = "approved";
+
+ /**
+ * 审批状态:审批驳回
+ */
private static final String APPROVAL_REJECTED = "rejected";
+
+ /**
+ * 金蝶协同状态:未推送(新增客商默认值,审批通过后参与推送)
+ */
private static final String KINGDEE_STATUS_NONE = "none";
+
+ /**
+ * 金蝶协同状态:金蝶已有档案(A902-1 查到已审核,审批通过后跳过推送,终态)
+ */
private static final String KINGDEE_STATUS_EXIST = "exist";
+
+ /**
+ * 金蝶协同状态:已推送成功(终态,重推时幂等跳过)
+ */
private static final String KINGDEE_STATUS_SYNCED = "synced";
+
+ /**
+ * 金蝶协同状态:推送失败 / 金蝶审核中(可列表「同步金蝶」人工重推)
+ */
private static final String KINGDEE_STATUS_FAILED = "failed";
+
+ /**
+ * 客商编号前缀
+ */
private static final String CUSTOMER_CODE_PREFIX = "KS";
/**
* A902-1 批量查询分批大小
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerBfiConverter.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerBfiConverter.java
index 941c96b2..39ec4c15 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerBfiConverter.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/CustomerBfiConverter.java
@@ -26,16 +26,18 @@
package org.springblade.transport.service.impl;
import lombok.RequiredArgsConstructor;
+import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringUtil;
import org.springblade.system.cache.DictBizCache;
import org.springblade.system.pojo.entity.DictBiz;
import org.springblade.thirdparty.bfi.constant.BfiConstant;
+import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerBankEntryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerGroupEntryDTO;
+import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerLinkmanEntryDTO;
import org.springblade.thirdparty.bfi.pojo.dto.BfiCustomerSaveDTO;
+import org.springblade.transport.config.BfiProperties;
import org.springblade.transport.constant.CustomerBfiConstants;
import org.springblade.transport.pojo.vo.CustomerArchiveVO;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
@@ -52,17 +54,7 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class CustomerBfiConverter {
- /**
- * 数据来源系统编码,默认 WLTMS(运输TMS)
- */
- @Value("${thirdParty.bfi.customer.srcSys:WLTMS}")
- private String srcSys;
-
- /**
- * 创建组织.编码,默认 WLTMS,需与财务确认
- */
- @Value("${thirdParty.bfi.customer.createOrg:WLTMS}")
- private String createOrg;
+ private final BfiProperties bfiProperties;
/**
* 组装 A902-2 客户保存参数
@@ -72,44 +64,161 @@ public class CustomerBfiConverter {
*/
public BfiCustomerSaveDTO buildSaveDTO(CustomerArchiveVO customer) {
BfiCustomerSaveDTO param = new BfiCustomerSaveDTO();
- // 金蝶客户编码与 TMS 客商编号保持一致
+ // 编码:不传由星瀚生成;金蝶客户编码与 TMS 客商编号保持一致
param.setNumber(customer.getCustomerCode());
- param.setStatus(BfiConstant.BILL_STATUS_SUBMITTED);
+ // 数据状态:固定传 B 已提交,金蝶校验工商信息通过后由机器人自动审核
+ // param.setStatus(BfiConstant.BILL_STATUS_SUBMITTED);
+ // 【必填】名称:客商名称
param.setName(customer.getFullName());
+ // 【必填】统一社会信用代码(候选键):个人为身份证号或手机号
param.setSocietycreditcode(customer.getUnifiedCreditCode());
+ // 纳税人识别号:与统一社会信用代码一致时推送
param.setTxRegisterNo(customer.getUnifiedCreditCode());
+ // 法人代表:企业法人
param.setArtificialperson(customer.getLegalPerson());
- param.setType(resolvePartnerType(customer.getCustomerNature()));
+ // 【必填】伙伴类型:客商性质字典 dictKey 即伙伴类型编码,直接推送,无效编码抛异常
+ param.setType(this.resolvePartnerType(customer.getCustomerNature()));
+ // 详细地址:注册地址(省市区 + 详细地址拼接文本)
param.setBizpartnerAddress(customer.getRegisteredAddress());
- param.setBusinessscope(buildBusinessScopeText(customer.getBusinessScope()));
- param.setBusinessterm(buildBusinessTerm(customer.getBusinessTermType(), customer.getBusinessEndDate()));
+ // 经营范围:多选编码 → 字典文本「、」拼接
+ param.setBusinessscope(this.buildBusinessScopeText(customer.getBusinessScope()));
+ // 营业期限:长期传「长期」,固定期限传「至 yyyy-MM-dd」(TMS 未采集起始日)
+ param.setBusinessterm(this.buildBusinessTerm(customer.getBusinessTermType(), customer.getBusinessEndDate()));
+ // 联系电话:客商联系电话
param.setBizpartnerPhone(customer.getContactPhone());
+ // 备注:客商备注,空时不传
param.setFcusbeizhu(customer.getRemark());
+ // 业务职能:固定全选(1销售,2结算,3付款,4收货)
param.setBizfunction(CustomerBfiConstants.BIZ_FUNCTION_ALL);
- param.setAwrpDatasourcesys(srcSys);
+ // 数据来源系统:thirdParty.bfi.srcSys(公共参数),默认 WLTMS(运输TMS)
+ param.setAwrpDatasourcesys(bfiProperties.getSrcSys());
+ // 【必填】是否为贸易客商:固定传 A 是
param.setAwrpCusfortrade(BfiConstant.CUS_FOR_TRADE_YES);
- param.setCreateorgNumber(createOrg);
+ // 【必填】分类标准分录:外部客商 1102、内部组织 1101
BfiCustomerGroupEntryDTO groupEntry = new BfiCustomerGroupEntryDTO();
groupEntry.setStandardidNumber(BfiConstant.GROUP_STANDARD_BASIC);
- groupEntry.setGroupidNumber(BfiConstant.CUSTOMER_GROUP_EXTERNAL);
+ groupEntry.setGroupidNumber(this.resolveGroupId(customer.getCustomerKind()));
param.setEntryGroupstandard(List.of(groupEntry));
+ // 银行信息分录:收款账户明细(账户名称传开户行,币种默认 RMB)
+ param.setEntryBank(this.buildBankEntries(customer));
+ // 联系人信息分录:页面填写的客商负责人与联系电话
+ param.setEntryLinkman(this.buildLinkmanEntries(customer));
return param;
}
/**
- * 客商性质(字典 dictKey)→ 金蝶伙伴类型编码,未命中走兜底值
+ * 解析分类标准分录客户分组编码:内部组织 1101,其余(外部客商)1102
*
- * @param customerNature 客商性质字典值
+ * @param customerKind 客商类型(internal 内部组织 / external 外部客商)
+ * @return 客户分组编码
+ */
+ private String resolveGroupId(String customerKind) {
+ if (CustomerBfiConstants.CUSTOMER_KIND_INTERNAL.equals(customerKind)) {
+ return BfiConstant.CUSTOMER_GROUP_INTERNAL;
+ }
+ return BfiConstant.CUSTOMER_GROUP_EXTERNAL;
+ }
+
+ /**
+ * 组装 A902-2 银行信息分录:每条收款账户一行分录,账户名称传开户行、币种默认 RMB,收款账户未填写时返回空分录
+ *
+ * @param customer 客商档案
+ * @return 银行信息分录
+ */
+ private List buildBankEntries(CustomerArchiveVO customer) {
+ if (Func.isEmpty(customer.getReceiptAccounts())) {
+ return List.of();
+ }
+ return customer.getReceiptAccounts().stream()
+ .filter(account -> Func.isNotBlank(account.getBankAccount()) || Func.isNotBlank(account.getBankName()))
+ .map(account -> {
+ BfiCustomerBankEntryDTO entry = new BfiCustomerBankEntryDTO();
+ // 银行账号
+ entry.setBankaccount(account.getBankAccount());
+ // 账户名称:传开户行
+ entry.setAccountname(account.getBankName());
+ // 开户银行.编码(行号) todo
+ entry.setBankNumber("001110012009");
+ // 币种:人民币(CNY)
+ entry.setCurrencyNumber(BfiConstant.CURRENCY_CNY);
+ // 是否默认银行
+ entry.setIsdefaultBank(true);
+ return entry;
+ })
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * 组装 A902-2 联系人信息分录:页面填写的客商负责人与联系电话,未填负责人时返回空分录
+ *
+ * @param customer 客商档案
+ * @return 联系人信息分录
+ */
+ private List buildLinkmanEntries(CustomerArchiveVO customer) {
+ if (Func.isBlank(customer.getPrincipal())) {
+ return List.of();
+ }
+ BfiCustomerLinkmanEntryDTO entry = new BfiCustomerLinkmanEntryDTO();
+ // 联系人:客商负责人
+ entry.setContactperson(customer.getPrincipal());
+ // 电话:联系电话
+ entry.setPhone(customer.getContactPhone());
+ // 默认联系人
+ entry.setIsdefaultLinkman(Boolean.TRUE);
+ return List.of(entry);
+ }
+
+ /**
+ * 金蝶伙伴类型编码:客商性质(nature_of_client 字典)——
+ * 值为 dictKey(即伙伴类型编码,1~17)时直接使用;
+ * 值为 dictValue 文本(前端字典下拉存文本,含存量数据,如「我区国企/国企控股」)时按字典反查对应 dictKey;
+ * 均无法解析时抛出异常,阻断推送
+ *
+ * @param customerNature 客商性质(dictKey 编码或 dictValue 文本)
* @return 金蝶伙伴类型编码
*/
public String resolvePartnerType(String customerNature) {
- if (Func.isNotEmpty(customerNature)) {
- String partnerType = CustomerBfiConstants.NATURE_TYPE_MAPPING.get(customerNature.trim());
- if (StringUtil.isNotBlank(partnerType)) {
- return partnerType;
+ String nature = Func.isEmpty(customerNature) ? "" : customerNature.trim();
+ if (nature.matches("\\d{1,2}")) {
+ int partnerType = Integer.parseInt(nature);
+ if (partnerType >= 1 && partnerType <= CustomerBfiConstants.PARTNER_TYPE_MAX) {
+ return nature;
}
}
- return CustomerBfiConstants.DEFAULT_PARTNER_TYPE;
+ String partnerType = this.resolvePartnerTypeFromDictValue(nature);
+ if (Func.isBlank(partnerType)) {
+ throw new ServiceException("客商性质未配置有效的金蝶伙伴类型编码(nature_of_client 字典 dictKey):" + customerNature);
+ }
+ return partnerType;
+ }
+
+ /**
+ * 按客商性质文本(dictValue)反查 nature_of_client 字典,返回对应 dictKey(即伙伴类型编码)
+ *
+ * @param natureValue 客商性质文本
+ * @return 金蝶伙伴类型编码,未命中返回 null
+ */
+ private String resolvePartnerTypeFromDictValue(String natureValue) {
+ if (Func.isEmpty(natureValue)) {
+ return null;
+ }
+ List dictList = DictBizCache.getList("nature_of_client");
+ if (dictList == null) {
+ return null;
+ }
+ return dictList.stream()
+ .filter(dict -> natureValue.equals(dict.getDictValue()))
+ .map(DictBiz::getDictKey)
+ .map(key -> Func.isEmpty(key) ? "" : key.trim())
+ .filter(key -> {
+ if (!key.matches("\\d{1,2}")) {
+ return false;
+ }
+ int partnerType = Integer.parseInt(key);
+ return partnerType >= 1 && partnerType <= CustomerBfiConstants.PARTNER_TYPE_MAX;
+ })
+ .findFirst()
+ .orElse(null);
}
/**
diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java
index 6a70d8bc..ff3bc356 100644
--- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java
+++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PaymentApplicationServiceImpl.java
@@ -82,6 +82,7 @@ import org.springblade.transport.pojo.entity.PaymentApplicationRecord;
import org.springblade.transport.pojo.entity.PaymentApplicationSettlement;
import org.springblade.transport.pojo.entity.PreSettlement;
import org.springblade.transport.pojo.entity.PreSettlementAdvance;
+import org.springblade.transport.config.BfiProperties;
import org.springblade.transport.pojo.entity.ProjectApply;
import org.springblade.transport.pojo.entity.TemporaryCreditLimit;
import org.springblade.transport.pojo.vo.PaymentApplicationReferenceAmountVO;
@@ -91,7 +92,6 @@ import org.springblade.transport.service.IPaymentApplicationService;
import org.springblade.transport.service.KingdeeSyncContext;
import org.springblade.transport.support.KingdeeApBillSyncSupport;
import org.springblade.transport.wrapper.PaymentApplicationWrapper;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -144,14 +144,7 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl selectPage(IPage page, PaymentApplicationVO query) {
@@ -678,7 +671,7 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl queryPayApplyPages(List awrpSrcCodes) {
BfiPayApplyQueryDTO param = new BfiPayApplyQueryDTO();
param.setAwrpSrcCode(awrpSrcCodes);
- param.setAwrpSrcSys(bfiPayApplySrcSys);
+ param.setAwrpSrcSys(bfiProperties.getSrcSys());
return BfiUtil.queryAllPages(pageNo -> {
param.setPageNo(pageNo);
param.setPageSize(PAY_RESULT_PAGE_SIZE);
@@ -849,9 +842,9 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl {
BfiApBillQueryDTO param = new BfiApBillQueryDTO();
param.setAwrpSrcCode(batch);
- param.setAwrpSrcSys(bfiPayApplySrcSys);
+ param.setAwrpSrcSys(bfiProperties.getSrcSys());
for (BfiApBillVO apBill : BfiUtil.queryAllPages(pageNo -> {
param.setPageNo(pageNo);
param.setPageSize(PAY_RESULT_PAGE_SIZE);
@@ -178,7 +177,7 @@ public class KingdeeApBillSyncSupport {
return context.apBillPlanCodeCache().computeIfAbsent(apBillSrcCode, code -> {
BfiApBillQueryDTO param = new BfiApBillQueryDTO();
param.setAwrpSrcCode(List.of(code));
- param.setAwrpSrcSys(bfiPayApplySrcSys);
+ param.setAwrpSrcSys(bfiProperties.getSrcSys());
List bills = BfiUtil.queryAllPages(pageNo -> {
param.setPageNo(pageNo);
param.setPageSize(PAY_RESULT_PAGE_SIZE);
@@ -262,7 +261,7 @@ public class KingdeeApBillSyncSupport {
param.setIspricetotal(true);
param.setIsintax(false);
// 汇率表.编码(非必传)
- // param.setExratetableNumber(bfiPayApplyExratetable);
+ // param.setExratetableNumber(bfiProperties.getPayApply().getExratetable());
// 汇率日期(非必传)
// param.setExratedate(billDateText);
// 往来单位名称(非必传)
@@ -270,7 +269,7 @@ public class KingdeeApBillSyncSupport {
// 备注(非必传)
// param.setRemark(subject);
// 【必填】外部系统编号(候选键)
- param.setAwrpSrcSys(bfiPayApplySrcSys);
+ param.setAwrpSrcSys(bfiProperties.getSrcSys());
// 【必填】外部系统来源单据号(候选键):正式结算单号_结算明细单据号1_单据号2...(复用预检已组装的防重键)
param.setAwrpSrcCode(apBillSrcCode);
// 来源单据(非必传,有上游合同时传 awrp_contract_info)
diff --git a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/constant/BfiConstant.java b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/constant/BfiConstant.java
index b462424d..0103f77c 100644
--- a/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/constant/BfiConstant.java
+++ b/blade-third-party-api/blade-bfi-api/src/main/java/org/springblade/thirdparty/bfi/constant/BfiConstant.java
@@ -285,6 +285,11 @@ public class BfiConstant {
*/
public static final String CUSTOMER_GROUP_EXTERNAL = "1102";
+ /**
+ * 客户分类:内部组织
+ */
+ public static final String CUSTOMER_GROUP_INTERNAL = "1101";
+
/**
* 币种:人民币
*/
diff --git a/doc/docs/TMS业财融合-集成流程图文字版与业务流程梳理.md b/doc/docs/TMS业财融合-集成流程图文字版与业务流程梳理.md
new file mode 100644
index 00000000..118228f6
--- /dev/null
+++ b/doc/docs/TMS业财融合-集成流程图文字版与业务流程梳理.md
@@ -0,0 +1,817 @@
+# TMS 业财融合 —— 集成流程图文字版与业务流程梳理
+
+> **文档来源**:对 `项目/文档` 目录下 6 张集成流程图(jpg/png)逐图 OCR 提取 + 人工校对后整理。
+> **交叉核对资料**:`合同业财接口排期.xlsx`(场景及流程图说明、接口导航)、`合同业财接口清单.xlsx`、`桂物合同集成相关接口说明-v4.docx`、`TMS业财融合-业务流程与接口梳理.md`。
+> **整理日期**:2026-09-14
+
+---
+
+## 0. 文档说明
+
+### 0.1 覆盖的图片
+
+| 序号 | 图片文件 | 图题/流程块 | 对应集成场景 |
+|---|---|---|---|
+| 01 | `01_客户新增与查询.jpg` | 模式一:有业务系统,ERP+合同合规系统+金蝶星瀚集成;块:客商新建 / 客商更新 | SC-01 客商主数据协同(含供应商查询) |
+| 02 | `02_合同新增及同步.jpeg` | 合同新建/变更 | SC-03 合同主数据协同(含 SC-02 项目) |
+| 03 | `03_财务应付及付款.jpg` | 付款单新增 / 反审核及删除 | SC-04 对公付款(应付+付款) |
+| 04 | `04_财务应收及开票.png` | 开票申请 | SC-08 销项开票(应收+开票) |
+| 05 | `05_付款-收票查询及认领.png` | 收票单新增/变更 | SC-05 进项收票 |
+| 06 | `收款查询及认领.jpg` | 收款认领 | SC-07 回款认领 |
+
+### 0.2 四栏(泳道)定义
+
+6 张图统一为同一张表格结构,表头固定为:
+
+| 栏位 | 含义 | 职责 |
+|---|---|---|
+| 备注 | 集成说明(集成方阅读用) | 描述该流程的目的、规则、限制 |
+| ERP | 业务系统(TMS/ERP) | 业务发起方,所有业务单据的产生与推送 |
+| 合同合规系统 | 集团合同合规系统 | 客商风险、合同、履约、付款合规校验与拦截 |
+| 司库/星瀚(经 IPASS 中转) | 金蝶云星瀚财务系统 | 应收应付、发票、资金收付、财务核算 |
+
+> 图示中 ERP 与金蝶之间标注 **"经 IPASS 中转"**,即 A 类接口调用统一走 iPaaS 网关(`/gwzh/BFI`),不直连。
+
+### 0.3 OCR 校对说明
+
+图片中流程图节点字号较小,OCR 存在个别错字。下表为已确认的识别误差与校正值,正文已统一采用校正后的写法:
+
+| 识别结果 | 校正为 | | 识别结果 | 校正为 |
+|---|---|---|---|---|
+| 金媒/金煤/金淋/金洪/金卦 | 金蝶 | | 足瀚/星洽/星溶/星避/早溶 | 星瀚 |
+| 客者/善商/容商/咨商 | 客商 | | 史新/更新客商微据 | 更新客商数据 |
+| 报据/来据 | 根据 | | 哈寻/音询 | 查询 |
+| 创理 | 创建 | | 业务单据锁定 | 业务单据锁定 |
+| 信B变更 | 信息变更 | | 新姓完成 | 新建完成 |
+| 只能审核 | 智能审核 | | 团增量客商数据 | 增量客商数据 |
+| 准送付款相关材料 | 推送付款相关材料 | | 豆是否通过 | 审查是否通过 |
+| 付款申请羊查询 | 付款申请单查询 | | 一失败 | 失败(连线标注) |
+
+> 泳道划分按文本框横向中心聚类得到,**靠近栏位边界的说明性标注(如接口编号气泡)可能与相邻栏位归属互换**,不影响流程时序的理解。
+
+---
+
+## 1. 集成全景
+
+```
+业务发起(ERP/TMS) 合规管控(合同合规系统) 财务核算(金蝶星瀚)
+客商 → 项目 → 合同 → 履约计划 ──► 风险等级校验 / 黑名单校验 ──► 客户/供应商、合同档案、
+ 应付单、应收单、发票、收付款
+应付结算 ─► 付款申请 ──► 额度校验 + 风险校验(不通过走特批) ─► 付款申请单 → 财务共享审批 → 付款
+应收结算 ─► 开票申请 ──► 开票单 + 履约监控 ──► 开票申请单 → 发票云开票
+进项收票 ─► 收票认领 ──► 收票记录 + 履约监控 ──► 收票单 → 指定应付单
+银行回款 ─► 回款二次认领 ──► 履约收款数据更新 ──► 收款单(金蝶先一次认领到客户)
+```
+
+贯穿全流程的三条硬约束:**无合规不结算、无合同不入账、无履约不付款**;高风险客商不特批不得签约、不得付款。
+
+---
+
+## 2. 图 01:客户新增与查询(客商主数据协同)
+
+- **图片文件**:`01_客户新增与查询.jpg`(3228×5791)
+- **图题**:模式一:有业务系统,ERP+合同合规系统+金蝶星瀚集成
+- **图内流程块**:客商新建(含客商数据定时同步子流程)、客商更新(含客商数据定时同步子流程)
+- **对应场景**:客商主数据协同;同批还包含"供应商查询(客户自行下推供应商)"
+
+**图 1 流程图(Mermaid,接口编号已标注在连线上)**
+
+```mermaid
+flowchart TD
+ subgraph ERP["ERP / TMS(业务系统)"]
+ e0(["开始"]) --> e1["录入统一社会信用代码"]
+ e1 --> d1{"金蝶是否已有该客商"}
+ d1 -->|"已审核:金蝶已创建该客户"| e2["获取金蝶工商信息"]
+ d1 -->|"暂存 / 已提交"| e3["提示:金蝶审核中,请稍后重新添加"]
+ e2 --> e4["填写客商业务信息"]
+ e4 --> e5["提交客商,走内部审批"]
+ e5 -->|"审批退回"| e4
+ e5 -->|"审批通过"| e6["推送客商工商信息"]
+ e6 --> d2{"客商合规性审核是否通过"}
+ d2 -->|"不通过"| e3
+ d2 -->|"通过"| e7(["新建完成:业务系统可使用该客商"])
+ e8["客商更新"] --> e9["工商 / 个人信息变更"]
+ e8 -->|"业务信息由 ERP 自行维护"| e11(["结束"])
+ e9 -->|"非接口,人工修改"| e10["人工审批通过后更新客商信息"]
+ e10 --> e11
+ e12["定时任务:获取全集 / 增量客商数据"] --> e13["更新客商数据与使用状态"]
+ e13 --> e14(["结束"])
+ end
+
+ subgraph HT["合同合规系统"]
+ h1["客商合规性审核
客商工商信息同步为相对方"]
+ end
+
+ subgraph JD["司库 / 星瀚(经 IPASS 中转)"]
+ j1["按统一社会信用代码查询是否已有该客商"]
+ j2["校验工商信息并创建客商
当前为机器人审核"]
+ j3["客户新增后自动下推供应商"]
+ end
+
+ e1 -->|"A902-1 客户查询"| j1
+ j1 --> d1
+ e6 -->|"A902-2 客商保存"| j2
+ j2 --> j3
+ d2 -.->|"合规性审核、企查查状态"| h1
+ e12 -->|"A902-1 客户查询 / A901-1 供应商查询"| j1
+```
+
+### 2.1 备注栏原文
+
+> **客商创建集成说明**
+>
+> 1、ERP 创建客户时查询金蝶是否已有该客商,如果已有,获取客商的工商信息(工商信息不允许业务系统变更,只在金蝶系统进行维护),补充客户业务信息。
+>
+> 2、如果 ERP 查询到金蝶尚无该客商,在业务系统新建客商,审核通过后同步客商工商信息到金蝶,金蝶校验工商信息通过后完成客商创建,业务系统可使用该客商。
+>
+> 3、业务系统创建成功客商后,同步客商工商信息到合同合规系统的相对方。
+
+### 2.2 泳道节点文字版
+
+**ERP 栏(客商新建)**
+
+开始 → 日常使用 → 录入统一社会信用代码 → 日常使用 → 提示"金蝶已创建该客户,将获取金蝶的工商信息" / 提示"金蝶审核中,请稍后重新添加" → 填写客商业务信息 → 获取金蝶的工商信息 → 审批通过,流程挂起 / 流程返回发起人修改 → 客商合规性审核 → 更新客商审核状态 → 审查是否通过 →(是)审批流程结束 → 新建完成 → 结束
+
+**ERP 栏(客商更新)**
+
+开始 → 业务信息变更(ERP 自行维护) / 工商/个人信息变更 → 人工审批通过 → 更新客商信息 → 结束
+
+**合同合规系统栏**
+
+星瀚接口:A902-1 客户查询接口;状态==已审核;状态==暂存;状态已提交;星瀚接口:A902-2 客商保存接口;星瀚接口:A902-1 客户查询接口 + A901-1_供应商查询
+
+**司库/星瀚栏**
+
+根据"统一社会信用代码"查询是否已有该客商 → 客商新建(客商状态:已提交) → 客商合规性审核 → 更新客商审核状态 → 金蝶客商工商信息及使用状态 → 更新工商/个人信息
+
+**客商数据定时同步子流程**(图中出现两次,挂在新建与更新之后)
+
+开始 → 定时获取全集/增量客商数据 → 调用星瀚接口 A902-1 客户查询接口、A901-1_供应商查询 → 获取金蝶客商工商信息及使用状态 → 更新客商数据 → 结束
+
+### 2.3 流程步骤还原
+
+| 步骤 | 责任方 | 动作 | 涉及接口 | 分支/条件 |
+|---|---|---|---|---|
+| 1 | ERP | 录入客商统一社会信用代码,发起客商新增 | A902-1 客户查询 | — |
+| 2 | 金蝶星瀚 | 按统一社会信用代码查询客商是否已存在 | A902-1 | — |
+| 3 | 金蝶星瀚 | 返回客商状态 | A902-1 | **已审核**:金蝶已有该客商 → 步 4;**暂存/已提交**:金蝶审核中,提示"请稍后重新添加",流程终止 |
+| 4 | ERP | 提示"金蝶已创建该客户",获取金蝶工商信息,补充填写客商业务信息 | A902-1(取工商信息) | 工商信息不可改,仅金蝶可维护 |
+| 5 | ERP | 提交客商,走内部审批 | A902-2 客商保存 | 审批通过 → 步 6;退回 → 返回发起人修改 |
+| 6 | ERP→金蝶 | 推送客商工商信息至金蝶,金蝶校验工商信息并完成客商创建 | A902-2 客商保存 | 客商状态:已提交 |
+| 7 | 合同合规系统 | 客商合规性审核,更新客商审核状态、企查查状态 | — | 审查通过 → 审批流程结束;不通过 → 阻塞使用 |
+| 8 | ERP | 客商新建完成,业务系统可使用该客商;同步工商信息至合同合规系统相对方 | — | 客户新增成功后金蝶自动下推供应商 |
+| 9 | ERP(定时) | 定时获取全集/增量客商数据,更新客商数据与使用状态 | A902-1 客户查询、A901-1 供应商查询 | 供应商仅支持查询 |
+| 10 | ERP | 客商更新:业务信息由 ERP 自行维护;工商/个人信息变更走人工流程(非接口,金蝶客商关联员通知 ERP 审批人员,人工审批通过后人工修改) | 无接口,人工修改 | 工商信息变更后,金蝶需同时维护客户与供应商 |
+
+### 2.4 关键规则摘录
+
+- 客商信息分**工商信息**与**业务信息**:工商信息全集团统一、只在金蝶维护,TMS 不允许变更;业务信息由 TMS 自行维护,不上传金蝶。
+- 新增金蝶不存在的客商,**须金蝶审核通过后 TMS 才能使用**;新增加工由机器人自动审核。
+- 金蝶客户自动下推供应商;**客户与供应商编码不一致**,除新增外信息不同步;客户工商信息变更后需分别维护客户与供应商。
+- 客商风险等级由合同合规系统提供(C101-1),**风险等级当天有效**;国资委黑名单通过金蝶黑名单查询接口(A801-5)拦截。
+
+---
+
+## 3. 图 02:合同新增及同步(合同主数据协同)
+
+- **图片文件**:`02_合同新增及同步.jpeg`(4857×4833)
+- **图内流程块**:合同新建/变更
+- **对应场景**:合同主数据协同(同批含项目立项同步)
+
+**图 2 流程图(Mermaid,接口编号已标注在连线上)**
+
+```mermaid
+flowchart TD
+ subgraph ERP["ERP / TMS"]
+ e0(["开始"]) --> e1["创建 / 变更合同"]
+ e1 --> e2["合同审核通过"]
+ e2 -->|"C101-1 客商风险等级查询(签约前必调)"| d1{"相对方风险等级"}
+ d1 -->|"非高风险"| e3["合规校验通过,推送合同数据"]
+ d1 -->|"高风险客商"| e4["特批申请(内部审批)"]
+ e3 --> e5["完成签订"]
+ e4 -->|"C103-8 合同发起特批"| e6["流程挂起"]
+ e6 -->|"集团审批通过(流程结束)"| e7["接收特批结果"]
+ e7 --> e5
+ e5 --> d2{"合同是否涉及收付款"}
+ d2 -->|"涉及收付款"| e8["创建 / 变更履约计划"]
+ d2 -->|"不涉及"| e9(["仅在合同系统存档,结束"])
+ e8 --> e10["推送合同至金蝶"]
+ e10 --> e11["合同系统同步成功标识
失败则异常处理 → 重新推送"]
+ e11 --> e12(["结束"])
+ end
+
+ subgraph HT["合同合规系统"]
+ h1["可提供能力(按需集成):
电子签署(集成 E 签宝,图中标注待定)
资信报告查询下载、合同文件智能审核"]
+ h2["合同模板 / 分类前置:C103-6 合同模板列表获取
C103-7 合同分类列表查询"]
+ h3["C103-1 合同同步、C103-2 合同附件上传
新建 / 变更合同台账"]
+ h4["C103-9 履约计划保存、C103-10 履约计划更新
创建 / 变更履约计划"]
+ h5["C103-3 合同列表查询、C103-4 合同详情查询"]
+ h6["B103 特批结果回传"]
+ end
+
+ subgraph JD["司库 / 星瀚(经 IPASS 中转)"]
+ j1["A101-1 合同信息表保存
创建 / 变更金蝶合同档案"]
+ j2["A101-2 合同信息表查询
A902 附件上传到指定单据"]
+ end
+
+ h1 -.->|"非必须,ERP 按业务实际情况集成"| e1
+ e2 --> h2
+ e3 -->|"C103-1 / C103-2"| h3
+ e4 --> h6
+ e6 -.->|"B103 特批结果回传"| e7
+ e8 -->|"C103-9 / C103-10"| h4
+ e5 -->|"C103-1(完成签订)"| h3
+ e11 -->|"C103-3 / C103-4"| h5
+ e10 -->|"收付款相关的合同推送金蝶:A101-1
实时推送 + 支持按钮手动同步"| j1
+ j1 --> j2
+```
+
+### 3.1 备注栏原文
+
+> **合同集成说明**
+>
+> 1、所有合同都要同步到合同系统。涉及收付款的合同,还必须创建履约计划,经合同合规校验通过才能发起收付款。
+>
+> 2、合同签订过程在业务系统处理,推送审核后合同及附件到合同合规系统即可。合同系统核验相对方是否可用,相对方是高风险的,不能签订合同。
+>
+> 3、合同系统可提供相对方风险等级查询接口,ERP 发起合同时调用,避免 ERP 审核通过后合同校验不通过,合同系统无法完成合同创建。
+>
+> 4、合同系统可提供电子签署能力(集成 E 签宝)、资信报告、智能审核,ERP 可根据业务实际情况集成使用。
+
+### 3.2 泳道节点文字版
+
+**ERP 栏**
+
+开始 → 创建/变更合同(调用合同系统能力) → 合同审核通过 → 合规校验通过 → 推送合同数据 → 合同新建/变更 → 高风险客商(如有)→ 特批申请(内部审批) → 完成签订 → 合同系统同步成功标识 → 异常处理 / 重新推送 → 金蝶同步成功标识 → 结束
+
+**合同合规系统栏**
+
+电子签署(待定)、根据证件号码查询/下载相对方资信报告、合同文件智能审核(图中标注 **--非必须---**,属可选集成能力)
+必须:C101-1_客商风险等级查询
+调用合同系统能力:C101-1_客商风险等级查询
+推送合同数据:C103-1_合同同步;C103-2_合同附件上传
+高风险客商分支:C103-8_合同发起特批、C103-6_合同模板列表获取、C103-7_合同分类列表查询 → 流程挂起 → 集团审批通过(流程结束)
+B103_特批结果回传
+成功 → 新增/变更合同 → 创建/变更履约计划(如有)(完成签订)
+C103-3_合同列表查询、C103-4_合同详情查询
+异常处理 / 重新推送 / 失败 → 成功 → 金蝶同步成功标识
+
+**司库/星瀚栏**
+
+根据证件号码查询相对方风险等级(调用 C101-1)
+收付款相关的合同推送金蝶(**·实时推送 ·支持按钮手动同步**)
+A101-1 合同信息表保存、A101-2 合同信息表查询、A902 附件上传到指定单据
+创建/变更合同 → 成功 / 失败
+
+### 3.3 流程步骤还原
+
+| 步骤 | 责任方 | 动作 | 涉及接口 | 分支/条件 |
+|---|---|---|---|---|
+| 1 | ERP | 发起合同创建/变更,合同审核通过 | — | — |
+| 2 | ERP→合同合规 | 按证件号码查询相对方风险等级(签约前必调) | **C101-1 客商风险等级查询** | 图中标注"必须";配套能力:资信报告下载、合同文件智能审核、电子签署(集成 E 签宝)均为非必须 |
+| 3 | ERP | 合规校验通过后推送合同数据(合同+附件)至合同系统 | C103-1 合同同步、C103-2 合同附件上传 | 合同系统核验相对方可用性 |
+| 4 | 合同合规 | 合同新建/变更登记完成(完成签订) | C103-1 / C103-11 合同信息更新 | 模板与分类前置:C103-6 合同模板列表获取、C103-7 合同分类列表查询 |
+| 5 | 合同合规 | **高风险客商**:不允许直接签约 → 发起合同特批 | C103-8 合同发起特批 | 流程挂起;流程在合同系统配置 |
+| 6 | 合同合规→ERP | 集团审批通过 → 流程结束;特批结果回传 ERP | **B103 特批结果回传** | 回传失败则 ERP 保持阻断状态 |
+| 7 | ERP | 完成签订;合同系统同步成功标识回写 | C103-3 合同列表查询、C103-4 合同详情查询 | 异常处理:失败 → 重新推送 |
+| 8 | ERP→合同合规 | 涉及收付款的合同创建/变更履约计划(履约类型、款项性质、收票规则、收票周期等) | C103-9 履约计划保存、C103-10 履约计划更新 | 履约计划是收付款前置条件 |
+| 9 | ERP→金蝶 | 收付款相关的合同推送金蝶,创建/变更金蝶合同档案并上传附件 | **A101-1 合同信息表保存**(二开接口)、A902 附件上传到指定单据、A101-2 合同信息表查询 | 实时推送 + 支持按钮手动同步;成功 → 金蝶同步成功标识;失败 → 异常处理重新推送 |
+| 10 | — | 不涉及收付款的合同仅在合同系统存档,不推送金蝶 | — | — |
+
+### 3.4 关键规则摘录
+
+- **所有合同都必须同步到合同系统**;涉及收付款的合同才推送金蝶,且必须创建履约计划。
+- 合同签订全过程在业务系统完成,合同系统只做接收、核验与风控拦截。
+- 相对方为**高风险**不能签合同,只能走合同特批;特批流程需在合同系统预先配置。
+- 合同系统可提供的能力:电子签署(集成 E 签宝,图中标注"待定")、资信报告查询下载、合同文件智能审核。
+
+---
+
+## 4. 图 03:财务应付及付款(对公付款)
+
+- **图片文件**:`03_财务应付及付款.jpg`(3228×5150)
+- **图内流程块**:付款单新增、反审核及删除(异常回收)
+- **对应场景**:对公付款(财务应付单 → 付款申请 → 财务共享审批 → 付款)
+
+**图 3 流程图(Mermaid,接口编号已标注在连线上)**
+
+```mermaid
+flowchart TD
+ subgraph ERP["ERP / TMS"]
+ e0(["开始"]) --> e1["发起付款申请
正式结算付款 / 预付款"]
+ e1 --> e2["付款审核通过"]
+ e2 --> e3["推送金蝶(合规性校验通过)"]
+ e3 --> e4["业务单据锁定(锁单)"]
+ e4 --> e5["定时查询付款结果
更新付款信息与履约付款数据"]
+ e5 --> e6["推送付款相关材料
关键附件文件 + 详细材料下载地址"]
+ e6 --> e7(["结束"])
+ e8(["开始(异常回收)"]) --> e9["金蝶反审核及删除(如有)→ 解锁单据
→ 反审核及删除 → 更新付款结果"]
+ e9 --> e10(["结束"])
+ end
+
+ subgraph HT["合同合规系统"]
+ h1["C106-1 项目 / 合同额度校验
ERP 无额度校验则需调用"]
+ h2["C101-1 客商风险等级查询(按证件号码)"]
+ h3["C106-3 付款特批流程发起
C106-4 付款特批流程更新"]
+ h4["C106-2 付款附件推送
同 C103-2 上传接口,每日定时推送"]
+ h5["B901 锁单 / 解锁"]
+ end
+
+ subgraph JD["司库 / 星瀚(经 IPASS 中转)"]
+ j1["A103-1 付款申请保存(应付下推)
A103-3 付款申请保存(预付款)
A902 附件上传到指定单据"]
+ j2["创建应付单 / 付款申请单(预付)
财务共享审批(当前机器人处理)"]
+ j3["付款处理 → 付款完成"]
+ j4["A103-2 付款申请单查询
A103-4 付款处理查询"]
+ j5["A102-4 财务应付单查询"]
+ end
+
+ e1 --> h1
+ h1 --> h2
+ h2 --> d1{"是否高风险客商(如有)"}
+ d1 -->|"否"| e2
+ d1 -->|"是:拦截付款"| h3
+ h3 -->|"流程挂起 → 集团审批通过(流程结束)"| e2
+ h3 -.->|"B103 特批结果回传:通知允许本次付款"| e2
+ e2 -->|"合规性校验通过"| e3
+ e3 -->|"A103-1 / A103-3 / A902"| j1
+ j1 --> j2
+ j2 -->|"通过"| j3
+ j2 -->|"不通过:异常处理 → 重新推送"| e8
+ j3 --> j4
+ j4 --> e5
+ e3 -.->|"核对应付金额与已付款"| j5
+ e5 -->|"A103-2 / A103-4 定时查询"| j4
+ e4 -->|"B901 锁单 / 解锁"| h5
+ e6 -->|"C106-2 每日定时推送"| h4
+ e9 -.->|"B901 解锁"| h5
+```
+
+### 4.1 备注栏原文
+
+> **付款单集成说明**
+>
+> 场景:业务发起合同付款,满足付款合规性的,允许发起付款,并将付款结果同步至合同系统,以完成履约付款情况监控,不满足付款合规性的,中止业务系统发起的付款。如有付款需要,可走特批流程。
+>
+> 1、发起付款申请:由 ERP 发起付款申请,涉及合同的付款,必须通过付款合规性校验,才可推送金蝶。合同系统提供付款控制相关查询接口,ERP 在发起付款时、以及推送单据时调用,避免付款合规性风险。
+>
+> 2、金蝶创建付款单:合规性校验校验通过后创建付款单。
+>
+> 3、同步付款信息:合同系统定时查询金蝶,更新付款结果。
+>
+> 4、已推送金蝶的付款单,ERP 进行锁单,财务共享审批后,如被驳回,ERP 推送的字段不允许进行修改;如需对单据进行修改,需在金蝶对该单据进行反审核及删除后,由 ERP 重新推送。
+
+### 4.2 泳道节点文字版
+
+**ERP 栏**
+
+开始 → 付款申请 → 付款审核通过 → 合规性校验通过 → 推送金蝶 → 高风险客商(如有)→ 特批申请(内部审批) → 重新推送付款申请 → 异常处理 / 重新推送 → 金蝶同步标识成功 → 业务单据锁定 → 更新付款结果 → 推送付款相关材料(关键附件文件 + 详细材料下载地址,**·每日定时推送**) → 反审核及删除 → 更新付款结果
+
+**合同合规系统栏**
+
+付款额度校验(**ERP 无额度校验则需调用**)
+根据证件号码查询相对方风险等级 → 对方风险等级
+推送金蝶:A103-1 应付下推付款申请、A103-1 预付款申请、A103-2 付款申请单查询、A902 附件上传到指定单据
+特批申请 → 流程挂起 → C106-3_付款特批流程发起 → 集团审批通过(流程结束) → B103_特批结果回传 → 通知 → 允许本次付款
+不通过 → A103-2 付款申请单查询
+**·定时查询** → 查询金蝶付款结果 → A103-2 付款申请单查询 → 更新付款信息
+解锁单据,反审核及删除 → B901 锁单/解锁 → 更新付款结果 → 结束
+
+**司库/星瀚栏**
+
+创建应付单 / 付款申请单(预付) → 财务共享审批 →(不通过 / 通过)→ 付款处理 → 付款完成
+**·定时查询** → 查询金蝶付款结果 → A103-2 付款申请单查询
+反审核及删除(如有)
+
+### 4.3 流程步骤还原
+
+| 步骤 | 责任方 | 动作 | 涉及接口 | 分支/条件 |
+|---|---|---|---|---|
+| 1 | ERP | 发起付款申请(正式结算付款 / 预付款) | — | 付款前先做额度与风险校验 |
+| 2 | 合同合规 | 付款额度校验(项目/合同剩余额度) | C106-1 项目/合同额度校验 | **ERP 无额度校验则必须调用** |
+| 3 | 合同合规 | 按证件号码查询相对方风险等级 | **C101-1 客商风险等级查询** | 非高风险、非黑名单方可继续 |
+| 4 | ERP | 付款审核通过后推送金蝶 | 正式付款:**A103-1 付款申请保存(应付下推)**;预付款:**A103-3 付款申请保存(预付款)**;附件:A902 附件上传到指定单据 | 正式付款须先推财务应付单(A102-2)再推付款申请;预付款只推付款申请单 |
+| 5 | ERP | 查询付款申请单状态;核对应付金额与已付款情况 | A103-2 付款申请单查询;A102-4 财务应付单查询 | 异常 → 异常处理 → 重新推送 |
+| 6 | 合同合规 | **高风险客商(如有)**:拦截付款 → 发起付款特批 | C106-3 付款特批流程发起(更新用 C106-4) | 流程挂起;审批流需在合同系统配置 |
+| 7 | 合同合规→ERP | 集团审批通过(流程结束),允许本次付款 → 通知 ERP | **B103 特批结果回传** | 特批单次有效,每次付款都要重新申请 |
+| 8 | 金蝶 | 创建应付单/付款申请单(预付),进入财务共享审批 | A103-1 / A103-3 | 新增付款申请单在财务系统需审核,当前为机器人处理 |
+| 9 | 金蝶 | 财务共享审批(不通过 / 通过)→ 付款处理 → 付款完成 | — | 财务共享审批只校验内部风险与资金计划,不再调合同合规接口 |
+| 10 | ERP | 金蝶同步标识成功后**业务单据锁定**(锁单) | B901 锁单/解锁 | 已推金蝶单据 ERP 不可改 |
+| 11 | ERP/合同合规 | **·定时查询** 金蝶付款结果,更新付款信息与履约付款数据 | A103-2 付款申请单查询、A103-4 付款处理查询 | 付款结果同步至合同系统 |
+| 12 | ERP→合同合规 | 推送付款相关材料:关键附件文件 + 详细材料下载地址 | C106-2 付款附件推送(同 C103-2 上传接口) | **每日定时推送** |
+| 13 | 金蝶/ERP | 异常回收:金蝶反审核及删除(如有)→ 解锁单据 → 反审核及删除 → 更新付款结果 | B901 锁单/解锁 | 被驳回的推送字段不允许修改,须金蝶反审核+删除后由 ERP 重新推送 |
+
+### 4.4 关键规则摘录
+
+- **正式付款**:先推财务应付单(A102-2),再推付款申请单(A103-1);**预付款**只推付款申请单(A103-3、付款类型=预付款,不绑应付单)。
+- 涉及合同的付款**必须通过付款合规性校验**才可推送金蝶;不通过则中止付款,可走特批。
+- **特批单次有效**,每次付款都要重新申请;额度校验需同时满足客户额度与项目额度。
+- 已推金蝶的付款单 ERP **锁单**;财务共享驳回后 TMS 只能看到"已提交"状态,看不到审批节点与驳回原因,需金蝶反审核+删除后 ERP 重推。
+- 收款账号变更 TMS 与金蝶流程不对接,需人工双系统确认;止付按整单(冻结→关闭)或明细(冻结→关闭)处理,对应应付单由金蝶财务调减、红冲。
+
+---
+
+## 5. 图 04:财务应收及开票(销项开票)
+
+- **图片文件**:`04_财务应收及开票.png`(4842×4461)
+- **图内流程块**:开票申请(正向/反向开票)
+- **对应场景**:财务应收 + 销项开票
+
+**图 4 流程图(Mermaid,接口编号已标注在连线上)**
+
+```mermaid
+flowchart TD
+ subgraph ERP["ERP / TMS"]
+ e0(["开始"]) --> e1["基于已审批结算单提交开票申请
正向 / 反向开票"]
+ e1 --> e2["审核通过后推送,附件随单上传"]
+ e2 --> e3["定时查询开票结果与发票凭证
更新开票结果"]
+ e3 --> e4(["结束"])
+ e5["已推金蝶的开票单 ERP 锁单
需修改时先金蝶红冲,再由 ERP 重新推送"] --> e4
+ end
+
+ subgraph HT["合同合规系统"]
+ h1["A303-1 开票申请单新增"]
+ h2["创建开票单 → 审核通过"]
+ h3["A303-5 开票申请单发票查询(定时查询)
A303-4 开票申请单查询(同步申请附件)"]
+ h4["发票红冲(如有)→ 更新开票结果"]
+ end
+
+ subgraph JD["司库 / 星瀚(经 IPASS 中转)"]
+ j0["财务应收侧:运单对账 → 应收结算审核 → 全额推送财务应收单"]
+ j1["创建开票单 → 审核开票申请 → 开票处理 → 开票完成"]
+ end
+
+ j0 -.->|"A302-2 财务应收单保存 / A302-4 财务应收单查询
正式结算开票须先推财务应收单"| e1
+ e2 -->|"A303-1,附件随单 A902 上传"| h1
+ h1 --> h2
+ h2 --> j1
+ j1 -->|"开票完成,回写开票结果与凭证"| h4
+ h4 --> e3
+ e3 -->|"A303-5 / A303-4"| h3
+ h3 -.->|"业务系统在合同系统查询开票结果及凭证"| e3
+```
+
+### 5.1 备注栏原文
+
+> **付款单集成说明**
+>场景:业务发起合同付款,满足付款合规性的,允许发起付款,并将付款结果同步至合同系统,以完成履约付款情况监控。不满足受控付款合规性,不满足付款合规性的,中止业务系统发起的付款。如有付款需要,可走特批流程。
+>
+>1. **发起付款申请:** 由ERP发起付款申请,涉及合同的付款,必须通过付款合规性校验,才可推送金蝶。合同系统提供付款控制相关查询接口,ERP在发起付款时、以及推送单据时调用,避免付款合规性风险。
+> 2. **金蝶创建付款单:** 合规性校验校验通过后创建付款单。
+>3. **同步付款信息:** 合同系统定时查询金蝶,更新付款结果。
+> 4. **已推送金蝶的付款单,ERP进行锁单,财务共享审批后,如被驳回,ERP推送的字段不允许进行修改,如需对单据进行修改,需在金蝶对该单据进行反审核及删除后,由ERP重新推送。**
+
+### 5.2 泳道节点文字版
+
+**ERP 栏**
+
+开始 → 提交开票申请(正向/反向开票) → 审核通过 → 异常处理 / 重新推送 → 更新开票结果 → 结束
+
+**合同合规系统栏**
+
+A303-1 开票申请单新增、A303-4 开票申请单查询、A902 附件上传到指定单据
+创建开票单 → 审核通过 → **·定时查询** → A303-5 开票申请单发票查询 → 开票完成 → 发票红冲(如有)→ 更新开票结果 → 同步申请附件 → 更新开票结果 → 结束
+
+**司库/星瀚栏**
+
+创建开票单 → 审核通过 → 开票完成 → 发票红冲(如有)
+
+### 5.3 流程步骤还原
+
+| 步骤 | 责任方 | 动作 | 涉及接口 | 分支/条件 |
+|---|---|---|---|---|
+| 1 | ERP | 基于已审批结算单提交开票申请(正向/反向开票) | A303-1 开票申请单保存 | 结算流程与开票流程分开审批,须先校验结算审批通过 |
+| 2 | ERP | 开票申请审核通过后推送,附件随单上传 | A902 附件上传到指定单据 | 失败 → 异常处理 → 重新推送 |
+| 3 | 合同合规/金蝶 | 创建开票单,审核通过,进行开票处理,完成开票;支持发票红冲(如有) | A303-1、A303-4 开票申请单查询 | 新增开票申请单在财务系统需审核,当前为机器人处理 |
+| 4 | ERP/合同合规 | **·定时查询** 开票结果与发票凭证,更新开票结果与履约数据,同步申请附件 | **A303-5 开票申请单发票查询**、A303-4 | 业务系统在合同系统查询开票结果及凭证 |
+| 5 | ERP | 已推金蝶的开票单 ERP 锁单;需修改时先金蝶红冲,再由 ERP 重新推送 | — | 已真实开出的数电票不能作废,只能红冲后重开 |
+| 6 | — | 财务应收侧:运单完成对账生成应收结算,审核通过后全额推金蝶生成财务应收单(口径见 `TMS业财融合-业务流程与接口梳理.md`) | A302-2 财务应收单保存、A302-4 财务应收单查询 | 正式结算开票须先推财务应收单再推开票申请单 |
+
+### 5.4 关键规则摘录
+
+- 开票基于已审批的结算单发起,一张 TMS 开票申请按"发票张数"生成多个金蝶开票申请单,按票面行拆分开票明细。
+- **运输发票需单独开具**,不可与其他费用混开。
+- 发票凭证支持接口查询、下载,并发送到业务部公用邮箱;开票结果及附件定时推送合同系统。
+- 已推金蝶的开票单锁单:仅申请未开票/开票失败的可直接作废或撤销;**已真实开出数电票的(当月或跨月)必须走红冲流程**。
+
+### 5.5 流程梳理
+
+整个业务流程围绕“合同付款的合规性管控”展开,涉及ERP系统、合同合规系统以及司库/星瀚(金蝶)系统。整体流程可以划分为以下五大核心阶段:
+
+- 阶段一:付款申请与合规校验(ERP ↔ 合同合规系统)
+
+1. **发起申请**:业务流程在ERP中发起【付款申请】。
+2. **初步审核**:ERP进行【付款审核】。
+3. **合规校验**:系统调用合同合规系统进行【合规性校验】(通过C101-1进行客商风险等级查询,根据证件号码查询对方风险等级)。
+4. **高风险处理(如需)**:
+ - 如果命中高风险客户,ERP进入【特批申请(内部审批)】。
+ - 合同系统【流程挂起】,发起C106-3付款特批流程。
+ - 集团【审批通过】后,通知B103特批结果回传至ERP。
+ - 如果允许本次付款,则继续流程;否则需在ERP【重新推送付款申请】。
+
+- 阶段二:推送金蝶与单据创建
+
+1. **推送数据**:合规校验通过后,合同系统向司库/星瀚推送数据(包含:A103-1应付下推付款申请、A103-1预付付款申请、A103-2付款申请单查询、A902附件上传到指定单据)。
+2. **创建付款单**:司库/星瀚(金蝶)生成【金蝶应付单/付款单/退单(预付)】。
+3. **异常处理**:如果推送或创建**失败**,流程流转至ERP【异常处理重新推送】。
+4. **锁单处理**:如果**成功**,ERP接收信号后执行【金蝶同步标识成功 业务单据锁定】。(注意:此时ERP端字段被锁定,不可修改)。
+
+- 阶段三:财务审批与付款执行
+
+1. **共享审批**:单据进入司库/星瀚,进行【财务共享审批】。
+2. **审批驳回**:如果【不通过】,通过A103-2付款申请单查询反馈至ERP,ERP【更新付款结果】。
+3. **审批通过**:如果【通过】,进入【付款处理】并完成【付款完成】。
+
+- 阶段四:付款结果同步与附件归档
+
+1. **结果查询**:合同合规系统通过【定时查询】,调用A103-2查询金蝶付款结果。
+2. **更新ERP**:合同系统将结果同步至ERP,ERP【更新付款结果】。
+3. **附件推送**:合同系统每日定时推送(C106-2付款附件推送),将关键附件文件、详细材料及下载地址推送至ERP并【更新付款信息】。
+4. 流程正常【结束】。
+
+- 阶段五:反审核与删除(逆向流程)
+
+- 如果已推送金蝶的付款单需要修改(需遵循备注4的原则):
+
+1. 司库/星瀚发起【反审核及删除(如有)】。
+2. 执行【解锁单据,反审核及删除 B901锁单/解锁】。
+3. 通知ERP端进行【反审核及删除】。
+4. ERP完成操作后【更新付款结果】,流程【结束】。
+
+
+
+
+
+---
+
+## 6. 图 05:付款-收票查询及认领(进项收票)
+
+- **图片文件**:`05_付款-收票查询及认领.png`(4842×4857)
+- **图内流程块**:收票单新增/变更
+- **对应场景**:收票查询及认领(发票池查询 → 收票单 → 指定应付单)
+
+**图 5 流程图(Mermaid,接口编号已标注在连线上)**
+
+```mermaid
+flowchart TD
+ subgraph ERP["ERP / TMS"]
+ e0(["开始"]) --> e1["基于结算单发起收票"]
+ e1 --> d1{"是否有发票"}
+ d1 -->|"否"| e2["查询金蝶全票池,获取发票票面信息"]
+ d1 -->|"是"| e3["随财务应付单推送"]
+ e2 --> e4["收票单新增 / 变更
ERP 内部完成收票认领"]
+ e3 --> e4
+ e4 --> e5["推送收票单,并指定对应应付单"]
+ e5 --> e6["业务单据锁定"]
+ e6 --> e7["推送收票信息,更新收票信息"]
+ e7 --> e8(["结束"])
+ e9(["异常处理"]) --> e10["发票红冲(如有)→ 解锁单据,反审核及删除
→ 重新推送"]
+ e10 --> e8
+ end
+
+ subgraph HT["合同合规系统"]
+ h1["A303-2 收票单批量保存
创建收票单"]
+ h2["A302-6 收票指定应付
关联应付单"]
+ h3["C107-1 收票认领结果同步
拟开发 / 开发中"]
+ end
+
+ subgraph JD["司库 / 星瀚(经 IPASS 中转)"]
+ j1["企业进项发票票池"]
+ j2["创建收票单 → 关联应付单"]
+ j3["金蝶暂不支持一张发票指定多张应付单分摊金额
合同系统暂不推送金蝶收票单"]
+ end
+
+ e2 -->|"A801-1 查询全票池发票数据"| j1
+ e5 -->|"A303-2 / A302-6"| h1
+ h1 --> h2
+ h2 --> j2
+ j2 -.-> j3
+ e7 -->|"C107-1 收票认领结果同步"| h3
+ h3 -.->|"更新收票信息"| e7
+```
+
+### 6.1 备注栏原文
+
+> **收票单集成说明**
+>
+> 场景:将业务合同关联的收票信息同步到合同系统,以完成合同履约-收票情况监控。
+>
+> 1、发起收票:收票单由 ERP 发起,审核通过后推送合同系统生成收票记录。
+>
+> 2、金蝶创建收票单:金蝶当前暂不支持一张发票指定多张应付单分摊金额,合同系统暂不推送金蝶收票单。
+
+### 6.2 泳道节点文字版
+
+**ERP 栏**
+
+开始 → 结算单 → 是否有发票
+ ├ **否**:A801-1 查询全票池发票数据(企业进项发票票池)→ 获取发票
+ └ **是**:随财务应付单推送
+→ 收票单新增/变更 → 异常处理 / 重新推送 / 失败 → 创建收票单 → 成功 → A302-6_收票指定应付 → 关联应付单 → 同步标识成功 → 业务单据锁定 → 发票红冲(如有)→ 解锁单据,反审核及删除 → 推送收票信息 → C107-1 收票认领结果同步 → 更新收票信息 → 结束
+
+**合同合规系统栏**
+
+否,A801-1 查询全票池发票数据
+A303-2 收票单批量保存、A302-6_收票指定应付
+创建收票单 → 关联应付单 → 发票红冲(如有)→ 解锁单据,反审核及删除 → 更新收票信息 → 结束
+
+**司库/星瀚栏**
+
+企业进项发票票池 → 创建收票单 → 关联应付单 → 发票红冲(如有)
+
+### 6.3 流程步骤还原
+
+| 步骤 | 责任方 | 动作 | 涉及接口 | 分支/条件 |
+|---|---|---|---|---|
+| 1 | ERP | 基于结算单发起收票,判断是否有发票 | — | **无发票** → 步 2;**已有发票** → 随财务应付单一起推送 |
+| 2 | ERP→金蝶 | 按发票号查询金蝶全票池发票数据,获取票面信息 | **A801-1 查询全票池发票数据** | 对应金蝶侧"企业进项发票票池" |
+| 3 | ERP | 收票单新增/变更,完成 ERP 内部收票认领 | — | 收票时按品类与结算单校验数量、税率、含税金额一致 |
+| 4 | ERP→合同合规 | 推送收票单,合同系统生成收票记录 | **A303-2 收票单批量保存** | 失败 → 异常处理 → 重新推送;单张进项票 = 单个收票单,按票面行拆明细 |
+| 5 | ERP→金蝶 | 收票单指定(关联)对应财务应付单,完成进项票与应付单绑定 | **A302-6 收票指定应付** | 同步标识成功后业务单据锁定 |
+| 6 | ERP→合同合规 | 推送收票认领结果,更新履约收票数据 | **C107-1 收票认领结果同步**(拟开发/开发中) | — |
+| 7 | 金蝶/ERP | 发票红冲(如有)→ 解锁单据,反审核及删除 | — | 收票单异常须先解除收票与应付单关系,再反审核删除,由 ERP 重推 |
+
+### 6.4 关键规则摘录
+
+- **金蝶当前暂不支持一张发票指定多张应付单分摊金额,因此合同系统暂不推送金蝶收票单**(图中明确标注)。
+- 接口生成的收票单默认审核通过,**不支持实时验真验重**;金蝶每 5 分钟查验,异常结果可通过收票单关联的应付单查询。
+- 金蝶不支持直接推送数电票 OFD 附件;发票须先关联结算单再推金蝶。
+- 进项发票凭证查询下载:A801-2 进项发票下载;收票单查询:A801-3。
+
+---
+
+## 7. 图 06:收款查询及认领(回款认领)
+
+- **图片文件**:`收款查询及认领.jpg`(4842×2685)
+- **图内流程块**:收款认领
+- **对应场景**:收款查询及认领(两种集成方式可选)
+
+**图 6 流程图(Mermaid,接口编号已标注在连线上)**
+
+```mermaid
+flowchart TD
+ subgraph JD["司库 / 星瀚(经 IPASS 中转)"]
+ j0(["开始"]) --> j1["司库收到银行流水"]
+ j1 --> j2["金蝶第一轮自动认领
仅能认领到客户维度"]
+ j3["生成 / 更新收款单,更新认领结果"]
+ end
+
+ subgraph ERP["ERP / TMS"]
+ e1["二次认领:认领到合同 / 履约计划名称 / 批次维度
一笔回款对应多笔结算单时手工分摊"]
+ e2["推送认领结果(认领至合同履约计划)"]
+ e3(["结束"])
+ end
+
+ subgraph HT["合同合规系统"]
+ h1["更新履约收款数据"]
+ h2["定时查询金蝶认领数据"]
+ end
+
+ j2 --> e1
+ e1 -->|"A301-1 收款单查询 / A301-2 收款认领公告查询"| e2
+ e2 --> e3
+
+ e2 -->|"场景一:C104-1 收款信息同步(认领结果不推金蝶时调用,拟开发)"| h1
+ j3 -.->|"场景二"| h2
+ h2 -->|"场景二:A301-1 收款单查询认领结果"| h1
+ e2 -->|"A301-3 收款认领结果推送
(ERP 推送认领结果给金蝶生成收款单)"| j3
+```
+
+### 7.1 备注栏原文
+
+> **收款认领集成说明**
+>
+> 场景:将业务合同关联的收款结果同步到合同系统,以完成合同履约-收款情况监控。
+>
+> 1、银行流水金蝶自动认领:司库收到银行流水,金蝶可实现第一轮的自动认领(到客户的维度)。
+>
+> 2、认领银行流水:由于金蝶当前只能认领到客户,具体流水是属于哪个合同/履约计划名称/批次,需要 ERP 完成认领。
+>
+> 3、认领结果推送合同系统:合同系统定时查询金蝶认领数据,合同系统更新履约收款数据。
+
+### 7.2 泳道节点文字版
+
+**ERP 栏**
+
+收款认领(认领到合同履约计划)→ 推送认领结果 → 推送认领结果(场景一):C104-1_收款信息同步 / 查询认领结果(场景二):A301-1_收款单查询
+
+**合同合规系统栏**
+
+A301-1_收款单查询 / A301-2_收款认领公告查询
+A301-3_收款认领结果推送(认领至合同履约计划)
+更新履约收款数据 → 查询认领结果(场景二)→ A301-1_收款单查询
+
+**司库/星瀚栏**
+
+开始 → 司库收到银行流水 → 更新认领结果
+
+### 7.3 流程步骤还原
+
+| 步骤 | 责任方 | 动作 | 涉及接口 | 分支/条件 |
+|---|---|---|---|---|
+| 1 | 金蝶/司库 | 司库收到银行流水,金蝶完成**第一轮自动认领(到客户维度)** | — | 金蝶只能认领到客户 |
+| 2 | ERP | TMS 认领银行流水到**合同/履约计划名称/批次**维度 | A301-1 收款单查询、A301-2 收款认领公告查询 | 一笔回款对应多笔结算单时手工分摊 |
+| 3 | ERP | 推送认领结果 | **A301-3 收款认领结果推送**(认领至合同履约计划) | — |
+| 4 | 合同合规 | 定时查询金蝶认领数据,更新履约收款数据 | C104-1 收款信息同步(拟开发) | 认领结果不推金蝶时调用 C104-1 |
+
+### 7.4 两种集成方式(源自 `合同业财接口排期.xlsx`「场景及流程图说明」原文)
+
+- **场景一(财务先行认领)**:财务进行"一次认领"至客户 → ERP 查询财务收款单(A301-1)→ ERP 进行"二次认领"至合同或更细维度 → ERP 推送二次认领结果给合同系统(C104-1)。
+- **场景二(业务先行认领)**:ERP 查询财务收款公告(A301-2)→ ERP 进行"一次认领"至合同 → ERP 推送认领结果给金蝶生成收款单(A301-3)→ 合同系统查询财务系统收款单的认领结果(A301-1)。
+- 两种方式**可根据各单位财务部需求选择不同集成方式**。
+
+### 7.5 关键规则摘录
+
+- 收款流水定时拉取有延时;时效性高的收款由财务人工在 TMS 录入。
+- 认领结果回写合同系统更新履约台账,支持认领作废;项目预付(无关联结算单)在后续正式结算时与尾款核销。
+
+---
+
+## 8. 业务流程串联梳理
+
+### 8.1 主数据流(客商 / 项目 / 合同)
+
+1. **客商**:ERP 查金蝶(A902-1/A901-1)→ 不存在则在 ERP 新建并审核 → 推金蝶工商信息(A902-2)→ 金蝶校验并创建(机器人审核)→ 同步合同合规系统相对方 → 风险等级(C101-1,当天有效)与黑名单(A801-5)作为签约、付款的准入条件。
+2. **项目**:无法通过合同付款计划管控、需按项目管控收付款额度的,项目创建后推送合同系统(C102-1/C102-2),后续依赖项目做履约校验;可通过合同付款计划管控的可不做项目集成。
+3. **合同**:ERP 创建并审批 → 签约前查风险等级(C101-1)→ 推送合同及附件(C103-1/C103-2)→ 涉及收付款的创建履约计划(C103-9/C103-10)→ 推送金蝶合同档案(A101-1);高风险客商走合同特批(C103-8,结果经 B103 回传)。
+
+### 8.2 付款流(应付 → 付款)
+
+预付款路径:预结算单 → 付款申请(A103-3,不绑应付单)→ 金蝶创建付款申请单 → 财务共享审批 → 付款。
+正式付款路径:正式结算单 → 财务应付单(A102-2,金额与状态可用 A102-4 财务应付单查询 核对)→ 付款申请(A103-1 应付下推)→ 金蝶付款申请单 → 财务共享审批 → 付款 → 结果回写(A103-2/A103-4)→ 推送合同系统更新履约(C106-2 附件)。
+两条路径前置均需:额度校验(C106-1)+ 风险校验(C101-1),不通过走付款特批(C106-3/C106-4),特批结果经 B103 回传。
+
+### 8.3 收票流(进项)
+
+结算 → 是否有发票 → 无票则查全票池(A801-1)→ 收票认领 → 推收票单(A303-2)→ 指定应付单(A302-6)→ 推送收票认领结果至合同系统(C107-1)。
+
+### 8.4 开票流(应收/销项)
+
+运单对账 → 应收结算审核 → 全额推财务应收单(A302-2)→ 基于结算单提交开票申请(A303-1)→ 金蝶开票处理 → 查开票结果及凭证(A303-5)→ 更新履约与开票结果。
+
+### 8.5 回款流(收款)
+
+司库收流水 → 金蝶一次认领到客户 → ERP 二次认领到合同/履约计划(A301-1/A301-2)→ 推送认领结果(A301-3)→ 合同系统定时查询并更新履约收款数据(C104-1)。
+
+---
+
+## 9. 通用机制与异常处理
+
+| 机制 | 说明 |
+|---|---|
+| 校验前置 | 签约前查客商风险(C101-1);付款前查风险 + 额度(C101-1、C106-1);不通过即拦截,可走特批 |
+| 特批 | 合同特批(C103-8)、付款特批(C106-3/C106-4)**均单次有效**;结果经 B103 回传 ERP;审批流需在合同系统预配置 |
+| 锁单 | 已推金蝶的单据 ERP 执行锁单;修改须金蝶反审核 + 删除后 ERP 重推;锁单/解锁经 B901 通知 |
+| 红冲 | 数电票开出后不能作废只能红冲;红冲应收须先红冲发票再冲销应收单,ERP 定时同步状态并自动作废内部单据 |
+| 定时同步 | 付款结果、开票结果、收票/收款认领结果、客商数据均由定时任务查询回写;付款附件每日定时推送 |
+| 汇率 | 汇率由金蝶维护,TMS 结算时通过 **A801-4 汇率查询** 获取并记录在结算单据上;期末调汇、汇兑损益全部在金蝶处理,TMS 只记录原币与折算人民币 |
+| 异常重推 | 推送失败统一走"异常处理 → 重新推送";收票单异常须先解除收票-应付关系再反审核删除 |
+| 黑盒限制 | 财务共享审批对 TMS 黑盒,仅"已提交"状态,看不到审批节点与驳回原因 |
+
+---
+
+## 10. 本批流程图涉及的接口速查
+
+| 编号 | 名称 | 提供方 | 所属流程 |
+|---|---|---|---|
+| A902-1 / A902-2 | 客户查询 / 客户保存 | 金蝶 | 客商新建与同步 |
+| A901-1 | 供应商查询 | 金蝶 | 客商同步(客户自动下推供应商) |
+| A801-4 | 汇率查询 | 金蝶 | 结算取汇率(记录在结算单据上) |
+| A801-5 | 黑名单查询 | 金蝶 | 客商准入 |
+| A913 | 项目信息保存 | 金蝶 | 项目同步 |
+| C101-1 | 客商风险等级查询 | 合同合规 | 签约、付款前置校验 |
+| C102-1/2/3 | 项目立项新增/更新/查询 | 合同合规 | 项目同步 |
+| C103-1 / C103-11 | 合同同步 / 合同信息更新 | 合同合规 | 合同新增及同步 |
+| C103-2 | 合同附件上传(C106-2 付款附件推送复用) | 合同合规 | 合同、付款附件 |
+| C103-3 / C103-4 / C103-5 | 合同列表查询 / 详情查询 / 附件下载 | 合同合规 | 合同同步结果回查 |
+| C103-6 / C103-7 / C103-12 | 合同模板列表 / 合同分类列表 / 合同币种列表 | 合同合规 | 合同创建前置 |
+| C103-8 | 合同发起特批 | 合同合规 | 高风险客商签约 |
+| C103-9 / C103-10 | 履约计划保存 / 更新 | 合同合规 | 履约计划 |
+| C106-1 | 项目/合同额度校验 | 合同合规 | 付款前置校验 |
+| C106-3 / C106-4 | 付款特批流程发起 / 更新 | 合同合规 | 付款特批 |
+| C108-1 / C108-2 | 履约记录新建 / 更新 | 合同合规 | 履约数据同步 |
+| C104-1 | 收款信息同步(拟开发) | 合同合规 | 收款认领场景一 |
+| C107-1 | 收票认领结果同步(开发中) | 合同合规 | 进项收票 |
+| A101-1 / A101-2 | 合同信息表保存(二开)/ 查询 | 金蝶 | 合同推送金蝶 |
+| A102-1 / A102-2 | 暂估应付单保存 / 财务应付单保存 | 金蝶 | 应付 |
+| A102-4 | 财务应付单查询 | 金蝶 | 查询财务应付单金额与已付款情况,付款前后核对 |
+| A103-1 / A103-2 / A103-3 / A103-4 | 付款申请保存(应付下推)/ 付款申请单查询 / 预付款申请 / 付款处理查询 | 金蝶 | 对公付款 |
+| A302-1 / A302-2 | 暂估应收单保存 / 财务应收单保存 | 金蝶 | 应收 |
+| A303-1 / A303-4 / A303-5 | 开票申请单保存 / 查询 / 发票查询 | 金蝶 | 销项开票 |
+| A801-1 | 查询全票池发票数据 | 金蝶 | 进项收票 |
+| A303-2 / A302-6 / A801-2 / A801-3 | 收票单批量保存 / 收票指定应付 / 进项发票下载 / 收票单查询 | 金蝶 | 进项收票 |
+| A301-1 / A301-2 / A301-3 | 收款单查询 / 收款认领公告查询 / 收款认领结果推送 | 金蝶 | 收款认领 |
+| A902 | 附件上传到指定单据 | 金蝶 | 各类单据附件 |
+| A100-1/2/3、C100-1/2 | 认证接口 | 金蝶 / 合同合规 | 全局 |
+| B901 | 锁单/解锁通知 | ERP | 锁单机制 |
+| B103 | 特批结果回传(拟开发) | ERP | 合同特批、付款特批 |
+
+> 完整 62 项接口清单(含地址、出入参)见 `TMS业财融合-业务流程与接口梳理.md` 第 5 节及 `合同业财接口排期.xlsx`「接口导航」。
+
+---
+
+## 11. 未决事项与待确认
+
+1. **图中标注"待定/非必须"的能力**:合同电子签署(集成 E 签宝)标注"待定";资信报告查询下载、合同文件智能审核标注"非必须",由 ERP 按实际情况决定是否集成。
+2. **拟开发/开发中接口**:C104-1 收款信息同步、C107-1 收票认领结果同步(开发中 50%)、B103 特批结果回传(拟开发),联调前需补齐。
+3. **图中的业务限制**:金蝶暂不支持一张发票指定多张应付单分摊金额,收票单暂不推送金蝶;金蝶收款只能认领到客户维度,合同/履约维度需 ERP 完成。
+4. **本文字版系图片 OCR + 人工校对所得**,与 `TMS业财融合方案.docx` 中的原型/流程图如存在差异,以最新合同合规与金蝶接口文档为准;建议对照原图核验第 2.2、3.2、4.2、5.2、6.2、7.2 节中靠近栏位边界的少量标注。
diff --git a/doc/docs/TMS业财融合方案.docx b/doc/docs/TMS业财融合方案.docx
new file mode 100644
index 0000000000000000000000000000000000000000..6e20a65a28ce76623db1a229601b4c965267f81b
GIT binary patch
literal 4090790
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