feat: 金蝶票池选票统一查镜像(收票登记与结算单认领统一分页查询+按票号补查+A801-1限定正常票,下线实时透传假分页)
This commit is contained in:
-74
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 正式结算单认领查询 全票池发票查询条件
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class FormalSettlementInvoicePoolQueryDTO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 页码,默认 1
|
||||
*/
|
||||
private Long current = 1L;
|
||||
/**
|
||||
* 每页条数,默认 10,最大 500
|
||||
*/
|
||||
private Long size = 10L;
|
||||
/**
|
||||
* 发票号码
|
||||
*/
|
||||
private String invoiceNo;
|
||||
/**
|
||||
* 开票日期起 yyyy-MM-dd
|
||||
*/
|
||||
private String invoiceDateStart;
|
||||
/**
|
||||
* 开票日期止 yyyy-MM-dd
|
||||
*/
|
||||
private String invoiceDateEnd;
|
||||
/**
|
||||
* 销方税号
|
||||
*/
|
||||
private String salerTaxNo;
|
||||
/**
|
||||
* 购方税号
|
||||
*/
|
||||
private String buyerTaxNo;
|
||||
/**
|
||||
* 单据使用状态,多个用英文逗号分隔[1未用,30在用,60已用,65已入账]
|
||||
*/
|
||||
private String expenseStatus;
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 金蝶票据池镜像统一查询条件(收票登记选票与正式结算单认领共用)
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "金蝶票据池镜像统一查询条件")
|
||||
public class KingdeeInvoicePoolQueryDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 当前页
|
||||
*/
|
||||
@Schema(description = "当前页")
|
||||
private Long current = 1L;
|
||||
|
||||
/**
|
||||
* 每页条数
|
||||
*/
|
||||
@Schema(description = "每页条数")
|
||||
private Long size = 10L;
|
||||
|
||||
/**
|
||||
* 发票号码,模糊
|
||||
*/
|
||||
@Schema(description = "发票号码(模糊)")
|
||||
private String invoiceNo;
|
||||
|
||||
/**
|
||||
* 开票日期起 yyyy-MM-dd
|
||||
*/
|
||||
@Schema(description = "开票日期起 yyyy-MM-dd")
|
||||
private String invoiceDateStart;
|
||||
|
||||
/**
|
||||
* 开票日期止 yyyy-MM-dd
|
||||
*/
|
||||
@Schema(description = "开票日期止 yyyy-MM-dd")
|
||||
private String invoiceDateEnd;
|
||||
|
||||
/**
|
||||
* 开票单位(销方名称),模糊
|
||||
*/
|
||||
@Schema(description = "开票单位(销方名称,模糊)")
|
||||
private String salerName;
|
||||
|
||||
/**
|
||||
* 受票单位(购方名称),模糊
|
||||
*/
|
||||
@Schema(description = "受票单位(购方名称,模糊)")
|
||||
private String buyerName;
|
||||
|
||||
/**
|
||||
* 发票类型名称,模糊(镜像存中文名)
|
||||
*/
|
||||
@Schema(description = "发票类型名称(模糊)")
|
||||
private String invoiceType;
|
||||
|
||||
/**
|
||||
* 销方税号,精确
|
||||
*/
|
||||
@Schema(description = "销方税号")
|
||||
private String salerTaxNo;
|
||||
|
||||
/**
|
||||
* 购方税号,精确
|
||||
*/
|
||||
@Schema(description = "购方税号")
|
||||
private String buyerTaxNo;
|
||||
|
||||
/**
|
||||
* 认领过滤:true 仅已认领,false 仅未认领,null 不过滤(已认领=存在正式结算单发票行)
|
||||
*/
|
||||
@Schema(description = "认领过滤:true已认领/false未认领/null不限")
|
||||
private Boolean claimed;
|
||||
|
||||
/**
|
||||
* 登记过滤:true 仅已登记,false 仅未登记,null 不过滤(已登记=存在非作废收票登记)
|
||||
*/
|
||||
@Schema(description = "登记过滤:true已登记/false未登记/null不限")
|
||||
private Boolean registered;
|
||||
}
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.pojo.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 正式结算单认领查询 全票池发票VO
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class FormalSettlementInvoicePoolVO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 发票号码
|
||||
*/
|
||||
private String invoiceNo;
|
||||
/**
|
||||
* 发票流水号
|
||||
*/
|
||||
private String serialNo;
|
||||
/**
|
||||
* 开票日期
|
||||
*/
|
||||
private String invoiceDate;
|
||||
/**
|
||||
* 发票类型名称
|
||||
*/
|
||||
private String invoiceTypeName;
|
||||
/**
|
||||
* 税率(百分数,如 13);票池明细缺失时为 null
|
||||
*/
|
||||
private BigDecimal taxRate;
|
||||
/**
|
||||
* 发票金额(含税,取票池价税合计)
|
||||
*/
|
||||
private BigDecimal invoiceAmount;
|
||||
/**
|
||||
* 可匹配发票金额(含税,本次口径等于价税合计)
|
||||
*/
|
||||
private BigDecimal availableInvoiceAmount;
|
||||
/**
|
||||
* 认领金额(默认等于可匹配金额,由前端按结算余额分配)
|
||||
*/
|
||||
private BigDecimal matchedAmount;
|
||||
/**
|
||||
* 开票单位(销方名称)
|
||||
*/
|
||||
private String salerName;
|
||||
/**
|
||||
* 受票单位(购方名称)
|
||||
*/
|
||||
private String buyerName;
|
||||
/**
|
||||
* 附件信息JSON,结构 {"source":"piaozone","path":"A801-2下载path","name":"文件名"}
|
||||
*/
|
||||
private String attachmentJson;
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.transport.pojo.vo;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 金蝶票据池镜像统一视图(含本地认领/登记标记;认领口径:可匹配与默认认领金额=价税合计)
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "金蝶票据池镜像统一视图")
|
||||
public class KingdeeInvoicePoolVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 镜像主键,收票登记保存绑定用(kingdeeInvoicePoolId) */
|
||||
@Schema(description = "镜像主键")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/** 发票号码 */
|
||||
@Schema(description = "发票号码")
|
||||
private String invoiceNo;
|
||||
|
||||
/** 金蝶发票流水号(票池唯一标识) */
|
||||
@Schema(description = "金蝶发票流水号")
|
||||
private String serialNo;
|
||||
|
||||
/** 开票日期 yyyy-MM-dd */
|
||||
@Schema(description = "开票日期")
|
||||
private String invoiceDate;
|
||||
|
||||
/** 发票类型名称(镜像落库时已由编码转名称) */
|
||||
@Schema(description = "发票类型名称")
|
||||
private String invoiceType;
|
||||
|
||||
/** 税率百分数,如 13 */
|
||||
@Schema(description = "税率百分数")
|
||||
private BigDecimal taxRate;
|
||||
|
||||
/** 价税合计 */
|
||||
@Schema(description = "发票金额(价税合计)")
|
||||
private BigDecimal invoiceAmount;
|
||||
|
||||
/** 税额 */
|
||||
@Schema(description = "税额")
|
||||
private BigDecimal taxAmount;
|
||||
|
||||
/** 受票单位(购方名称) */
|
||||
@Schema(description = "受票单位")
|
||||
private String receiverName;
|
||||
|
||||
/** 购方税号 */
|
||||
@Schema(description = "购方税号")
|
||||
private String buyerTaxNo;
|
||||
|
||||
/** 开票单位(销方名称) */
|
||||
@Schema(description = "开票单位")
|
||||
private String issuerName;
|
||||
|
||||
/** 销方税号 */
|
||||
@Schema(description = "销方税号")
|
||||
private String salerTaxNo;
|
||||
|
||||
/** 销方开户行名称 */
|
||||
@Schema(description = "销方开户行名称")
|
||||
private String bankName;
|
||||
|
||||
/** 销方银行账号 */
|
||||
@Schema(description = "销方银行账号")
|
||||
private String bankAccount;
|
||||
|
||||
/** 销方开户行及账号 */
|
||||
@Schema(description = "开户行及账号")
|
||||
private String issuingBank;
|
||||
|
||||
/** 销方电话 */
|
||||
@Schema(description = "电话")
|
||||
private String phone;
|
||||
|
||||
/** 客户邮箱 JSON 串 */
|
||||
@Schema(description = "客户邮箱JSON")
|
||||
private String customerEmails;
|
||||
|
||||
/** 部门邮箱 JSON 串 */
|
||||
@Schema(description = "部门邮箱JSON")
|
||||
private String departmentEmails;
|
||||
|
||||
/** 金蝶流水号(登记侧展示为金蝶单据号) */
|
||||
@Schema(description = "金蝶单据号")
|
||||
private String kingdeeBillNo;
|
||||
|
||||
/** 同步状态 unsynced/synced/failed */
|
||||
@Schema(description = "金蝶同步状态")
|
||||
private String kingdeeStatus;
|
||||
|
||||
/** 查验状态 */
|
||||
@Schema(description = "查验状态")
|
||||
private String checkStatus;
|
||||
|
||||
/** 附件 JSON(票易通下载 path) */
|
||||
@Schema(description = "附件信息JSON")
|
||||
private String attachmentsJson;
|
||||
|
||||
/** 可认领金额,口径同发票金额 */
|
||||
@Schema(description = "可认领金额")
|
||||
private BigDecimal availableInvoiceAmount;
|
||||
|
||||
/** 默认认领金额,口径同发票金额 */
|
||||
@Schema(description = "默认认领金额")
|
||||
private BigDecimal matchedAmount;
|
||||
|
||||
/** 是否已被正式结算单认领 */
|
||||
@Schema(description = "是否已认领")
|
||||
private Boolean claimed;
|
||||
|
||||
/** 是否已存在非作废收票登记 */
|
||||
@Schema(description = "是否已登记")
|
||||
private Boolean registered;
|
||||
}
|
||||
+14
-5
@@ -27,14 +27,15 @@ import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementInvoiceClaimRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementInvoicePoolQueryDTO;
|
||||
import org.springblade.transport.pojo.dto.KingdeeInvoicePoolQueryDTO;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementInvoicePoolVO;
|
||||
import org.springblade.transport.pojo.vo.KingdeeInvoicePoolVO;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementVO;
|
||||
import org.springblade.transport.excel.FormalSettlementExcel;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
import org.springblade.transport.service.IFormalSettlementService;
|
||||
import org.springblade.transport.service.IInvoiceReceiptService;
|
||||
import org.springblade.transport.service.IPreSettlementService;
|
||||
import org.springblade.transport.service.IReceiptFlowService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -63,6 +64,7 @@ public class FormalSettlementController extends BladeController {
|
||||
private final IFormalSettlementService formalSettlementService;
|
||||
private final IPreSettlementService preSettlementService;
|
||||
private final IReceiptFlowService receiptFlowService;
|
||||
private final IInvoiceReceiptService invoiceReceiptService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@@ -260,8 +262,15 @@ public class FormalSettlementController extends BladeController {
|
||||
|
||||
@GetMapping("/invoice-pool")
|
||||
@ApiOperationSupport(order = 21)
|
||||
@Operation(summary = "查询发票云全票池发票(认领查询)")
|
||||
public R<IPage<FormalSettlementInvoicePoolVO>> invoicePool(FormalSettlementInvoicePoolQueryDTO query) {
|
||||
return R.data(formalSettlementService.invoicePoolQuery(query));
|
||||
@Operation(summary = "金蝶票据池镜像分页查询(认领查询)")
|
||||
public R<IPage<KingdeeInvoicePoolVO>> invoicePool(KingdeeInvoicePoolQueryDTO query) {
|
||||
return R.data(invoiceReceiptService.invoicePoolPage(query));
|
||||
}
|
||||
|
||||
@PostMapping("/invoice-pool/fetch")
|
||||
@ApiOperationSupport(order = 22)
|
||||
@Operation(summary = "按发票号码从金蝶票池补查单张发票")
|
||||
public R<KingdeeInvoicePoolVO> fetchInvoicePool(@RequestParam String invoiceNo) {
|
||||
return R.data(invoiceReceiptService.fetchKingdeeInvoiceByNo(invoiceNo));
|
||||
}
|
||||
}
|
||||
|
||||
+12
-4
@@ -37,8 +37,9 @@ import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.transport.pojo.dto.InvoiceReceiptSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.InvoiceReceiptStatusRequest;
|
||||
import org.springblade.transport.pojo.entity.KingdeeInvoicePool;
|
||||
import org.springblade.transport.pojo.dto.KingdeeInvoicePoolQueryDTO;
|
||||
import org.springblade.transport.pojo.vo.InvoiceReceiptVO;
|
||||
import org.springblade.transport.pojo.vo.KingdeeInvoicePoolVO;
|
||||
import org.springblade.transport.service.IInvoiceReceiptService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -80,9 +81,16 @@ public class InvoiceReceiptController extends BladeController {
|
||||
|
||||
@GetMapping("/invoice-pool")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "查询金蝶进项发票票据池")
|
||||
public R<List<KingdeeInvoicePool>> invoicePool(@RequestParam(required = false) String keyword) {
|
||||
return R.data(invoiceReceiptService.invoicePool(keyword));
|
||||
@Operation(summary = "金蝶票据池镜像分页查询(含认领/登记标记)")
|
||||
public R<IPage<KingdeeInvoicePoolVO>> invoicePool(KingdeeInvoicePoolQueryDTO query) {
|
||||
return R.data(invoiceReceiptService.invoicePoolPage(query));
|
||||
}
|
||||
|
||||
@PostMapping("/invoice-pool/fetch")
|
||||
@ApiOperationSupport(order = 14)
|
||||
@Operation(summary = "按发票号码从金蝶票池补查单张发票")
|
||||
public R<KingdeeInvoicePoolVO> fetchInvoicePool(@RequestParam String invoiceNo) {
|
||||
return R.data(invoiceReceiptService.fetchKingdeeInvoiceByNo(invoiceNo));
|
||||
}
|
||||
|
||||
@GetMapping("/settlement-candidates")
|
||||
|
||||
+25
@@ -26,8 +26,12 @@
|
||||
package org.springblade.transport.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springblade.transport.pojo.dto.KingdeeInvoicePoolQueryDTO;
|
||||
import org.springblade.transport.pojo.entity.KingdeeInvoicePool;
|
||||
import org.springblade.transport.pojo.vo.KingdeeInvoicePoolVO;
|
||||
|
||||
/**
|
||||
* 金蝶进项发票票据池 Mapper 接口
|
||||
@@ -36,4 +40,25 @@ import org.springblade.transport.pojo.entity.KingdeeInvoicePool;
|
||||
*/
|
||||
@Mapper
|
||||
public interface KingdeeInvoicePoolMapper extends BaseMapper<KingdeeInvoicePool> {
|
||||
|
||||
/**
|
||||
* 金蝶票据池镜像统一分页查询:认领/登记标记由 EXISTS 子查询直出
|
||||
*
|
||||
* @param page 分页参数
|
||||
* @param query 统一查询条件(已在上层完成 trim 与日期格式校验)
|
||||
* @param tenantId 当前租户
|
||||
* @return 统一视图分页
|
||||
*/
|
||||
IPage<KingdeeInvoicePoolVO> selectInvoicePoolPage(IPage<KingdeeInvoicePoolVO> page,
|
||||
@Param("query") KingdeeInvoicePoolQueryDTO query, @Param("tenantId") String tenantId);
|
||||
|
||||
/**
|
||||
* 按发票号码查询单张镜像统一视图(补查落库后回读)
|
||||
*
|
||||
* @param invoiceNo 发票号码
|
||||
* @param tenantId 当前租户
|
||||
* @return 统一视图,无镜像时 null
|
||||
*/
|
||||
KingdeeInvoicePoolVO selectInvoicePoolVO(@Param("invoiceNo") String invoiceNo,
|
||||
@Param("tenantId") String tenantId);
|
||||
}
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.transport.mapper.KingdeeInvoicePoolMapper">
|
||||
|
||||
<!-- 已认领:任一有效正式结算单发票行出现过(结算单作废不删发票行,须关联主单剔除作废与已删;自定义 SQL 无租户插件,手工带租户与逻辑删除) -->
|
||||
<sql id="claimedExists">
|
||||
EXISTS (SELECT 1 FROM blade_formal_settlement_invoice c
|
||||
WHERE c.is_deleted = 0 AND c.tenant_id = p.tenant_id AND c.invoice_no = p.invoice_no
|
||||
AND EXISTS (SELECT 1 FROM blade_formal_settlement s
|
||||
WHERE s.id = c.formal_settlement_id AND s.is_deleted = 0
|
||||
AND s.approval_status != 'voided'))
|
||||
</sql>
|
||||
|
||||
<!-- 已登记:存在非作废收票登记 -->
|
||||
<sql id="registeredExists">
|
||||
EXISTS (SELECT 1 FROM blade_invoice_receipt r
|
||||
WHERE r.is_deleted = 0 AND r.tenant_id = p.tenant_id
|
||||
AND r.approval_status != 'voided' AND r.invoice_no = p.invoice_no)
|
||||
</sql>
|
||||
|
||||
<!-- 统一视图列:价税合计与可认领/默认认领金额同源;镜像 invoice_type 落库即中文名 -->
|
||||
<sql id="invoicePoolVoColumns">
|
||||
p.id, p.invoice_no, p.serial_no,
|
||||
DATE_FORMAT(p.invoice_date, '%Y-%m-%d') AS invoice_date,
|
||||
p.invoice_type, p.tax_rate, p.invoice_amount, p.tax_amount,
|
||||
p.receiver_name, p.buyer_tax_no, p.issuer_name, p.saler_tax_no,
|
||||
p.bank_name, p.bank_account, p.issuing_bank, p.phone,
|
||||
p.customer_emails, p.department_emails,
|
||||
p.kingdee_bill_no, p.kingdee_status, p.check_status, p.attachments_json,
|
||||
p.invoice_amount AS available_invoice_amount,
|
||||
p.invoice_amount AS matched_amount,
|
||||
<include refid="claimedExists"/> AS claimed,
|
||||
<include refid="registeredExists"/> AS registered
|
||||
</sql>
|
||||
|
||||
<select id="selectInvoicePoolPage" resultType="org.springblade.transport.pojo.vo.KingdeeInvoicePoolVO">
|
||||
SELECT
|
||||
<include refid="invoicePoolVoColumns"/>
|
||||
FROM blade_kingdee_invoice_pool p
|
||||
WHERE p.is_deleted = 0 AND p.status = 1 AND p.tenant_id = #{tenantId}
|
||||
<if test="query.invoiceNo != null and query.invoiceNo != ''">
|
||||
AND p.invoice_no LIKE CONCAT('%', #{query.invoiceNo}, '%')
|
||||
</if>
|
||||
<if test="query.salerName != null and query.salerName != ''">
|
||||
AND p.issuer_name LIKE CONCAT('%', #{query.salerName}, '%')
|
||||
</if>
|
||||
<if test="query.buyerName != null and query.buyerName != ''">
|
||||
AND p.receiver_name LIKE CONCAT('%', #{query.buyerName}, '%')
|
||||
</if>
|
||||
<if test="query.invoiceType != null and query.invoiceType != ''">
|
||||
AND p.invoice_type LIKE CONCAT('%', #{query.invoiceType}, '%')
|
||||
</if>
|
||||
<if test="query.salerTaxNo != null and query.salerTaxNo != ''">
|
||||
AND p.saler_tax_no = #{query.salerTaxNo}
|
||||
</if>
|
||||
<if test="query.buyerTaxNo != null and query.buyerTaxNo != ''">
|
||||
AND p.buyer_tax_no = #{query.buyerTaxNo}
|
||||
</if>
|
||||
<if test="query.invoiceDateStart != null and query.invoiceDateStart != ''">
|
||||
AND p.invoice_date >= #{query.invoiceDateStart}
|
||||
</if>
|
||||
<if test="query.invoiceDateEnd != null and query.invoiceDateEnd != ''">
|
||||
AND p.invoice_date <= #{query.invoiceDateEnd}
|
||||
</if>
|
||||
<if test="query.claimed != null and query.claimed">
|
||||
AND <include refid="claimedExists"/>
|
||||
</if>
|
||||
<if test="query.claimed != null and !query.claimed">
|
||||
AND NOT <include refid="claimedExists"/>
|
||||
</if>
|
||||
<if test="query.registered != null and query.registered">
|
||||
AND <include refid="registeredExists"/>
|
||||
</if>
|
||||
<if test="query.registered != null and !query.registered">
|
||||
AND NOT <include refid="registeredExists"/>
|
||||
</if>
|
||||
ORDER BY p.source_updated_time DESC, p.create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectInvoicePoolVO" resultType="org.springblade.transport.pojo.vo.KingdeeInvoicePoolVO">
|
||||
SELECT
|
||||
<include refid="invoicePoolVoColumns"/>
|
||||
FROM blade_kingdee_invoice_pool p
|
||||
WHERE p.is_deleted = 0 AND p.status = 1 AND p.tenant_id = #{tenantId} AND p.invoice_no = #{invoiceNo}
|
||||
LIMIT 1
|
||||
</select>
|
||||
</mapper>
|
||||
-3
@@ -13,7 +13,6 @@ import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementInvoicePoolVO;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementVO;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
import org.springblade.transport.pojo.entity.PreSettlement;
|
||||
@@ -23,7 +22,6 @@ import java.util.List;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementInvoiceClaimRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementInvoicePoolQueryDTO;
|
||||
|
||||
/**
|
||||
* 正式结算单服务
|
||||
@@ -50,5 +48,4 @@ public interface IFormalSettlementService extends BaseService<FormalSettlement>
|
||||
String applyPayment(FormalSettlementPaymentRequest request);
|
||||
List<String> applyPayments(FormalSettlementBatchPaymentRequest request);
|
||||
void claimInvoices(FormalSettlementInvoiceClaimRequest request);
|
||||
IPage<FormalSettlementInvoicePoolVO> invoicePoolQuery(FormalSettlementInvoicePoolQueryDTO query);
|
||||
}
|
||||
|
||||
+18
-1
@@ -29,10 +29,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.transport.pojo.dto.InvoiceReceiptSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.InvoiceReceiptStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.KingdeeInvoicePoolQueryDTO;
|
||||
import org.springblade.transport.pojo.entity.InvoiceReceipt;
|
||||
import org.springblade.transport.pojo.entity.InvoiceReceiptRecord;
|
||||
import org.springblade.transport.pojo.entity.KingdeeInvoicePool;
|
||||
import org.springblade.transport.pojo.vo.InvoiceReceiptVO;
|
||||
import org.springblade.transport.pojo.vo.KingdeeInvoicePoolVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -48,7 +50,22 @@ public interface IInvoiceReceiptService extends BaseService<InvoiceReceipt> {
|
||||
|
||||
InvoiceReceiptVO detail(Long id);
|
||||
|
||||
List<KingdeeInvoicePool> invoicePool(String keyword);
|
||||
/**
|
||||
* 金蝶票据池镜像分页查询(含本地认领/登记标记),收票登记选票与正式结算单认领共用
|
||||
*
|
||||
* @param query 统一查询条件
|
||||
* @return 镜像分页
|
||||
*/
|
||||
IPage<KingdeeInvoicePoolVO> invoicePoolPage(KingdeeInvoicePoolQueryDTO query);
|
||||
|
||||
/**
|
||||
* 按发票号码从金蝶票池精确补查单张发票:与定时同步同一套白名单校验,
|
||||
* 通过后 upsert 入镜像并返回;不受增量时间窗口约束
|
||||
*
|
||||
* @param invoiceNo 发票号码
|
||||
* @return 镜像统一视图
|
||||
*/
|
||||
KingdeeInvoicePoolVO fetchKingdeeInvoiceByNo(String invoiceNo);
|
||||
|
||||
List<Map<String, Object>> settlementCandidates(String keyword, Long receiptId);
|
||||
|
||||
|
||||
-118
@@ -11,7 +11,6 @@ package org.springblade.transport.service.impl;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
@@ -19,14 +18,6 @@ import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.thirdparty.bfi.constant.BfiConstant;
|
||||
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoicePoolQueryDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.dto.BfiInvoicePoolQueryDataDTO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoicePoolItemVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiInvoicePoolVO;
|
||||
import org.springblade.thirdparty.bfi.pojo.vo.BfiPageVO;
|
||||
import org.springblade.thirdparty.bfi.service.IBfiService;
|
||||
import org.springblade.transport.mapper.FormalSettlementDetailMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementDetailFeeMapper;
|
||||
import org.springblade.transport.mapper.FormalSettlementChangeRecordMapper;
|
||||
@@ -54,7 +45,6 @@ import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementInvoiceClaimRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementInvoicePoolQueryDTO;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
@@ -80,7 +70,6 @@ import org.springblade.transport.pojo.entity.ReceivablePayableDetail;
|
||||
import org.springblade.transport.pojo.entity.ReceivablePayableCargoFee;
|
||||
import org.springblade.transport.pojo.entity.SettlementAdjustment;
|
||||
import org.springblade.transport.pojo.entity.Waybill;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementInvoicePoolVO;
|
||||
import org.springblade.transport.pojo.vo.FormalSettlementVO;
|
||||
import org.springblade.transport.pojo.vo.PreSettlementVO;
|
||||
import org.springblade.transport.pojo.vo.SettlementAdjustmentVO;
|
||||
@@ -110,7 +99,6 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -151,7 +139,6 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
private final IWaybillService waybillService;
|
||||
private final KingdeeApBillSyncSupport kingdeeApBillSyncSupport;
|
||||
private final KingdeeArBillSyncSupport kingdeeArBillSyncSupport;
|
||||
private final IBfiService bfiService;
|
||||
|
||||
@Override
|
||||
public IPage<FormalSettlementVO> selectPage(IPage<FormalSettlement> page, FormalSettlementVO query) {
|
||||
@@ -1449,109 +1436,4 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
private String required(String value, String field) { if (Func.isEmpty(value)) throw new ServiceException("请填写" + field); return value; }
|
||||
private String firstNotEmpty(Object first, Object second) { return Func.isNotEmpty(first) ? String.valueOf(first) : String.valueOf(second); }
|
||||
private String limit(String value, int max) { if (value != null && value.length() > max) throw new ServiceException("内容不能超过" + max + "个字"); return value; }
|
||||
|
||||
@Override
|
||||
public IPage<FormalSettlementInvoicePoolVO> invoicePoolQuery(FormalSettlementInvoicePoolQueryDTO query) {
|
||||
long pageNo = Math.max(query.getCurrent() == null ? 1 : query.getCurrent(), 1);
|
||||
// 上限 499:预留 1 条给 hasMore 探测,单次远程请求不超过 rim 契约 pageSize 上限 500
|
||||
long pageSize = Math.min(Math.max(query.getSize() == null ? 10 : query.getSize(), 1), 499);
|
||||
String invoiceNo = query.getInvoiceNo();
|
||||
String invoiceDateStart = query.getInvoiceDateStart();
|
||||
String invoiceDateEnd = query.getInvoiceDateEnd();
|
||||
String salerTaxNo = query.getSalerTaxNo();
|
||||
String buyerTaxNo = query.getBuyerTaxNo();
|
||||
String expenseStatus = query.getExpenseStatus();
|
||||
// A801-1 rim 契约不支持全量且不返回总数:透传 pageNo/pageSize 单页查询,
|
||||
// 多取 1 条探测是否还有下一页,total 合成为当前已知的最小精确值供前端分页器翻页
|
||||
BfiInvoicePoolQueryDataDTO data = new BfiInvoicePoolQueryDataDTO();
|
||||
data.setPageNo((int) pageNo);
|
||||
data.setPageSize((int) pageSize + 1);
|
||||
if (StringUtil.isNotBlank(invoiceNo)) {
|
||||
data.setInvoiceNo(invoiceNo.trim());
|
||||
}
|
||||
if (StringUtil.isNotBlank(invoiceDateStart)) {
|
||||
data.setInvoiceDateStart(invoiceDateStart.trim());
|
||||
}
|
||||
if (StringUtil.isNotBlank(invoiceDateEnd)) {
|
||||
data.setInvoiceDateEnd(invoiceDateEnd.trim());
|
||||
}
|
||||
if (StringUtil.isNotBlank(salerTaxNo)) {
|
||||
data.setSalerTaxNo(salerTaxNo.trim());
|
||||
}
|
||||
if (StringUtil.isNotBlank(buyerTaxNo)) {
|
||||
data.setBuyerTaxNo(buyerTaxNo.trim());
|
||||
}
|
||||
if (StringUtil.isNotBlank(expenseStatus)) {
|
||||
data.setExpenseStatus(expenseStatus.trim());
|
||||
}
|
||||
BfiInvoicePoolQueryDTO param = new BfiInvoicePoolQueryDTO();
|
||||
param.setQueryParam(data);
|
||||
BfiPageVO<BfiInvoicePoolVO> poolPage = bfiService.queryInvoicePool(param);
|
||||
List<FormalSettlementInvoicePoolVO> invoices = poolPage.getRows() == null ? List.of()
|
||||
: poolPage.getRows().stream()
|
||||
.map(this::toInvoicePoolVO)
|
||||
.toList();
|
||||
// 多取的 1 条仅用于 hasMore 判断,不返回给前端
|
||||
boolean hasMore = invoices.size() > pageSize;
|
||||
List<FormalSettlementInvoicePoolVO> records = hasMore ? invoices.subList(0, (int) pageSize) : invoices;
|
||||
long total = hasMore ? pageNo * pageSize + 1 : (pageNo - 1) * pageSize + records.size();
|
||||
log.info("正式结算单认领查询 全票池第 {} 页 {} 条/页,返回 {} 条,hasMore:{}", pageNo, pageSize, records.size(), hasMore);
|
||||
Page<FormalSettlementInvoicePoolVO> page = new Page<>(pageNo, pageSize);
|
||||
page.setRecords(records);
|
||||
page.setTotal(total);
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* A801-1 全票池发票 -> 正式结算单认领VO 字段映射
|
||||
*/
|
||||
private FormalSettlementInvoicePoolVO toInvoicePoolVO(BfiInvoicePoolVO poolInvoice) {
|
||||
FormalSettlementInvoicePoolVO vo = new FormalSettlementInvoicePoolVO();
|
||||
// 发票号码
|
||||
vo.setInvoiceNo(poolInvoice.getInvoiceNo());
|
||||
// 发票流水号,票池发票唯一标识
|
||||
vo.setSerialNo(poolInvoice.getSerialNo());
|
||||
// 开票日期 yyyy-MM-dd
|
||||
vo.setInvoiceDate(poolInvoice.getInvoiceDate());
|
||||
// 发票类型编码转名称,未知编码原样返回
|
||||
vo.setInvoiceTypeName(BfiConstant.INVOICE_TYPE_NAMES.getOrDefault(poolInvoice.getInvoiceType(),
|
||||
poolInvoice.getInvoiceType()));
|
||||
// 税率:顶层优先、回退首条明细,小数转百分数(0.13 -> 13)
|
||||
vo.setTaxRate(resolveTaxRate(poolInvoice));
|
||||
// 价税合计作为发票金额,可匹配金额、默认认领金额与发票金额同源
|
||||
BigDecimal totalAmount = parseAmount(poolInvoice.getTotalAmount());
|
||||
vo.setInvoiceAmount(totalAmount);
|
||||
vo.setAvailableInvoiceAmount(totalAmount);
|
||||
vo.setMatchedAmount(totalAmount);
|
||||
// 开票单位(销方名称)
|
||||
vo.setSalerName(poolInvoice.getSalerName());
|
||||
// 受票单位(购方名称)
|
||||
vo.setBuyerName(poolInvoice.getBuyerName());
|
||||
// 附件信息JSON:path 供 A801-2 进项发票下载,文件名以发票号码命名
|
||||
Map<String, Object> attachment = new LinkedHashMap<>();
|
||||
attachment.put("source", "piaozone");
|
||||
attachment.put("path", poolInvoice.getDownloadUrl());
|
||||
attachment.put("name", poolInvoice.getInvoiceNo() + ".pdf");
|
||||
vo.setAttachmentJson(JsonUtil.toJson(attachment));
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 税率优先取顶层税率的小数值换算为百分数,如 0.13 -> 13;顶层为空时回退取首条明细税率,均无时返回 null
|
||||
*/
|
||||
private BigDecimal resolveTaxRate(BfiInvoicePoolVO poolInvoice) {
|
||||
if (StringUtil.isNotBlank(poolInvoice.getTaxRate())) {
|
||||
return new BigDecimal(poolInvoice.getTaxRate()).multiply(BigDecimal.valueOf(100));
|
||||
}
|
||||
return Optional.ofNullable(poolInvoice.getItems()).orElse(List.of()).stream()
|
||||
.map(BfiInvoicePoolItemVO::getTaxRate)
|
||||
.filter(StringUtil::isNotBlank)
|
||||
.findFirst()
|
||||
.map(taxRate -> new BigDecimal(taxRate).multiply(BigDecimal.valueOf(100)))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private BigDecimal parseAmount(String value) {
|
||||
return StringUtil.isBlank(value) ? BigDecimal.ZERO : new BigDecimal(value);
|
||||
}
|
||||
}
|
||||
|
||||
+80
-9
@@ -28,6 +28,7 @@ package org.springblade.transport.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -58,6 +59,7 @@ import org.springblade.transport.mapper.InvoiceReceiptSettlementMapper;
|
||||
import org.springblade.transport.mapper.KingdeeInvoicePoolMapper;
|
||||
import org.springblade.transport.pojo.dto.InvoiceReceiptSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.InvoiceReceiptStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.KingdeeInvoicePoolQueryDTO;
|
||||
import org.springblade.transport.pojo.entity.CustomerArchive;
|
||||
import org.springblade.transport.pojo.entity.CustomerContact;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
@@ -66,6 +68,7 @@ import org.springblade.transport.pojo.entity.InvoiceReceiptRecord;
|
||||
import org.springblade.transport.pojo.entity.InvoiceReceiptSettlement;
|
||||
import org.springblade.transport.pojo.entity.KingdeeInvoicePool;
|
||||
import org.springblade.transport.pojo.vo.InvoiceReceiptVO;
|
||||
import org.springblade.transport.pojo.vo.KingdeeInvoicePoolVO;
|
||||
import org.springblade.transport.service.IInvoiceReceiptService;
|
||||
import org.springblade.transport.wrapper.InvoiceReceiptWrapper;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
@@ -78,6 +81,7 @@ import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -135,6 +139,9 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
/** 定时绑定 single-flight 锁键前缀,按租户区分,同租户同一时刻只允许一轮全票池同步 */
|
||||
private static final String POOL_SYNC_LOCK_PREFIX = "transport:invoice-receipt:kingdee-pool-sync:";
|
||||
|
||||
/** A801-1 查询限定发票状态:0 正常(票易通字典),作废/异常票不进镜像、不可补查 */
|
||||
private static final String POOL_INVOICE_STATUS_NORMAL = "0";
|
||||
|
||||
private final KingdeeInvoicePoolMapper invoicePoolMapper;
|
||||
private final InvoiceReceiptSettlementMapper settlementRelationMapper;
|
||||
private final InvoiceReceiptRecordMapper recordMapper;
|
||||
@@ -202,15 +209,75 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KingdeeInvoicePool> invoicePool(String keyword) {
|
||||
return invoicePoolMapper.selectList(Wrappers.<KingdeeInvoicePool>lambdaQuery()
|
||||
.eq(KingdeeInvoicePool::getStatus, 1)
|
||||
.and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(KingdeeInvoicePool::getInvoiceNo, keyword)
|
||||
.or().like(KingdeeInvoicePool::getIssuerName, keyword)
|
||||
.or().like(KingdeeInvoicePool::getReceiverName, keyword))
|
||||
.orderByDesc(KingdeeInvoicePool::getSourceUpdatedTime)
|
||||
.orderByDesc(KingdeeInvoicePool::getCreateTime)
|
||||
.last("limit 200"));
|
||||
public IPage<KingdeeInvoicePoolVO> invoicePoolPage(KingdeeInvoicePoolQueryDTO query) {
|
||||
long current = query.getCurrent() == null ? 1L : Math.max(query.getCurrent(), 1L);
|
||||
long size = query.getSize() == null ? 10L : Math.min(Math.max(query.getSize(), 1L), 100L);
|
||||
query.setCurrent(current);
|
||||
query.setSize(size);
|
||||
query.setInvoiceNo(trimOrNull(query.getInvoiceNo()));
|
||||
query.setSalerName(trimOrNull(query.getSalerName()));
|
||||
query.setBuyerName(trimOrNull(query.getBuyerName()));
|
||||
query.setInvoiceType(trimOrNull(query.getInvoiceType()));
|
||||
query.setSalerTaxNo(trimOrNull(query.getSalerTaxNo()));
|
||||
query.setBuyerTaxNo(trimOrNull(query.getBuyerTaxNo()));
|
||||
query.setInvoiceDateStart(normalizeQueryDate(query.getInvoiceDateStart()));
|
||||
query.setInvoiceDateEnd(normalizeQueryDate(query.getInvoiceDateEnd()));
|
||||
Page<KingdeeInvoicePoolVO> page = new Page<>(current, size);
|
||||
return invoicePoolMapper.selectInvoicePoolPage(page, query, AuthUtil.getTenantId());
|
||||
}
|
||||
|
||||
/** 空白串归一为 null,便于 XML 的 != '' 判空条件 */
|
||||
private String trimOrNull(String text) {
|
||||
return StringUtil.isBlank(text) ? null : text.trim();
|
||||
}
|
||||
|
||||
/** 查询日期清洗:空转 null,格式非法直接报业务异常(自定义 SQL 无类型保护,先校验再进 XML) */
|
||||
private String normalizeQueryDate(String text) {
|
||||
if (StringUtil.isBlank(text)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return LocalDate.parse(text.trim()).toString();
|
||||
} catch (DateTimeParseException exception) {
|
||||
throw new ServiceException("开票日期格式应为 yyyy-MM-dd");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KingdeeInvoicePoolVO fetchKingdeeInvoiceByNo(String invoiceNo) {
|
||||
if (StringUtil.isBlank(invoiceNo)) {
|
||||
throw new ServiceException("请填写发票号码");
|
||||
}
|
||||
String trimmedInvoiceNo = invoiceNo.trim();
|
||||
// 镜像优先回读:白名单只约束「入镜像」,回读镜像不受限;镜像已有票不再打远程,不受金蝶可用性影响
|
||||
KingdeeInvoicePoolVO existingVo = invoicePoolMapper.selectInvoicePoolVO(trimmedInvoiceNo, AuthUtil.getTenantId());
|
||||
if (existingVo != null) {
|
||||
return existingVo;
|
||||
}
|
||||
// A801-1 无时间窗口约束,票池更新时间滑出增量窗口的老票也能精确命中;复用窄查后仍保留票号全等匹配的防御过滤
|
||||
List<BfiInvoicePoolVO> poolRows = queryPoolByInvoiceNo(trimmedInvoiceNo);
|
||||
BfiInvoicePoolVO poolRow = poolRows.stream()
|
||||
.filter(row -> StringUtil.isNotBlank(row.getInvoiceNo())
|
||||
&& trimmedInvoiceNo.equals(row.getInvoiceNo().trim()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (poolRow == null) {
|
||||
throw new ServiceException("金蝶票池未查询到发票 " + trimmedInvoiceNo);
|
||||
}
|
||||
if (filterByInvoiceTypes(List.of(poolRow)).isEmpty()) {
|
||||
throw new ServiceException("发票 " + trimmedInvoiceNo + " 的票种不在同步白名单内,不能补查");
|
||||
}
|
||||
if (filterByArchiveTaxNos(customerTaxNoSet(), List.of(poolRow)).isEmpty()) {
|
||||
throw new ServiceException("发票 " + trimmedInvoiceNo
|
||||
+ " 购销双方存在未建档税号,请先在客商档案维护统一社会信用代码后再补查");
|
||||
}
|
||||
// upsert 自带票面指纹比对,无变化不重写,重复点击安全;随后从镜像回读统一视图(含认领/登记标记)
|
||||
batchUpsertInvoicePool(List.of(poolRow));
|
||||
KingdeeInvoicePoolVO vo = invoicePoolMapper.selectInvoicePoolVO(trimmedInvoiceNo, AuthUtil.getTenantId());
|
||||
if (vo == null) {
|
||||
throw new ServiceException("补查失败:镜像回读不到发票 " + trimmedInvoiceNo);
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -752,6 +819,8 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
data.setPageNo(1);
|
||||
data.setPageSize(POOL_PAGE_SIZE);
|
||||
data.setInvoiceNo(invoiceNo.trim());
|
||||
// 只认发票状态正常的票,作废/异常票不再进入镜像
|
||||
data.setInvoiceStatus(POOL_INVOICE_STATUS_NORMAL);
|
||||
BfiInvoicePoolQueryDTO param = new BfiInvoicePoolQueryDTO();
|
||||
param.setQueryParam(data);
|
||||
BfiPageVO<BfiInvoicePoolVO> page = bfiService.queryInvoicePool(param);
|
||||
@@ -767,6 +836,8 @@ public class InvoiceReceiptServiceImpl extends BaseServiceImpl<InvoiceReceiptMap
|
||||
data.setPageSize(POOL_PAGE_SIZE);
|
||||
data.setUpdateTime(windowStart.format(POOL_TIME_FORMATTER));
|
||||
data.setUpdateTimeEnd(windowEnd.format(POOL_TIME_FORMATTER));
|
||||
// 只认发票状态正常的票,作废/异常票不再进入镜像
|
||||
data.setInvoiceStatus(POOL_INVOICE_STATUS_NORMAL);
|
||||
BfiInvoicePoolQueryDTO param = new BfiInvoicePoolQueryDTO();
|
||||
param.setQueryParam(data);
|
||||
BfiPageVO<BfiInvoicePoolVO> page = bfiService.queryInvoicePool(param);
|
||||
|
||||
Reference in New Issue
Block a user