feat: 收票登记增加往来户供应商代码字段与手选结算组织金蝶组织派生

This commit is contained in:
刘泉佳
2026-10-31 16:06:25 +08:00
parent f0c551358a
commit 9e3240712c
4 changed files with 84 additions and 2 deletions
@@ -58,6 +58,14 @@ public class InvoiceReceiptSaveRequest implements Serializable {
private String departmentEmails;
private String attachmentsJson;
private String remark;
/**
* 结算组织(页面手选部门,先票后款链路收票登记不再必选关联结算单)
*/
private Long deptId;
private String deptName;
/**
* 关联结算单分摊(兼容历史入参:先票后款链路不再传,关联关系由付款结算单侧写入)
*/
private List<SettlementRow> settlements;
/**
@@ -112,6 +112,10 @@ public class InvoiceReceipt extends TenantEntity {
* 收款方
*/
private String payeeName;
/**
* 往来户金蝶供应商代码(发票销售方,保存时经客商档案/A901-1 回填,推送 A303-2 前强校验)
*/
private String supplierCode;
/**
* 开票单位开户银行
*/
@@ -968,6 +968,25 @@ public class KingdeeApBillSyncSupport {
return this.kingdeeOrgNumber(contract.getProjectId(), context);
}
/**
* 金蝶组织编码:指定部门沿部门树向上反查唯一平台公司(是否平台公司=是),取该平台公司的金蝶组织编码。
* 先票后款链路收票登记不挂合同/项目,结算组织由页面手选部门派生(A303-2 org_number)
*
* @param deptId 手选部门id(收票登记 deptId)
* @param context 金蝶同步上下文(缓存载体)
* @return 组织编码
*/
public String kingdeeOrgNumberByDept(Long deptId, KingdeeSyncContext context) {
if (deptId == null) {
throw new ServiceException("推送金蝶失败,收票登记未选择结算组织,无法确定金蝶组织编码");
}
Dept dept = SysCache.getDept(deptId);
if (dept == null) {
throw new ServiceException("推送金蝶失败,所选结算组织[" + deptId + "]不存在,无法确定金蝶组织编码");
}
return this.platformCompanyOrgNumber(dept, dept.getDeptName());
}
/**
* 金蝶组织编码:项目业务部门沿部门树向上反查唯一平台公司(是否平台公司=是),取该平台公司的金蝶组织编码;
* 项目未关联/未维护业务部门/业务部门未归属平台公司/平台公司未维护金蝶组织编码时拦截
@@ -978,8 +997,15 @@ public class KingdeeApBillSyncSupport {
*/
public String kingdeeOrgNumber(Long projectId, KingdeeSyncContext context) {
ProjectApply project = this.requireOrgProject(projectId, context);
// 沿部门树向上反查平台公司,上限 20 级防脏数据成环死循环
Dept dept = SysCache.getDept(project.getBusinessDeptId());
if (dept == null) {
throw new ServiceException("推送金蝶失败,项目[" + Func.toStr(project.getProjectName()) + "]业务部门不存在,无法确定金蝶组织编码");
}
return this.platformCompanyOrgNumber(dept, project.getBusinessDeptName());
}
/** 部门树向上反查平台公司金蝶组织编码(上限 20 级防脏数据成环死循环),未归属平台公司时拦截 */
private String platformCompanyOrgNumber(Dept dept, String startDeptName) {
for (int depth = 0; dept != null && depth < 20; depth++) {
if (Objects.equals(dept.getIsPlatformCompany(), 1)) {
if (Func.isBlank(dept.getKingdeeDeptCode())) {
@@ -989,7 +1015,7 @@ public class KingdeeApBillSyncSupport {
}
dept = dept.getParentId() == null ? null : SysCache.getDept(dept.getParentId());
}
throw new ServiceException("推送金蝶失败,项目业务部门[" + Func.toStr(project.getBusinessDeptName()) + "]未归属平台公司,无法确定金蝶组织编码");
throw new ServiceException("推送金蝶失败,部门[" + Func.toStr(startDeptName) + "]未归属平台公司,无法确定金蝶组织编码");
}
/**
@@ -0,0 +1,44 @@
-- 先票后款改造(收票登记A303-2 + 付款结算单A102-2 + A302-6指定应付)
-- ① blade_invoice_receipt 新增 supplier_code:往来户=发票销售方在金蝶的供应商代码(A901-1),保存时尽力回填、推送前强校验
-- ② 付款结算单(payment_settlement)下新增「发票登记」按钮权限:结算单审批后发票登记关联收票单并推送指定应付
-- 幂等可重复执行:列查 information_schema,菜单 NOT EXISTS 防重
-- ① 收票登记表新增 supplier_code 列
SET @ddl = (
SELECT IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_invoice_receipt'
AND COLUMN_NAME = 'supplier_code') = 0,
'ALTER TABLE `blade_invoice_receipt` ADD COLUMN `supplier_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''往来户金蝶供应商代码(发票销售方,A901-1,保存时尽力回填、推送前强校验)'' AFTER `payee_name`',
'SELECT 1'));
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- ② 付款结算单「发票登记」按钮权限(先票后款路径B:列表发票登记 → 关联收票单 → 推送 A302-6 指定应付)
INSERT INTO `blade_menu`
(`id`,`parent_id`,`code`,`name`,`alias`,`path`,`source`,`sort`,`category`,`action`,`is_open`,`component`,`remark`,`is_deleted`)
SELECT
2090000000000002300,
p.id,
'payment_settlement_invoice_register',
'发票登记',
'payment_settlement_invoice_register',
'',
'',
2,
2,
0,
1,
NULL,
'先票后款:结算单审批后发票登记关联收票单并推送金蝶指定应付',
0
FROM `blade_menu` p
WHERE p.`code` = 'payment_settlement'
AND p.`is_deleted` = 0
AND NOT EXISTS (
SELECT 1 FROM `blade_menu` x
WHERE x.`code` = 'payment_settlement_invoice_register' AND x.`is_deleted` = 0
)
LIMIT 1;