mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
1、软件购买是否纯赠送金判断购买记录是否可开票状态修复;2、组织过期判断需要包含当天完善;3、申请开票增加购买记录开票状态校验;
This commit is contained in:
+12
@@ -90,4 +90,16 @@ public class AssertUtils {
|
||||
throw exception(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
public static void isFalse(boolean expression, ErrorCode errorCode) {
|
||||
if (!expression) {
|
||||
throw exception(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
public static void isTrue(boolean expression, ErrorCode errorCode) {
|
||||
if (expression) {
|
||||
throw exception(errorCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -446,6 +446,8 @@ public class ErrorCodeConstants {
|
||||
public static final ErrorCode PRODUCTS_NOT_NOLIST = new ErrorCode(1_002_043_033, "当前产品未上架");
|
||||
public static final ErrorCode ORG_PRODUCT_PURCHASE_LOCK_ERROR = new ErrorCode(1_002_043_034, "组织下存在购买中的产品操作,请稍后再试");
|
||||
public static final ErrorCode INVOICE_TITLE_ENTERPRISE_TAXNUMBER_EMPTY_ERROR = new ErrorCode(1_002_043_035, "企业统一信用代码不能为空");
|
||||
public static final ErrorCode INVOICE_AMOUNT_ZERO_ERROR = new ErrorCode(1_002_043_036, "可开票金额为,请检查购买记录");
|
||||
public static final ErrorCode INVOICE_APPLY_UNINVOICEABLE_EXIST = new ErrorCode(1_002_043_036, "当前提交记录中存在不可开票记录,请刷新列表后重新选择提交");
|
||||
|
||||
//=========== 支付相关 1-002-048-000 ============
|
||||
public static final ErrorCode PAY_CHANNEL_NOT_SUPPORT = new ErrorCode(1_002_048_000, "暂不支持的支付渠道,请使用其他支付渠道");
|
||||
|
||||
+5
-2
@@ -63,12 +63,15 @@ public class OrganApiImpl implements OrganApi {
|
||||
// 当前产品购买记录有效期是否超过当前时间
|
||||
boolean productMatch = false;
|
||||
if (ObjectUtil.isNotNull(previouPurchaseRecord)) {
|
||||
productMatch = previouPurchaseRecord.getEndTime().isAfter(LocalDate.now());
|
||||
LocalDate endTime = previouPurchaseRecord.getEndTime();
|
||||
productMatch = endTime.isAfter(LocalDate.now()) || endTime.isEqual(LocalDate.now());
|
||||
}
|
||||
// 延期记录中是否有超过当前时间的记录
|
||||
boolean delayMatch = false;
|
||||
if (CollUtil.isNotEmpty(delayRespVOList)) {
|
||||
delayMatch = delayRespVOList.stream().anyMatch(item -> item.getDelayTime().isAfter(LocalDate.now()));
|
||||
delayMatch = delayRespVOList.stream()
|
||||
.anyMatch(item -> item.getDelayTime().isAfter(LocalDate.now())
|
||||
|| item.getDelayTime().isEqual(LocalDate.now()));
|
||||
}
|
||||
// 产品过期且没有有效的延期记录时,提示产品已过期
|
||||
if (!productMatch && !delayMatch) {
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
public class InvoiceRecordsReqVO {
|
||||
|
||||
@Schema(description = "购买记录ID")
|
||||
@Size(max = 300, message = "单次开票选择记录不能超过100条")
|
||||
@Size(max = 100, message = "单次开票选择记录不能超过100条")
|
||||
@NotEmpty
|
||||
private List<Long> purchaseRecordId;
|
||||
|
||||
|
||||
+2
@@ -47,6 +47,8 @@ public class InvoiceRecordsRespVO {
|
||||
@Schema(description = "发票附件保存路径")
|
||||
private String invoiceAttachmentPath;
|
||||
|
||||
@Schema(description = "发票附件名称")
|
||||
private String invoiceAttachmentName;
|
||||
|
||||
@Schema(description = "开票人")
|
||||
private String invoicePerson;
|
||||
|
||||
+9
-9
@@ -16,15 +16,15 @@ public interface InvoiceRecordsMapper extends BaseMapperX<InvoiceRecordsDO> {
|
||||
|
||||
default PageResult<InvoiceRecordsDO> selectInvoiceRecordsPage(InvoiceDetailsPageReqVO pageReqVO) {
|
||||
return selectPage(pageReqVO, new LambdaQueryWrapperX<InvoiceRecordsDO>()
|
||||
.eq(InvoiceRecordsDO::getDeleted,false)
|
||||
.eqIfPresent(InvoiceRecordsDO::getOrganId,pageReqVO.getOrganId())
|
||||
.likeIfPresent(InvoiceRecordsDO::getInvoiceNo,pageReqVO.getInvoiceNo())
|
||||
.eqIfPresent(InvoiceRecordsDO::getStatus,pageReqVO.getStatus())
|
||||
.likeIfPresent(InvoiceRecordsDO::getCreator,pageReqVO.getCreator())
|
||||
.likeIfPresent(InvoiceRecordsDO::getInvoicePerson,pageReqVO.getInvoicePerson())
|
||||
.betweenIfPresent(InvoiceRecordsDO::getInvoiceAmount,pageReqVO.getInvoiceAmount())
|
||||
.betweenIfPresent(InvoiceRecordsDO::getCreateTime,pageReqVO.getCreateTime())
|
||||
.betweenIfPresent(InvoiceRecordsDO::getInvoiceTime,pageReqVO.getInvoiceTime())
|
||||
.eq(InvoiceRecordsDO::getDeleted, false)
|
||||
.eqIfPresent(InvoiceRecordsDO::getOrganId, pageReqVO.getOrganId())
|
||||
.likeIfPresent(InvoiceRecordsDO::getInvoiceNo, pageReqVO.getInvoiceNo())
|
||||
.eqIfPresent(InvoiceRecordsDO::getStatus, pageReqVO.getStatus())
|
||||
.likeIfPresent(InvoiceRecordsDO::getCreator, pageReqVO.getCreator())
|
||||
.likeIfPresent(InvoiceRecordsDO::getInvoicePerson, pageReqVO.getInvoicePerson())
|
||||
.betweenIfPresent(InvoiceRecordsDO::getInvoiceAmount, pageReqVO.getInvoiceAmount())
|
||||
.betweenIfPresent(InvoiceRecordsDO::getCreateTime, pageReqVO.getCreateTime())
|
||||
.betweenIfPresent(InvoiceRecordsDO::getInvoiceTime, pageReqVO.getInvoiceTime())
|
||||
.orderByDesc(InvoiceRecordsDO::getId));
|
||||
}
|
||||
|
||||
|
||||
+48
-6
@@ -1,11 +1,14 @@
|
||||
package com.cf.imes.module.system.service.funds.invoice;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||
import com.cf.imes.framework.common.exception.ServiceException;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.Assert.AssertUtils;
|
||||
@@ -47,15 +50,20 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
import static cn.hutool.core.date.DatePattern.NORM_DATE_FORMATTER;
|
||||
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.cf.imes.framework.common.util.json.JsonUtils.parseObject;
|
||||
import static com.cf.imes.framework.common.util.json.JsonUtils.toJsonString;
|
||||
import static com.cf.imes.framework.common.util.json.JsonUtils.unzipString;
|
||||
import static com.cf.imes.framework.common.util.json.JsonUtils.zipString;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.INVOICE_AMOUNT_ZERO_ERROR;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.INVOICE_APPLY_UNINVOICEABLE_EXIST;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.INVOICE_NO_EXIST;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.INVOICE_TITLE_ENTERPRISE_TAXNUMBER_EMPTY_ERROR;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.INVOICE_TITLE_NOT_EXISTS_ERROR;
|
||||
@@ -165,12 +173,13 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
* @param id
|
||||
* @param organId
|
||||
*/
|
||||
private void validTitleOrg(Long id, Long organId) {
|
||||
private InvoiceTitleInfoDO validTitleOrg(Long id, Long organId) {
|
||||
InvoiceTitleInfoDO titleInfoDO = invoiceTitleInfoMapper.selectById(id);
|
||||
// 抬头不存在
|
||||
AssertUtils.notEmpty(titleInfoDO, INVOICE_TITLE_NOT_EXISTS_ERROR);
|
||||
// 抬头组织不匹配
|
||||
AssertUtils.notEquals(titleInfoDO.getOrganId(), organId, INVOICE_TITLE_NOT_EXISTS_ERROR);
|
||||
return titleInfoDO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,8 +226,15 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
|
||||
AssertUtils.notEmpty(invoiceTitleInfoDO, INVOICE_TITLE_NOT_EXISTS_ERROR);
|
||||
|
||||
// 检查关联记录的购买记录,不能有已开票的
|
||||
List<PurchaseRecordDO> purchaseRecordDOS = purchaseRecordMapper.selectByIds(purchaseRecordId);
|
||||
boolean uninvoicableExist = purchaseRecordDOS.stream().filter(p -> !InvoiceStatusEnum.INVOICABLE.getCode().equals(p.getIsInvocing())).findAny().isPresent();
|
||||
AssertUtils.isTrue(uninvoicableExist, INVOICE_APPLY_UNINVOICEABLE_EXIST);
|
||||
|
||||
// 查询可开票金额
|
||||
BigDecimal invoicableAmount = purchaseRecordMapper.getInvoicableAmount(organId, purchaseRecordId);
|
||||
// 可开票金额不能为0
|
||||
AssertUtils.isTrue(ObjectUtils.isNull(invoicableAmount) || invoicableAmount.compareTo(BigDecimal.ZERO) == 0, INVOICE_AMOUNT_ZERO_ERROR);
|
||||
|
||||
// 更新购买记录表的发票状态
|
||||
int update = purchaseRecordMapper.update(new LambdaUpdateWrapper<PurchaseRecordDO>()
|
||||
@@ -256,7 +272,7 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
PageResult<InvoiceRecordsDO> pageResult = invoiceRecordsMapper.selectInvoiceRecordsPage(pageReqVO);
|
||||
List<InvoiceRecordsDO> resultList = pageResult.getList();
|
||||
|
||||
if(CollUtil.isEmpty(resultList)){
|
||||
if (CollUtil.isEmpty(resultList)) {
|
||||
return new PageResult<>();
|
||||
}
|
||||
List<InvoiceRecordsRespVO> recordsRespVOS = BeanUtils.toBean(resultList, InvoiceRecordsRespVO.class);
|
||||
@@ -266,7 +282,7 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
@Override
|
||||
public InvoiceDetailsRespVO getInvoiceRecordDetail(Long recordId) {
|
||||
InvoiceRecordsDO invoiceRecordsDO = invoiceRecordsMapper.selectById(recordId);
|
||||
AssertUtils.notEmpty(invoiceRecordsDO,INVOICE_NO_EXIST);
|
||||
AssertUtils.notEmpty(invoiceRecordsDO, INVOICE_NO_EXIST);
|
||||
|
||||
// 记录中的购买记录id数组转list
|
||||
String purchaseIds = Optional.ofNullable(invoiceRecordsDO.getPurchaseIds()).orElse("[]");
|
||||
@@ -321,6 +337,9 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
List<Long> purchaseIdList = JSON.parseArray(purchaseIds).toJavaList(Long.class).stream().distinct().toList();
|
||||
List<PurchaseRecordDO> purchaseRecordDOS = validatePurchaseRecordExists(purchaseIdList);
|
||||
|
||||
// 获取对应组织的抬头信息
|
||||
InvoiceTitleInfoDO invoiceTitleInfoDO = validTitleOrg(invoiceRecordsDO.getInvoiceTitleId(), invoiceRecordsDO.getOrganId());
|
||||
|
||||
if (reqVO.isAgree()) {
|
||||
// 同意开票
|
||||
// 更新发票申请记录状态
|
||||
@@ -333,11 +352,13 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
if (ObjectUtil.isNull(file) || file.isEmpty()) {
|
||||
throw new ServiceException(ORG_INVOICE_AGREE_FILE_NULL_ERROR);
|
||||
}
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String filePath = fileApi.createFile(IoUtil.readBytes(file.getInputStream()), originalFilename);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
String invoiceFileName = invoiceTitleInfoDO.getInvoiceTitle() + "-" + LocalDateTimeUtil.format(now, NORM_DATE_FORMATTER) + invoiceRecordsDO.getInvoiceAmount() + getFileExtension(file.getOriginalFilename());
|
||||
String filePath = fileApi.createFile(IoUtil.readBytes(file.getInputStream()), invoiceFileName);
|
||||
invoiceRecordsDO.setInvoiceAttachmentPath(filePath);
|
||||
invoiceRecordsDO.setInvoiceAttachmentName(originalFilename);
|
||||
invoiceRecordsDO.setInvoiceAttachmentName(invoiceFileName);
|
||||
invoiceRecordsDO.setInvoiceNo(reqVO.getInvoiceNo());
|
||||
invoiceRecordsDO.setInvoiceTime(now);
|
||||
} else {
|
||||
// 拒绝开票
|
||||
// 更新发票申请记录状态
|
||||
@@ -359,6 +380,27 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
purchaseRecordMapper.updateBatch(purchaseRecordDOS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取文件类型
|
||||
*
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static String getFileExtension(String fileName) {
|
||||
if (StrUtil.isEmpty(fileName)) {
|
||||
return ""; // 或者返回 null,看你需求
|
||||
}
|
||||
|
||||
int lastDotIndex = fileName.lastIndexOf('.');
|
||||
if (lastDotIndex < 0 || lastDotIndex == fileName.length() - 1) {
|
||||
// 没有点号,或者点号在最后一位(例如 "file.")
|
||||
return "";
|
||||
}
|
||||
|
||||
// 截取后缀部分并转小写
|
||||
return "." + fileName.substring(lastDotIndex + 1).toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验发票申请记录
|
||||
*
|
||||
|
||||
+27
-2
@@ -268,7 +268,7 @@ public class PayProductProcessor {
|
||||
.originalAmount(originalPrice)
|
||||
.monthAverageAmount(monthAverageAmount)
|
||||
.accountBalanceSpent(price)
|
||||
.isInvocing(InvoiceStatusEnum.INVOICABLE.getCode())
|
||||
.isInvocing(null)
|
||||
.initial(initialized)
|
||||
.status(PurchaseRecordStatusEnum.ACTIVE.getStatus())
|
||||
.build();
|
||||
@@ -412,6 +412,8 @@ public class PayProductProcessor {
|
||||
purchaseRecordDO.setPreviousId(previousPurchaseRecord.getId());
|
||||
}
|
||||
|
||||
// 是否只用了赠送金
|
||||
boolean justPayGift = true;
|
||||
// 先用赠送金
|
||||
if (gift != null && gift.compareTo(BigDecimal.ZERO) > 0) {
|
||||
usedGift = remaining.min(gift);
|
||||
@@ -424,6 +426,7 @@ public class PayProductProcessor {
|
||||
usedBalance = remaining.min(balance);
|
||||
remaining = remaining.subtract(usedBalance);
|
||||
purchaseRecordDO.setAccountBalanceSpent(usedBalance);
|
||||
justPayGift = false;
|
||||
}
|
||||
|
||||
// 剩下走第三方
|
||||
@@ -449,6 +452,11 @@ public class PayProductProcessor {
|
||||
.giftAmount(newGift)
|
||||
.build();
|
||||
|
||||
// 如果只用赠送金那么不可开票
|
||||
if (justPayGift) {
|
||||
purchaseRecordDO.setIsInvocing(null);
|
||||
}
|
||||
|
||||
// 更新余额
|
||||
organAmountDO.setAmount(newAmounta);
|
||||
organAmountDO.setGiftAmount(newGift);
|
||||
@@ -570,7 +578,9 @@ public class PayProductProcessor {
|
||||
purchaseRecordDO.setPreviousId(previousPurchaseRecord.getId());
|
||||
}
|
||||
|
||||
// 先用余额
|
||||
// 是否只用赠送金
|
||||
boolean justPayGift = true;
|
||||
// 先用赠送金
|
||||
if (gift != null && gift.compareTo(BigDecimal.ZERO) > 0) {
|
||||
usedGift = remaining.min(gift);
|
||||
remaining = remaining.subtract(usedGift);
|
||||
@@ -605,6 +615,12 @@ public class PayProductProcessor {
|
||||
purchaseRecordDO.setWechatSpent(remaining);
|
||||
}
|
||||
purchaseRecordDO.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
justPayGift = false;
|
||||
}
|
||||
|
||||
// 如果只用赠送金那么不可开票
|
||||
if (justPayGift) {
|
||||
purchaseRecordDO.setIsInvocing(null);
|
||||
}
|
||||
|
||||
// 更新余额
|
||||
@@ -651,6 +667,8 @@ public class PayProductProcessor {
|
||||
purchaseRecordDO.setPreviousId(previousPurchaseRecord.getId());
|
||||
}
|
||||
|
||||
// 是否只用了赠送金
|
||||
boolean justPayGift = true;
|
||||
// 先用赠送金
|
||||
if (gift != null && gift.compareTo(BigDecimal.ZERO) > 0) {
|
||||
usedGift = remaining.min(gift);
|
||||
@@ -663,6 +681,7 @@ public class PayProductProcessor {
|
||||
usedBalance = remaining.min(balance);
|
||||
remaining = remaining.subtract(usedBalance);
|
||||
purchaseRecordDO.setAccountBalanceSpent(usedBalance);
|
||||
justPayGift = false;
|
||||
}
|
||||
|
||||
// 新增收支明细
|
||||
@@ -694,6 +713,12 @@ public class PayProductProcessor {
|
||||
purchaseRecordDO.setWechatSpent(remaining);
|
||||
}
|
||||
purchaseRecordDO.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
justPayGift = false;
|
||||
}
|
||||
|
||||
// 如果只用赠送金那么不可开票
|
||||
if (justPayGift) {
|
||||
purchaseRecordDO.setIsInvocing(null);
|
||||
}
|
||||
|
||||
// 更新余额
|
||||
|
||||
Reference in New Issue
Block a user