package com.by4cloud.platformx.business.controller;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.by4cloud.platformx.admin.api.entity.SysDept;
|
import com.by4cloud.platformx.admin.api.feign.RemoteDeptService;
|
import com.by4cloud.platformx.business.entity.*;
|
import com.by4cloud.platformx.business.entity.invoice.vo.InvoicingVo;
|
import com.by4cloud.platformx.business.invoice.service.BIPYsService;
|
import com.by4cloud.platformx.business.entity.invoice.vo.BipResVo;
|
import com.by4cloud.platformx.business.invoice.service.FpInvoiceResultService;
|
import com.by4cloud.platformx.business.service.*;
|
import com.by4cloud.platformx.business.vo.ContractOutBoundVo;
|
import com.by4cloud.platformx.business.vo.InvoicePreviewVo;
|
import com.by4cloud.platformx.common.core.util.R;
|
import com.by4cloud.platformx.common.data.mybatis.BaseModel;
|
import com.by4cloud.platformx.common.log.annotation.SysLog;
|
import com.by4cloud.platformx.common.security.annotation.Inner;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
import jakarta.persistence.Column;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
import com.by4cloud.platformx.common.excel.annotation.ResponseExcel;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import org.springdoc.core.annotations.ParameterObject;
|
import org.springframework.http.HttpHeaders;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.Operation;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.web.bind.annotation.*;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 开票信息
|
*
|
* @author wjli
|
* @date 2026-06-04 10:50:20
|
*/
|
@RestController
|
@RequiredArgsConstructor
|
@RequestMapping("/billingInfo" )
|
@Tag(description = "billingInfo" , name = "开票信息管理" )
|
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
public class BillingInfoController {
|
|
private final BillingInfoService billingInfoService;
|
private final BillingItemService billingItemService;
|
private final ContractService contractService;
|
private final ContractOutBoundService contractOutBoundService;
|
private final InvoiceService invoiceService;
|
private final BIPYsService bipYsService;
|
|
/**
|
* 通过id查询开票信息
|
* @param id id
|
* @return R
|
*/
|
@Operation(summary = "通过id查询" , description = "通过id查询" )
|
@GetMapping("/getById/{id}" )
|
public R getById(@PathVariable("id" ) Long id) {
|
return R.ok(billingInfoService.getById(id));
|
}
|
|
/**
|
* 拼接发票信息
|
* @param previewVo 合同ID和出库单ID
|
* @return R
|
*/
|
@Operation(summary = "拼接发票信息" , description = "拼接发票信息" )
|
@SysLog("拼接发票信息" )
|
@GetMapping("/saveInvoice")
|
@Inner(value = false)
|
public R saveInvoice(@ParameterObject InvoicePreviewVo previewVo) {
|
|
//参数判断
|
if(previewVo.getContractId() == null){
|
return R.failed("合同id不能为空");
|
}
|
|
Contract contractTemp = contractService.getById(previewVo.getContractId());
|
if(contractTemp == null){
|
return R.failed("合同id错误");
|
}
|
BillingInfo billingInfo = billingInfoService.getInviceByContractId(previewVo,contractTemp,1);
|
|
//拼装开票项内容
|
List<ContractOutBoundVo> contractOutBoundVos = billingInfo.getContractOutBoundList();
|
if(contractOutBoundVos!=null && !contractOutBoundVos.isEmpty()) {
|
for(ContractOutBoundVo vo : contractOutBoundVos){
|
|
BillingItem item = new BillingItem();
|
//开票信息id
|
item.setBillingInfoId(billingInfo.getId());
|
//关联合同ID
|
item.setContractId(billingInfo.getContractId());
|
//开票产品名称
|
item.setInvoiceName(vo.getInvoiceName());
|
//客商ID
|
item.setBusGuestId(vo.getBusGuestId());
|
//产品id
|
item.setProductId(vo.getProductId());
|
//标的物规格/型号
|
item.setSpecification(vo.getSpecification());
|
//开票产品数量
|
item.setProductNum(vo.getOutBoundNum());
|
//标的物编码
|
item.setSubjectMatterCode(vo.getSubjectMatterCode());
|
//标的物名称
|
item.setSubjectMatterName(vo.getSubjectMatterName());
|
//计量单位(个/台/吨/项/套等)
|
item.setUnit(vo.getUnit());
|
//开票状态(0-未开票 1-开票中 2-已开票)
|
item.setBillingStatus(1);
|
//总单价
|
item.setTotalPrice(vo.getTotalPrice());
|
//单价
|
item.setUnitPrice(vo.getUnitPrice());
|
//税收分类
|
item.setTaxClass(vo.getTaxClass());
|
//税收编码
|
item.setTaxCode(vo.getTaxCode());
|
//总税额
|
item.setTotalTax(vo.getTotalTax());
|
//税率(百分比,如13表示13%)
|
item.setTaxRate(vo.getTaxRate());
|
//不含税总额
|
item.setTotalPriceNoTax(vo.getTotalPriceNoTax());
|
//所关联出库单ID
|
item.setContractOutBoundIds(vo.getContractOutBoundIds());
|
billingItemService.save(item);
|
}
|
}
|
|
//生成vo
|
/*InvoicingVo invoicingVo = invoiceService.toGetByCompareByVo1(billingInfo,contractOutBoundVos);
|
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){
|
billingInfo.setBlueResultStatus(1);
|
billingInfoService.updateById(billingInfo);
|
//推bi'p
|
BipResVo bipResVo = bipYsService.sendBIPYss(billingInfo);
|
if (!bipResVo.getCode().equals("200")) {
|
*//*if (StrUtil.isNotEmpty(errMsg)) {
|
errMsg.append(",");
|
}
|
errMsg.append(saleCredit.getCreditCodeB()+ "应收发票推送失败:" + bipResVo.getMessage());*//*
|
billingInfo.setBipStatus(1);
|
billingInfoService.updateById(billingInfo);
|
|
return R.failed("开票成功,推送bip失败,err:" + bipResVo.getMessage());
|
}else{
|
billingInfo.setBipStatus(200);
|
billingInfoService.updateById(billingInfo);
|
return R.ok("开票成功,推送big成功!");
|
}
|
}else{
|
billingInfo.setBlueResultStatus(2);
|
billingInfoService.updateById(billingInfo);
|
return R.failed("开票失败!err:" + message);
|
}
|
|
}catch (Exception e){
|
billingInfo.setStatus(3);
|
billingInfoService.updateById(billingInfo);
|
return R.failed("开票失败!err:" + e.getMessage());
|
}*/
|
|
//出库单已开票
|
List<ContractOutBound> contractOutBounds = contractOutBoundService.list(new LambdaQueryWrapper<ContractOutBound>()
|
.eq(ContractOutBound::getSaleCreditId,billingInfo.getId())
|
);
|
for(ContractOutBound contractOutBound : contractOutBounds){
|
contractOutBound.setInvoiceSatus(2);
|
}
|
contractOutBoundService.updateBatchById(contractOutBounds);
|
|
//开票成功
|
//开票记录单蓝票信息存储
|
billingInfo.setBlueResultStatus(1);
|
billingInfo.setInvoiceRemark("开票成功!");
|
billingInfo.setBlueInvoiceTime(DateTime.now());
|
billingInfoService.updateById(billingInfo);
|
|
//相关合同金额和开票状态进行修改。
|
Contract contract = contractService.getById(billingInfo.getContractId());
|
String billingStatus = contract.getBillingStatus();
|
|
if(contract.getBillingAmout()==null){
|
contract.setBillingAmout(billingInfo.getTotalAmount());
|
}else{
|
contract.setBillingAmout(contract.getBillingAmout().add(billingInfo.getTotalAmount()));
|
}
|
|
int res = contract.getAmount().compareTo(contract.getBillingAmout());
|
|
if("2".equals(billingStatus)) {
|
if (res == 0) {
|
contract.setBillingStatus("3");
|
} else if (res > 0) {
|
contract.setBillingStatus("2");
|
} else {
|
return R.failed("已付金额不能大于总金额!");
|
}
|
}
|
|
contractService.updateById(contract);
|
return R.ok("开票成功,推送bip成功!");
|
}
|
|
/**
|
* 拼接销售挂账
|
* @param billingInfo1 开票信息
|
* @return R
|
*/
|
@Operation(summary = "开发票" , description = "开发票" )
|
@SysLog("开发票" )
|
@PostMapping("/toRedStamp")
|
@PreAuthorize("@pms.hasPermission('business_saleCredit_edit')" )
|
public R toRedStamp(@RequestBody BillingInfo billingInfo1) {
|
if(billingInfo1.getId()==null){
|
return R.failed("开票信息id不能为空!");
|
}
|
BillingInfo billingInfo = billingInfoService.getById(billingInfo1.getId());
|
if(billingInfo==null){
|
return R.failed("开票信息id不能错误!");
|
}
|
|
/* try {
|
Map<String, Object> map = invoiceService.toRedTicket1(billingInfo);
|
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("红字开票失败");
|
}*/
|
|
|
//出库单恢复到未开票状态
|
List<ContractOutBound> outBoundList = contractOutBoundService.list(new LambdaQueryWrapper<ContractOutBound>()
|
.eq(ContractOutBound::getSaleCreditId,billingInfo.getId())
|
);
|
for(ContractOutBound outBound : outBoundList){
|
outBound.setInvoiceSatus(0);
|
outBound.setSaleCreditId(0l);
|
}
|
contractOutBoundService.updateBatchById(outBoundList);
|
|
billingInfo.setRedInvoiceTime(DateTime.now());
|
billingInfo.setRedResultStatus(1);
|
billingInfo.setInvoiceRemark("开红票成功!");
|
billingInfoService.updateById(billingInfo);
|
|
//合同已开票金额和状态还原
|
Contract contract = contractService.getById(billingInfo.getContractId());
|
String billingStatus = contract.getBillingStatus();
|
BigDecimal bill = contract.getBillingAmout() == null ? BigDecimal.ZERO : contract.getBillingAmout();
|
BigDecimal credit = billingInfo.getTotalAmount() == null ? BigDecimal.ZERO : billingInfo.getTotalAmount();
|
BigDecimal diff = bill.subtract(credit);
|
int res = diff.compareTo(BigDecimal.ZERO);
|
|
if("3".equals(billingStatus)){
|
if(res>=0){
|
contract.setBillingStatus("2");
|
contract.setBillingAmout(BigDecimal.ZERO);
|
}else{
|
return R.failed("已开票金额负数报错!");
|
}
|
}
|
contractService.updateById(contract);
|
return R.ok("红冲开票成功!");
|
}
|
|
|
/**
|
* 拼接发票信息
|
* @param previewVo 合同ID和出库单ID
|
* @return R
|
*/
|
@Operation(summary = "拼接发票信息" , description = "拼接发票信息" )
|
@SysLog("拼接发票信息" )
|
@GetMapping("/generatorInvoice")
|
@Inner(value = false)
|
public R generatorInvoice(@ParameterObject InvoicePreviewVo previewVo) {
|
|
//参数判断
|
if(previewVo.getContractId() == null){
|
return R.failed("合同id不能为空");
|
}
|
|
Contract contract = contractService.getById(previewVo.getContractId());
|
if(contract == null){
|
return R.failed("合同id错误");
|
}
|
|
BillingInfo billingInfo = billingInfoService.getInviceByContractId(previewVo,contract,0);
|
|
return R.ok(billingInfo);
|
}
|
|
}
|