红冲接口

This commit is contained in:
王奎兴
2026-09-10 15:33:51 +08:00
parent 76ded7ed01
commit 3387d1712d
14 changed files with 257 additions and 19 deletions
@@ -626,6 +626,22 @@ public class BillManageApplicationService {
return originalBill;
}
/**
* 应收账单-红冲
*/
@Transactional
public Boolean redFlushBill(BillManageDTO billManageDTO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
if (billManageDTO.getBillManageId() == null) {
throw new ServiceException("账单id不能为空");
}
return billManageDomainService.redFlushBill(billManageDTO);
}
/**
* 应收账单-客户确认
*/
@@ -156,8 +156,6 @@ public class ReceiptManageApplicationService {
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
//校验支付密码
CheckPasswordUtil.checkPayPassword(receiptManageDO.getPayPassword(),null);
return receiptManageDomainService.cancelCollection(receiptManageDO);
}
@@ -47,8 +47,8 @@ public class BillManage extends BaseVOEntity{
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款)")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@ApiModelProperty("账单流程节点(1-发起对账,2-客户确认,3-财务审核,4-收款/付款)")
@@ -52,8 +52,8 @@ public class BillManagePO extends BaseVOEntity{
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款)")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@ApiModelProperty("账单流程节点(1-发起对账,2-客户确认,3-财务审核,4-收款/付款)")
@@ -47,8 +47,8 @@ public class BillManageDO extends BaseVOEntity{
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款)")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@ApiModelProperty("账单流程节点(1-发起对账,2-客户确认,3-财务审核,4-收款/付款)")
@@ -14,6 +14,7 @@ import com.mhd.bms.domain.billManage.repository.todo.BillDetailDO;
import com.mhd.bms.domain.billManage.repository.todo.BillManageDO;
import com.mhd.bms.interfaces.dto.billManage.CustomerMonthBillVO;
import com.mhd.bms.domain.billOperationLog.entity.BillOperationLog;
import com.mhd.bms.domain.billOperationLog.repository.po.BillOperationLogPO;
import com.mhd.bms.domain.billOperationLog.repository.todo.BillOperationLogDO;
import com.mhd.bms.domain.billOperationLog.service.BillOperationLogDomainService;
import com.mhd.bms.domain.billingStatement.entity.BillingStatement;
@@ -45,6 +46,7 @@ import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -747,6 +749,185 @@ public class BillManageDomainService {
return flag && three;
}
/**
* 应收账单红冲:生成一条金额为负数的红冲账单对冲原账单,不操作收款单等数据
*/
public Boolean redFlushBill(BillManageDTO billManageDTO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
if (null == billManageDTO.getBillManageId()) {
throw new ServiceException("账单id不能为空");
}
BillManage originalBill = billManageService.getById(billManageDTO.getBillManageId());
if (null == originalBill || ObjectUtil.equal(originalBill.getDelFlag(), 2)) {
throw new ServiceException("原账单信息未找到,请刷新后重试");
}
if (ObjectUtil.equal(originalBill.getBillType(), 2)) {
throw new ServiceException("仅支持应收账单红冲");
}
if (!ObjectUtil.equal(originalBill.getBillState(), 5)) {
throw new ServiceException("仅已收款状态的账单可以红冲,请刷新后重试");
}
//校验账单是否已红冲,避免重复生成红冲账单
BillOperationLogDO redFlushLogQuery = new BillOperationLogDO();
redFlushLogQuery.setBillManageId(originalBill.getBillManageId());
redFlushLogQuery.setOperationType(13);
List<BillOperationLogPO> redFlushLogList = billOperationLogDomainService.queryList(redFlushLogQuery);
if (null != redFlushLogList && redFlushLogList.stream().anyMatch(info -> ObjectUtil.equal(info.getDelFlag(), 1))) {
throw new ServiceException("该账单已红冲,不能重复红冲");
}
//生成红冲账单编号
String billNumber = OrderSequence.getOrderCode("ZD");
BigDecimal redFlushAmount = negateAmount(originalBill.getBillAmount());
//构建红冲账单,金额全部取负对冲原账单
BillManage redBill = new BillManage();
BeanUtils.copyProperties(originalBill, redBill);
redBill.setBillManageId(null);
redBill.setBillNumber(billNumber);
redBill.setBillAmount(redFlushAmount);
redBill.setBillTotalAmount(negateAmount(originalBill.getBillTotalAmount()));
redBill.setBillDiscountAmount(negateAmount(originalBill.getBillDiscountAmount()));
redBill.setBillAmountSettlement(negateAmount(originalBill.getBillAmountSettlement()));
redBill.setBillAmountUnsettled(BigDecimal.ZERO);
redBill.setActualReceivedAmount(negateAmount(originalBill.getActualReceivedAmount()));
redBill.setSettlementDiscountsAmount(negateAmount(originalBill.getSettlementDiscountsAmount()));
redBill.setTaxAmount(negateAmount(originalBill.getTaxAmount()));
redBill.setTaxFreeFee(negateAmount(originalBill.getTaxFreeFee()));
//红冲账单状态为红冲、已核对无误
redBill.setBillState(8);
redBill.setBillStep(4);
redBill.setReconciliationStatus(4);
redBill.setSettlementTime(new Date());
//重置对账、审核、开票、同步等状态,红冲账单不需要再走这些流程
redBill.setBillExpectedAmount(null);
redBill.setReconciliationOpinion(null);
redBill.setVoucherAddress(null);
redBill.setFinancialReviewFlag(null);
redBill.setFinancialReviewOpinion(null);
redBill.setIsInvoice(0);
redBill.setInvoiceId(null);
redBill.setInvoiceMakeTime(null);
redBill.setApplyNumber(null);
redBill.setSynchronousStatus(0);
redBill.setSynchronousTime(null);
redBill.setNcId(null);
redBill.setSkSynchronousStatus(0);
redBill.setSkSynchronousTime(null);
redBill.setSkNcId(null);
//红冲原因写入账单备注
String billRemark = "红冲原账单编号:" + originalBill.getBillNumber();
if (StringUtils.isNotEmpty(billManageDTO.getRedFlushRemark())) {
billRemark = billRemark + ",红冲原因:" + billManageDTO.getRedFlushRemark();
}
redBill.setBillRemark(billRemark);
redBill.setDelFlag(1);
redBill.setCreateBy(loginUser.getUserid());
redBill.setCreateByName(loginUser.getUserPo().getUserName());
redBill.setCreateTime(new Date());
redBill.setUpdateBy(loginUser.getUserid());
redBill.setUpdateByName(loginUser.getUserPo().getUserName());
redBill.setUpdateTime(new Date());
Boolean flag = billManageService.save(redBill);
if (!flag || null == redBill.getBillManageId()) {
throw new ServiceException("生成红冲账单失败");
}
//镜像红冲计费流水(金额取负),并记录原流水id与新流水的映射
Map<Long, BillingStatementDO> statementMapping = new HashMap<>();
List<BillingStatementPO> originalStatementList = billingStatementDomainService.getDetailsByManageId(originalBill.getBillManageId());
if (null != originalStatementList && originalStatementList.size() > 0) {
for (BillingStatementPO originalStatement : originalStatementList) {
BillingStatementDO redStatement = new BillingStatementDO();
BeanUtils.copyProperties(originalStatement, redStatement);
redStatement.setBillingStatementId(null);
redStatement.setBillManageId(redBill.getBillManageId());
redStatement.setBillingFlow(OrderSequence.getOrderCode("JFLS"));
redStatement.setBillingAmount(negateAmount(originalStatement.getBillingAmount()));
redStatement.setTaxAmount(negateAmount(originalStatement.getTaxAmount()));
redStatement.setTaxFreeFee(negateAmount(originalStatement.getTaxFreeFee()));
redStatement.setBillingState(3);
redStatement.setRedFlushState(1);
redStatement.setRedFlushRemark("红冲自计费流水:" + originalStatement.getBillingFlow());
redStatement.setReviewRemarks(null);
redStatement.setBusinessDocumentId(null);
redStatement.setDelFlag(1);
redStatement.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
redStatement.setOrganizationId(loginUser.getUserPo().getOrganizationId());
redStatement.setOrganizationName(loginUser.getUserPo().getOrganizationName());
redStatement.setCreateBy(loginUser.getUserid());
redStatement.setCreateByName(loginUser.getUserPo().getUserName());
redStatement.setCreateTime(new Date());
redStatement.setUpdateBy(loginUser.getUserid());
redStatement.setUpdateByName(loginUser.getUserPo().getUserName());
redStatement.setUpdateTime(new Date());
redStatement.setBillingStatementId(billingStatementDomainService.insertAndReturnId(redStatement));
statementMapping.put(originalStatement.getBillingStatementId(), redStatement);
}
}
//镜像红冲账单明细(金额取负),并关联新计费流水
Boolean flagTwo = true;
LambdaQueryWrapper<BillDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
detailQueryWrapper.eq(BillDetail::getBillManageId, originalBill.getBillManageId());
detailQueryWrapper.eq(BillDetail::getDelFlag, 1);
List<BillDetail> originalDetailList = billDetailDomainService.queryByLambda(detailQueryWrapper);
if (null != originalDetailList && originalDetailList.size() > 0) {
List<BillDetail> redDetailList = new ArrayList<>();
for (BillDetail originalDetail : originalDetailList) {
BillDetail redDetail = new BillDetail();
BeanUtils.copyProperties(originalDetail, redDetail);
redDetail.setBillDetailId(null);
redDetail.setBillManageId(redBill.getBillManageId());
redDetail.setBillNumber(billNumber);
redDetail.setBillingTotalAmount(negateAmount(originalDetail.getBillingTotalAmount()));
redDetail.setBillingAmount(negateAmount(originalDetail.getBillingAmount()));
redDetail.setBillingDiscountAmount(negateAmount(originalDetail.getBillingDiscountAmount()));
redDetail.setTaxAmount(negateAmount(originalDetail.getTaxAmount()));
redDetail.setTaxFreeFee(negateAmount(originalDetail.getTaxFreeFee()));
redDetail.setBillingExpectedAmount(null);
BillingStatementDO redStatement = statementMapping.get(originalDetail.getBillingStatementId());
if (null != redStatement) {
redDetail.setBillingStatementId(redStatement.getBillingStatementId());
redDetail.setBillingFlow(redStatement.getBillingFlow());
} else {
redDetail.setBillingStatementId(null);
redDetail.setBillingFlow(null);
}
redDetail.setDelFlag(1);
redDetail.setCreateBy(loginUser.getUserid());
redDetail.setCreateByName(loginUser.getUserPo().getUserName());
redDetail.setCreateTime(new Date());
redDetail.setUpdateBy(loginUser.getUserid());
redDetail.setUpdateByName(loginUser.getUserPo().getUserName());
redDetail.setUpdateTime(new Date());
redDetailList.add(redDetail);
}
flagTwo = billDetailDomainService.insertBatch(redDetailList);
}
//红冲账单保存创建账单操作日志
BillOperationLogDO redBillLog = new BillOperationLogDO();
redBillLog.setBillManageId(redBill.getBillManageId());
redBillLog.setOperationInfo(StringUtils.format(BillLogsConstants.create_bill_text, billNumber, redFlushAmount));
redBillLog.setOperationType(1);
Boolean flagThree = billOperationLogDomainService.saveBillOperationLog(redBillLog);
//原账单保存红冲操作日志
BillOperationLogDO originalBillLog = new BillOperationLogDO();
originalBillLog.setBillManageId(originalBill.getBillManageId());
originalBillLog.setOperationInfo(StringUtils.format(BillLogsConstants.red_flush_bill_text, billNumber, null == redFlushAmount ? BigDecimal.ZERO : redFlushAmount.abs()));
originalBillLog.setOperationType(13);
Boolean flagFour = billOperationLogDomainService.saveBillOperationLog(originalBillLog);
return flag && flagTwo && flagThree && flagFour;
}
/**
* 金额取负(空值返回null)
*/
private BigDecimal negateAmount(BigDecimal amount) {
return null == amount ? null : amount.negate();
}
/**
* 更改账单状态(付款)
*/
@@ -42,8 +42,8 @@ public class BillOperationLog extends BaseVOEntity{
@Excel(name = "账单管理id")
private Long billManageId;
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款)")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款")
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
private Integer operationType;
@ApiModelProperty("操作信息")
@@ -41,8 +41,8 @@ public class BillOperationLogPO extends BaseVOEntity{
@Excel(name = "账单管理id")
private Long billManageId;
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款)")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款")
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
private Integer operationType;
@ApiModelProperty("操作信息")
@@ -42,8 +42,8 @@ public class BillOperationLogDO extends BaseVOEntity{
@Excel(name = "账单管理id")
private Long billManageId;
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款)")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款")
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
private Integer operationType;
@ApiModelProperty("操作信息")
@@ -112,4 +112,11 @@ public class BillLogsConstants
public static final String copy_bill_text = "原账单编号:{},新账单编号:{}";
/**
* 红冲账单
* 红冲账单编号:{},红冲金额:{}元
*/
public static final String red_flush_bill_title = "红冲账单";
public static final String red_flush_bill_text = "红冲账单编号:{},红冲金额:{}元";
}
@@ -47,8 +47,8 @@ public class BillManageDTO extends BaseVOEntity{
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款)")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@ApiModelProperty("账单状态(1-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@ApiModelProperty("账单流程节点(1-发起对账,2-客户确认,3-财务审核,4-收款/付款)")
@@ -279,4 +279,8 @@ public class BillManageDTO extends BaseVOEntity{
@ApiModelProperty("账单月份(yyyy-MM,按创建时间月份筛选,用于客户月账单分组查询)")
private String billMonth;
@ApiModelProperty("红冲原因")
@Excel(name = "红冲原因")
private String redFlushRemark;
}
@@ -28,7 +28,7 @@ public class BillManageExportVO {
@Excel(name = "账单类型", readConverterExp = "1=-应收,2-应付")
private Integer billType;
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款")
@Excel(name = "账单状态", readConverterExp = "1=-未确认,2-对账中,3-未收款/付款,4-部分收款/付款,5-已收款/付款,6-已作废,7-已退款,8-红冲")
private Integer billState;
@Excel(name = "账单流程节点", readConverterExp = "1=-发起对账,2-客户确认,3-财务审核,4-收款/付款")
@@ -40,8 +40,8 @@ public class BillOperationLogDTO extends BaseVOEntity{
@Excel(name = "账单管理id")
private Long billManageId;
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款)")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款")
@ApiModelProperty("操作类型(1-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
@Excel(name = "操作类型", readConverterExp = "1=-创建账单,2-调整账单,3-确认账单,4-发起对账,5-客户确认,6-财务审核,7-收款,8-作废账单,9-删除账单,10-退款,11-付款,12-撤销收款,13-红冲")
private Integer operationType;
@ApiModelProperty("操作信息")
@@ -396,6 +396,38 @@ public class BillManageApi extends BaseController{
}
@ApiOperation("应收账单-红冲")
@PostMapping("/redFlushBill")
public AjaxResult redFlushBill(@RequestBody BillManageDTO billManageDTO)
{
if(billManageDTO.getBillManageId() == null){
throw new ServiceException("账单id不能为空");
}
//加锁
RLock lock = null;
RedisLockTypeEnum redisLockTypeEnum = RedisLockTypeEnum.BMS;
String key = redisLockTypeEnum.getUniqueKey(UniqueKeyUtil.getBillingKey(String.valueOf(billManageDTO.getBillManageId())));
try {
lock = redisLock.getRLock(key);
//尝试获取锁 不等待 持有锁10分钟
if (!lock.tryLock(-1, 10, TimeUnit.MINUTES)) {
lock = null;
throw new ServiceException("账单正在操作中,请稍后重试");
}
log.info("红冲账单加锁成功");
billManageApplicationService.redFlushBill(billManageDTO);
return AjaxResult.success("操作成功");
}catch (Exception e){
return AjaxResult.error("红冲账单失败:"+e.getMessage());
} finally {
if (lock != null && lock.isHeldByCurrentThread()){
lock.unlock();
log.info("红冲账单释放锁成功");
}
}
}
@ApiOperation("应收账单-客户确认")
@PostMapping("/customerConfirmation")
public AjaxResult customerConfirmation(@RequestBody BillManageDTO billManageDTO)