子单分账时抵扣超时罚金

This commit is contained in:
Hawking 2023-05-05 17:20:40 +08:00
parent 6b064b7fe1
commit acf7a47be6
3 changed files with 131 additions and 37 deletions

View File

@ -23,6 +23,8 @@ import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialChangeRecord; import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail; import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster; import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.OrderTimeoutRecord;
import com.ghy.payment.mapper.OrderFineRecordMapper;
import com.ghy.payment.service.AdapayService; import com.ghy.payment.service.AdapayService;
import com.ghy.payment.service.FinancialChangeRecordService; import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService; import com.ghy.payment.service.FinancialDetailService;
@ -79,6 +81,8 @@ public class OrderDetailServiceImpl implements OrderDetailService {
private FinancialChangeRecordService financialChangeRecordService; private FinancialChangeRecordService financialChangeRecordService;
@Resource @Resource
private OrderGoodsService orderGoodsService; private OrderGoodsService orderGoodsService;
@Resource
private OrderFineRecordMapper orderFineRecordMapper;
// Adapay 手续费率 默认0.008 // Adapay 手续费率 默认0.008
@Value("${adapay.fee_rate:0.008}") @Value("${adapay.fee_rate:0.008}")
@ -457,11 +461,45 @@ public class OrderDetailServiceImpl implements OrderDetailService {
if (paid || payedAdd) { if (paid || payedAdd) {
ArrayList<DivMember> divMembers = new ArrayList<>(); ArrayList<DivMember> divMembers = new ArrayList<>();
addPrice = fcRecord.getChangeMoney(); addPrice = fcRecord.getChangeMoney();
// 待提现金额里加入改价单金额 BigDecimal fineMoney = BigDecimal.ZERO;
dtx = dtx.add(fcRecord.getChangeMoney()); // 查询师傅的超时扣款记录
// 这里先自己承担手续费 后面再用平台抽成来补偿 List<OrderTimeoutRecord> fineRecords = orderFineRecordMapper.selectUnFine(orderDetail.getWorkerId());
DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), true); ArrayList<Long> fineIds = new ArrayList<>();
divMembers.add(divMember); for (OrderTimeoutRecord fineRecord : fineRecords) {
// 抵扣超时罚金 这里的罚金是按创建时间升序排列的 优先抵扣最早的罚金
if (fineMoney.add(fineRecord.getPayMoney()).compareTo(fcRecord.getChangeMoney()) > 0) {
// 加价单金额不足以抵扣罚金
logger.info("子订单[{}]的加价单[{}]不足以抵扣罚金{}元", orderDetailId, fcRecord.getId(), fineRecord.getPayMoney());
break;
} else {
// 抵扣罚金
logger.info("子订单[{}]的加价单[{}]抵扣罚金{}元", orderDetailId, fcRecord.getId(), fineRecord.getPayMoney());
fineMoney = fineMoney.add(fineRecord.getPayMoney());
// 被抵扣的罚金记录ID先存下来分账成功后修改状态
fineIds.add(fineRecord.getId());
}
}
// 是否有罚金
boolean haveFine = BigDecimal.ZERO.compareTo(fineMoney) < 0;
if (haveFine) { // 有罚金
// 扣除罚金后的加价金额
BigDecimal workerAddMoney = fcRecord.getChangeMoney().subtract(fineMoney);
// 待提现金额里加入加价金额
dtx = dtx.add(workerAddMoney);
// 这里由平台承担手续费
DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(workerAddMoney), false);
DivMember planDivMember = new DivMember("0", AdapayUtils.bigDecimalToString(fineMoney), true);
divMembers.add(divMember);
divMembers.add(planDivMember);
} else { // 没有罚金
// 待提现金额里加入加价金额
dtx = dtx.add(fcRecord.getChangeMoney());
// 这里先自己承担手续费 后面再用平台抽成来补偿
DivMember divMember = new DivMember(memberId, AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), true);
divMembers.add(divMember);
}
//调用分账 //调用分账
logger.info("子订单[code={}]的[改价单]发起分账", odCode); logger.info("子订单[code={}]的[改价单]发起分账", odCode);
JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(), JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), fcRecord.getRemark(),
@ -469,21 +507,25 @@ public class OrderDetailServiceImpl implements OrderDetailService {
AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), divMembers, null, null); AdapayUtils.bigDecimalToString(fcRecord.getChangeMoney()), divMembers, null, null);
if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) { // 分账成功 if (AdapayStatusEnum.succeeded.code.equals(response.getString("status"))) { // 分账成功
logger.info("子订单[code={}]的[改价单]分账成功", odCode); logger.info("子订单[code={}]的[改价单]分账成功", odCode);
// 这是被扣掉的手续费 按理说这里肯定大于0 // 分账成功 把罚金状态改为已扣除
String fee_amt = response.getString("fee_amt"); fineIds.forEach(fineRecordId -> orderFineRecordMapper.updateFineStatus(fineRecordId, 1));
feeAmt = new BigDecimal(fee_amt); if (!haveFine) { // 没有罚金的情况才需要补偿手续费 有罚金的话直接在罚金里承担手续费
if (feeAmt.compareTo(platformFeeFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) { // 这是被扣掉的手续费 按理说这里应该大于0
// 0.00<改价单的手续费<=平台抽成金额 String fee_amt = response.getString("fee_amt");
// 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额 feeAmt = new BigDecimal(fee_amt);
fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(feeAmt)); if (feeAmt.compareTo(platformFeeFD.getPayMoney()) < 0 && !"0.00".equals(fee_amt)) {
int i = financialDetailService.updateFinancialDetail(fdUpdate); // 0.00<改价单的手续费<=平台抽成金额
compensate = i > 0; // 用平台抽成来补偿改价单的手续费 修改平台抽成子财务单金额
} else { fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(feeAmt));
logger.warn("主订单[code={}]的平台抽成金额不足以承担子订单[code={}]的[改价单]的手续费", int i = financialDetailService.updateFinancialDetail(fdUpdate);
orderDetail.getOrderMasterCode(), odCode); compensate = i > 0;
// 平台抽成不足以承担改价单手续费了 那没办法了只能自己承担 } else {
// 待提现金额里减去改价单手续费 logger.warn("主订单[code={}]的平台抽成金额不足以承担子订单[code={}]的[改价单]的手续费",
dtx = dtx.subtract(feeAmt); orderDetail.getOrderMasterCode(), odCode);
// 平台抽成不足以承担改价单手续费了 那没办法了只能自己承担
// 待提现金额里减去改价单手续费
dtx = dtx.subtract(feeAmt);
}
} }
} else { // 分账失败 } else { // 分账失败
if (AdapayErrorCode.CONFIRM_AMT_OVER_LIMIT.equals(response.getString("error_code"))) { if (AdapayErrorCode.CONFIRM_AMT_OVER_LIMIT.equals(response.getString("error_code"))) {
@ -522,27 +564,57 @@ public class OrderDetailServiceImpl implements OrderDetailService {
payMoney = fdPayMoney; payMoney = fdPayMoney;
} }
if (BigDecimal.ZERO.compareTo(payMoney) > -1) { if (BigDecimal.ZERO.compareTo(payMoney) > -1) {
logger.info("子财务单[code={}] 应支付金额={} 不需要分账", financialDetail.getCode(), payMoney); logger.info("子财务单[{}] 应支付金额={} 不需要分账", financialDetail.getId(), payMoney);
} else { } else {
// 查询师傅的超时扣款记录
List<OrderTimeoutRecord> fineRecords = orderFineRecordMapper.selectUnFine(orderDetail.getWorkerId());
// 超时罚金
BigDecimal fineMoney = BigDecimal.ZERO;
ArrayList<Long> fineIds = new ArrayList<>();
for (OrderTimeoutRecord fineRecord : fineRecords) {
// 抵扣超时罚金 这里的罚金是按创建时间升序排列的 优先抵扣最早的罚金
if (fineMoney.add(fineRecord.getPayMoney()).compareTo(fdPayMoney) > 0) {
// 加价单金额不足以抵扣罚金
logger.info("子订单[{}]的派单金额[{}元]不足以抵扣罚金{}元", orderDetailId, fdPayMoney, fineRecord.getPayMoney());
break;
} else {
// 抵扣罚金
logger.info("子订单[{}]的加价单[{}]抵扣罚金{}元", orderDetailId, fdPayMoney, fineRecord.getPayMoney());
fineMoney = fineMoney.add(fineRecord.getPayMoney());
// 被抵扣的罚金记录ID先存下来分账成功后修改状态
fineIds.add(fineRecord.getId());
}
}
// 总分账金额
BigDecimal fee = BigDecimal.ZERO;
// 接单师傅的分账信息 // 接单师傅的分账信息
String payMoneyS = AdapayUtils.bigDecimalToString(payMoney); String payMoneyS = AdapayUtils.bigDecimalToString(payMoney.subtract(fineMoney));
DivMember divMember = new DivMember(memberId, payMoneyS, false); DivMember divMember = new DivMember(memberId, payMoneyS, false);
divMembers.add(divMember); divMembers.add(divMember);
// 是否有罚金
// 计算本次分账的手续费 保留两位小数(向上取整) boolean haveFine = BigDecimal.ZERO.compareTo(fineMoney) < 0;
BigDecimal fee = payMoney.multiply(new BigDecimal(feeRate)).setScale(2, RoundingMode.UP); if (haveFine) { // 有罚金 从罚金里扣除手续费
// 平台的分账信息 用来承担手续费 // 平台的分账信息 用来承担罚金
DivMember feeDivMember = new DivMember("0", fee.toString(), true); DivMember fineDivMember = new DivMember("0", AdapayUtils.bigDecimalToString(fineMoney), true);
divMembers.add(feeDivMember); divMembers.add(fineDivMember);
} else { // 没有罚金 需要扣除手续费
// 计算本次分账的手续费 保留两位小数(向上取整)
fee = payMoney.multiply(new BigDecimal(feeRate)).setScale(2, RoundingMode.UP);
// 平台的分账信息 用来承担手续费
DivMember feeDivMember = new DivMember("0", fee.toString(), true);
divMembers.add(feeDivMember);
}
logger.info("子订单[code={}]发起分账", odCode); logger.info("子订单[code={}]发起分账", odCode);
JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), payment.getId(), payment.getOrderNo() + "_" + System.currentTimeMillis(), JSONObject response = adapayService.paymentConfirm(financialDetail.getDeptId(), payment.getId(),
fee.add(payMoney).toString(), divMembers, null, null); payment.getOrderNo() + "_" + System.currentTimeMillis(),
AdapayUtils.bigDecimalToString(fee.add(payMoney)), divMembers, null, null);
boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status")); boolean status = AdapayStatusEnum.succeeded.code.equals(response.getString("status"));
// 如果确认支付失败 这里抛出异常 回滚订单状态 // 如果确认支付失败 这里抛出异常 回滚订单状态
Assert.isTrue(status, response.toString()); Assert.isTrue(status, response.toString());
// 分账成功 把罚金状态改为已扣除
fineIds.forEach(fineRecordId -> orderFineRecordMapper.updateFineStatus(fineRecordId, 1));
// 待提现金额里加入子财务单金额 // 待提现金额里加入子财务单金额
dtx = dtx.add(fdPayMoney); dtx = dtx.add(fdPayMoney.subtract(fineMoney));
// 修改平台抽成子财务单金额 减去手续费 // 修改平台抽成子财务单金额 减去手续费
fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(fee)); fdUpdate.setPayMoney(fdUpdate.getPayMoney().subtract(fee));

View File

@ -10,11 +10,21 @@ import java.util.List;
*/ */
public interface OrderFineRecordMapper { public interface OrderFineRecordMapper {
OrderTimeoutRecord selectByDetailIdAndStatus(@Param("orderDetailId")Long orderDetailId, @Param("orderStatus")Integer orderStatus); OrderTimeoutRecord selectByDetailIdAndStatus(@Param("orderDetailId") Long orderDetailId, @Param("orderStatus") Integer orderStatus);
List<OrderTimeoutRecord> selectList(OrderTimeoutRecord orderTimeoutRecord); List<OrderTimeoutRecord> selectList(OrderTimeoutRecord orderTimeoutRecord);
int insert(OrderTimeoutRecord orderTimeoutRecord); int insert(OrderTimeoutRecord orderTimeoutRecord);
int update(OrderTimeoutRecord orderTimeoutRecord); // int update(OrderTimeoutRecord orderTimeoutRecord);
int updateFineStatus(@Param("id") Long id, @Param("fineStatus") int fineStatus);
/**
* 查询某师傅的未扣款的罚金
*
* @param workerId 师傅id
*/
List<OrderTimeoutRecord> selectUnFine(@Param("workerId") Long workerId);
} }

View File

@ -46,12 +46,24 @@
</where> </where>
</select> </select>
<select id="selectUnFine" resultMap="OrderFineRecordResult">
<include refid="selectOrderFineRecord"/>
WHERE worker_id = #{workerId}
AND fine_status = 0
ORDER BY create_time
</select>
<insert id="insert" parameterType="com.ghy.payment.domain.OrderTimeoutRecord" useGeneratedKeys="true" keyProperty="id"> <insert id="insert" parameterType="com.ghy.payment.domain.OrderTimeoutRecord" useGeneratedKeys="true" keyProperty="id">
INSERT INTO order_timeout_record (order_detail_id, worker_id, fine_status, order_status, pay_money) INSERT INTO order_timeout_record (order_detail_id, worker_id, order_status, pay_money)
VALUES (#{orderDetailId}, #{workerId}, #{fineStatus}, #{orderStatus}, #{payMoney}) VALUES (#{orderDetailId}, #{workerId}, #{orderStatus}, #{payMoney})
</insert> </insert>
<update id="update"> <!-- <update id="update">-->
<!-- UPDATE order_timeout_record SET fine_status = #{fineStatus}-->
<!-- WHERE id = #{id}-->
<!-- </update>-->
<update id="updateFineStatus">
UPDATE order_timeout_record SET fine_status = #{fineStatus} UPDATE order_timeout_record SET fine_status = #{fineStatus}
WHERE id = #{id} WHERE id = #{id}
</update> </update>