李白
2026-05-29 c865989f10e5a1ae4bb78831a879210fcdca2f83
开票(开蓝票,红票,上传bip)
3个文件已修改
33个文件已添加
4255 ■■■■■ 已修改文件
platformx-boot/src/main/resources/application-dev.yml 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/constant/FlowNameEnum.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/BipInvoice.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/BipResVo.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/BipTokenVo.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/FileBip.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/InvoiceResult.java 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/InvoiceResultItem.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/InvoicingVo.java 291 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/RedConfirmVo.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/pom.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/InvoiceResultController.java 353 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/controller/FpInvoiceResultController.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/BipInvoiceMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/FileBipMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/FpInvoiceResultItemMapper.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/FpInvoiceResultMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/BipInvoiceService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FileBipService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FileUploadService.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FpInvoiceResultItemService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FpInvoiceResultService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/BipInvoiceServiceImpl.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FileBipServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FileUploadServiceImpl.java 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FpInvoiceResultItemServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FpInvoiceResultServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/utils/BipApiEnum.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/utils/BipHttpUtil.java 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/utils/NumUtils.java 305 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/InvoiceService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/InvoiceServiceImpl.java 1458 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/resources/mapper/BipInvoiceMapper.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/resources/mapper/FileBipMapper.xml 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/resources/mapper/FpInvoiceResultItemMapper.xml 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-business-finance-biz/src/main/resources/mapper/FpInvoiceResultMapper.xml 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platformx-boot/src/main/resources/application-dev.yml
@@ -38,18 +38,33 @@
swagger:
  token-url: ${swagger.gateway}/admin/oauth2/token
#bip 配置
bip:
  url:
  codes: 111111111111111111111111,222222222222222222
  appKey:
  appSecret:
# 文件上传配置
file:
  local:
    base-path: D:\\Users\\platformx\\Downloads\\img
#bip 配置
bip:
  url: ''
  codes: 111111111111111111111111,222222222222222222
  ip: https://bip01.res.jzeg.cn/
  filePath: D:\test\
  fontPath: /Users/kongdeqiang/Desktop/SIMSUN.TTC
  appKey: 800b2805c5584f0abb8705acbe487dc5
  appSecret: 59ba72c62a6a27203d7e517787a738be89ba55cb
BWInvoice:
  ip: https://einv01.res.jzeg.cn/post
  kaipiao: ?method=baiwang.output.invoice.issue&version=1.0&requestId=
  chaxun: ?method=baiwang.output.format.query&version=1.0&request_id=
  redConfirmAdd: ?method=baiwang.output.redinvoice.add&version=1.0&requestId=
  redConfirmSearch: ?method=baiwang.output.redinvoice.formlist&version=1.0&requestId=
  search: ?method=baiwang.input.invoice.queryinvoicepool&version=1.0&requestId=
  bind: ?method=baiwang.image.invoices.invoicemanageadd&version=1.0&requestId=
  ocr: ?baiwang.image.invoices.recogcollect&version=1.0&requestId=
# 5家单位id
dept:
  smj: 2056555602756063234
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/constant/FlowNameEnum.java
@@ -11,6 +11,9 @@
@Getter
@AllArgsConstructor
public enum FlowNameEnum {
    合同审批("合同审批");
    合同审批("合同审批"),
    排产计划审批("排产计划审批");
    private String name;
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/BipInvoice.java
New file
@@ -0,0 +1,232 @@
package com.by4cloud.platformx.business.entity.invoice;
import io.swagger.v3.oas.annotations.media.Schema;
import com.baomidou.mybatisplus.annotation.TableField;
import com.by4cloud.platformx.common.data.mybatis.BaseModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.Table;
import lombok.Data;
import org.hibernate.annotations.Comment;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Transient;
import java.util.Date;
/**
 * @author wjli
 * @description
 * @date 2026/4/29 10:51
 **/
@Data
@Entity
@org.hibernate.annotations.Table(appliesTo="bip_invoice",comment = "bip对应单据表")//bip对应单据表
@jakarta.persistence.Table(name = "bip对应单据表")//bip对应单据表
@Comment("bip对应单据表")
public class BipInvoice extends BaseModel<BipInvoice> {
    @Schema(description = "传入单据信息")
    @Column(columnDefinition = "text comment '传入单据信息'")
    private String invoice;
    @Schema(description = "对应BIP系统编号")
    @Column(columnDefinition = "varchar(128) comment '对应BIP系统编号'")
    private String bipNumber;
    @Schema(description = "上传日期")
    @Column(columnDefinition="date comment '上传日期'")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date day;
    @Schema(description = "暂估月份")
    @Column(columnDefinition="date comment '暂估月份'")
    @DateTimeFormat(pattern = "yyyy-MM")
    @JsonFormat(pattern = "yyyy-MM")
    private Date month;
    @Schema(description = "商品ID")
    @Column(columnDefinition = "int comment '商品ID'")
    private Integer coalId;
    @Schema(description = "结算客户ID")
    @Column(columnDefinition = "int comment '结算客户ID'")
    private Integer customerId;
    @Schema(description = "收货客户ID")
    @Column(columnDefinition = "int comment '收货客户ID'")
    private Integer customerAddressId;
//
    @Schema(description = "单价")
    @Column(columnDefinition = "double comment '单价'")
    private Double price;
    @Schema(description = "无税单价")
    @Column(columnDefinition = "double comment '无税单价'")
    private Double noTaxPrice;
    @Schema(description = "数量")
    @Column(columnDefinition = "double comment '数量'")
    private Double tonnage;
    @Schema(description = "含税金额")
    @Column(columnDefinition = "double comment '含税金额'")
    private Double money;
//
//
    @Schema(description = "传回单据信息")
    @Column(columnDefinition = "text comment '传回单据信息'")
    private String resInvoice;
    @Schema(description = "修改发送单据信息")
    @Column(columnDefinition = "text comment '修改发送单据信息'")
    private String updInvoice;
    @Schema(description = "失败信息")
    @Column(columnDefinition = "VARCHAR(512) comment '失败信息'")
    private String message;
    @Schema(description = "合同编号")
    @Column(columnDefinition = "VARCHAR(50) comment '合同编号'")
    private String contractNum;
    @Schema(description = "修改发送单据信息")
    @Column(columnDefinition = "VARCHAR(512) comment '修改发送单据信息'")
    private String updMessage;
    @Schema(description = "bip编号")
    @Column(columnDefinition = "VARCHAR(32) comment 'bip编号'")
    private String code;
    @Schema(description = "bip内部客商编号")
    @Column(columnDefinition="VARCHAR(32) comment 'bip内部客商编号'")
    private String bipCompNumber;
    @Schema(description = "运输方式 1地销/2路运/3船运")
    @Column(columnDefinition = "char(1) comment '运输方式 1地销/2路运/3船运'")
    private Integer trainType;
    @Schema(description = "bip返回状态信息")
    @Column(columnDefinition = "int comment 'bip返回状态信息'")
    private Integer returnCode;
    @Schema(description = "单据类型 0结算单1暂估")
    @Column(columnDefinition = "char(1) comment '单据类型 0结算单1暂估'")
    private Integer type;
    @Schema(description = "单据类型 0应收 1应付")
    @Column(columnDefinition = "char(1) comment '单据类型  0应收 1应付'")
    private Integer invoiceType;
    @Schema(description = "单据方向 1蓝 -1红")
    @Column(columnDefinition = "char(10) comment '单据方向 1蓝 -1红'")
    private Integer direction;
    @Schema(description = "红冲单据ID")
    @Column(columnDefinition = "int comment '红冲单据ID'")
    private Long redInvoiceId;
    @Schema(description = "红冲掉的单据状态")
    @Column(columnDefinition = "VARCHAR(20) comment '红冲掉的单据状态'")
    private String redInvoiceStatus;
    @Schema(description = "红冲掉的单据返回信息")
    @Column(columnDefinition = "VARCHAR(500) comment '红冲掉的单据返回信息'")
    private String redInvoiceMessage;
    @Schema(description = "主结算单ID")
    @Column(columnDefinition = "int comment '主结算单ID'")
    private Long allId;
    @Schema(description = "对应每个结算单ID")
    @Column(columnDefinition = "int comment '对应每个结算单ID'")
    private Long railwayEntrustId;
    @Schema(description = "bip状态0:开立、1:审批中、2:已审批、3:终止、4:已驳回")
    @Column(columnDefinition = "int comment 'bip状态0:开立、1:审批中、2:已审批、3:终止、4:已驳回'")
    private Integer verifyState;
    @Schema(description = "状态0:开立、1:审批中、2:已审批、3:终止、4:已驳回-1:已删除")
    @Column(columnDefinition = "int comment 'bip状态0:开立、1:审批中、2:已审批、3:终止、4:已驳回-1:已删除'")
    private Integer status;
    @Schema(description = "bip返回状态码")
    @Column(columnDefinition = "VARCHAR(20) comment 'bip返回状态码'")
    private String resStatus;
    @Schema(description = "删除返回信息")
    @Column(columnDefinition = "VARCHAR(200) comment '删除返回信息'")
    private String delMessage;
    @Transient
    @TableField(exist = false)
    private Integer isTs;//0已推送1未推送
    @Transient
    @TableField(exist = false)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date startDate;
    @Transient
    @TableField(exist = false)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date endDate;
    /**
     * 客户名称
     */
    @Transient
    @TableField(exist = false)
    private String customerName;
    public String getCustomerName(){
        /*if (customerId != null){
            Customer customer = RedisCacheYunXiaoHelper.getInstance().getCustomerById(customerId);
            if (customer != null){
                this.customerName = customer.getCustomerName();
            }
        }*/
        return this.customerName;
    }
    /**
     * 客户名称
     */
    @Transient
    @TableField(exist = false)
    private String coalName;
    public String getCoalName() {
        /*if (coalId != null) {
            Coal c = RedisCacheYunXiaoHelper.getInstance().getCoalById(coalId);
            coalName = c.getCoalName();
        }*/
        return coalName;
    }
    /**
     * 收货客户名称
     */
    @Transient
    @TableField(exist = false)
    private String customerAddressName;
    public String getCustomerAddressName() {
        /*if (customerAddressId != null) {
            Customer customer = RedisCacheYunXiaoHelper.getInstance().getCustomerById(customerAddressId);
            if (customer != null) {
                this.customerAddressName = customer.getCustomerName();
            }
        }*/
        return this.customerAddressName;
    }
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/BipResVo.java
New file
@@ -0,0 +1,10 @@
package com.by4cloud.platformx.business.entity.invoice;
import lombok.Data;
@Data
public class BipResVo<T> {
    private String code;
    private String message;
    private T data;
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/BipTokenVo.java
New file
@@ -0,0 +1,9 @@
package com.by4cloud.platformx.business.entity.invoice;
import lombok.Data;
@Data
public class BipTokenVo {
    private String access_token;
    private long expire;
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/FileBip.java
New file
@@ -0,0 +1,94 @@
package com.by4cloud.platformx.business.entity.invoice;
import com.baomidou.mybatisplus.annotation.TableName;
import com.by4cloud.platformx.common.data.mybatis.BaseModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.hibernate.annotations.Comment;
import jakarta.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Entity;
/**
 * @author kdq
 * @version 1.0.0
 * @ClassName FileBip.java
 * @Description TODO
 * @createTime 2024年09月06日 07:55:00
 */
@Data
//@TableName("file_bip")
@Entity
//@Table(name = "file_bip")
@Comment("bip电子影像表")
public class FileBip extends BaseModel<FileBip> {
    @Schema(description = "文件id")
    @Column(columnDefinition="VARCHAR(500) comment '文件id'")
    private String fileId;
    @Schema(description = "文件路径")
    @Column(columnDefinition="VARCHAR(500) comment '文件路径'")
    private String filePath;
    @Schema(description = "文件本地路径")
    @Column(columnDefinition="VARCHAR(500) comment '文件本地路径'")
    private String fileLocalPath;
    @Schema(description = "文件创建时间戳")
    @Column(columnDefinition="VARCHAR(500) comment '文件创建时间戳'")
    private String fileCTime;
    @Schema(description = "文件更新时间戳")
    @Column(columnDefinition="VARCHAR(500) comment '文件更新时间戳'")
    private String fileUTime;
    @Schema(description = "bip系统id")
    @Column(columnDefinition="VARCHAR(500) comment 'bip系统id'")
    private String fileBipId;
    @Schema(description = "文件后缀")
    @Column(columnDefinition="VARCHAR(500) comment '文件后缀'")
    private String fileExtension;
    @Schema(description = "文件大小")
    @Column(columnDefinition="double comment '文件大小'")
    private double fileSize;
    @Schema(description = "文件大小文本")
    @Column(columnDefinition="VARCHAR(500) comment '文件大小文本'")
    private String fileSizeText;
    @Schema(description = "文件名称")
    @Column(columnDefinition="VARCHAR(500) comment '文件名称'")
    private String fileName;
    @Schema(description = "文件全称")
    @Column(columnDefinition="VARCHAR(500) comment '文件全称'")
    private String name;
    @Schema(description = "用户id")
    @Column(columnDefinition="VARCHAR(500) comment '用户id'")
    private String yhtUserId;
    @Schema(description = "租户id")
    @Column(columnDefinition="VARCHAR(500) comment '租户id'")
    private String tenantId;
    @Schema(description = "签名")
    @Column(columnDefinition="VARCHAR(500) comment '签名'")
    private String sign;
    @Schema(description = "复制")
    @Column(columnDefinition="VARCHAR(500) comment '复制'")
    private String copy;
    @Schema(description = "结算单id")
    @Column(columnDefinition="int comment '结算单id'")
    private Long entrustId;
    @Schema(description = "结算单编号")
    @Column(columnDefinition="VARCHAR(500) comment '结算单编号'")
    private String entrustCode;
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/InvoiceResult.java
New file
@@ -0,0 +1,218 @@
package com.by4cloud.platformx.business.entity.invoice;
import com.baomidou.mybatisplus.annotation.TableName;
import com.by4cloud.platformx.common.data.mybatis.BaseModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.hibernate.annotations.Comment;
import jakarta.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Entity;
/**
 * @author kdq
 * @version 1.0.0
 * @ClassName InvoiceResult.java
 * @Description TODO
 * @createTime 10024年11月05日 17:10:00
 */
@Data
@Entity
@org.hibernate.annotations.Table(appliesTo="fp_invoice_result",comment = "开具发票返回值")//给表加注释
@jakarta.persistence.Table(name = "fp_invoice_result")//开具发票返回值
@Comment("开具发票返回值")
public class InvoiceResult extends BaseModel<InvoiceResult> {
    @Schema(description = "销售挂账id")
    @Column(columnDefinition = "bigint default null comment '销售挂账id'")
    private Long saleCreditId;
    @Schema(description = "推送bip")
    @Column(columnDefinition = "int comment '推送bip'")
    private Integer pushBip;
    @Schema(description = "推送bip应付")
    @Column(columnDefinition = "int comment '推送bip应付'")
    private Integer pushBipyf;
    @Schema(description = "推送bip红票")
    @Column(columnDefinition = "int comment '推送bip红票'")
    private Integer pushRedBip;
    @Schema(description = "推送bip红票应付")
    @Column(columnDefinition = "int comment '推送bip红票应付'")
    private Integer pushRedBipyf;
    @Schema(description = "是否成功")
    @Column(columnDefinition = "tinyint(1) comment '是否成功'")
    private Boolean success;
    @Schema(description = "销方税号")
    @Column(columnDefinition = "varchar(100) comment '销方税号'")
    private String xTaxNo;
    @Schema(description = "销方名称")
    @Column(columnDefinition = "varchar(100) comment '销方名称'")
    private String xName;
    @Schema(description = "购方税号")
    @Column(columnDefinition = "varchar(100) comment '购方税号'")
    private String gTaxNo;
    @Schema(description = "购方名称")
    @Column(columnDefinition = "varchar(100) comment '购方名称'")
    private String gName;
    @Schema(description = "销方code")
    @Column(columnDefinition = "varchar(100) comment '销方code'")
    private String xOrgCode;
    @Schema(description = "请求id")
    @Column(columnDefinition = "varchar(50) comment '请求id'")
    private String requestId;
    @Schema(description = "发票下载请求id")
    @Column(columnDefinition = "varchar(50) comment '发票下载请求id'")
    private String fpRequestId;
    @Schema(description = "请求结果")
    @Column(columnDefinition = "varchar(100) comment '请求结果'")
    private String result;
    @Schema(description = "请求结果")
    @Column(columnDefinition = "varchar(100) comment '请求结果'")
    private String message;
    @Schema(description = "请求接口")
    @Column(columnDefinition = "varchar(100) comment '请求接口'")
    private String methodName;
    @Schema(description = "项目名称")
    @Column(columnDefinition = "varchar(100) comment '项目名称'")
    private String projectName;
    @Schema(description = "蓝票合计金额")
    @Column(columnDefinition = "double comment '蓝票合计金额'")
    private Double originInvoiceTotalPrice;
    @Schema(description = "开票流水号")
    @Column(columnDefinition = "varchar(100) comment '开票流水号'")
    private String serialNo;
    @Schema(description = "合计税额")
    @Column(columnDefinition = "double comment '合计税额'")
    private Double invoiceTotalTax;
    @Schema(description = "合计金额")
    @Column(columnDefinition = "double comment '合计金额'")
    private Double invoiceTotalPrice;
    @Schema(description = "蓝票合计税额")
    @Column(columnDefinition = "double comment '蓝票合计税额'")
    private Double originInvoiceTotalTax;
    @Schema(description = "价税合计")
    @Column(columnDefinition = "double comment '价税合计'")
    private Double invoiceTotalPriceTax;
    @Schema(description = "中心code")
    @Column(columnDefinition = "varchar(100) comment '中心code'")
    private String taxControlCode;
    @Schema(description = "发票url")
    @Column(columnDefinition = "varchar(100) comment '发票url'")
    private String eInvoiceUrl;
    @Schema(description = "发票名称")
    @Column(columnDefinition = "varchar(100) comment '发票名称'")
    private String eInvoiceName;
    @Schema(description = "发票核验编号")
    @Column(columnDefinition = "varchar(100) comment '发票核验编号'")
    private String invoiceCheckCode;
    @Schema(description = "发票qrCode")
    @Column(columnDefinition = "varchar(1000) comment '发票qrCode'")
    private String invoiceQrCode;
    @Schema(description = "发票号")
    @Column(columnDefinition = "varchar(50) comment '发票号'")
    private String invoiceNo;
    @Schema(description = "蓝票发票号")
    @Column(columnDefinition = "varchar(50) comment '蓝票发票号'")
    private String originalInvoiceNo;
    @Schema(description = "红票开票编号")
    @Column(columnDefinition = "varchar(100) comment '红票开票编号'")
    private String redInvoiceNo;
    @Schema(description = "红票开票原因")
    @Column(columnDefinition = "varchar(100) comment '红票开票原因'")
    private String redInvoiceLabel;
    @Schema(description = "开票时间")
    @Column(columnDefinition = "varchar(100) comment '发票号'")
    private String invoiceDate;
    @Schema(description = "红票开票时间")
    @Column(columnDefinition = "varchar(100) comment '红票开票时间'")
    private String redInvoiceDate;
    @Schema(description = "录入时间")
    @Column(columnDefinition = "varchar(100) comment '录入时间'")
    private String entryDate;
    @Schema(description = "录入身份")
    @Column(columnDefinition = "varchar(100) comment '录入身份'")
    private String entryIdentity;
    @Schema(description = "有效标志")
    @Column(columnDefinition = "varchar(100) comment '有效标志'")
    private String validFlag;
    @Schema(description = "是否纸质发票")
    @Column(columnDefinition = "varchar(100) comment '是否纸质发票'")
    private String originInvoiceIsPaper;
    @Schema(description = "蓝票类型")
    @Column(columnDefinition = "varchar(100) comment '蓝票类型'")
    private String originInvoiceType;
    @Schema(description = "蓝票开票时间")
    @Column(columnDefinition = "varchar(100) comment '蓝票开票时间'")
    private String originalInvoiceDate;
    @Schema(description = "开票类型")
    @Column(columnDefinition = "varchar(100) comment '开票类型'")
    private String invoiceTyCode;
    @Schema(description = "关联结算单")
    @Column(columnDefinition = "varchar(100) comment '关联结算单'")
    private String entrustCode;
    @Schema(description = "有无共同购买方")
    @Column(columnDefinition = "varchar(100) comment '有无共同购买方'")
    private String mulPurchaserMark;
    @Schema(description = "红字确认单UUID")
    @Column(columnDefinition = "varchar(100) comment '红字确认单UUID'")
    private String redConfirmUuid;
    @Schema(description = "红字确认单状态")
    @Column(columnDefinition = "varchar(100) comment '红字确认单状态'")
    private String confirmState;
    @Schema(description = "税局确认即开标志")
    @Column(columnDefinition = "varchar(100) comment '税局确认即开标志'")
    private String confirmBillingMark;
    @Schema(description = "确认红票标志")
    @Column(columnDefinition = "varchar(100) comment '确认红票标志'")
    private String alreadyRedInvoiceFlag;
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/InvoiceResultItem.java
New file
@@ -0,0 +1,110 @@
package com.by4cloud.platformx.business.entity.invoice;
import com.baomidou.mybatisplus.annotation.TableName;
import com.by4cloud.platformx.common.data.mybatis.BaseModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.hibernate.annotations.Comment;
import jakarta.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Entity;
/**
 * @author kdq
 * @version 1.0.0
 * @ClassName InvoiceResultItem.java
 * @Description TODO
 * @createTime 2024年11月28日 10:45:00
 */
@Data
@Entity
@org.hibernate.annotations.Table(appliesTo="fp_invoice_result_item",comment = "开具发票返回值明细行")//开具发票返回值明细行
@jakarta.persistence.Table(name = "fp_invoice_result_item")//开具发票返回值明细行
@Comment("开具发票返回值明细行")
public class InvoiceResultItem extends BaseModel<InvoiceResultItem> {
    @Schema(description = "返回值id")
    @Column(columnDefinition = "int comment '返回值id'")
    private Long resultId;
    @Schema(description = "原票据行")
    @Column(columnDefinition = "int comment '原票据行'")
    private Integer originalInvoiceDetailNo;
    @Schema(description = "票据行")
    @Column(columnDefinition = "int comment '票据行'")
    private Integer goodsLineNo;
    @Schema(description = "商品编号")
    @Column(columnDefinition = "varchar(100) comment '商品编号'")
    private String goodsCode;
    @Schema(description = "商品类型")
    @Column(columnDefinition = "varchar(100) comment '商品类型'")
    private String goodsType;
    @Schema(description = "商品名称")
    @Column(columnDefinition = "varchar(100) comment '商品名称'")
    private String goodsName;
    @Schema(description = "煤种名称")
    @Column(columnDefinition = "varchar(100) comment '煤种名称'")
    private String coalName;
    @Schema(description = "关联结算单")
    @Column(columnDefinition = "varchar(100) comment '关联结算单'")
    private String entrustCode;
    @Schema(description = "商品简称")
    @Column(columnDefinition = "varchar(100) comment '商品简称'")
    private String goodsSimpleName;
    @Schema(description = "项目名称")
    @Column(columnDefinition = "varchar(100) comment '项目名称'")
    private String projectName;
    @Schema(description = "单位")
    @Column(columnDefinition = "varchar(100) comment '单位'")
    private String goodsUnit;
    @Schema(description = "单价")
    @Column(columnDefinition = "double comment '单位'")
    private Double goodsPrice;
    @Schema(description = "数量")
    @Column(columnDefinition = "double comment '数量'")
    private Double goodsQuantity;
    @Schema(description = "商品金额")
    @Column(columnDefinition = "double comment '商品金额'")
    private Double goodsTotalPrice;
    @Schema(description = "税率")
    @Column(columnDefinition = "double comment '税率'")
    private Double goodsTaxRate;
    @Schema(description = "税额")
    @Column(columnDefinition = "double comment '税额'")
    private Double goodsTotalTax;
    @Schema(description = "是否合并")
    @Column(columnDefinition = "varchar(10) comment '税额'")
    private String goodsLineNature;
    @Schema(description = "规格型号")
    @Column(columnDefinition = "varchar(50) comment '规格型号'")
    private String goodsSpecification;
    @Schema(description = "含税标志")
    @Column(columnDefinition = "varchar(10) comment '含税标志'")
    private String priceTaxMark;
    @Schema(description = "类别")
    @Column(columnDefinition = "varchar(10) comment '煤种类别'")
    private String coalType;
    @Schema(description = "长协时间")
    @Column(columnDefinition = "varchar(10) comment '长协时间'")
    private String agreementTerm;
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/InvoicingVo.java
New file
@@ -0,0 +1,291 @@
package com.by4cloud.platformx.business.entity.invoice;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
 * @author kdq
 * @version 1.0.0
 * @ClassName InvoicingVo.java
 * @Description TODO
 * @createTime 2024年10月08日 11:16:00
 */
@Data
public class InvoicingVo {//发票开具
    private Long saleCreditId;
    private String taxNo; //税号
    private String entrustCode; //结算单号
    private Integer fatherEntrustId; //父结算单id
    private Integer settlementPathId; //结算路径id
    private Integer sort; //排序
    private String ledgerName; //销方名称
    private String taxUserName;//登录名
    private String invoiceTerminalCode;//开票终端代码
    private Boolean isSplit;//是否需要拆分开具,默认不拆分
    private String orgCode;//组织机构编码
    private String taxDiskNo;//设备编号
    private Boolean formatGenerate;//是否需要生成版式返回版式链接(true / false)
    private Boolean formatPushType;// 版式生成是否推送(true / false)
    /**
     * 值为(1/0 1 需要补全 0不需要补全,默认为0)是否根据客户编码,购方税号,购方名称查询客户信息补全未填写的购
     * 方信息(购方税号,购方名称,购方地址电话,购方银行账号,邮箱,手机)
     */
    private String completionCustom;
    /**
     * 开具请求类型:isAsync 0 同步 1 异步 默认同步开具(仅支持rpa)
     */
    private String isAsync;
    /**
     * 是否返回蓝票已红冲红票信息,0否,1是,默认为0(仅支持税控发票)
     */
    private String isReturnRedInfo;
    private InvoicingVoInfo data;
    @Data
    public static class InvoicingVoInfo {
        /**
         * 发票类型代码, 004:增值税专用发票;007:增值税普通发票;026:增值税电子发票;025:增值税卷式发票;028:增值税电子专用发票
         *  01:全电发票(增值税专用发票) 02:全电发票(普通发票)
         */
        private String invoiceTypeCode;
        /**
         * 数电纸质发票标志,Y:是,N:否。税控类发票开具不校验此字段;暂只支持用数电电票红冲数电纸票
         */
        private String paperInvoiceFlag;
        /**
         * 选择纸质发票标志为Y时,纸票类型必填。票种为 普通发票02时可传: 04 2016版增值税普通发票(二联折叠票), 052016版增值税普通发票(五联折叠票);
         * 票种为 增值税专用发票01可传: 1130 增值税专用发票(中文三联无金额限制版) ,1140 增值税专用发票(中文四联无金额限制版) 1160增值,税专用发票(中文六联无金额限制版) ,
         * 1170 增值税专用发票(中文七联无金额限制版)
         */
        private String paperInvoiceTypeCode;
        /**
         * 开票类型 0:正数发票(蓝票) 1:负数发票(红票)默认0
         */
        private String invoiceType;
        /**
         * 特殊票种标志, 00:普通发票;01:农产品销售;02:农产品收购;08:成品油 机动车(默认是00普通发票);16矿产品;03稀土; 全电类发票特殊票种标志:01 成品油发票;
         * 03:建筑服务发票;04:货物运输服务发票;05:不动产销售服务发票;06:不动产租赁服务发票;09:旅客运输发票;12:自产农产品销售;
         * 13:拖拉机和联合收割机;14:机动车;15:二手车;16:农产品收购;31:二手车*;24:报废产品收购;02:稀土;17:光伏收购;07:代收车船税;32:电子烟;18卷烟
         */
        private String invoiceSpecialMark;
        /**
         * 成品油单价过低是否确认开具标识:Y 是; N 否 为空时默认值为N (备注:专票单价过低强制开票会记入异常发票,红冲需要在电子税务局申请解除然后再红冲;普票单价过
         * 低开具成功发票可以正常红冲)
         */
        private String  isConfirmIssue;
        /**
         * 税局二次确认是否继续开票,1:是;0:否;(03建筑服务发票,建筑服务发生地和销方注册地址不同时是否继续开票,24报废产品收购需要缴纳购置税的提示是否继续开具
         * ),若不传值,系统默认按照“是”处理;
         */
        private String  confirmIssue;
        /**
         * 征税方式, 0:普通征税;2:差额征税(默认是0普通征税)
         */
        private String  taxationMethod;
        /**
         * 差额征税标签:01 全额开票、 02 差额开票 ;发票类型代码为01,02时且征税方式为2必填
         */
        private String  taxationLabel;
        /**
         * 减按征税标识,01:个人出租住房;03:销售自己使用过的固定资产;05:住房租赁。默认为空,空代表无。
         */
        private String  reducedTaxCode;
        /**
         * 0:无清单;1:带清单(专普票发票明细大于等于8行必须带清单):大于8行必须为清单票(电子票只能为非请单票)(默认是0无清单),发票类型代码为01,02时该字段无
         */
        private String  invoiceListMark;
        /**
         * 含税标志, 0:不含税;1:含税(默认不含税)
         */
        private String  priceTaxMark;
        /**
         * 开票流水号, 唯一标志开票请求。支持数字字母下划线组合。
         */
        private String  serialNo;
        /**
         * 发票请求流水号
         */
        private String  orderNo;
        /**
         * 购方单位税号, invoiceTypeCode=004、028、01(增值税专用发票、增值税电子专用发票、全电发票(增值税专用发票))开具时必传 invoiceSpecialMark=16|17(农产品收购、光伏收购)开具时必传
         */
        private String  buyerTaxNo;
        /**
         * 购方单位名称 全电为100个字符
         */
        private String  buyerName;
        /**
         * 购方地址及电话, 增值税专用发票开具时必填,发票类型代码为01、02时该字段拆分为地址电话两个字段
         */
        private String  buyerAddressPhone;
        /**
         * 购方开户行及账号, 增值税专用发票开具时必填,发票类型代码为01、02时该字段拆分为银行名称、账号两个字段
         */
        private String  buyerBankAccount;
        /**
         * 开票人,税票选填,取值逻辑:如果终端有值取终端,如果没有去机构获取,如果都没有会自动获取机构下随机用户名称;数电票Web连接器选填,
         * 取值逻辑:taxUserName>drawer>默认开票人>终端授权开票人,如果以上四处都未取到随机获取该税号下最近一次登录的数电账号对应的开
         * 票人;数电票乐企连接器必填,长度最大300字符。
         */
        private String  drawer;
        /**
         * 复核人, 16个字符;税控开具时: 为空时,如果终端有值取终端,如果没有去机构获取,若都没有则为空!全电类开具时:此字段非必填,即发票类型代码为01,02时该字段非必填
         */
        private String   checker;
        /**
         * 收款人, 16个字符;税控类开具时:若为空,如果终端有值取终端,如果没有去机构获取,若都没有则为空;全电类开具时:此字段非必填,即发票类型代码为01,02时该字段非必填
         */
        private String   payee;
        /**
         *合计金额, 保留两位小数;支持价税分离
         */
        private BigDecimal   invoiceTotalPrice;
        /**
         * 合计税额, 保留两位小数;支持价税分离
         */
        private BigDecimal   invoiceTotalTax;
        /**
         * 价税合计, 保留两位小数;支持价税分离
         */
        private BigDecimal   invoiceTotalPriceTax;
        /**
         * 备注 乐企长度为230个字符
         */
        private String   remarks;
        /**
         * 红字信息表/确认单编号,仅invoiceType=1时需要传入数据税控类红票开具时,invoiceTypeCode=004、028时必须传值,传入红字信息表编号; 全电类红票开具时,
         * invoiceTypeCode=01、02时必须传值,传入红字确认单编号;
         */
        private String    redInfoNo;
        /**
         * 原发票代码, invoiceType=1,税控负数普票开具时必传;红票选数电票时,此项可为空。
         */
        private String     originalInvoiceCode;
        /**
         * 原发票号码, invoiceType=1,税控负数普票开具时必传;红票选数电票时,此项可为空。
         */
        private String     originalInvoiceNo;
        /**
         * 扣除额, taxationLabel=2,差额征税时必传。数值必须小于价税合计。
         */
        private BigDecimal     deductibleAmount;
        /**
         * 销方地址及电话,发票类型代码为01、02时该字段拆分为地址、电话两个字段
         */
        private String     sellerAddressPhone;
        /**
         * 销方开户行及账号,发票类型代码为01、02时不用此字段
         */
        private String     sellerBankAccount;
        private Map ext;//扩展字段
        /**
         * 第三方系统名称
         */
        private String     systemName;
        /**
         * 第三方系统id
         */
        private String     systemId;
        /**
         * 客户邮箱
         */
        private String     buyerEmail;
        /**
         * 抄送邮箱
         */
        private String     emailCarbonCopy;
        /**
         * 客户电话
         */
        private String     buyerPhone;
        /**
         * 用户账号,用于个人维度数据标记
         */
        private String     userAccount;
        /**
         * 红冲原因(1 销货退回 2 开票有误 3 服务终止 4 销售折让)税控红冲原因:建议按实际开票情况传入红冲原因,若不传系统会自动根据情况判断并赋值;全电红冲原因:必填
         */
        private String     redIssueReason;
        private String     buyerBankName;
        private String     buyerBankNumber;
        private String     buyerAddress;
        private String     buyerTelphone;
        private String     redConfirmUuid;
        private String     coalCalorificValue;  //每千克煤炭发热量( 千卡 ) ,大于1000w必填
        private String     totalSulfurOnDryBasis; //干基全硫( % ) ,大于1000w必填
        private String     dryAshFreeVolatileMatter; //干煤无灰基挥发分(%) ,大于1000w必填
        private List<InvoiceDetail> invoiceDetailsList;
    }
    @Data
    public static class InvoiceDetail{
        private Map<String,Object> ext;
        private String goodsType;
        /**
         * 明细行号
         */
        private Integer goodsLineNo;
        /**
         * 对应蓝票明细行号 税控类红字发票开具时无需传值; 全电类红字发票开具时必须传值;
         */
        private String originalInvoiceDetailNo;
        /**
         * 发票行性质, 0:正常行;1:折扣行;2:被折扣行,默认为0
         */
        private String invoiceLineNature;
        /**
         * 税收分类编码
         */
        private String goodsCode;
        /**
         * 商品编码
         */
        private String goodsPersonalCode;
        /**
         * 商品名称
         */
        private String goodsName;
        /**
         * 规格型号
         */
        private String goodsSpecification;
        /**
         * 计量单位
         */
        private String goodsUnit;
        /**
         * 金额,小数点后2位,超长自动保留两位小数
         */
        private BigDecimal goodsTotalPrice;
        /**
         * 商品数量
         */
        private BigDecimal goodsQuantity;
        /**
         * 商品单价
         */
        private BigDecimal goodsPrice;
        /**
         * 税率,超长自动保留三位小数
         */
        private Double goodsTaxRate;
        /**
         * 税额,两位小数
         */
        private BigDecimal goodsTotalTax;
        private String coalType;
        private String agreementTerm;
    }
}
platformx-business-finance-api/src/main/java/com/by4cloud/platformx/business/entity/invoice/RedConfirmVo.java
New file
@@ -0,0 +1,64 @@
package com.by4cloud.platformx.business.entity.invoice;
import lombok.Data;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * @author kdq
 * @version 1.0.0
 * @ClassName RedConfirmVo.java
 * @Description TODO
 * @createTime 2024年11月06日 11:35:00
 */
@Data
public class RedConfirmVo {//红票确认
    private String taxNo;
    private String orgCode;
    private String taxUserName;
    private String redConfirmSerialNo; //红字确认单流水号
    private String entryIdentity; //录入方身份 01:销方,02:购方,03:二手车市场/拍卖企业
    private String sellerTaxNo; //销售方统一社会信用代码/纳税人识别号/身份证件号码
    private String sellerTaxName;//销售方名称
    private String buyerTaxNo;//购买方统一社会信用代码/纳税人识别号/身份证件号码, 录入方身份为【购方】时必填
    private String buyerTaxName;//购买方名称
    private String originInvoiceIsPaper;//是否纸质发票标志 Y:纸质发票 N:电子发票
    private String originalInvoiceNo;//蓝字发票全电发票号码,【发票来源】为2时必填
    private String originalPaperInvoiceCode;//纸质、税控发票代码,【发票来源】为1时或全电纸票时必填
    private String originalPaperInvoiceNo;//纸质、税控发票号码,【发票来源】为1时或全电纸票时必填
    private String originInvoiceDate;//蓝字发票开票日期 yyyy-MM-dd HH:mm:ss
    private String originInvoiceType;//蓝字发票票种代码 01:增值税专用发票 02:普通发票 03:机动车统一销售发票 04:二手车统一销售发票
    private String originInvoiceSetCode;//
    private String autoIssueSwitch;//非确认即开——自动开票 Y:自动开票 N:不自动开票 默认为N
    private String redInvoiceLabel;//红字发票冲红原因代码 01:开票有误 02:销货退回 03:服务中止 04:销售折让。二手车销售统一发票仅可使用01、02
    private String invoiceSource;//发票来源  1:增值税发票管理系统: 2:电子发票服务平台:
    private Double originInvoiceTotalPrice;//蓝字发票合计金额
    private Double originInvoiceTotalTax;//蓝字发票合计税额
    private Double invoiceTotalPrice;//红字冲销金额
    private Double invoiceTotalTax;//红字冲销税额
    private List<RedConfirmDetail> redConfirmDetailReqEntityList;
    @Data
    public static class RedConfirmDetail{
        private Map<String, Object> ext;
        private Integer originalInvoiceDetailNo; //蓝字发票明细序号
        private Integer goodsLineNo; //行号
        private String goodsCode; //税收分类编码
        private String goodsName; //商品全称
        private String goodsSimpleName; //商品服务简称
        private String projectName; //项目名称(自定义商品名称)
        private String goodsSpecification; //规格型号
        private String goodsUnit;//单位
        private String goodsPrice;//单价
        private String goodsQuantity;//数量
        private Double goodsTaxRate; //税率
        private Double goodsTotalPrice; //金额
        private Double goodsTotalTax; //税额
        private String coalType;
        private String agreementTerm;
    }
}
platformx-business-finance-biz/pom.xml
@@ -141,6 +141,23 @@
            <artifactId>poi-tl</artifactId>
            <version>1.12.2</version> <!-- 请使用最新稳定版 -->
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.24</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.14</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.14</version>
        </dependency>
    </dependencies>
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/controller/InvoiceResultController.java
New file
@@ -0,0 +1,353 @@
package com.by4cloud.platformx.business.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.by4cloud.platformx.business.entity.ContractOutBound;
import com.by4cloud.platformx.business.entity.SaleCredit;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResult;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResultItem;
import com.by4cloud.platformx.business.entity.invoice.InvoicingVo;
import com.by4cloud.platformx.business.invoice.service.FpInvoiceResultItemService;
import com.by4cloud.platformx.business.service.ContractOutBoundService;
import com.by4cloud.platformx.business.service.InvoiceService;
import com.by4cloud.platformx.business.service.SaleCreditService;
import com.by4cloud.platformx.common.core.util.R;
import com.by4cloud.platformx.common.log.annotation.SysLog;
import com.google.gson.Gson;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 销售挂账
 *
 * @author wjli
 * @date 2026-05-21 16:16:31
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/invoiceResult" )
@Tag(description = "invoice" , name = "开票管理" )
public class InvoiceResultController {
    //发票结果
    private final FpInvoiceResultItemService invoiceResultItemService;
    private final InvoiceService invoiceService;
    private final SaleCreditService saleCreditService;
    private final ContractOutBoundService contractOutBoundService;
    @Operation(summary = "推送应付蓝票" , description = "推送应付蓝票" )
    @GetMapping("/pushYfBlue" )
    public R pushYfBlue(@RequestBody SaleCredit saleCredit1) {
        SaleCredit byId = saleCreditService.getById(saleCredit1.getId());
        if(byId.getBipStatus()==null ||!byId.getBipStatus().equals("200")){
            return R.failed("请先推送单据后再推送发票");
        }
        if(byId.getBlueInvoiceResultId()==null){
            return R.failed("发票未开具");
        }
        boolean b = invoiceService.pushBlue(saleCredit1.getId(), 1);
        if(b){
            return R.ok(null,"推送成功");
        }else {
            return R.failed(null,"推送失败");
        }
    }
    @Operation(summary = "推送应收蓝票" , description = "推送应收蓝票" )
    @GetMapping("/pushYsBlue" )
    public R pushYsBlue(@RequestBody SaleCredit saleCredit1) {
        SaleCredit byId = saleCreditService.getById(saleCredit1.getId());
        if(byId.getBipStatus()==null || !byId.getBipStatus().equals("200")){
            return R.failed("请先推送单据后再推送发票");
        }
        if(byId.getBlueInvoiceResultId()==null){
            return R.failed("发票未开具");
        }
        boolean b = invoiceService.pushBlue(saleCredit1.getId(),0);
        if(b){
            return R.ok(null,"推送成功");
        }else {
            return R.failed(null,"推送失败");
        }
    }
    /**
     * 去开蓝票
     * @param saleCredit1 去开蓝票
     * @return R
     */
    @Operation(summary = "去开蓝票" , description = "去开蓝票" )
    @SysLog("去开蓝票" )
    @PostMapping("/toBluePiao")
    @PreAuthorize("@pms.hasPermission('business_saleCredit_add')" )
    public R toBluePiao(@RequestBody SaleCredit saleCredit1) {
        if(saleCredit1.getId()==null){
            return R.failed("销售挂账id不能为空!");
        }
        SaleCredit saleCredit = saleCreditService.getById(saleCredit1.getId());
        List<ContractOutBound> contractOutBoundList = contractOutBoundService.list(new LambdaQueryWrapper<ContractOutBound>()
                .eq(ContractOutBound::getSaleCreditId,saleCredit.getId())
        );
        //生成vo
        InvoicingVo invoicingVo = invoiceService.toGetByCompare(saleCredit,contractOutBoundList);
        try {
            Map<String, Object> objectMap = invoiceService.toKaipiao(invoicingVo);
            Boolean success = (Boolean) objectMap.get("success");
            String message = (String) objectMap.get("message");
            System.out.println(saleCredit.getEntrustCode() + "的railwayEntrust蓝字开票结果为:" + success + "------" + message);
            if(success){
                saleCredit.setStatus(2);
                saleCreditService.updateById(saleCredit);
                return R.ok("开票成功!");
            }else{
                saleCredit.setStatus(3);
                saleCreditService.updateById(saleCredit);
                return R.failed("开票失败!");
            }
        }catch (Exception e){
            saleCredit.setStatus(3);
            saleCreditService.updateById(saleCredit);
            return R.failed("开票失败!");
        }
    }
    @Operation(summary = "发票查看" , description = "发票查看" )
    @GetMapping("/downInvoice" )
    public R downInvoice(String code) {
        QueryWrapper<InvoiceResult> invoiceResultQueryWrapper = new QueryWrapper<>();
        invoiceResultQueryWrapper.lambda()
                .eq(InvoiceResult::getEntrustCode,code)
                .eq(InvoiceResult::getMethodName,"蓝字开票接口")
                .eq(InvoiceResult::getSuccess,1)
                .orderByDesc(InvoiceResult::getCreateTime);
        List<InvoiceResult> list = invoiceService.list(invoiceResultQueryWrapper);
        if(list !=null && list.size()>0){
            InvoiceResult result = list.get(0);
            Map<String, Object> objectMap = invoiceService.downInvoiceMethod(result);
            Boolean success = (Boolean) objectMap.get("success");
            String message = (String) objectMap.get("message");
            if(success){
//                if(result.getPushBip()==null||result.getPushBip()!=1){
//                    QueryWrapper<RailwayEntrust> wrapper = new QueryWrapper<>();
//                    wrapper.lambda()
//                            .eq(RailwayEntrust::getEntrustCode,code);
//                    List<RailwayEntrust> railwayEntrusts = railwayEntrustService.list(wrapper);
//                    if(railwayEntrusts !=null && railwayEntrusts.size()>0){
//                        RailwayEntrust railwayEntrust = railwayEntrusts.get(0);
//                        System.out.println(railwayEntrust.getEntrustCode()+"开始推送bip蓝票");
//                        try {
//                            pushBip(railwayEntrust.getId(),railwayEntrust.getInvoicUrl());
//                            System.out.println(railwayEntrust.getEntrustCode()+"推送bip蓝票成功");
//                            result.setPushBip(1);
//                            result.setPushBipyf(1);
//                            invoiceResultService.updateById(result);
//                        }catch (Exception e){
//                            e.printStackTrace();
//                        }
//                    }
//                }
                return R.ok(objectMap);
            }else {
                return R.failed(message);
            }
        }else {
            return R.failed("未查询到开票记录");
        }
    }
    /**
     * 去开红票
     * @param saleCredit1 去开红票
     * @return R
     */
    @Operation(summary = "去开红票" , description = "去开红票" )
    @SysLog("去开红票" )
    @PostMapping("/toRedPiao")
    @PreAuthorize("@pms.hasPermission('business_saleCredit_add')" )
    public R toRedPiao(@RequestBody SaleCredit saleCredit1){
        if(saleCredit1.getId()==null){
            return R.failed("销售挂账id不能为空!");
        }
        SaleCredit saleCredit = saleCreditService.getById(saleCredit1.getId());
        try {
            Map<String, Object> map = invoiceService.toRedTicket(saleCredit);
            Boolean success = (Boolean) map.get("success");
            if(success){
                return R.ok("红字开票成功");
            }else {
                return R.failed((String) map.get("message"));
            }
        }catch (Exception e){
            e.printStackTrace();
            return R.failed("红字开票失败");
        }
    }
    @Operation(summary = "红票查看" , description = "红票查看" )
    @GetMapping("/downRedInvoice" )
    public R downRedInvoice(String code) {
        QueryWrapper<InvoiceResult> invoiceResultQueryWrapper = new QueryWrapper<>();
        invoiceResultQueryWrapper.lambda()
                .eq(InvoiceResult::getEntrustCode,code)
                .eq(InvoiceResult::getMethodName,"红字确认单确认接口")
                .eq(InvoiceResult::getSuccess,1)
                .orderByDesc(InvoiceResult::getCreateTime);
        List<InvoiceResult> list = invoiceService.list(invoiceResultQueryWrapper);
        if(list !=null && list.size()>0){
            Map<String, Object> objectMap = null;
            Boolean success = null;
            String message = null;
            InvoiceResult result = list.get(0);
            if(result.getConfirmBillingMark().equals("Y")){
                objectMap = invoiceService.downInvoiceMethod(result);
                success = (Boolean) objectMap.get("success");
                message = (String) objectMap.get("message");
            }else {
                QueryWrapper<InvoiceResult> invoiceResultQueryWrapper1 = new QueryWrapper<>();
                invoiceResultQueryWrapper1.lambda()
                        .eq(InvoiceResult::getEntrustCode,code)
                        .eq(InvoiceResult::getMethodName,"红字开票接口")
                        .eq(InvoiceResult::getSuccess,1)
                        .orderByDesc(InvoiceResult::getCreateTime);
                List<InvoiceResult> list1 = invoiceService.list(invoiceResultQueryWrapper1);
                InvoiceResult result1 = list1.get(0);
                objectMap = invoiceService.downInvoiceMethod(result1);
                success = (Boolean) objectMap.get("success");
                message = (String) objectMap.get("message");
            }
            if(success){
                return R.ok(objectMap);
            }else {
                return R.failed(message);
            }
        }else {
            return R.failed("未查询到开票记录");
        }
    }
   /* @Operation(summary = "红冲确认单" , description = "红冲确认单" )
    @PostMapping("/redConfirm" )
    public R redConfirm(@RequestBody InvoicingVo vo) {
        SaleCredit saleCredit = saleCreditService.getOne(new LambdaQueryWrapper<SaleCredit>()
                .eq(SaleCredit::getEntrustCode,vo.getEntrustCode())
                .last("limit 1")
        );
        if(saleCredit==null){
            return R.failed("未找到对应结算单");
        }
        try {
            Map<String, Object> objectMap = invoiceService.toRedTicket(saleCredit);
            Boolean success = (Boolean) objectMap.get("success");
            String message = (String) objectMap.get("message");
            if(success){
                return R.ok(null,message);
            }else {
                return R.failed(null,message);
            }
        }catch (Exception e){
            e.printStackTrace();
            return R.failed("开红票失败");
        }
    }*/
    //发红冲之前,先进行红票确认。
    @Operation(summary = "红冲发票form" , description = "红冲发票form" )
    @GetMapping("/issueRed" )
    public R issueRed(@RequestBody SaleCredit saleCredit1) {
        SaleCredit saleCredit = saleCreditService.getById(saleCredit1.getId());
        InvoiceResult blueResult = null;
        InvoiceResult redResult = null;
        if(saleCredit.getBlueInvoiceResultId()==null){
            return R.failed("请先开具蓝字发票");
        }
        blueResult = invoiceService.getById(saleCredit.getRedInvoiceResultId());
        InvoicingVo invoicingVo = new InvoicingVo();
        QueryWrapper<InvoiceResultItem> itemQueryWrapper  = new QueryWrapper<>();
        itemQueryWrapper.lambda()
                .eq(InvoiceResultItem::getResultId,blueResult.getId());
        List<InvoiceResultItem> resultItems = invoiceResultItemService.list(itemQueryWrapper);
        if(saleCredit!=null) {
            invoicingVo.setTaxNo(saleCredit.getCreditCodeB());
            invoicingVo.setLedgerName(saleCredit.getPartyB());
            invoicingVo.setOrgCode(saleCredit.getCreditCodeB());
            invoicingVo.setFormatGenerate(false);
            invoicingVo.setIsSplit(false);
            invoicingVo.setFormatPushType(false);
            invoicingVo.setTaxUserName(saleCredit.getContactPhoneB());
            invoicingVo.setEntrustCode(saleCredit.getEntrustCode());
            InvoicingVo.InvoicingVoInfo invoicingVoInfo = new InvoicingVo.InvoicingVoInfo();
            invoicingVoInfo.setInvoiceTypeCode("01");
            invoicingVoInfo.setInvoiceType("1");
            invoicingVoInfo.setSerialNo("MX_REDPP_" + System.currentTimeMillis());
//            invoicingVoInfo.setRedInfoNo(redResult.getInvoiceNo());
//            invoicingVoInfo.setRedIssueReason("1");
//            invoicingVoInfo.setRedConfirmUuid(redResult.getRedConfirmUuid());
            invoicingVoInfo.setDrawer(saleCredit.getContactPhoneB());
            /*Map<String, Object> ext1 = new HashMap<>();
            ContractOrder order = contractOrderService.getOrderByNum(railwayEntrust.getOrderNumber());
            if(order!=null){
                ext1.put("htbh",order.getContractNum());
                invoicingVoInfo.setExt(ext1);
            }*/
            invoicingVoInfo.setSystemName("**销售管理信息系统");
            List<InvoicingVo.InvoiceDetail> details = new ArrayList<>();
            for (int i = 0; i < resultItems.size(); i++) {
                InvoiceResultItem resultItem = resultItems.get(i);
                Map<String,Object> ext = new HashMap<>();
                ext.put("coalType",resultItem.getCoalType());
                InvoicingVo.InvoiceDetail invoiceDetail = new InvoicingVo.InvoiceDetail();
                invoiceDetail.setGoodsLineNo(resultItem.getGoodsLineNo());
                invoiceDetail.setOriginalInvoiceDetailNo(resultItem.getGoodsLineNo()+"");
                invoiceDetail.setGoodsTaxRate(resultItem.getGoodsTaxRate());
                invoiceDetail.setGoodsUnit(resultItem.getGoodsUnit());
                invoiceDetail.setGoodsName(resultItem.getCoalName());
                invoiceDetail.setGoodsType(resultItem.getGoodsType());
                invoiceDetail.setGoodsCode(resultItem.getGoodsCode());
                invoiceDetail.setGoodsSpecification(resultItem.getGoodsSpecification());
                invoiceDetail.setExt(ext);
                invoiceDetail.setGoodsQuantity(new BigDecimal(resultItem.getGoodsQuantity()*-1).setScale(3,BigDecimal.ROUND_HALF_UP));
                invoiceDetail.setGoodsPrice(new BigDecimal(resultItem.getGoodsPrice()).setScale(8,BigDecimal.ROUND_HALF_UP));
                invoiceDetail.setGoodsTotalPrice(new BigDecimal(resultItem.getGoodsTotalPrice()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
                invoiceDetail.setGoodsTotalTax(new BigDecimal(resultItem.getGoodsTotalTax()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
                details.add(invoiceDetail);
            }
            invoicingVoInfo.setBuyerTaxNo(saleCredit.getCreditCodeA());
            invoicingVoInfo.setBuyerName(saleCredit.getPartyA());
            invoicingVoInfo.setInvoiceTotalPrice(new BigDecimal(blueResult.getInvoiceTotalPrice()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
            invoicingVoInfo.setInvoiceTotalTax(new BigDecimal(blueResult.getInvoiceTotalTax()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
            invoicingVoInfo.setInvoiceTotalPriceTax(new BigDecimal(blueResult.getInvoiceTotalPriceTax()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
            invoicingVoInfo.setBuyerBankName(saleCredit.getBankNameA());
            invoicingVoInfo.setBuyerBankNumber(saleCredit.getBankAccountA());
            //invoicingVoInfo.setBuyerAddress(invoiceCustomer.getBuyerAddress());
            invoicingVoInfo.setBuyerTelphone(saleCredit.getContactPhoneA());
            invoicingVoInfo.setInvoiceDetailsList(details);
            invoicingVo.setData(invoicingVoInfo);
            Gson gson =new Gson();
            String vostr = gson.toJson(invoicingVo);
            System.out.println(vostr);
            return R.ok(invoicingVo);
        }else {
            return R.failed("暂未查询到销方开票信息");
        }
    }
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/controller/FpInvoiceResultController.java
New file
@@ -0,0 +1,117 @@
package com.by4cloud.platformx.business.invoice.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResult;
import com.by4cloud.platformx.business.invoice.service.FpInvoiceResultService;
import com.by4cloud.platformx.common.excel.annotation.ResponseExcel;
import com.by4cloud.platformx.common.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import com.by4cloud.platformx.common.core.util.R;
import java.util.List;
/**
 * 开具发票返回值
 *
 * @author kdq
 * @date 2024-11-05 18:44:09
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/fpinvoiceresult" )
@Tag(description = "fpinvoiceresult" , name = "开具发票返回值管理" )
public class FpInvoiceResultController {
    private final FpInvoiceResultService fpInvoiceResultService;
    /**
     * 分页查询
     * @param page 分页对象
     * @param fpInvoiceResult 开具发票返回值
     * @return
     */
    @Operation(summary = "分页查询" , description = "分页查询" )
    @GetMapping("/page" )
    @PreAuthorize("@pms.hasPermission('business_fpinvoiceresult_view')" )
    public R getFpInvoiceResultPage(Page page, InvoiceResult fpInvoiceResult) {
        QueryWrapper<InvoiceResult> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(InvoiceResult::getSuccess,fpInvoiceResult.getSuccess())
                .eq(StringUtils.isNotBlank(fpInvoiceResult.getMethodName()),InvoiceResult::getMethodName,fpInvoiceResult.getMethodName())
                .like(fpInvoiceResult.getEntrustCode() !=null,InvoiceResult::getEntrustCode,fpInvoiceResult.getEntrustCode())
                .orderByDesc(InvoiceResult::getCreateTime);
        return R.ok(fpInvoiceResultService.page(page, wrapper));
    }
    /**
     * 通过id查询开具发票返回值
     * @param id id
     * @return R
     */
    @Operation(summary = "通过id查询" , description = "通过id查询" )
    @GetMapping("/{id}" )
    @PreAuthorize("@pms.hasPermission('business_fpinvoiceresult_view')" )
    public R getById(@PathVariable("id" ) Integer id) {
        return R.ok(fpInvoiceResultService.getById(id));
    }
    /**
     * 新增开具发票返回值
     * @param fpInvoiceResult 开具发票返回值
     * @return R
     */
    @Operation(summary = "新增开具发票返回值" , description = "新增开具发票返回值" )
    @SysLog("新增开具发票返回值" )
    @PostMapping
    @PreAuthorize("@pms.hasPermission('business_fpinvoiceresult_add')" )
    public R save(@RequestBody InvoiceResult fpInvoiceResult) {
        return R.ok(fpInvoiceResultService.save(fpInvoiceResult));
    }
    /**
     * 修改开具发票返回值
     * @param fpInvoiceResult 开具发票返回值
     * @return R
     */
    @Operation(summary = "修改开具发票返回值" , description = "修改开具发票返回值" )
    @SysLog("修改开具发票返回值" )
    @PutMapping
    @PreAuthorize("@pms.hasPermission('business_fpinvoiceresult_edit')" )
    public R updateById(@RequestBody InvoiceResult fpInvoiceResult) {
        return R.ok(fpInvoiceResultService.updateById(fpInvoiceResult));
    }
    /**
     * 通过id删除开具发票返回值
     * @param id id
     * @return R
     */
    @Operation(summary = "通过id删除开具发票返回值" , description = "通过id删除开具发票返回值" )
    @SysLog("通过id删除开具发票返回值" )
    @DeleteMapping("/{id}" )
    @PreAuthorize("@pms.hasPermission('business_fpinvoiceresult_del')" )
    public R removeById(@PathVariable Integer id) {
        return R.ok(fpInvoiceResultService.removeById(id));
    }
    /**
     * 导出excel 表格
     * @param fpInvoiceResult 查询条件
     * @return excel 文件流
     */
    @ResponseExcel
    @GetMapping("/export")
    @PreAuthorize("@pms.hasPermission('business_fpinvoiceresult_export')" )
    public List<InvoiceResult> export(InvoiceResult fpInvoiceResult) {
        return fpInvoiceResultService.list(Wrappers.query(fpInvoiceResult));
    }
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/BipInvoiceMapper.java
New file
@@ -0,0 +1,17 @@
package com.by4cloud.platformx.business.invoice.mapper;
import com.by4cloud.platformx.common.data.datascope.PlatformxBaseMapper;
import com.by4cloud.platformx.business.entity.invoice.BipInvoice;
import org.apache.ibatis.annotations.Mapper;
/**
 * bip对应单据表
 *
 * @author zzl
 * @date 2024-09-05 17:59:36
 */
@Mapper
public interface BipInvoiceMapper extends PlatformxBaseMapper<BipInvoice> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/FileBipMapper.java
New file
@@ -0,0 +1,17 @@
package com.by4cloud.platformx.business.invoice.mapper;
import com.by4cloud.platformx.common.data.datascope.PlatformxBaseMapper;
import com.by4cloud.platformx.business.entity.invoice.FileBip;
import org.apache.ibatis.annotations.Mapper;
/**
 * bip电子影像表
 *
 * @author kdq
 * @date 2024-09-06 08:51:32
 */
@Mapper
public interface FileBipMapper extends PlatformxBaseMapper<FileBip> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/FpInvoiceResultItemMapper.java
New file
@@ -0,0 +1,19 @@
package com.by4cloud.platformx.business.invoice.mapper;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResultItem;
import org.apache.ibatis.annotations.Mapper;
import com.by4cloud.platformx.common.data.datascope.PlatformxBaseMapper;
/**
 * 开具发票返回值明细行
 *
 * @author kdq
 * @date 2024-11-28 15:35:41
 */
@Mapper
public interface FpInvoiceResultItemMapper extends PlatformxBaseMapper<InvoiceResultItem> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/mapper/FpInvoiceResultMapper.java
New file
@@ -0,0 +1,18 @@
package com.by4cloud.platformx.business.invoice.mapper;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResult;
import com.by4cloud.platformx.common.data.datascope.PlatformxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * 开具发票返回值
 *
 * @author kdq
 * @date 2024-11-05 18:44:09
 */
@Mapper
public interface FpInvoiceResultMapper extends PlatformxBaseMapper<InvoiceResult> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/BipInvoiceService.java
New file
@@ -0,0 +1,16 @@
package com.by4cloud.platformx.business.invoice.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.by4cloud.platformx.business.entity.invoice.BipInvoice;
/**
 * bip对应单据表
 *
 * @author zzl
 * @date 2024-09-05 17:59:36
 */
public interface BipInvoiceService extends IService<BipInvoice> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FileBipService.java
New file
@@ -0,0 +1,17 @@
package com.by4cloud.platformx.business.invoice.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.by4cloud.platformx.business.entity.invoice.FileBip;
/**
 * bip电子影像表
 *
 * @author kdq
 * @date 2024-09-06 08:51:32
 */
public interface FileBipService extends IService<FileBip> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FileUploadService.java
New file
@@ -0,0 +1,31 @@
package com.by4cloud.platformx.business.invoice.service;
/**
 * @author kdq
 * @version 1.0.0
 * @ClassName FileUploadService.java
 * @Description TODO
 * @createTime 2024年09月03日 10:04:00
 */
import com.by4cloud.platformx.business.entity.Contract;
import java.util.List;
/**
 * 电子影像接口
 *
 * @author kdq
 */
public interface FileUploadService {
    //上传文件到bip
    String uploadToBip(Long railwayEntrustId, String businessId, String filename);
    String uploadUrlToBip(Long railwayEntrustId, String businessId, String fileUrl);
    String deleteFileBip(Integer railwayEntrustId, String businessId, String fid);
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FpInvoiceResultItemService.java
New file
@@ -0,0 +1,17 @@
package com.by4cloud.platformx.business.invoice.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResultItem;
/**
 * 开具发票返回值明细行
 *
 * @author kdq
 * @date 2024-11-28 15:35:41
 */
public interface FpInvoiceResultItemService extends IService<InvoiceResultItem> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/FpInvoiceResultService.java
New file
@@ -0,0 +1,20 @@
package com.by4cloud.platformx.business.invoice.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.by4cloud.platformx.business.entity.invoice.*;
import com.by4cloud.platformx.common.core.util.R;
import java.util.Map;
/**
 * 开具发票返回值
 *
 * @author kdq
 * @date 2024-11-05 18:44:09
 */
public interface FpInvoiceResultService extends IService<InvoiceResult> {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/BipInvoiceServiceImpl.java
New file
@@ -0,0 +1,24 @@
package com.by4cloud.platformx.business.invoice.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by4cloud.platformx.business.invoice.mapper.BipInvoiceMapper;
import com.by4cloud.platformx.business.invoice.service.BipInvoiceService;
import com.by4cloud.platformx.business.entity.invoice.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
/**
 * bip对应单据表
 *
 * @author zzl
 * @date 2024-09-05 17:59:36
 */
@Service
@AllArgsConstructor
public class BipInvoiceServiceImpl extends ServiceImpl<BipInvoiceMapper, BipInvoice> implements BipInvoiceService {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FileBipServiceImpl.java
New file
@@ -0,0 +1,19 @@
package com.by4cloud.platformx.business.invoice.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by4cloud.platformx.business.entity.invoice.FileBip;
import com.by4cloud.platformx.business.invoice.mapper.FileBipMapper;
import com.by4cloud.platformx.business.invoice.service.FileBipService;
import org.springframework.stereotype.Service;
/**
 * bip电子影像表
 *
 * @author kdq
 * @date 2024-09-06 08:51:32
 */
@Service
public class FileBipServiceImpl extends ServiceImpl<FileBipMapper, FileBip> implements FileBipService {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FileUploadServiceImpl.java
New file
@@ -0,0 +1,138 @@
package com.by4cloud.platformx.business.invoice.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.by4cloud.platformx.business.entity.SaleCredit;
import com.by4cloud.platformx.business.entity.invoice.FileBip;
import com.by4cloud.platformx.business.invoice.mapper.FileBipMapper;
import com.by4cloud.platformx.business.invoice.service.FileUploadService;
import com.by4cloud.platformx.business.invoice.utils.BipHttpUtil;
import com.by4cloud.platformx.business.service.SaleCreditService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * @author kdq
 * @version 1.0.0
 * @ClassName FileUploadServiceImpl.java
 * @Description TODO
 * @createTime 2024年09月03日 10:06:00
 */
@Service
public class FileUploadServiceImpl implements FileUploadService {
    @Autowired
    private SaleCreditService saleCreditService;
    @Autowired
    private FileBipMapper fileBipMapper;
    @Autowired
    private BipHttpUtil bipHttpUtil;
    @Value("${bip.filePath}")
    private String bipFilePath;
    @Override
    public String uploadToBip(Long railwayEntrustId,String businessId,String filename) {
        String s = bipHttpUtil.postUploadFile(businessId, filename);
        SaleCredit saleCredit = saleCreditService.getById(railwayEntrustId);
        JSONObject result = JSON.parseObject(s) ;
        String code = (String) result.get("code");
        if(code.equals("200")){
            // 使用JSON.parseObject()来解析JSON对象
            JSONObject jsonObject = JSON.parseObject(s);
            JSONObject data = jsonObject.getJSONObject("data");
            JSONArray jsonArray = data.getJSONArray("data");
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject obj = jsonArray.getJSONObject(i);
                FileBip fileBip = new FileBip();
                fileBip.setFileId(obj.get("fileId").toString());
                fileBip.setFilePath(obj.get("filePath").toString());
                fileBip.setFileCTime(obj.get("ctime")+"");
                fileBip.setFileUTime(obj.get("utime")+"");
                fileBip.setFileBipId(obj.get("id").toString());
                fileBip.setFileExtension(obj.get("fileExtension").toString());
                fileBip.setFileSize((Integer)obj.get("fileSize"));
                fileBip.setFileSizeText(obj.get("fileSizeText").toString());
                fileBip.setFileName(obj.get("fileName").toString());
                fileBip.setName(obj.get("name").toString());
                fileBip.setYhtUserId(obj.get("yhtUserId").toString());
                fileBip.setTenantId(obj.get("tenantId").toString());
                fileBip.setSign(obj.get("sign").toString());
                fileBip.setCopy(obj.get("copy")+"");
                fileBip.setEntrustId(railwayEntrustId);
                fileBip.setEntrustCode(saleCredit.getEntrustCode());
                fileBip.setFileLocalPath("/yunxiao/filebip/local/"+filename);
                fileBipMapper.insert(fileBip);
            }
        }
        return s;
    }
    @Override
    public String uploadUrlToBip(Long railwayEntrustId, String businessId, String fileUrl) {
        String s = bipHttpUtil.postUploadFileUrl(businessId, fileUrl);
        SaleCredit saleCredit = saleCreditService.getById(railwayEntrustId);
        JSONObject result = JSON.parseObject(s) ;
        String code = (String) result.get("code");
        if(code.equals("200")){
            // 使用JSON.parseObject()来解析JSON对象
            JSONObject jsonObject = JSON.parseObject(s);
            JSONObject data = jsonObject.getJSONObject("data");
            JSONArray jsonArray = data.getJSONArray("data");
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject obj = jsonArray.getJSONObject(i);
                FileBip fileBip = new FileBip();
                fileBip.setFileId(obj.get("fileId").toString());
                fileBip.setFilePath(obj.get("filePath").toString());
                fileBip.setFileCTime(obj.get("ctime")+"");
                fileBip.setFileUTime(obj.get("utime")+"");
                fileBip.setFileBipId(obj.get("id").toString());
                fileBip.setFileExtension(obj.get("fileExtension").toString());
                fileBip.setFileSize((Integer)obj.get("fileSize"));
                fileBip.setFileSizeText(obj.get("fileSizeText").toString());
                fileBip.setFileName(obj.get("fileName").toString());
                fileBip.setName(obj.get("name").toString());
                fileBip.setYhtUserId(obj.get("yhtUserId").toString());
                fileBip.setTenantId(obj.get("tenantId").toString());
                fileBip.setSign(obj.get("sign").toString());
                fileBip.setCopy(obj.get("copy")+"");
                fileBip.setEntrustId(railwayEntrustId);
                fileBip.setEntrustCode(saleCredit.getEntrustCode());
                fileBip.setFileLocalPath(fileUrl);
                fileBipMapper.insert(fileBip);
            }
        }
        return s;
    }
    @Override
    public String deleteFileBip(Integer railwayEntrustId,String businessId, String fid) {
        String s = bipHttpUtil.postDeleteFile(businessId, fid);
        JSONObject result = JSON.parseObject(s) ;
        String code = (String) result.get("code");
        if(code.equals("200")){
            QueryWrapper<FileBip> wrapper = new QueryWrapper<>();
            wrapper.lambda()
                    .eq(FileBip::getFileBipId,fid);
            List<FileBip> fileBips = fileBipMapper.selectList(wrapper);
            if(!fileBips.isEmpty() && fileBips.size()>0){
                for (FileBip fileBip : fileBips) {
                    fileBipMapper.deleteById(fileBip);
                }
            }
        }
        return s;
    }
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FpInvoiceResultItemServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.by4cloud.platformx.business.invoice.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResultItem;
import com.by4cloud.platformx.business.invoice.mapper.FpInvoiceResultItemMapper;
import com.by4cloud.platformx.business.invoice.service.FpInvoiceResultItemService;
import org.springframework.stereotype.Service;
/**
 * 开具发票返回值明细行
 *
 * @author kdq
 * @date 2024-11-28 15:35:41
 */
@Service
public class FpInvoiceResultItemServiceImpl extends ServiceImpl<FpInvoiceResultItemMapper, InvoiceResultItem> implements FpInvoiceResultItemService {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/service/impl/FpInvoiceResultServiceImpl.java
New file
@@ -0,0 +1,22 @@
package com.by4cloud.platformx.business.invoice.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by4cloud.platformx.business.invoice.service.FpInvoiceResultService;
import com.by4cloud.platformx.business.entity.invoice.*;
import com.by4cloud.platformx.business.invoice.mapper.FpInvoiceResultMapper;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
/**
 * 开具发票返回值
 *
 * @author kdq
 * @date 2024-11-05 18:44:09
 */
@Service
@EnableAsync
public class FpInvoiceResultServiceImpl extends ServiceImpl<FpInvoiceResultMapper, InvoiceResult> implements FpInvoiceResultService {
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/utils/BipApiEnum.java
New file
@@ -0,0 +1,32 @@
package com.by4cloud.platformx.business.invoice.utils;
public enum BipApiEnum {
    获取TOKEN("/iuap-api-auth/open-auth/selfAppAuth/getAccessToken"),
    应收发票保存接口("/iuap-api-gateway/yonbip/EFI/receivable/saveandsubmit"),
    应收发票删除接口("/iuap-api-gateway/yonbip/EFI/earap/openapi/bill/receivable/batchdelete"),
    应收发票查询接口("/iuap-api-gateway/yonbip/EFI/receivable/list"),
    应收发票修改接口("/iuap-api-gateway/yonbip/EFI/receivable/batchupdate"),
    应付发票保存接口("/iuap-api-gateway/yonbip/EFI/payable/saveandsubmit"),
    应付发票删除接口("/iuap-api-gateway/yonbip/EFI/earap/openapi/bill/payable/batchdelete"),
    应付发票查询接口("/iuap-api-gateway/yonbip/EFI/payable/list"),
    应付发票修改接口("/iuap-api-gateway/yonbip/EFI/payable/batchupdate"),
    收款单查询接口("/iuap-api-gateway/yonbip/EFI/collection/list"),
    收款退款单保存接口("/iuap-api-gateway/yonbip/EFI/arRefund/save"),
    收款退款单删除接口("/iuap-api-gateway/yonbip/EFI/arRefund/delete"),
    收款退款单查询接口("/iuap-api-gateway/yonbip/EFI/arRefund/list"),
    BIP文件上接口("/iuap-api-gateway/yonbip/uspace/iuap-apcom-file/rest/v1/file"),
    BIP文件删除接口("/iuap-api-gateway/yonbip/uspace/iuap-apcom-file/rest/v1/file/delete"),
    应收明细账查询("/iuap-api-gateway/h7rx7y0r/current_yonbip_default_sys/KKJCJK/DetailedAccountsReceivableController");
    private String url;
    BipApiEnum(String url) {
        this.url = url;
    }
    public String getUrl() {
        return url;
    }
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/utils/BipHttpUtil.java
New file
@@ -0,0 +1,308 @@
package com.by4cloud.platformx.business.invoice.utils;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.by4cloud.platformx.business.entity.invoice.BipResVo;
import com.by4cloud.platformx.business.entity.invoice.BipTokenVo;
import com.by4cloud.platformx.business.utils.SignHelper;
import lombok.RequiredArgsConstructor;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
@RequiredArgsConstructor
public class BipHttpUtil {
    private static final Logger log = LoggerFactory.getLogger(BipHttpUtil.class);
    @Value("${bip.ip}")
    private String ip;
    @Value("${bip.filePath}")
    private String bipFilePath;
    @Value("${bip.appKey}")
    private String appKey;
    @Value("${bip.appSecret}")
    private String appSecret;
    private final RedisTemplate redisTemplate;
    public String getToken(){
        String redisKey="BIP_TOKEN:";
//        String appKey = "800b2805c5584f0abb8705acbe487dc5";
//        String appSecret = "59ba72c62a6a27203d7e517787a738be89ba55cb";
        redisKey+=appKey;
        if (redisTemplate.hasKey(redisKey)){
            return (String) redisTemplate.opsForValue().get(redisKey);
        }
        for (int i=0;i<10;i++){
            long timestamp = System.currentTimeMillis();
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put("appKey",appKey);
            paramMap.put("timestamp",timestamp);
            String signature = null;
            try {
                signature = SignHelper.sign(paramMap,appSecret);
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            } catch (InvalidKeyException e) {
                throw new RuntimeException(e);
            }
            String url = ip+BipApiEnum.获取TOKEN.getUrl()+"?appKey="+appKey+"&timestamp="+timestamp+"&signature="+signature;
            String result = HttpUtil.get(url);
            if (result==null){
                continue;
            }
            try {
                BipResVo<BipTokenVo> tokenVo = JSON.parseObject(result,new TypeReference<BipResVo<BipTokenVo>>(){});
                if (tokenVo.getCode().equals("00000")){
                    redisTemplate.opsForValue().set(redisKey,tokenVo.getData().getAccess_token(),tokenVo.getData().getExpire()-10, TimeUnit.SECONDS);
                    System.out.println("-------bipToken:"+tokenVo.getData().getAccess_token());
                    return tokenVo.getData().getAccess_token();
                }
            }catch (Exception e){
                throw new RuntimeException("bip访问接口异常,请检查网络是否正常");
            }
        }
        return null;
    }
    public String post(BipApiEnum apiEnum,Object data){
        log.warn("-------------bipPost-url:"+ip+apiEnum.getUrl()+"?access_token="+getToken());
        log.warn("-------------bipPost-req:"+JSONUtil.toJsonStr(data));
        try {
            String result = HttpRequest.post(ip+apiEnum.getUrl()+"?access_token="+getToken())
                    .body(JSONUtil.toJsonStr(data))
                    .timeout(10*3000)
                    .execute().body();
            log.warn("-------------bipPost-res:"+result);
            return result;
        }catch (Exception e){
            e.printStackTrace();
            log.error("-------------bipPost-res:请求失败");
            throw new RuntimeException("BIP接口超时,请检查网络后重新尝试");
        }
            }
    public String postUploadFile(String businessId,String fileLocalPath){
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String param = "?access_token="+getToken()+"&businessType=yonbip-fi-earapbill&businessId="+businessId;
        // 创建HttpPost对象,并设置URL
        HttpPost httpPost = new HttpPost(ip+BipApiEnum.BIP文件上接口.getUrl()+param);
        // 创建MultipartEntityBuilder对象,并设置文件和其他参数
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addBinaryBody("files", new File(bipFilePath+fileLocalPath), ContentType.MULTIPART_FORM_DATA, fileLocalPath);
        // 将MultipartEntityBuilder构建的实体对象设置到HttpPost对象中
        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);
        // 执行HttpPost请求,获取响应
        HttpResponse response = null;
        String responseBody = null;
        try {
            response = httpClient.execute(httpPost);
            // 解析响应
            HttpEntity responseEntity = response.getEntity();
             responseBody= EntityUtils.toString(responseEntity);
            System.out.println(responseBody);
            // 关闭HttpClient
            httpClient.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return responseBody;
    }
    public String postUploadFileUrl(String businessId,String fileLocalPath){
        URL url = null;
        InputStream stream = null;
        String lastThreeChars = fileLocalPath.substring(fileLocalPath.length() - 3);
        String lowLast = lastThreeChars.toLowerCase();
        if (lowLast.equals("png") || lowLast.equals("jpeg") || lowLast.equals("jpg")) {
            stream = pngToPdf(fileLocalPath, lowLast);
        } else {
            try {
                url = new URL(fileLocalPath);
                URLConnection connection = url.openConnection();
                stream = connection.getInputStream();
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String param = "?access_token="+getToken()+"&businessType=yonbip-fi-earapbill&businessId="+businessId;
        // 创建HttpPost对象,并设置URL
        HttpPost httpPost = new HttpPost(ip+BipApiEnum.BIP文件上接口.getUrl()+param);
        // 创建MultipartEntityBuilder对象,并设置文件和其他参数
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        // 将MultipartEntityBuilder构建的实体对象设置到HttpPost对象中
        builder.addBinaryBody("files", stream, ContentType.MULTIPART_FORM_DATA, "MX_"+System.currentTimeMillis()+".pdf");
        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);
        // 执行HttpPost请求,获取响应
        HttpResponse response = null;
        String responseBody = null;
        try {
            response = httpClient.execute(httpPost);
            // 解析响应
            HttpEntity responseEntity = response.getEntity();
            responseBody= EntityUtils.toString(responseEntity);
            System.out.println(responseBody);
            // 关闭HttpClient
            httpClient.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return responseBody;
    }
    public  InputStream pngToPdf(String filePath,String format){
        //String bipFilePath = "/Users/kongdeqiang/Desktop/";
        long l = System.currentTimeMillis();
        InputStream stream = null;
        try {
            // 加载PNG图片
            URL url1 = new URL(filePath);
            InputStream inputStream = url1.openStream();
            OutputStream out = new FileOutputStream(bipFilePath+format+l+"."+format);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inputStream.read(buffer,0,8192)) !=-1){
                out.write(buffer,0,bytesRead);
            }
            out.close();
            inputStream.close();
            File file = new File(bipFilePath+format+l+"."+format);
            BufferedImage image = ImageIO.read(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, format, baos);
            byte[] bytes = baos.toByteArray();
            // 创建一个PDF文档
            PDDocument document = new PDDocument();
            PDPage page = new PDPage(new PDRectangle(image.getWidth(), image.getHeight()));
            document.addPage(page);
            // 将图片转换为PDF中的对象
            PDImageXObject pdImage = PDImageXObject.createFromByteArray(document, bytes, format);
            PDPageContentStream contents = new PDPageContentStream(document, page);
            contents.drawImage(pdImage, 0, 0, image.getWidth(), image.getHeight());
            contents.close();
            // 保存PDF文档
            document.save(bipFilePath+format+l+".pdf");
            document.close();
            stream = Files.newInputStream(Paths.get(bipFilePath+format+l+".pdf"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stream;
    }
    public String postDeleteFile(String businessId, String fid){
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String param = "?access_token="+getToken()+"&businessType=yonbip-fi-earapbill&businessId="+businessId+"&fid="+fid;
        // 创建HttpPost对象,并设置URL
        HttpPost httpPost = new HttpPost(ip+BipApiEnum.BIP文件删除接口.getUrl()+param);
        // 执行HttpPost请求,获取响应
        HttpResponse response = null;
        String responseBody = null;
        try {
            response = httpClient.execute(httpPost);
            // 解析响应
            HttpEntity responseEntity = response.getEntity();
            responseBody= EntityUtils.toString(responseEntity);
            System.out.println(responseBody);
            // 关闭HttpClient
            httpClient.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return responseBody;
    }
    public static void main1(String[] args) {
    /*    File file = new File("/Users/kongdeqiang/Desktop/1725590083564FFDXJS.pdf");
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("access_token","");
        paramMap.put("businessType","yonbip-fi-earapbill");
        paramMap.put("businessId","");
        paramMap.put("file",file);
        Map<String,Object> dataBody = new HashMap<>();
        String result = HttpRequest.post("https://bip01.res.jzeg.cn"+BipApiEnum.BIP文件上接口.getUrl())
                .form(paramMap)
                .timeout(10*1000)
                .execute().body();
        System.out.println(result);*/
    }
    public static void main(String[] args) throws Exception {
        //正式
//        String appKey = "800b2805c5584f0abb8705acbe487dc5";
//        String appSecret = "59ba72c62a6a27203d7e517787a738be89ba55cb";
        //测试
//        String appKey = "91d28a4b776a4ab992db225958cf2d93";
//        String appSecret = "77abbe9a3bc647ccf4a2a08629a7a0316ffff830";
//        for (int i=0;i<100;i++){
//            long timestamp = System.currentTimeMillis();
//            Map<String,Object> paramMap = new HashMap<>();
//            paramMap.put("appKey",appKey);
//            paramMap.put("timestamp",timestamp);
//            String signature = SignHelper.sign(paramMap,appSecret);
//            System.out.println("signature:"+signature);
//            String url = "https://bip.res.jzeg.cn"+BipApiEnum.获取TOKEN.getUrl()+"?appKey="+appKey+"&timestamp="+timestamp+"&signature="+signature;
//            System.out.println(url);
//            String result = HttpUtil.get(url);
//            System.out.println(result);
//            Thread.sleep(300);
//        }
        //InputStream pdf = BipHttpUtil.pngToPdf("/Users/kongdeqiang/Desktop/WechatIMG316.png", "png");
    }
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/invoice/utils/NumUtils.java
New file
@@ -0,0 +1,305 @@
package com.by4cloud.platformx.business.invoice.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
 * @author xfei
 * @date 2022/5/27下午8:26
 */
public class NumUtils {
    /**
     * 精确小数
     * @param f 小数
     * @param length 精确位数
     * @return
     */
    public static Float accurateFloat(Float f,int length){
        BigDecimal b = new BigDecimal(f.toString());
        f = b.setScale(length,BigDecimal.ROUND_HALF_UP).floatValue();
        return f;
    }
    public static Float accurateFloat(Float f){
        return accurateFloat(f,3);
    }
    public static Double accurateFloat(Double f,int length){
        BigDecimal b = new BigDecimal(f.toString());
        f = b.setScale(length,BigDecimal.ROUND_HALF_UP).doubleValue();
        return f;
    }
    public static Double accurateFloat(Double f){
        return accurateFloat(f,3);
    }
    public static Double accurateDouble(Double f,int length){
        if(f==null){
            f=0d;
        }
        BigDecimal b2 = new BigDecimal(f.toString());
        f = b2.setScale(length,BigDecimal.ROUND_HALF_UP).doubleValue();
        return f;
    }
    public static Double accurateDouble(Double f){
        return accurateDouble(f,3);
    }
    /**
     * 加
     * @param a
     * @param b
     * @return
     */
    public static Double addDouble(Double a,Double b){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.add(bb);
        aa = aa.setScale(2,BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    public static Double addDoubles(Double ... a){
        Double result = 0d;
        for (Double d :a){
            result =addDouble(result,d);
        }
        return result;
    }
    public static Double addDoubles(int len,Double ... a){
        Double result = 0d;
        for (Double d :a){
            result =addDouble(result,d,len);
        }
        return result;
    }
    /**
     * 减
     * @param a
     * @param b
     * @return
     */
    public static Double subtractDouble(Double a,Double b){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.subtract(bb);
        aa = aa.setScale(2,BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    /**
     * 减 只舍不入
     * @param a
     * @param b
     * @return
     */
    public static Double subtractDoubleDown(Double a,Double b){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.subtract(bb);
        aa = aa.setScale(2,BigDecimal.ROUND_DOWN);
        return aa.doubleValue();
    }
    /**
     * 乘
     * @param a
     * @param b
     * @return
     */
    public static Double multiplyDouble(Double a,Double b){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.multiply(bb);
        aa = aa.setScale(2,BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    /**
     * 乘 只舍不入
     * @param a
     * @param b
     * @return
     */
    public static Double multiplyDoubleDown(Double a,Double b){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.multiply(bb);
        aa = aa.setScale(2,BigDecimal.ROUND_DOWN);
        return aa.doubleValue();
    }
    /**
     * 安全的除法运算,处理 null 和除以零,并返回保留两位小数的结果。
     *
     * @param a 被除数
     * @param b 除数
     * @return (a / b) 的结果,保留两位小数。如果 b 为 0 或 null,则返回 0.0。
     */
    public static Double divideDouble(Double a, Double b) {
        // 使用 Double.valueOf(0d) 来避免自动装箱带来的潜在问题,虽然这里 0d 是字面量
        Double dividend = a==null? 0.0:a;
        Double divisor = b==null? 0.0:b;
        // 处理除以零的情况
        if (divisor.equals(0.0)) {
            // 可以根据业务逻辑选择返回 0.0、null 或抛出 IllegalArgumentException
            return 0.0;
        }
        // 使用 String.valueOf 或 toString() 来避免 double 构造器的精度问题
        BigDecimal bdDividend = new BigDecimal(dividend.toString());
        BigDecimal bdDivisor = new BigDecimal(divisor.toString());
        // 在除法的同时指定精度和舍入模式
        BigDecimal result = bdDividend.divide(bdDivisor, 2, RoundingMode.HALF_UP);
        return result.doubleValue();
    }
//    /**
//     * 除
//     * 除法
//     * @param a
//     * @param b
//     * @return
//     */
//    public static Double divideDouble(Double a,Double b){
//        if (a==null)a=0d;
//        if (b==null)b=0d;
//        BigDecimal aa = new BigDecimal(a+"");
//        BigDecimal bb = new BigDecimal(b+"");
//        aa = aa.divide(bb);
//        aa = aa.setScale(2,BigDecimal.ROUND_HALF_UP);
//        return aa.doubleValue();
//    }
    public static Double divideDoubleUp(Double a,Double b){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.divide(bb,BigDecimal.ROUND_HALF_UP);
        aa = aa.setScale(2,BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    /**
     * 除
     * 除法
     * @param a
     * @param b
     * @return
     */
    public static Double divideDoubleDown(Double a,Double b){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.divide(bb);
        aa = aa.setScale(2,BigDecimal.ROUND_DOWN);
        return aa.doubleValue();
    }
    /**
     * 加
     * @param a
     * @param b
     * @return
     */
    public static Double addDouble(Double a,Double b,int len){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.add(bb);
        aa = aa.setScale(len,BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    /**
     * 减
     * @param a
     * @param b
     * @return
     */
    public static Double subtractDouble(Double a,Double b,int len){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.subtract(bb);
        aa = aa.setScale(len,BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    /**
     * 乘
     * @param a
     * @param b
     * @return
     */
    public static Double multiplyDouble(Double a,Double b,int len){
        if (a==null)a=0d;
        if (b==null)b=0d;
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.multiply(bb);
        aa = aa.setScale(len,BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    /**
     * 除
     * @param a
     * @param b
     * @return
     */
    public static Double divideDouble(Double a,Double b,int len){
        if (a==null)a=0d;
        if (b==null)b=0d;
        if(b==0){
            return 0.0d;
        }
        BigDecimal aa = new BigDecimal(a+"");
        BigDecimal bb = new BigDecimal(b+"");
        aa = aa.divide(bb,len, BigDecimal.ROUND_HALF_UP);
        return aa.doubleValue();
    }
    public static Double floatToD(Float f){
        if (f == null) {
            return new Double(0);
        }
        return new Double(f);
    }
    public static void main(String[] args) {
//        System.out.println(NumUtils.accurateDouble(60.1575,3));
        System.out.println(NumUtils.addDoubles(6.1234d, 6.1234d, 4.33d));
    }
    /**
     * 只舍不入计算方法
     *
     * @param number
     * @param decimalPlaces
     * @return
     */
    public static double truncateToDecimalPlaces(double number, int decimalPlaces) {
        if (decimalPlaces < 0) {
            throw new IllegalArgumentException("小数位数不能为负数");
        }
        double multiplier = Math.pow(10, decimalPlaces);
        return (double) ((long) (number * multiplier)) / multiplier;
    }
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/InvoiceService.java
New file
@@ -0,0 +1,24 @@
package com.by4cloud.platformx.business.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.by4cloud.platformx.business.entity.ContractOutBound;
import com.by4cloud.platformx.business.entity.SaleCredit;
import com.by4cloud.platformx.business.entity.invoice.InvoiceResult;
import com.by4cloud.platformx.business.entity.invoice.InvoicingVo;
import java.util.List;
import java.util.Map;
public interface InvoiceService extends IService<InvoiceResult> {
    Map<String, Object> toRedTicket(SaleCredit saleCredit);
    InvoicingVo toGetByCompare(SaleCredit saleCredit, List<ContractOutBound> contractOutBoundList);
    Map<String, Object> toKaipiao(InvoicingVo invoicingVo);
    Map<String,Object> downInvoiceMethod(InvoiceResult invoiceResult);
    boolean pushBlue(Long railwayId, Integer type); //0应收 1应付
}
platformx-business-finance-biz/src/main/java/com/by4cloud/platformx/business/service/impl/InvoiceServiceImpl.java
New file
@@ -0,0 +1,1458 @@
package com.by4cloud.platformx.business.service.impl;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by4cloud.platformx.business.entity.ContractOutBound;
import com.by4cloud.platformx.business.entity.SaleCredit;
import com.by4cloud.platformx.business.entity.invoice.*;
import com.by4cloud.platformx.business.invoice.mapper.FpInvoiceResultItemMapper;
import com.by4cloud.platformx.business.invoice.mapper.FpInvoiceResultMapper;
import com.by4cloud.platformx.business.invoice.service.BipInvoiceService;
import com.by4cloud.platformx.business.invoice.service.FileUploadService;
import com.by4cloud.platformx.business.invoice.service.FpInvoiceResultService;
import com.by4cloud.platformx.business.service.InvoiceService;
import com.by4cloud.platformx.business.service.SaleCreditService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * 销售挂账
 *
 * @author wjli
 * @date 2026-05-21 16:16:31
 */
@Service
public class InvoiceServiceImpl extends ServiceImpl<FpInvoiceResultMapper, InvoiceResult> implements InvoiceService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private FpInvoiceResultItemMapper itemMapper;
    @Autowired
    private SaleCreditService saleCreditService;
    @Autowired
    private FpInvoiceResultService invoiceResultService;
    @Autowired
    private BipInvoiceService bipInvoiceService;
    @Autowired
    private FileUploadService fileUploadService;
    @Value("${BWInvoice.ip}")
    private String invoiceIp;
    @Value("${BWInvoice.kaipiao}")
    private String kpUrl;
    @Value("${BWInvoice.chaxun}")
    private String cxUrl;
    @Value("${BWInvoice.redConfirmAdd}")
    private String redConfirmUrl;
    @Value("${BWInvoice.redConfirmSearch}")
    private String redConfirmSearchUrl;
    @Override
    public Map<String, Object> toKaipiao(InvoicingVo invoicingVo) {
         Map<String, Object> stringObjectMap = zizhuKaiPiao(invoicingVo);
         return stringObjectMap;
    }
    @Override
    public Map<String, Object> toRedTicket(SaleCredit saleCredit) {
        return redTicket(saleCredit);
    }
    @Override
    public InvoicingVo toGetByCompare(SaleCredit saleCredit, List<ContractOutBound> contractOutBoundList) {
        return getByCompare(saleCredit,contractOutBoundList);
    }
    /**
     * 自主结算开票
     */
    Map<String, Object> zizhuKaiPiao(InvoicingVo vo){
        String s1 = redisTemplate.opsForValue().get("ZZKP_BLUE:" + vo.getEntrustCode());
        if(StringUtils.isNotBlank(s1)){
            System.out.println("结算单号:"+vo.getEntrustCode()+"正在开票,请勿重复点击");
            Map<String,Object> res = new HashMap<>();
            res.put("success",false);
            res.put("message","结算单号:"+vo.getEntrustCode()+"正在开票,请勿重复点击");
            return  res;
        }
        redisTemplate.opsForValue().set("ZZKP_BLUE:" + vo.getEntrustCode(),"true");
        try {
            Gson gson =new Gson();
            String str = gson.toJson(vo);
            System.out.println(str);
            String responseBody = "";
            responseBody = HttpRequest.post(invoiceIp+kpUrl+ UuidUtils.generateUuid())
                    .timeout(400000)
                    .body(str)
                    .execute()
                    .body();
            System.out.println(responseBody);
            JSONObject jsonObj = JSON.parseObject(responseBody);
            if(jsonObj!=null){
                boolean flag = (Boolean)jsonObj.get("success");
                JSONObject message = jsonObj.getJSONObject("message");
                String requestId = (String) jsonObj.get("requestId");
                if(!flag){
                    Map<String,Object> res = new HashMap<>();
                    res.put("success",flag);
                    res.put("message",message.get("errorMessage"));
                    InvoiceResult invoiceResult = new InvoiceResult();
                    invoiceResult.setSaleCreditId(vo.getSaleCreditId());
                    invoiceResult.setRequestId(requestId);
                    invoiceResult.setSuccess(flag);
                    invoiceResult.setMessage((String) message.get("errorMessage"));
                    invoiceResult.setMethodName("蓝字开票接口");
                    invoiceResult.setEntrustCode(vo.getEntrustCode());
                    invoiceResultService.save(invoiceResult);
                   SaleCredit saleCredit = saleCreditService.getById(invoiceResult.getSaleCreditId());
                   saleCredit.setInvoiceRemark((String) message.get("errorMessage"));
                   saleCreditService.updateById(saleCredit);
                   /* UpdateWrapper<RailwayEntrust> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.lambda().set(RailwayEntrust::getInvoiceResult,null)
                            .set(RailwayEntrust::getInvoiceResultId,null)
                            .set(RailwayEntrust::getTaskId,null)
                            .set(RailwayEntrust::getInvoiceProcInstId,null)
                            .set(RailwayEntrust::getInvoiceRemark,(String) message.get("errorMessage"))
                            .eq(RailwayEntrust::getEntrustCode,vo.getEntrustCode());
                    railwayEntrustMapper.update(null,updateWrapper);*/
                    redisTemplate.delete("ZZKP_BLUE:" + vo.getEntrustCode());
                    return res;
                }else {
                    String successMessage = (String)message.get("successMessage");
                    JSONObject model = jsonObj.getJSONObject("model");
                    JSONArray success = model.getJSONArray("success");
                    JSONObject modelObject = success.getJSONObject(0);
                    String invoiceTypeCode = (String)modelObject.get("invoiceTypeCode");
                    String invoiceNo = (String)modelObject.get("invoiceNo");
                    String invoiceDate = (String)modelObject.get("invoiceDate");
                    String invoiceQrCode = (String)modelObject.get("invoiceQrCode");
                    String serialNo = (String)modelObject.get("serialNo");
                    BigDecimal invoiceTotalPriceValue = (BigDecimal)modelObject.get("invoiceTotalPrice");
                    Double invoiceTotalPrice = Double.valueOf(invoiceTotalPriceValue.doubleValue());
                    BigDecimal invoiceTotalTaxValue = (BigDecimal)modelObject.get("invoiceTotalTax");
                    Double invoiceTotalTax = Double.valueOf(invoiceTotalTaxValue.doubleValue());
                    BigDecimal invoiceTotalPriceTaxValue = (BigDecimal)modelObject.get("invoiceTotalPriceTax");
                    Double invoiceTotalPriceTax = Double.valueOf(invoiceTotalPriceTaxValue.doubleValue());
                    String mulPurchaserMark = (String)modelObject.get("mulPurchaserMark");
                    String sellerTaxNo = (String)modelObject.get("sellerTaxNo");
                    String coalCalorificValue = (String)modelObject.get("coalCalorificValue");
                    String totalSulfurOnDryBasis = (String)modelObject.get("totalSulfurOnDryBasis");
                    String dryAshFreeVolatileMatter = (String)modelObject.get("dryAshFreeVolatileMatter");
                    InvoiceResult invoiceResult = new InvoiceResult();
                    invoiceResult.setSaleCreditId(vo.getSaleCreditId());
                    invoiceResult.setRequestId(requestId);
                    invoiceResult.setSuccess(flag);
                    invoiceResult.setMessage(successMessage);
                    invoiceResult.setInvoiceNo(invoiceNo);
                    invoiceResult.setInvoiceTyCode(invoiceTypeCode);
                    invoiceResult.setInvoiceDate(invoiceDate);
                    invoiceResult.setInvoiceQrCode(invoiceQrCode);
                    invoiceResult.setSerialNo(serialNo);
                    invoiceResult.setMethodName("蓝字开票接口");
                    invoiceResult.setEntrustCode(vo.getEntrustCode());
                    invoiceResult.setInvoiceTotalPrice(invoiceTotalPrice);
                    invoiceResult.setInvoiceTotalTax(invoiceTotalTax);
                    invoiceResult.setInvoiceTotalPriceTax(invoiceTotalPriceTax);
                    invoiceResult.setMulPurchaserMark(mulPurchaserMark);
                    invoiceResult.setXTaxNo(sellerTaxNo);
                    /*if(StringUtils.isNotBlank(coalCalorificValue)){
                        invoiceResult.setCoalCalorificValue(coalCalorificValue);
                    }
                    if(StringUtils.isNotBlank(totalSulfurOnDryBasis)){
                        invoiceResult.setTotalSulfurOnDryBasis(totalSulfurOnDryBasis);
                    }
                    if(StringUtils.isNotBlank(dryAshFreeVolatileMatter)){
                        invoiceResult.setDryAshFreeVolatileMatter(dryAshFreeVolatileMatter);
                    }*/
                    invoiceResultService.save(invoiceResult);
                    JSONArray invoiceDetailList1 = modelObject.getJSONArray("invoiceDetailsList");
                    for (int i = 0; i < invoiceDetailList1.size(); i++) {
                        JSONObject jsonObject = invoiceDetailList1.getJSONObject(i);
                        int goodsLineNo = (int) jsonObject.get("goodsLineNo");
                        String goodsName = (String) jsonObject.get("goodsName");
                        String goodsCode = (String) jsonObject.get("goodsCode");
                        BigDecimal goodsPriceValue = (BigDecimal)jsonObject.get("goodsPrice");
                        Double goodsPrice = Double.valueOf(goodsPriceValue.doubleValue());
                        double goodsQuantity=0.0;
                        try {
                            int goodsQuantity1 = (int) jsonObject.get("goodsQuantity");
                            goodsQuantity = goodsQuantity1;
                        }catch (Exception e){
                            e.printStackTrace();
                            BigDecimal goodsQuantityValue = (BigDecimal)jsonObject.get("goodsQuantity");
                            goodsQuantity = Double.valueOf(goodsQuantityValue.doubleValue());
                        }
                        BigDecimal goodsTotalPriceValue = (BigDecimal)jsonObject.get("goodsTotalPrice");
                        Double goodsTotalPrice = Double.valueOf(goodsTotalPriceValue.doubleValue());
                        BigDecimal goodsTotalTaxValue = (BigDecimal)jsonObject.get("goodsTotalTax");
                        Double goodsTotalTax = Double.valueOf(goodsTotalTaxValue.doubleValue());
                        BigDecimal goodsTaxRateValue = (BigDecimal)jsonObject.get("goodsTaxRate");
                        Double goodsTaxRate = Double.valueOf(goodsTaxRateValue.doubleValue());
                        String invoiceLineNature = (String) jsonObject.get("invoiceLineNature");
                        String goodsUnit = (String) jsonObject.get("goodsUnit");
                        String goodsSpecification = (String) jsonObject.get("goodsSpecification");
                        String coalType = (String)jsonObject.get("coalType");
                        String agreementTerm = (String)jsonObject.get("agreementTerm");
                        String name = "";
                        /*if(goodsLineNo==1){
                            name = "煤款";
                        }
                        if(goodsLineNo==2 && goodsTaxRate==0.13){
                            name = "取送车费";
                        }
                        if(goodsTaxRate==0.6){
                            name = "专线费";
                        }*/
                        InvoiceResultItem item = new InvoiceResultItem();
                        item.setGoodsLineNature(invoiceLineNature);
                        item.setGoodsCode(goodsCode);
                        item.setGoodsPrice(goodsPrice);
                        item.setGoodsLineNo(goodsLineNo);
                        item.setGoodsQuantity(goodsQuantity);
                        item.setGoodsTaxRate(goodsTaxRate);
                        item.setGoodsType(name);
                        item.setGoodsName(goodsName);
                        item.setGoodsTotalPrice(goodsTotalPrice);
                        item.setGoodsTotalTax(goodsTotalTax);
                        item.setGoodsUnit(goodsUnit);
                        item.setCoalType(coalType);
                        if(StringUtils.isNotBlank(agreementTerm)){
                            item.setAgreementTerm(agreementTerm);
                        }
                        if(goodsSpecification !=null){
                            item.setGoodsSpecification(goodsSpecification);
                        }
                        item.setResultId(invoiceResult.getId());
                        item.setEntrustCode(invoiceResult.getEntrustCode());
                        String[] split = goodsName.split("\\*");
                        int length = split.length;
                        String coalName = split[length - 1];
                        item.setCoalName(coalName);
                        itemMapper.insert(item);
                    }
                    /*QueryWrapper<RailwayEntrust> wrapper = new QueryWrapper<>();
                    wrapper.lambda().eq(RailwayEntrust::getEntrustCode,invoiceResult.getEntrustCode());
                    RailwayEntrust railwayEntrust = railwayEntrustMapper.selectList(wrapper).get(0);
                    railwayEntrust.setInvoiceResultId(invoiceResult.getId());
                    railwayEntrust.setInvoiceResult(2);
                    railwayEntrust.setInvoiceRemark("蓝字开票成功");
                    railwayEntrustMapper.updateById(railwayEntrust);*/
                    SaleCredit saleCredit = saleCreditService.getById(invoiceResult.getSaleCreditId());
                    saleCredit.setInvoiceRemark("蓝字开票成功");
                    saleCredit.setStatus(2);
                    saleCredit.setBlueInvoiceResultId(invoiceResult.getId());
                    saleCreditService.updateById(saleCredit);
                    Map<String,Object> res = new HashMap<>();
                    res.put("success",flag);
                    res.put("message",successMessage);
                    String s = redisTemplate.opsForValue().get("railwayEntrust_invoice_id:" + saleCredit.getId());
                    if(StringUtils.isNotBlank(s)){
                        redisTemplate.delete("railwayEntrust_invoice_id:" + saleCredit.getId());
                    }
                    redisTemplate.delete("ZZKP_BLUE:" + vo.getEntrustCode());
                    return res;
                }
            }else {
                InvoiceResult invoiceResult = new InvoiceResult();
                invoiceResult.setSuccess(false);
                invoiceResult.setMessage("蓝字开票接口无返回值");
                invoiceResult.setMethodName("蓝字开票接口");
                invoiceResult.setEntrustCode(vo.getEntrustCode());
                invoiceResultService.save(invoiceResult);
                Map<String,Object> res = new HashMap<>();
                res.put("success",false);
                res.put("message","蓝字开票接口无返回值");
                /*UpdateWrapper<RailwayEntrust> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().set(RailwayEntrust::getInvoiceResult,null)
                        .set(RailwayEntrust::getInvoiceResultId,null)
                        .set(RailwayEntrust::getTaskId,null)
                        .set(RailwayEntrust::getInvoiceProcInstId,null)
                        .set(RailwayEntrust::getInvoiceRemark,"蓝字开票接口无返回值")
                        .eq(RailwayEntrust::getEntrustCode,vo.getEntrustCode());
                railwayEntrustMapper.update(null,updateWrapper);*/
                SaleCredit saleCredit = saleCreditService.getById(invoiceResult.getSaleCreditId());
                saleCredit.setInvoiceRemark("蓝字开票接口无返回值");
                saleCredit.setStatus(3);
                saleCredit.setBlueInvoiceResultId(null);
                saleCredit.setEntrustCode(vo.getEntrustCode());
                saleCreditService.updateById(saleCredit);
                redisTemplate.delete("ZZKP_BLUE:" + vo.getEntrustCode());
                return res;
            }
        }catch (Exception e){
            e.printStackTrace();
            Map<String,Object> res = new HashMap<>();
            res.put("success",false);
            res.put("message","开票接口异常");
            InvoiceResult invoiceResult = new InvoiceResult();
            invoiceResult.setSuccess(false);
            invoiceResult.setMessage("蓝字开票接口异常");
            invoiceResult.setMethodName("蓝字开票接口");
            invoiceResult.setEntrustCode(vo.getEntrustCode());
            invoiceResultService.save(invoiceResult);
            /*UpdateWrapper<RailwayEntrust> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(RailwayEntrust::getInvoiceResult,null)
                    .set(RailwayEntrust::getInvoiceResultId,null)
                    .set(RailwayEntrust::getTaskId,null)
                    .set(RailwayEntrust::getInvoiceProcInstId,null)
                    .set(RailwayEntrust::getInvoiceRemark,"蓝字开票接口异常")
                    .eq(RailwayEntrust::getEntrustCode,vo.getEntrustCode());
            railwayEntrustMapper.update(null,updateWrapper);*/
            SaleCredit saleCredit = saleCreditService.getById(invoiceResult.getSaleCreditId());
            saleCredit.setInvoiceRemark("蓝字开票接口异常");
            saleCredit.setStatus(3);
            saleCredit.setBlueInvoiceResultId(null);
            saleCredit.setEntrustCode(vo.getEntrustCode());
            saleCreditService.updateById(saleCredit);
            redisTemplate.delete("ZZKP_BLUE:" + vo.getEntrustCode());
            return res;
        }
    }
    private InvoicingVo getByCompare(SaleCredit saleCredit, List<ContractOutBound> contractOutBoundList){
        InvoicingVo invoicingVo = new InvoicingVo();
        invoicingVo.setSaleCreditId(saleCredit.getId());
        invoicingVo.setEntrustCode(saleCredit.getEntrustCode());
        //销方
        invoicingVo.setTaxNo(saleCredit.getCreditCodeB());
        invoicingVo.setLedgerName(saleCredit.getPartyB());
        invoicingVo.setOrgCode(saleCredit.getCreditCodeB());
        invoicingVo.setFormatGenerate(false);
        invoicingVo.setIsSplit(false);
        invoicingVo.setFormatPushType(false);
        invoicingVo.setTaxUserName(saleCredit.getContactPhoneB());
        InvoicingVo.InvoicingVoInfo invoicingVoInfo = new InvoicingVo.InvoicingVoInfo();
        invoicingVoInfo.setInvoiceTypeCode("01");
        invoicingVoInfo.setSerialNo("MX_ZPP_" + System.currentTimeMillis());
        invoicingVoInfo.setDrawer(saleCredit.getContactPhoneB());
        Map<String, Object> ext = new HashMap<>();
        ext.put("htbh",saleCredit.getContractNo());
        invoicingVoInfo.setExt(ext);
        invoicingVoInfo.setSystemName("xx销售管理信息系统");
        List<InvoicingVo.InvoiceDetail> details = new ArrayList<>();
        int i = 0;
        for (ContractOutBound outBoundVo : contractOutBoundList){
            i++;
            InvoicingVo.InvoiceDetail invoiceDetail = new InvoicingVo.InvoiceDetail();
            invoiceDetail.setGoodsLineNo(i);
            invoiceDetail.setGoodsTaxRate(outBoundVo.getTaxRate());
            invoiceDetail.setGoodsType(outBoundVo.getSubjectMatterName());
            invoiceDetail.setGoodsUnit(outBoundVo.getUnit());
            invoiceDetail.setGoodsQuantity(outBoundVo.getOutBoundNum());
            invoiceDetail.setGoodsPrice(outBoundVo.getUnitPrice());
            invoiceDetail.setGoodsTotalPrice(outBoundVo.getTotalPrice());
            invoiceDetail.setGoodsTotalTax(outBoundVo.getTotalTax());
            details.add(invoiceDetail);
        }
        //购方
        invoicingVoInfo.setBuyerTaxNo(saleCredit.getCreditCodeA());
        invoicingVoInfo.setBuyerName(saleCredit.getPartyA());
        invoicingVoInfo.setInvoiceTotalPrice(saleCredit.getTotalAmount());
        //invoicingVoInfo.setInvoiceTotalTax(new BigDecimal(allTax).setScale(2,BigDecimal.ROUND_HALF_UP));
        invoicingVoInfo.setInvoiceTotalPriceTax(saleCredit.getTotalTax());
        invoicingVoInfo.setBuyerBankName(saleCredit.getBankNameB());
        invoicingVoInfo.setBuyerBankNumber(saleCredit.getBankAccountB());
        //invoicingVoInfo.setBuyerAddress(.getBuyerAddress());
        invoicingVoInfo.setBuyerTelphone(saleCredit.getContactPhoneA());
        invoicingVoInfo.setInvoiceDetailsList(details);
        invoicingVo.setData(invoicingVoInfo);
        return invoicingVo;
    }
    //@Async("myExecutor")
    public Map<String, Object> redTicket(SaleCredit saleCredit) {
        System.out.println("进入异步方法");
        System.out.println("当前线程名称:" + Thread.currentThread().getName());
        try {
            //红字确认单
            InvoiceResult result = invoiceResultService.getById(saleCredit.getBlueInvoiceResultId());
            Map<String, Object> objectMap = redTicketConfirm(result,saleCredit);
            Boolean success = (Boolean) objectMap.get("success");
            if(success){
                InvoiceResult obj = (InvoiceResult) objectMap.get("obj");
                //红字确认单确认接口
                Map<String, Object> stringObjectMap = redTicketConfirmSearch(obj,saleCredit);
                Boolean confimSuccess = (Boolean) stringObjectMap.get("success");
                if(confimSuccess){
                    //开票接口
                    InvoiceResult invoiceObj = (InvoiceResult) stringObjectMap.get("obj");
                    if(invoiceObj.getConfirmBillingMark().equals("Y")){
                        //无需开票
                        System.out.println(saleCredit.getEntrustCode()+"的railwayEntrust已开红字开票");
                        QueryWrapper<InvoiceResult> invoiceResultQueryWrapper = new QueryWrapper<>();
                        invoiceResultQueryWrapper.lambda()
                                .eq(InvoiceResult::getEntrustCode,saleCredit.getEntrustCode())
                                .eq(InvoiceResult::getMethodName,"蓝字开票接口")
                                .like(InvoiceResult::getMessage,"%发票开具成功%");
                        List<InvoiceResult> list = invoiceResultService.list(invoiceResultQueryWrapper);
                        if(list !=null && list.size()>0){
                            invoiceResultService.removeByIds(list);
                        }
                        /*UpdateWrapper<RailwayEntrust> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.lambda().set(RailwayEntrust::getInvoiceResult,null)
                                .set(RailwayEntrust::getInvoiceResultId,null)
                                .set(RailwayEntrust::getInvoiceRemark,"红字开票成功")
                                .set(RailwayEntrust::getInvoiceRedResultId,invoiceObj.getId())
                                .eq(RailwayEntrust::getEntrustCode,saleCredit.getEntrustCode());
                        railwayEntrustMapper.update(null,updateWrapper);*/
                        saleCredit.setInvoiceRemark("红字开票成功");
                        saleCredit.setRedInvoiceResultId(invoiceObj.getId());
                        saleCredit.setStatus(7);
                        saleCreditService.updateById(saleCredit);
                        return stringObjectMap;
                    }else {
                        InvoicingVo invoicingVo = redKaiPiaoVo(invoiceObj);
                        invoicingVo.setSaleCreditId(saleCredit.getId());
                        if(invoicingVo !=null){
                            Map<String, Object> stringObjectMap1 = redTicketKaiPiao(invoicingVo);
                            Boolean confimSuccess1 = (Boolean) stringObjectMap1.get("success");
                            String message1 = (String) stringObjectMap1.get("message");
                            if(confimSuccess1){
                                System.out.println(saleCredit.getEntrustCode()+"的railwayEntrust红字开票结果为:"+confimSuccess1+"------"+message1);
                                return stringObjectMap1;
                            }
                        }
                    }
                }else {
                    System.out.println(saleCredit.getEntrustCode()+"的红字确认单确认接口异常");
                    return stringObjectMap;
                }
            }else {
                System.out.println(saleCredit.getEntrustCode()+"的红字确认单新增接口异常");
                return objectMap;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("异步方法执行完成");
        Map<String, Object> result = new HashMap<>();
        result.put("success",false);
        result.put("message","开票异常");
        return result;
    }
    /**
     * 版式文件查询
     * @param invoiceResult
     * @return
     */
    @Override
    public Map<String, Object> downInvoiceMethod(InvoiceResult invoiceResult) {
        SaleCredit saleCredit = saleCreditService.getById(invoiceResult.getSaleCreditId());
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> map1 = new HashMap<>();
        map.put("taxNo",invoiceResult.getXTaxNo());
        map1.put("serialNo",invoiceResult.getSerialNo());
        if(invoiceResult.getMethodName().equals("红字确认单确认接口")){
            map1.put("einvoiceNo",invoiceResult.getRedInvoiceNo());
        }else {
            map1.put("einvoiceNo",invoiceResult.getInvoiceNo());
        }
        map1.put("returnType","1");
        map1.put("invoiceIssueMode","1");
        map.put("data",map1);
        Gson gson =new Gson();
        String str = gson.toJson(map);
        System.out.println(str);
        String responseBody = "";
        responseBody = HttpRequest.post(invoiceIp+cxUrl+UuidUtils.generateUuid())
                .timeout(400000)
                .body(str)
                .execute()
                .body();
        System.out.println(responseBody);
        JSONObject jsonObj = JSON.parseObject(responseBody);
        if(jsonObj!=null){
            boolean flag = (Boolean)jsonObj.get("success");
            JSONObject message = jsonObj.getJSONObject("message");
            if(!flag){
                String successMessage = (String) message.get("errorMessage");
                Map<String,Object> res = new HashMap<>();
                res.put("success",flag);
                res.put("message",successMessage);
                return res;
            }else {
                String requestId = (String) jsonObj.get("requestId");
                String successMessage = (String) message.get("successMessage");
                JSONObject model = jsonObj.getJSONObject("model");
                String modelRequestId = (String)model.get("requestId");
                String invoiceNo = (String)model.get("invoiceNo");
                String serialNo = (String)model.get("serialNo");
                String sellerTaxNo = (String)model.get("sellerTaxNo");
                String eInvoiceUrlOld = (String)model.get("eInvoiceUrl");
                String returnType = (String)model.get("returnType");
                String eInvoiceUrl = eInvoiceUrlOld.replace("http://","https://");
                InvoiceResult result = new InvoiceResult();
                result.setXTaxNo(sellerTaxNo);
                result.setRequestId(requestId);
                result.setFpRequestId(modelRequestId);
                result.setSuccess(flag);
                result.setMessage(successMessage);
                result.setSerialNo(serialNo);
                result.setInvoiceNo(invoiceNo);
                result.setEInvoiceUrl(eInvoiceUrl);
                result.setMethodName("版式文件查询接口");
                result.setEntrustCode(invoiceResult.getEntrustCode());
                invoiceResultService.save(result);
                /*QueryWrapper<RailwayEntrust> wrapper = new QueryWrapper<>();
                wrapper.lambda().eq(RailwayEntrust::getEntrustCode,invoiceResult.getEntrustCode());
                RailwayEntrust railwayEntrust = railwayEntrustMapper.selectList(wrapper).get(0);*/
                if(invoiceResult.getMethodName().contains("蓝字")){
                   /* railwayEntrust.setInvoiceRemark("蓝字发票已查询");
                    railwayEntrust.setInvoicUrl(result.getEInvoiceUrl());
                    if(railwayEntrust.getInvoiceResultId()==null){
                        railwayEntrust.setInvoiceResultId(result.getId());
                    }*/
                    saleCredit.setInvoiceRemark("蓝字发票已查询");
                    saleCredit.setInvoicUrl(result.getEInvoiceUrl());
                    saleCredit.setBlueInvoiceResultId(result.getId());
                    saleCreditService.updateById(saleCredit);
                }else {
                    /*railwayEntrust.setInvoiceRemark("红字发票已查询");
                    railwayEntrust.setInvoicRedUrl(result.getEInvoiceUrl());
                    if(railwayEntrust.getInvoiceRedResultId()==null){
                        railwayEntrust.setInvoiceRedResultId(result.getId());
                    }*/
                    saleCredit.setInvoiceRemark("红字发票已查询");
                    saleCredit.setInvoicUrl(result.getEInvoiceUrl());
                    saleCredit.setBlueInvoiceResultId(result.getId());
                    saleCreditService.updateById(saleCredit);
                }
                //railwayEntrustMapper.updateById(railwayEntrust);
                Map<String,Object> res = new HashMap<>();
                res.put("success",flag);
                res.put("message",successMessage);
                res.put("url",eInvoiceUrl);
                res.put("name",invoiceNo);
                return res;
            }
        }else {
            Map<String,Object> res = new HashMap<>();
            res.put("success",false);
            res.put("message","开票接口异常");
            return res;
        }
    }
    @Override
    public boolean pushBlue(Long railwayId, Integer type) {
        SaleCredit saleCredit = saleCreditService.getById(railwayId);
        if (saleCredit.getBipStatus() == null || !saleCredit.getBipStatus().equals("200")) {
            return false;
        } else {
            InvoiceResult result = null;
            QueryWrapper<InvoiceResult> invoiceResultQueryWrapper = new QueryWrapper<>();
            invoiceResultQueryWrapper.lambda()
                    .eq(InvoiceResult::getEntrustCode, saleCredit.getEntrustCode())
                    .eq(InvoiceResult::getMethodName,"蓝字开票接口")
                    .eq(InvoiceResult::getSuccess,1)
                    .like(InvoiceResult::getMessage,"%发票开具成功%")
                    .orderByAsc(InvoiceResult::getCreateTime)
                    .last( " limit 4 ");
            if(type==0){
                invoiceResultQueryWrapper.lambda().eq(InvoiceResult::getPushBip,1);
            }else {
                invoiceResultQueryWrapper.lambda().eq(InvoiceResult::getPushBipyf,1);
            }
            List<InvoiceResult> list = invoiceResultService.list(invoiceResultQueryWrapper);
            if(list !=null && list.size()>0){
                return false;
            }
            QueryWrapper<InvoiceResult> invoiceResultQueryWrapper1 = new QueryWrapper<>();
            invoiceResultQueryWrapper1.lambda()
                    .eq(InvoiceResult::getEntrustCode, saleCredit.getEntrustCode())
                    .eq(InvoiceResult::getMethodName,"蓝字开票接口")
                    .eq(InvoiceResult::getSuccess,1)
                    .like(InvoiceResult::getMessage,"%发票开具成功%")
                    .orderByAsc(InvoiceResult::getCreateTime)
                    .last( " limit 4 ");
            if(type==0){
                invoiceResultQueryWrapper1.lambda().isNull(InvoiceResult::getPushBip);
            }else {
                invoiceResultQueryWrapper1.lambda().isNull(InvoiceResult::getPushBipyf);
            }
            List<InvoiceResult> list1 = invoiceResultService.list(invoiceResultQueryWrapper1);
            if(list1 !=null && list1.size()>0){
                result = list1.get(0);
            }else {
                System.out.println(saleCredit.getEntrustCode()+"未查询到开票记录");
                return false;
            }
            if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(saleCredit.getInvoicUrl())){
                if(type==0){
                    if(result.getPushBip()==null||result.getPushBip()==0) {
                        System.out.println(saleCredit.getEntrustCode() + "开始推送bip应收蓝票");
                        try {
                            boolean b = pushBipYS(saleCredit.getId(), saleCredit.getInvoicUrl());
                            if(b){
                                System.out.println(saleCredit.getEntrustCode() + "推送bip应收蓝票成功");
                                result.setPushBip(1);
                                invoiceResultService.updateById(result);
                                return true;
                            }else {
                                System.out.println(saleCredit.getEntrustCode() + "推送bip应收蓝票失败");
                                return false;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }else if (type==1){
                    if(result.getPushBipyf()==null||result.getPushBipyf()==0) {
                        System.out.println(saleCredit.getEntrustCode() + "开始推送bip应付蓝票");
                        try {
                            boolean b = pushBipYF(saleCredit.getId(), saleCredit.getInvoicUrl());
                            if(b){
                                System.out.println(saleCredit.getEntrustCode() + "推送bip应付蓝票成功");
                                result.setPushBipyf(1);
                                invoiceResultService.updateById(result);
                                return true;
                            }else {
                                System.out.println(saleCredit.getEntrustCode() + "推送bip应付蓝票失败");
                                return false;
                            }
                        }catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }else {
                Map<String, Object> objectMap = downInvoiceMethod(result);
                Boolean success = (Boolean) objectMap.get("success");
                String message = (String) objectMap.get("message");
                String url = (String) objectMap.get("url");
                if(success){
                    try {
                        if(type==0){
                            boolean b = pushBipYS(saleCredit.getId(),url);
                            if(b){
                                System.out.println(saleCredit.getEntrustCode()+"推送bip应收蓝票成功");
                                result.setPushBip(1);
                                invoiceResultService.updateById(result);
                                return true;
                            }else {
                                System.out.println(saleCredit.getEntrustCode()+"推送bip应收蓝票失败");
                                return false;
                            }
                        }else if (type==1){
                            boolean b = pushBipYF(saleCredit.getId(),url);
                            if(b){
                                System.out.println(saleCredit.getEntrustCode()+"推送bip应付蓝票成功");
                                result.setPushBipyf(1);
                                invoiceResultService.updateById(result);
                                return true;
                            }else {
                                System.out.println(saleCredit.getEntrustCode()+"推送bip应付蓝票失败");
                                return false;
                            }
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }
        return false;
    }
    /**
     * 推送bip应收蓝票
     * @param id
     * @param file
     */
    public boolean pushBipYS(Long id,String file){
        //应收
        QueryWrapper<BipInvoice> bipInvoiceQueryWrapper = new QueryWrapper<>();
        bipInvoiceQueryWrapper.lambda()
                .eq(BipInvoice::getRailwayEntrustId, id)
                .eq(BipInvoice::getInvoiceType, 0)
                .in(BipInvoice::getResStatus, 200, 910)
                .orderByDesc(BipInvoice::getCreateTime);
        List<BipInvoice> list1 = bipInvoiceService.list(bipInvoiceQueryWrapper);
        if(list1!=null && list1.size()>0){
            BipInvoice bipInvoice = list1.get(0);
            String bipNumber = bipInvoice.getBipNumber();
            fileUploadService.uploadUrlToBip(id,bipNumber,file);
            return true;
        }else {
            return false;
        }
    }
    /**
     * 推送bip应付蓝票
     * @param id
     * @param file
     */
    public boolean pushBipYF(Long id,String file){
        //应付
        QueryWrapper<BipInvoice> bipInvoiceQueryWrapper1 = new QueryWrapper<>();
        bipInvoiceQueryWrapper1.lambda()
                .eq(BipInvoice::getRailwayEntrustId, id)
                .eq(BipInvoice::getInvoiceType, 1)
                .in(BipInvoice::getResStatus, 200, 910)
                .orderByDesc(BipInvoice::getCreateTime);
        List<BipInvoice> list2 = bipInvoiceService.list(bipInvoiceQueryWrapper1);
        if(list2!=null && list2.size()>0){
            BipInvoice bipInvoice = list2.get(0);
            String bipNumber = bipInvoice.getBipNumber();
            fileUploadService.uploadUrlToBip(id,bipNumber,file);
            return true;
        }else {
            return false;
        }
    }
    /**
     * 红冲开票接口
     */
    Map<String,Object> redTicketKaiPiao(InvoicingVo vo){
        SaleCredit saleCredit = saleCreditService.getById(vo.getSaleCreditId());
        Gson gson =new Gson();
        String str = gson.toJson(vo);
        System.out.println(str);
        String responseBody = "";
        responseBody = HttpRequest.post(invoiceIp+kpUrl+UuidUtils.generateUuid())
                .timeout(400000)
                .body(str)
                .execute()
                .body();
        System.out.println(responseBody);
        JSONObject jsonObj = JSON.parseObject(responseBody);
        if(jsonObj!=null){
            boolean flag = (Boolean)jsonObj.get("success");
            JSONObject message = jsonObj.getJSONObject("message");
            String requestId = (String) jsonObj.get("requestId");
            if(!flag){
                Map<String,Object> res = new HashMap<>();
                res.put("success",flag);
                res.put("message",message.get("errorMessage"));
                InvoiceResult invoiceResult = new InvoiceResult();
                invoiceResult.setRequestId(requestId);
                invoiceResult.setSuccess(flag);
                invoiceResult.setMessage((String) message.get("errorMessage"));
                invoiceResult.setMethodName("红字开票接口");
                invoiceResult.setEntrustCode(vo.getEntrustCode());
                invoiceResultService.save(invoiceResult);
                /*UpdateWrapper<RailwayEntrust> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda()
                        .set(RailwayEntrust::getInvoiceRemark,(String) message.get("errorMessage"))
                        .eq(RailwayEntrust::getEntrustCode,invoiceResult.getEntrustCode());
                railwayEntrustMapper.update(null,updateWrapper);*/
                saleCredit.setInvoiceRemark((String) message.get("errorMessage"));
                saleCreditService.updateById(saleCredit);
                return res;
            }else {
                String successMessage = (String)message.get("successMessage");
                JSONObject model = jsonObj.getJSONObject("model");
                JSONArray success = model.getJSONArray("success");
                JSONObject modelObject = success.getJSONObject(0);
                String invoiceTypeCode = (String) modelObject.get("invoiceTypeCode");
                String invoiceNo = (String) modelObject.get("invoiceNo");
                String invoiceDate = (String) modelObject.get("invoiceDate");
                String invoiceQrCode = (String) modelObject.get("invoiceQrCode");
                String serialNo = (String) modelObject.get("serialNo");
                BigDecimal invoiceTotalPriceValue = (BigDecimal) modelObject.get("invoiceTotalPrice");
                Double invoiceTotalPrice = Double.valueOf(invoiceTotalPriceValue.doubleValue());
                BigDecimal invoiceTotalTaxValue = (BigDecimal) modelObject.get("invoiceTotalTax");
                Double invoiceTotalTax = Double.valueOf(invoiceTotalTaxValue.doubleValue());
                BigDecimal invoiceTotalPriceTaxValue = (BigDecimal) modelObject.get("invoiceTotalPriceTax");
                Double invoiceTotalPriceTax = Double.valueOf(invoiceTotalPriceTaxValue.doubleValue());
                String mulPurchaserMark = (String) modelObject.get("mulPurchaserMark");
                String sellerTaxNo = (String) modelObject.get("sellerTaxNo");
                InvoiceResult issueRedResult = new InvoiceResult();
                issueRedResult.setRequestId(requestId);
                issueRedResult.setSuccess(flag);
                issueRedResult.setMessage(successMessage);
                issueRedResult.setInvoiceNo(invoiceNo);
                issueRedResult.setInvoiceTyCode(invoiceTypeCode);
                issueRedResult.setInvoiceDate(invoiceDate);
                issueRedResult.setInvoiceQrCode(invoiceQrCode);
                issueRedResult.setSerialNo(serialNo);
                issueRedResult.setMethodName("红字开票接口");
                issueRedResult.setEntrustCode(vo.getEntrustCode());
                issueRedResult.setInvoiceTotalPrice(invoiceTotalPrice);
                issueRedResult.setInvoiceTotalTax(invoiceTotalTax);
                issueRedResult.setInvoiceTotalPriceTax(invoiceTotalPriceTax);
                issueRedResult.setMulPurchaserMark(mulPurchaserMark);
                issueRedResult.setXTaxNo(sellerTaxNo);
                invoiceResultService.save(issueRedResult);
                JSONArray invoiceDetailList1 = modelObject.getJSONArray("invoiceDetailsList");
                for (int i = 0; i < invoiceDetailList1.size(); i++) {
                    JSONObject jsonObject = invoiceDetailList1.getJSONObject(i);
                    int goodsLineNo = (int) jsonObject.get("goodsLineNo");
                    String goodsName = (String) jsonObject.get("goodsName");
                    String goodsCode = (String) jsonObject.get("goodsCode");
                    BigDecimal goodsPriceValue = (BigDecimal)jsonObject.get("goodsPrice");
                    Double goodsPrice = Double.valueOf(goodsPriceValue.doubleValue());
                    double goodsQuantity=0.0;
                    try {
                        BigDecimal goodsQuantityValue = (BigDecimal)jsonObject.get("goodsQuantity");
                        goodsQuantity = Double.valueOf(goodsQuantityValue.doubleValue());
                    }catch (Exception e){
                        e.printStackTrace();
                        int goodsQuantity1 = (int) jsonObject.get("goodsQuantity");
                        goodsQuantity = goodsQuantity1;
                    }
                    BigDecimal goodsTotalPriceValue = (BigDecimal)jsonObject.get("goodsTotalPrice");
                    Double goodsTotalPrice = Double.valueOf(goodsTotalPriceValue.doubleValue());
                    BigDecimal goodsTotalTaxValue = (BigDecimal)jsonObject.get("goodsTotalTax");
                    Double goodsTotalTax = Double.valueOf(goodsTotalTaxValue.doubleValue());
                    BigDecimal goodsTaxRateValue = (BigDecimal)jsonObject.get("goodsTaxRate");
                    Double goodsTaxRate = Double.valueOf(goodsTaxRateValue.doubleValue());
                    String invoiceLineNature = (String) jsonObject.get("invoiceLineNature");
                    String goodsUnit = (String) jsonObject.get("goodsUnit");
                    String goodsSpecification = (String) jsonObject.get("goodsSpecification");
                    String coalType = (String)jsonObject.get("coalType");
                    String agreementTerm = (String)jsonObject.get("agreementTerm");
                    String name = "";
                    if(goodsLineNo==1){
                        name = "煤款";
                    }
                    if(goodsLineNo==2 && goodsTaxRate==0.13){
                        name = "取送车费";
                    }
                    if(goodsTaxRate==0.6){
                        name = "专线费";
                    }
                    InvoiceResultItem item = new InvoiceResultItem();
                    item.setGoodsLineNature(invoiceLineNature);
                    item.setGoodsCode(goodsCode);
                    item.setGoodsPrice(goodsPrice);
                    item.setGoodsType(name);
                    if(goodsSpecification != null){
                        item.setGoodsSpecification(goodsSpecification);
                    }
                    if(coalType !=null){
                        item.setCoalType(coalType);
                    }
                    if(agreementTerm !=null){
                        item.setAgreementTerm(agreementTerm);
                    }
                    item.setGoodsLineNo(goodsLineNo);
                    item.setGoodsQuantity(goodsQuantity);
                    item.setGoodsTaxRate(goodsTaxRate);
                    item.setGoodsName(goodsName);
                    item.setGoodsTotalPrice(goodsTotalPrice);
                    item.setGoodsTotalTax(goodsTotalTax);
                    item.setGoodsUnit(goodsUnit);
                    item.setResultId(issueRedResult.getId());
                    item.setEntrustCode(issueRedResult.getEntrustCode());
                    String[] split = goodsName.split("\\*");
                    int length = split.length;
                    String coalName = split[length - 1];
                    item.setCoalName(coalName);
                    itemMapper.insert(item);
                }
                QueryWrapper<InvoiceResult> invoiceResultQueryWrapper = new QueryWrapper<>();
                invoiceResultQueryWrapper.lambda()
                        .eq(InvoiceResult::getEntrustCode,issueRedResult.getEntrustCode())
                        .eq(InvoiceResult::getMethodName,"蓝字开票接口");
                List<InvoiceResult> list = invoiceResultService.list(invoiceResultQueryWrapper);
                List<Long> collect = list.stream().map(item -> item.getId()).collect(Collectors.toList());
                removeByIds(collect);
                /*UpdateWrapper<RailwayEntrust> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().set(RailwayEntrust::getInvoiceResult,null)
                        .set(RailwayEntrust::getInvoiceResultId,null)
                        .set(RailwayEntrust::getInvoiceRemark,"红字开票成功")
                        .set(RailwayEntrust::getInvoiceRedResult,2)
                        .set(RailwayEntrust::getInvoicUrl,null)
                        .set(RailwayEntrust::getInvoiceRedResultId,issueRedResult.getId())
                        .eq(RailwayEntrust::getEntrustCode,issueRedResult.getEntrustCode());
                railwayEntrustMapper.update(null,updateWrapper);*/
                saleCredit.setInvoiceRemark("红字开票成功");
                saleCredit.setRedInvoiceResultId(issueRedResult.getId());
                saleCredit.setStatus(7);
                saleCreditService.updateById(saleCredit);
                Map<String,Object> res = new HashMap<>();
                res.put("success",flag);
                res.put("message",successMessage);
                return res;
            }
        }else {
            Map<String,Object> res = new HashMap<>();
            res.put("success",false);
            res.put("message","红字开票接口异常");
            InvoiceResult invoiceResult = new InvoiceResult();
            invoiceResult.setSuccess(false);
            invoiceResult.setMessage("红字开票接口异常");
            invoiceResult.setMethodName("红字开票接口");
            invoiceResult.setEntrustCode(vo.getEntrustCode());
            invoiceResultService.save(invoiceResult);
           /* QueryWrapper<RailwayEntrust> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(RailwayEntrust::getEntrustCode,invoiceResult.getEntrustCode());
            RailwayEntrust railwayEntrust = railwayEntrustMapper.selectList(wrapper).get(0);
            railwayEntrust.setInvoiceRemark("红字开票接口异常");
            railwayEntrustMapper.updateById(railwayEntrust);*/
            saleCredit.setInvoiceRemark("红字开票接口异常");
            saleCredit.setStatus(6);
            saleCreditService.updateById(saleCredit);
            return res;
        }
    }
    /**
     * 数电红字确认单新增接口
     */
    Map<String,Object> redTicketConfirm(InvoiceResult invoiceResult,SaleCredit saleCredit){
        String format = strToFormat(invoiceResult.getInvoiceDate());
        List<InvoiceResultItem> resultItems = itemMapper.selectList(new LambdaQueryWrapper<InvoiceResultItem>()
                .eq(InvoiceResultItem::getResultId,invoiceResult.getId())
        );
        if(saleCredit!=null) {
            RedConfirmVo confirmVo = new RedConfirmVo();
            confirmVo.setTaxNo(saleCredit.getCreditCodeB());
            confirmVo.setOrgCode(saleCredit.getCreditCodeB());
            confirmVo.setTaxUserName(saleCredit.getContactPhoneB());
            confirmVo.setRedConfirmSerialNo("MX_RPP_"+System.currentTimeMillis());
            confirmVo.setEntryIdentity("01");
            confirmVo.setSellerTaxNo(saleCredit.getCreditCodeB());
            confirmVo.setSellerTaxName(saleCredit.getPartyB());
            confirmVo.setBuyerTaxName(saleCredit.getPartyA());
            confirmVo.setBuyerTaxNo(saleCredit.getCreditCodeA());
            confirmVo.setOriginInvoiceIsPaper("N");
            confirmVo.setInvoiceSource("2");
            confirmVo.setOriginalInvoiceNo(invoiceResult.getInvoiceNo());
            confirmVo.setOriginInvoiceDate(format);
            confirmVo.setOriginInvoiceTotalPrice(invoiceResult.getInvoiceTotalPrice());
            confirmVo.setOriginInvoiceTotalTax(invoiceResult.getInvoiceTotalTax());
            confirmVo.setOriginInvoiceType("01");
            confirmVo.setInvoiceTotalPrice(invoiceResult.getInvoiceTotalPrice()*-1);
            confirmVo.setInvoiceTotalTax(invoiceResult.getInvoiceTotalTax()*-1);
            confirmVo.setRedInvoiceLabel("02");
            confirmVo.setAutoIssueSwitch("N");
            List<RedConfirmVo.RedConfirmDetail> detailList = new ArrayList<>();
            for (InvoiceResultItem resultItem : resultItems) {
                RedConfirmVo.RedConfirmDetail detail = new RedConfirmVo.RedConfirmDetail();
                detail.setOriginalInvoiceDetailNo(resultItem.getGoodsLineNo());
                detail.setGoodsLineNo(resultItem.getGoodsLineNo());
                detail.setGoodsCode(resultItem.getGoodsCode());
                detail.setGoodsTaxRate(resultItem.getGoodsTaxRate());
                detail.setGoodsName(resultItem.getCoalName());
                detail.setProjectName(resultItem.getCoalName());
                detail.setGoodsPrice(resultItem.getGoodsPrice()+"");
                detail.setGoodsSpecification(resultItem.getGoodsSpecification());
                detail.setGoodsUnit(resultItem.getGoodsUnit());
                detail.setGoodsQuantity(resultItem.getGoodsQuantity()*-1+"");
                detail.setGoodsTotalPrice(resultItem.getGoodsTotalPrice()*-1);
                detail.setGoodsTotalTax(resultItem.getGoodsTotalTax()*-1);
                detail.setCoalType(resultItem.getCoalType());
                detail.setAgreementTerm(resultItem.getAgreementTerm());
                detailList.add(detail);
            }
            confirmVo.setRedConfirmDetailReqEntityList(detailList);
            Gson gson =new Gson();
            String str = gson.toJson(confirmVo);
            System.out.println(str);
            String responseBody = "";
            responseBody = HttpRequest.post(invoiceIp+redConfirmUrl+ UuidUtils.generateUuid())
                    .timeout(400000)
                    .body(str)
                    .execute()
                    .body();
            System.out.println(responseBody);
            JSONObject jsonObj = JSON.parseObject(responseBody);
            if(jsonObj!=null) {
                boolean flag = (Boolean) jsonObj.get("success");
                JSONObject message = jsonObj.getJSONObject("message");
                String requestId = (String) jsonObj.get("requestId");
                if (!flag) {
                    Map<String,Object> res = new HashMap<>();
                    res.put("success",flag);
                    res.put("message",message.get("errorMessage"));
                    InvoiceResult result = new InvoiceResult();
                    result.setRequestId(requestId);
                    result.setSuccess(flag);
                    result.setMessage((String) message.get("errorMessage"));
                    result.setMethodName("红字确认单新增接口");
                    result.setEntrustCode(saleCredit.getEntrustCode());
                    invoiceResultService.save(result);
                    saleCredit.setInvoiceRemark((String) message.get("errorMessage"));
                    saleCreditService.updateById(saleCredit);
                    return res;
                } else {
                    String successMessage = (String) message.get("successMessage");
                    JSONArray modelarr = jsonObj.getJSONArray("model");
                    JSONObject model = modelarr.getJSONObject(0);
                    String redConfirmSerialNo = (String)model.get("redConfirmSerialNo");
                    String redConfirmNo = (String)model.get("redConfirmNo");
                    String redConfirmUuid = (String)model.get("redConfirmUuid");
                    String confirmState = (String)model.get("confirmState");
                    String confirmBillingMark = (String)model.get("confirmBillingMark");
                    InvoiceResult result = new InvoiceResult();
                    result.setXTaxNo(invoiceResult.getXTaxNo());
                    result.setRequestId(requestId);
                    result.setSuccess(flag);
                    result.setMessage(successMessage);
                    result.setSerialNo(redConfirmSerialNo);
                    result.setInvoiceNo(redConfirmNo);
                    result.setRedConfirmUuid(redConfirmUuid);
                    result.setConfirmState(confirmState);
                    result.setConfirmBillingMark(confirmBillingMark);
                    result.setMethodName("红字确认单新增接口");
                    result.setOriginalInvoiceNo(invoiceResult.getInvoiceNo());
                    result.setEntrustCode(invoiceResult.getEntrustCode());
                    invoiceResultService.save(result);
                    Map<String,Object> res = new HashMap<>();
                    res.put("success",flag);
                    res.put("message",successMessage);
                    res.put("obj",result);
                    return res;
                }
            }else {
                Map<String,Object> res = new HashMap<>();
                res.put("success",false);
                res.put("message","开票接口异常");
                InvoiceResult result = new InvoiceResult();
                result.setSuccess(false);
                result.setMessage("红字确认单新增接口异常");
                result.setMethodName("红字确认单新增接口");
                result.setEntrustCode(saleCredit.getEntrustCode());
                invoiceResultService.save(result);
                saleCredit.setInvoiceRemark("红字确认单新增接口异常");
                saleCreditService.updateById(saleCredit);
                return res;
            }
        }else {
            Map<String,Object> res = new HashMap<>();
            res.put("success",false);
            res.put("message","红字确认单新增接口异常");
            InvoiceResult result = new InvoiceResult();
            result.setSuccess(false);
            result.setMessage("红字确认单新增接口异常");
            result.setMethodName("红字确认单新增接口");
            result.setEntrustCode(saleCredit.getEntrustCode());
            invoiceResultService.save(result);
            saleCredit.setInvoiceRemark("红字确认单新增接口异常");
            saleCreditService.updateById(saleCredit);
            return res;
        }
    }
    /**
     * 数电红字确认单查询接口
     */
    Map<String,Object> redTicketConfirmSearch(InvoiceResult invoiceResult,SaleCredit saleCredit){
       /* QueryWrapper<RailwayEntrust> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(RailwayEntrust::getEntrustCode,invoiceResult.getEntrustCode());
        RailwayEntrust railwayEntrust = railwayEntrustMapper.selectList(wrapper).get(0);*/
        Map<String,Object> map = new HashMap<>();
        map.put("taxNo",invoiceResult.getXTaxNo());
        //map.put("taxUserName",dwuser);
        map.put("sellerTaxNo",invoiceResult.getXTaxNo());
        map.put("redConfirmUuid",invoiceResult.getRedConfirmUuid());
        Gson gson =new Gson();
        String str = gson.toJson(map);
        System.out.println(str);
        String responseBody = "";
        responseBody = HttpRequest.post(invoiceIp+redConfirmSearchUrl+UuidUtils.generateUuid())
                .timeout(400000)
                .body(str)
                .execute()
                .body();
        System.out.println(responseBody);
        JSONObject jsonObj = JSON.parseObject(responseBody);
        if(jsonObj!=null) {
            boolean flag = (Boolean) jsonObj.get("success");
            JSONObject message = jsonObj.getJSONObject("message");
            String requestId = (String) jsonObj.get("requestId");
            if (!flag) {
                Map<String,Object> res = new HashMap<>();
                res.put("success",false);
                res.put("message","红字确认单确认接口异常");
                InvoiceResult result = new InvoiceResult();
                result.setSuccess(false);
                result.setRequestId(requestId);
                result.setMessage("红字确认单确认接口异常");
                result.setMethodName("红字确认单确认接口");
                result.setEntrustCode(invoiceResult.getEntrustCode());
                invoiceResultService.save(result);
                saleCredit.setInvoiceRemark("红字确认单确认接口异常");
                saleCreditService.updateById(saleCredit);
                return res;
            } else {
                String successMessage = (String) message.get("successMessage");
                JSONArray modelarr = jsonObj.getJSONArray("model");
                JSONObject model = modelarr.getJSONObject(0);
                String redConfirmSerialNo = (String)model.get("redConfirmSerialNo");
                String redConfirmNo = (String)model.get("redConfirmNo");
                String redConfirmUuid = (String)model.get("redConfirmUuid");
                String confirmState = (String)model.get("confirmState");
                String confirmBillingMark = (String)model.get("confirmBillingMark");
                String entryIdentity = (String)model.get("entryIdentity");
                String sellerTaxNo = (String)model.get("sellerTaxNo");
                String sellerName = (String)model.get("sellerName");
                String buyerTaxNo = (String)model.get("buyerTaxNo");
                String buyerName = (String)model.get("buyerName");
                String originalInvoiceNo = (String)model.get("originalInvoiceNo");
                String originInvoiceIsPaper = (String)model.get("originInvoiceIsPaper");
                String originInvoiceDate = (String)model.get("originInvoiceDate");
                String originInvoiceType = (String)model.get("originInvoiceType");
                String redInvoiceLabel = (String)model.get("redInvoiceLabel");
                String alreadyRedInvoiceFlag = (String)model.get("alreadyRedInvoiceFlag");
                String redInvoiceNo = (String)model.get("redInvoiceNo");
                String redInvoiceDate = (String)model.get("redInvoiceDate");
                String entryDate = (String)model.get("entryDate");
                String validFlag = (String)model.get("validFlag");
                String invoiceSource = (String)model.get("invoiceSource");
                String tenantCode = (String)model.get("tenantCode");
                String orgCode = (String)model.get("orgCode");
                String buySelSelector = (String)model.get("buySelSelector");
                String autoIssueSwitch = (String)model.get("autoIssueSwitch");
                String priceTaxMark = (String)model.get("priceTaxMark");
                BigDecimal originInvoiceTotalPriceValue = (BigDecimal) model.get("originInvoiceTotalPrice");
                Double originInvoiceTotalPrice = Double.valueOf(originInvoiceTotalPriceValue.doubleValue());
                BigDecimal originInvoiceTotalTaxValue = (BigDecimal) model.get("originInvoiceTotalTax");
                Double originInvoiceTotalTax = Double.valueOf(originInvoiceTotalTaxValue.doubleValue());
                BigDecimal invoiceTotalPriceValue = (BigDecimal) model.get("invoiceTotalPrice");
                Double invoiceTotalPrice = Double.valueOf(invoiceTotalPriceValue.doubleValue());
                BigDecimal invoiceTotalTaxValue = (BigDecimal) model.get("invoiceTotalTax");
                Double invoiceTotalTax = Double.valueOf(invoiceTotalTaxValue.doubleValue());
                InvoiceResult result = new InvoiceResult();
                result.setRequestId(requestId);
                result.setMessage(successMessage);
                result.setSerialNo(redConfirmSerialNo);
                result.setInvoiceNo(redConfirmNo);
                result.setSuccess(flag);
                result.setInvoiceNo(invoiceResult.getInvoiceNo());
                result.setEntrustCode(invoiceResult.getEntrustCode());
                result.setXTaxNo(sellerTaxNo);
                result.setXOrgCode(orgCode);
                result.setXName(sellerName);
                result.setGName(buyerName);
                result.setGTaxNo(buyerTaxNo);
                result.setEntryDate(entryDate);
                result.setEntryIdentity(entryIdentity);
                result.setAlreadyRedInvoiceFlag(alreadyRedInvoiceFlag);
                result.setOriginInvoiceType(originInvoiceType);
                result.setOriginalInvoiceDate(originInvoiceDate);
                result.setOriginInvoiceIsPaper(originInvoiceIsPaper);
                result.setOriginalInvoiceNo(originalInvoiceNo);
                result.setRedInvoiceNo(redInvoiceNo);
                result.setRedInvoiceDate(redInvoiceDate);
                result.setValidFlag(validFlag);
                result.setRedInvoiceLabel(redInvoiceLabel);
                result.setRedConfirmUuid(redConfirmUuid);
                result.setConfirmState(confirmState);
                result.setConfirmBillingMark(confirmBillingMark);
                result.setMethodName("红字确认单确认接口");
                result.setInvoiceTotalPrice(invoiceTotalPrice);
                result.setInvoiceTotalTax(invoiceTotalTax);
                result.setOriginInvoiceTotalPrice(originInvoiceTotalPrice);
                result.setOriginInvoiceTotalTax(originInvoiceTotalTax);
                invoiceResultService.save(result);
                JSONArray invoiceDetailList1 = model.getJSONArray("electricInvoiceDetails");
                for (int i = 0; i < invoiceDetailList1.size(); i++) {
                    JSONObject jsonObject = invoiceDetailList1.getJSONObject(i);
                    int goodsLineNo = (int) jsonObject.get("goodsLineNo");
                    int originalInvoiceDetailNo = (int) jsonObject.get("originalInvoiceDetailNo");
                    String goodsName = (String) jsonObject.get("goodsName");
                    String goodsCode = (String) jsonObject.get("goodsCode");
                    BigDecimal goodsPriceValue = (BigDecimal)jsonObject.get("goodsPrice");
                    Double goodsPrice = Double.valueOf(goodsPriceValue.doubleValue());
                    double goodsQuantity=0.0;
                    try {
                        BigDecimal goodsQuantityValue = (BigDecimal)jsonObject.get("goodsQuantity");
                        goodsQuantity = Double.valueOf(goodsQuantityValue.doubleValue());
                    }catch (Exception e){
                        e.printStackTrace();
                        int goodsQuantity1 = (int) jsonObject.get("goodsQuantity");
                        goodsQuantity = goodsQuantity1;
                    }
                    BigDecimal goodsTotalPriceValue = (BigDecimal)jsonObject.get("goodsTotalPrice");
                    Double goodsTotalPrice = Double.valueOf(goodsTotalPriceValue.doubleValue());
                    BigDecimal goodsTotalTaxValue = (BigDecimal)jsonObject.get("goodsTotalTax");
                    Double goodsTotalTax = Double.valueOf(goodsTotalTaxValue.doubleValue());
                    BigDecimal goodsTaxRateValue = (BigDecimal)jsonObject.get("goodsTaxRate");
                    Double goodsTaxRate = Double.valueOf(goodsTaxRateValue.doubleValue());
                    String invoiceLineNature = (String) jsonObject.get("invoiceLineNature");
                    String goodsUnit = (String) jsonObject.get("goodsUnit");
                    String goodsSpecification = (String) jsonObject.get("goodsSpecification");
                    String coalType = (String)jsonObject.get("coalType");
                    String agreementTerm = (String)jsonObject.get("agreementTerm");
                    String name = "";
                    if(goodsLineNo==1){
                        name = "煤款";
                    }
                    if(goodsLineNo==2){
                        name = "取送车费";
                    }
                    if(goodsLineNo==3){
                        name = "专线费";
                    }
                    InvoiceResultItem item = new InvoiceResultItem();
                    item.setGoodsLineNature(invoiceLineNature);
                    item.setOriginalInvoiceDetailNo(originalInvoiceDetailNo);
                    item.setGoodsCode(goodsCode);
                    item.setGoodsPrice(goodsPrice);
                    item.setGoodsType(name);
                    if(goodsSpecification !=null){
                        item.setGoodsSpecification(goodsSpecification);
                    }
                    item.setGoodsLineNo(goodsLineNo);
                    item.setGoodsQuantity(goodsQuantity);
                    item.setGoodsTaxRate(goodsTaxRate);
                    item.setGoodsName(goodsName);
                    item.setGoodsTotalPrice(goodsTotalPrice);
                    item.setGoodsTotalTax(goodsTotalTax);
                    item.setGoodsUnit(goodsUnit);
                    item.setResultId(result.getId());
                    item.setEntrustCode(result.getEntrustCode());
                    if(coalType !=null){
                        item.setCoalType(coalType);
                    }
                    if(agreementTerm !=null){
                        item.setAgreementTerm(agreementTerm);
                    }
                    String[] split = goodsName.split("\\*");
                    int length = split.length;
                    String coalName = split[length - 1];
                    item.setCoalName(coalName);
                    itemMapper.insert(item);
                }
                Map<String,Object> res = new HashMap<>();
                res.put("success",flag);
                res.put("message",successMessage);
                res.put("obj",result);
                saleCredit.setInvoiceRemark("红字确认单确认接口成功");
                saleCredit.setRedInvoiceResultId(result.getId());
                saleCreditService.updateById(saleCredit);
                return res;
            }
        }else {
            Map<String,Object> res = new HashMap<>();
            res.put("success",false);
            res.put("message","红字确认单确认接口异常");
            InvoiceResult result = new InvoiceResult();
            result.setSuccess(false);
            result.setMessage("红字确认单确认接口异常");
            result.setMethodName("红字确认单确认接口");
            result.setEntrustCode(invoiceResult.getEntrustCode());
            invoiceResultService.save(result);
            saleCredit.setInvoiceRemark("红字确认单确认接口异常");
            saleCreditService.updateById(saleCredit);
            return res;
        }
    }
    /**
     * 红字确认单form
     * @param result
     * @return
     */
    InvoicingVo redKaiPiaoVo(InvoiceResult result){
        SaleCredit saleCredit = saleCreditService.getById(result.getSaleCreditId());
        InvoiceResult blueResult = null;
        InvoiceResult redResult = null;
        QueryWrapper<InvoiceResult> invoiceResultQueryWrapper = new QueryWrapper<>();
        invoiceResultQueryWrapper.lambda()
                .eq(InvoiceResult::getEntrustCode,result.getEntrustCode())
                .eq(InvoiceResult::getMethodName,"蓝字开票接口")
                .eq(InvoiceResult::getSuccess,1)
                .orderByDesc(InvoiceResult::getCreateTime);
        List<InvoiceResult> InvoiceResultList = invoiceResultService.list(invoiceResultQueryWrapper);
        if(InvoiceResultList!=null&&InvoiceResultList.size()>0){
            blueResult = InvoiceResultList.get(0);
            redResult = result;
        }else {
            return null;
        }
        InvoicingVo invoicingVo = new InvoicingVo();
        QueryWrapper<InvoiceResultItem> itemQueryWrapper  = new QueryWrapper<>();
        itemQueryWrapper.lambda()
                .eq(InvoiceResultItem::getResultId,blueResult.getId());
        List<InvoiceResultItem> resultItems = itemMapper.selectList(itemQueryWrapper);
        if(saleCredit!=null) {
            invoicingVo.setTaxNo(saleCredit.getCreditCodeB());
            invoicingVo.setEntrustCode(blueResult.getEntrustCode());
            invoicingVo.setLedgerName(saleCredit.getPartyB());
            invoicingVo.setOrgCode(saleCredit.getCreditCodeB());
            invoicingVo.setFormatGenerate(false);
            invoicingVo.setIsSplit(false);
            invoicingVo.setFormatPushType(false);
            invoicingVo.setTaxUserName(saleCredit.getContactPhoneB());
            InvoicingVo.InvoicingVoInfo invoicingVoInfo = new InvoicingVo.InvoicingVoInfo();
            invoicingVoInfo.setInvoiceTypeCode("01");
            invoicingVoInfo.setInvoiceType("1");
            invoicingVoInfo.setSerialNo("MX_REDPP_" + System.currentTimeMillis());
            invoicingVoInfo.setRedInfoNo(redResult.getInvoiceNo());
            invoicingVoInfo.setRedIssueReason("1");
            invoicingVoInfo.setRedConfirmUuid(redResult.getRedConfirmUuid());
            invoicingVoInfo.setDrawer(saleCredit.getContactPhoneB());
            Map<String, Object> ext1 = new HashMap<>();
            ext1.put("htbh",saleCredit.getContractNo());
            invoicingVoInfo.setExt(ext1);
            invoicingVoInfo.setSystemName("**销售管理信息系统");
            List<InvoicingVo.InvoiceDetail> details = new ArrayList<>();
            for (InvoiceResultItem resultItem : resultItems) {
                InvoicingVo.InvoiceDetail invoiceDetail = new InvoicingVo.InvoiceDetail();
                invoiceDetail.setGoodsLineNo(resultItem.getGoodsLineNo());
                invoiceDetail.setCoalType(resultItem.getCoalType());
                invoiceDetail.setAgreementTerm(resultItem.getAgreementTerm());
                invoiceDetail.setOriginalInvoiceDetailNo(resultItem.getGoodsLineNo()+"");
                invoiceDetail.setGoodsTaxRate(resultItem.getGoodsTaxRate());
                invoiceDetail.setGoodsUnit(resultItem.getGoodsUnit());
                invoiceDetail.setGoodsName(resultItem.getCoalName());
                invoiceDetail.setGoodsCode(resultItem.getGoodsCode());
                invoiceDetail.setGoodsType(resultItem.getGoodsType());
                invoiceDetail.setGoodsSpecification(resultItem.getGoodsSpecification());
                invoiceDetail.setGoodsQuantity(new BigDecimal(resultItem.getGoodsQuantity()*-1).setScale(3,BigDecimal.ROUND_HALF_UP));
                invoiceDetail.setGoodsPrice(new BigDecimal(resultItem.getGoodsPrice()).setScale(8,BigDecimal.ROUND_HALF_UP));
                invoiceDetail.setGoodsTotalPrice(new BigDecimal(resultItem.getGoodsTotalPrice()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
                invoiceDetail.setGoodsTotalTax(new BigDecimal(resultItem.getGoodsTotalTax()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
                details.add(invoiceDetail);
            }
            invoicingVoInfo.setBuyerTaxNo(saleCredit.getCreditCodeA());
            invoicingVoInfo.setBuyerName(saleCredit.getPartyA());
            invoicingVoInfo.setInvoiceTotalPrice(new BigDecimal(blueResult.getInvoiceTotalPrice()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
            invoicingVoInfo.setInvoiceTotalTax(new BigDecimal(blueResult.getInvoiceTotalTax()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
            invoicingVoInfo.setInvoiceTotalPriceTax(new BigDecimal(blueResult.getInvoiceTotalPriceTax()*-1).setScale(2,BigDecimal.ROUND_HALF_UP));
            invoicingVoInfo.setBuyerBankName(saleCredit.getBankNameA());
            invoicingVoInfo.setBuyerBankNumber(saleCredit.getBankAccountA());
            //invoicingVoInfo.setBuyerAddress(invoiceCustomer.getBuyerAddress());
            invoicingVoInfo.setBuyerTelphone(saleCredit.getContactPhoneA());
            invoicingVoInfo.setInvoiceDetailsList(details);
            /*if(invoicingVoInfo.getInvoiceTotalPriceTax().compareTo(new BigDecimal(10000000))>=0){
                invoicingVoInfo.setCoalCalorificValue(blueResult.getCoalCalorificValue());
                invoicingVoInfo.setDryAshFreeVolatileMatter(blueResult.getDryAshFreeVolatileMatter());
                invoicingVoInfo.setTotalSulfurOnDryBasis(blueResult.getTotalSulfurOnDryBasis());
            }*/
            invoicingVo.setData(invoicingVoInfo);
            return invoicingVo;
        }else {
            return null;
        }
    }
    /**
     * 时间格式化工具
     * @param s
     * @return
     */
    String strToFormat(String s){
        String year = s.substring(0, 4);
        String month = s.substring(4, 6);
        String day = s.substring(6, 8);
        String hour = s.substring(8, 10);
        String minute = s.substring(10, 12);
        String second = s.substring(12);
        String date = year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
        System.out.println(date);
        return date;
    }
}
platformx-business-finance-biz/src/main/resources/mapper/BipInvoiceMapper.xml
New file
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~
  ~      Copyright (c) 2018-2025, platform All rights reserved.
  ~
  ~  Redistribution and use in source and binary forms, with or without
  ~  modification, are permitted provided that the following conditions are met:
  ~
  ~ Redistributions of source code must retain the above copyright notice,
  ~  this list of conditions and the following disclaimer.
  ~  Redistributions in binary form must reproduce the above copyright
  ~  notice, this list of conditions and the following disclaimer in the
  ~  documentation and/or other materials provided with the distribution.
  ~  Neither the name of the pig4cloud.com developer nor the names of its
  ~  contributors may be used to endorse or promote products derived from
  ~  this software without specific prior written permission.
  ~  Author: platform
  ~
  -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by4cloud.platformx.business.invoice.mapper.BipInvoiceMapper">
  <resultMap id="bipInvoiceMap" type="com.by4cloud.platformx.business.entity.invoice.BipInvoice">
                  <id property="id" column="id"/>
                        <result property="compId" column="comp_id"/>
                        <result property="createBy" column="create_by"/>
                        <result property="createTime" column="create_time"/>
                        <result property="delFlag" column="del_flag"/>
                        <result property="updateBy" column="update_by"/>
                        <result property="updateTime" column="update_time"/>
                        <result property="bipNumber" column="bip_number"/>
                        <result property="day" column="day"/>
                        <result property="invoice" column="invoice"/>
                        <result property="returnInvoice" column="return_invoice"/>
            </resultMap>
</mapper>
platformx-business-finance-biz/src/main/resources/mapper/FileBipMapper.xml
New file
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~
  ~      Copyright (c) 2018-2025, platform All rights reserved.
  ~
  ~  Redistribution and use in source and binary forms, with or without
  ~  modification, are permitted provided that the following conditions are met:
  ~
  ~ Redistributions of source code must retain the above copyright notice,
  ~  this list of conditions and the following disclaimer.
  ~  Redistributions in binary form must reproduce the above copyright
  ~  notice, this list of conditions and the following disclaimer in the
  ~  documentation and/or other materials provided with the distribution.
  ~  Neither the name of the pig4cloud.com developer nor the names of its
  ~  contributors may be used to endorse or promote products derived from
  ~  this software without specific prior written permission.
  ~  Author: platform
  ~
  -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by4cloud.platformx.business.invoice.mapper.FileBipMapper">
  <resultMap id="fileBipMap" type="com.by4cloud.platformx.business.entity.invoice.FileBip">
                  <id property="id" column="id"/>
                        <result property="compId" column="comp_id"/>
                        <result property="createBy" column="create_by"/>
                        <result property="createTime" column="create_time"/>
                        <result property="delFlag" column="del_flag"/>
                        <result property="updateBy" column="update_by"/>
                        <result property="updateTime" column="update_time"/>
                        <result property="fileId" column="file_id"/>
                        <result property="copy" column="copy"/>
                        <result property="fileBipId" column="file_bip_id"/>
                        <result property="filectime" column="filectime"/>
                        <result property="fileExtension" column="file_extension"/>
                        <result property="fileName" column="file_name"/>
                        <result property="filePath" column="file_path"/>
                        <result property="fileSize" column="file_size"/>
                        <result property="fileSizeText" column="file_size_text"/>
                        <result property="fileutime" column="fileutime"/>
                        <result property="name" column="name"/>
                        <result property="railwayEntrustId" column="railway_entrust_id"/>
                        <result property="sign" column="sign"/>
                        <result property="tenantId" column="tenant_id"/>
                        <result property="yhtUserId" column="yht_user_id"/>
            </resultMap>
</mapper>
platformx-business-finance-biz/src/main/resources/mapper/FpInvoiceResultItemMapper.xml
New file
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~
  ~      Copyright (c) 2018-2025, platform All rights reserved.
  ~
  ~  Redistribution and use in source and binary forms, with or without
  ~  modification, are permitted provided that the following conditions are met:
  ~
  ~ Redistributions of source code must retain the above copyright notice,
  ~  this list of conditions and the following disclaimer.
  ~  Redistributions in binary form must reproduce the above copyright
  ~  notice, this list of conditions and the following disclaimer in the
  ~  documentation and/or other materials provided with the distribution.
  ~  Neither the name of the pig4cloud.com developer nor the names of its
  ~  contributors may be used to endorse or promote products derived from
  ~  this software without specific prior written permission.
  ~  Author: platform
  ~
  -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by4cloud.platformx.business.invoice.mapper.FpInvoiceResultItemMapper">
  <resultMap id="fpInvoiceResultItemMap" type="com.by4cloud.platformx.business.entity.invoice.InvoiceResultItem">
                  <id property="id" column="id"/>
                        <result property="compId" column="comp_id"/>
                        <result property="createBy" column="create_by"/>
                        <result property="createTime" column="create_time"/>
                        <result property="delFlag" column="del_flag"/>
                        <result property="updateBy" column="update_by"/>
                        <result property="updateTime" column="update_time"/>
                        <result property="goodsCode" column="goods_code"/>
                        <result property="goodsLineNature" column="goods_line_nature"/>
                        <result property="goodsLineNo" column="goods_line_no"/>
                        <result property="goodsName" column="goods_name"/>
                        <result property="goodsPrice" column="goods_price"/>
                        <result property="goodsQuantity" column="goods_quantity"/>
                        <result property="goodsSimpleName" column="goods_simple_name"/>
                        <result property="goodsTaxRate" column="goods_tax_rate"/>
                        <result property="goodsTotalPrice" column="goods_total_price"/>
                        <result property="goodsTotalTax" column="goods_total_tax"/>
                        <result property="goodsUnit" column="goods_unit"/>
                        <result property="originalInvoiceDetailNo" column="original_invoice_detail_no"/>
                        <result property="priceTaxMark" column="price_tax_mark"/>
                        <result property="projectName" column="project_name"/>
                        <result property="resultId" column="result_id"/>
            </resultMap>
</mapper>
platformx-business-finance-biz/src/main/resources/mapper/FpInvoiceResultMapper.xml
New file
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~
  ~      Copyright (c) 2018-2025, platform All rights reserved.
  ~
  ~  Redistribution and use in source and binary forms, with or without
  ~  modification, are permitted provided that the following conditions are met:
  ~
  ~ Redistributions of source code must retain the above copyright notice,
  ~  this list of conditions and the following disclaimer.
  ~  Redistributions in binary form must reproduce the above copyright
  ~  notice, this list of conditions and the following disclaimer in the
  ~  documentation and/or other materials provided with the distribution.
  ~  Neither the name of the pig4cloud.com developer nor the names of its
  ~  contributors may be used to endorse or promote products derived from
  ~  this software without specific prior written permission.
  ~  Author: platform
  ~
  -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by4cloud.platformx.business.invoice.mapper.FpInvoiceResultMapper">
  <resultMap id="fpInvoiceResultMap" type="com.by4cloud.platformx.business.entity.invoice.InvoiceResult">
                  <id property="id" column="id"/>
                        <result property="compId" column="comp_id"/>
                        <result property="createBy" column="create_by"/>
                        <result property="createTime" column="create_time"/>
                        <result property="delFlag" column="del_flag"/>
                        <result property="updateBy" column="update_by"/>
                        <result property="updateTime" column="update_time"/>
                        <result property="eInvoiceUrl" column="e_invoice_url"/>
                        <result property="invoiceCheckCode" column="invoice_check_code"/>
                        <result property="invoiceNo" column="invoice_no"/>
                        <result property="invoiceQrCode" column="invoice_qr_code"/>
                        <result property="invoiceTotalPrice" column="invoice_total_price"/>
                        <result property="invoiceTotalPriceTax" column="invoice_total_price_tax"/>
                        <result property="invoiceTotalTax" column="invoice_total_tax"/>
                        <result property="methodName" column="method_name"/>
                        <result property="requestId" column="request_id"/>
                        <result property="result" column="result"/>
                        <result property="serialNo" column="serial_no"/>
                        <result property="taxControlCode" column="tax_control_code"/>
            </resultMap>
</mapper>