客户余额修改
This commit is contained in:
+7
-1
@@ -42,9 +42,15 @@ public class CustomerBalanceFlow extends BaseEntity
|
||||
/** 客户账户ID */
|
||||
private Long accountId;
|
||||
|
||||
/** 币种 */
|
||||
/** 币种(业务原币) */
|
||||
private String currency;
|
||||
|
||||
/** 对CNY汇率(1原币=?CNY,CNY为1) */
|
||||
private BigDecimal exchangeRate;
|
||||
|
||||
/** 本位币金额(CNY,实际参与余额变动的金额) */
|
||||
private BigDecimal baseAmount;
|
||||
|
||||
/** 业务类型:RECEIPT/BILL_PAY/REFUND/ADJUST/FREEZE/UNFREEZE */
|
||||
private String bizType;
|
||||
|
||||
|
||||
+7
-1
@@ -59,9 +59,15 @@ public class CustomerReceipt extends BaseEntity
|
||||
/** 待核销金额 */
|
||||
private BigDecimal unallocatedAmount;
|
||||
|
||||
/** 币种 */
|
||||
/** 币种(收款原币) */
|
||||
private String currency;
|
||||
|
||||
/** 对CNY汇率(1原币=?CNY,CNY为1;默认取汇率表,可手工修改) */
|
||||
private BigDecimal exchangeRate;
|
||||
|
||||
/** 本位币金额(CNY,原币金额×汇率) */
|
||||
private BigDecimal baseAmount;
|
||||
|
||||
/** 收款方式:BANK_TRANSFER/ALIPAY/WECHAT/CASH/OTHER */
|
||||
private String payMethod;
|
||||
|
||||
|
||||
+62
-12
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.customer.customermoney.service.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
@@ -20,6 +21,8 @@ import com.ruoyi.customer.customermoney.domain.CustomerBalanceFlow;
|
||||
import com.ruoyi.customer.customermoney.domain.CustomerReceipt;
|
||||
import com.ruoyi.customer.customermoney.mapper.CustomerMoneyMapper;
|
||||
import com.ruoyi.customer.customermoney.service.ICustomerMoneyService;
|
||||
import com.ruoyi.system.domain.BmsExchangeRate;
|
||||
import com.ruoyi.system.service.IBmsExchangeRateService;
|
||||
|
||||
/**
|
||||
* 客户余额/收款/流水 Service实现
|
||||
@@ -32,12 +35,20 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService
|
||||
{
|
||||
private static final DateTimeFormatter NO_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
|
||||
|
||||
/** 本位币币种 */
|
||||
private static final String BASE_CURRENCY = BmsExchangeRate.BASE_CURRENCY;
|
||||
/** 金额保留位数 */
|
||||
private static final int MONEY_SCALE = 2;
|
||||
|
||||
@Autowired
|
||||
private CustomerMoneyMapper customerMoneyMapper;
|
||||
|
||||
@Autowired
|
||||
private BmsCustomerMapper bmsCustomerMapper;
|
||||
|
||||
@Autowired
|
||||
private IBmsExchangeRateService exchangeRateService;
|
||||
|
||||
@Override
|
||||
public List<CustomerAccount> selectAccountList(Long customerId)
|
||||
{
|
||||
@@ -81,12 +92,41 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService
|
||||
}
|
||||
if (!StringUtils.hasText(receipt.getCurrency()))
|
||||
{
|
||||
receipt.setCurrency("CNY");
|
||||
receipt.setCurrency(BASE_CURRENCY);
|
||||
}
|
||||
else
|
||||
{
|
||||
receipt.setCurrency(receipt.getCurrency().trim().toUpperCase());
|
||||
}
|
||||
// 汇率与本位币金额:CNY 固定 1:1;外币默认取汇率表即期汇率,也允许页面手工修改后传入
|
||||
BigDecimal rate = receipt.getExchangeRate();
|
||||
if (BASE_CURRENCY.equals(receipt.getCurrency()))
|
||||
{
|
||||
rate = BigDecimal.ONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rate == null || rate.compareTo(BigDecimal.ZERO) <= 0)
|
||||
{
|
||||
Date bizDate = receipt.getReceivedAt() != null ? receipt.getReceivedAt() : new Date();
|
||||
BmsExchangeRate rateConfig = exchangeRateService.resolveRate(
|
||||
receipt.getCurrency(), BASE_CURRENCY, BmsExchangeRate.RATE_TYPE_SPOT, bizDate);
|
||||
rate = rateConfig.getExchangeRate();
|
||||
}
|
||||
if (rate.compareTo(BigDecimal.ZERO) <= 0)
|
||||
{
|
||||
throw new ServiceException("汇率必须大于0,请检查录入的汇率");
|
||||
}
|
||||
}
|
||||
receipt.setExchangeRate(rate.setScale(8, RoundingMode.HALF_UP));
|
||||
BigDecimal baseAmount = receipt.getAmount().multiply(rate).setScale(MONEY_SCALE, RoundingMode.HALF_UP);
|
||||
receipt.setBaseAmount(baseAmount);
|
||||
|
||||
receipt.setReceiptNo(generateNo("SK"));
|
||||
receipt.setStatus(CustomerReceipt.STATUS_PENDING);
|
||||
receipt.setAllocatedAmount(BigDecimal.ZERO);
|
||||
receipt.setUnallocatedAmount(receipt.getAmount());
|
||||
// 核销口径统一为本位币 CNY
|
||||
receipt.setUnallocatedAmount(baseAmount);
|
||||
if (!StringUtils.hasText(receipt.getInvoiceStatus()))
|
||||
{
|
||||
receipt.setInvoiceStatus("NONE");
|
||||
@@ -113,17 +153,26 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService
|
||||
throw new ServiceException("仅待确认的收款单可以审核");
|
||||
}
|
||||
|
||||
String currency = StringUtils.hasText(receipt.getCurrency()) ? receipt.getCurrency() : "CNY";
|
||||
String currency = StringUtils.hasText(receipt.getCurrency()) ? receipt.getCurrency().trim().toUpperCase()
|
||||
: BASE_CURRENCY;
|
||||
String username = SecurityUtils.getUsername();
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
|
||||
// 1. 行锁锁定客户币种账户,不存在则自动初始化
|
||||
CustomerAccount account = customerMoneyMapper.selectAccountForUpdate(receipt.getCustomerId(), currency);
|
||||
// 本位币入账金额(兼容历史数据:未折算时按原金额/汇率1处理)
|
||||
BigDecimal rate = receipt.getExchangeRate() != null && receipt.getExchangeRate().compareTo(BigDecimal.ZERO) > 0
|
||||
? receipt.getExchangeRate() : BigDecimal.ONE;
|
||||
BigDecimal originalAmount = nz(receipt.getAmount());
|
||||
BigDecimal baseAmount = receipt.getBaseAmount() != null
|
||||
? receipt.getBaseAmount()
|
||||
: originalAmount.multiply(rate).setScale(MONEY_SCALE, RoundingMode.HALF_UP);
|
||||
|
||||
// 1. 行锁锁定客户本位币(CNY)账户,不存在则自动初始化。无论收什么币种,一律折算 CNY 入账
|
||||
CustomerAccount account = customerMoneyMapper.selectAccountForUpdate(receipt.getCustomerId(), BASE_CURRENCY);
|
||||
if (account == null)
|
||||
{
|
||||
account = new CustomerAccount();
|
||||
account.setCustomerId(receipt.getCustomerId());
|
||||
account.setCurrency(currency);
|
||||
account.setCurrency(BASE_CURRENCY);
|
||||
account.setBalance(BigDecimal.ZERO);
|
||||
account.setFrozenBalance(BigDecimal.ZERO);
|
||||
account.setTotalCredit(BigDecimal.ZERO);
|
||||
@@ -135,16 +184,15 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService
|
||||
customerMoneyMapper.insertAccount(account);
|
||||
}
|
||||
|
||||
// 2. 变动余额(预充值/混合增加余额;还款核销释放已用额度)
|
||||
BigDecimal amount = nz(receipt.getAmount());
|
||||
// 2. 本位币余额变动(预充值/混合增加余额;还款核销释放已用额度)
|
||||
BigDecimal beforeBalance = nz(account.getBalance());
|
||||
BigDecimal afterBalance = beforeBalance.add(amount);
|
||||
BigDecimal afterBalance = beforeBalance.add(baseAmount);
|
||||
BigDecimal frozenBalance = nz(account.getFrozenBalance());
|
||||
|
||||
account.setBalance(afterBalance);
|
||||
if (CustomerReceipt.TYPE_REPAY.equals(receipt.getReceiptType()))
|
||||
{
|
||||
account.setUsedCredit(nz(account.getUsedCredit()).subtract(amount).max(BigDecimal.ZERO));
|
||||
account.setUsedCredit(nz(account.getUsedCredit()).subtract(baseAmount).max(BigDecimal.ZERO));
|
||||
}
|
||||
account.setUpdateBy(username);
|
||||
|
||||
@@ -154,17 +202,19 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService
|
||||
throw new ServiceException("账户余额已被其他操作变动,请刷新后重试");
|
||||
}
|
||||
|
||||
// 3. 写余额流水
|
||||
// 3. 写余额流水:原币金额留痕,本位币金额参与余额变动
|
||||
CustomerBalanceFlow flow = new CustomerBalanceFlow();
|
||||
flow.setFlowNo(generateNo("LS"));
|
||||
flow.setCustomerId(receipt.getCustomerId());
|
||||
flow.setAccountId(account.getId());
|
||||
flow.setCurrency(currency);
|
||||
flow.setExchangeRate(rate);
|
||||
flow.setBaseAmount(baseAmount);
|
||||
flow.setBizType(CustomerBalanceFlow.BIZ_RECEIPT);
|
||||
flow.setBizId(receipt.getId());
|
||||
flow.setBizNo(receipt.getReceiptNo());
|
||||
flow.setDirection(1);
|
||||
flow.setAmount(amount);
|
||||
flow.setAmount(originalAmount);
|
||||
flow.setBeforeBalance(beforeBalance);
|
||||
flow.setAfterBalance(afterBalance);
|
||||
flow.setBeforeFrozenBalance(frozenBalance);
|
||||
|
||||
Reference in New Issue
Block a user