diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java index f7b4c29b..52cd3376 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceReceiptSaveRequest.java @@ -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 settlements; /** diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java index 91a33972..f3d58532 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceReceipt.java @@ -112,6 +112,10 @@ public class InvoiceReceipt extends TenantEntity { * 收款方 */ private String payeeName; + /** + * 往来户金蝶供应商代码(发票销售方,保存时经客商档案/A901-1 回填,推送 A303-2 前强校验) + */ + private String supplierCode; /** * 开票单位开户银行 */ diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java index 4b1e9c93..653180b7 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/KingdeeApBillSyncSupport.java @@ -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) + "]未归属平台公司,无法确定金蝶组织编码"); } /** diff --git a/doc/sql/transport/lqj/temp/06_blade_invoice_receipt_supplier_code_menu_20261031.sql b/doc/sql/transport/lqj/temp/06_blade_invoice_receipt_supplier_code_menu_20261031.sql new file mode 100644 index 00000000..a8279540 --- /dev/null +++ b/doc/sql/transport/lqj/temp/06_blade_invoice_receipt_supplier_code_menu_20261031.sql @@ -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;