/* * Copyright (C) 2019 Alpha Jiang. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package io.github.alphajiang.hyena.biz.calculator; import io.github.alphajiang.hyena.model.po.PointRecPo; import io.github.alphajiang.hyena.utils.DecimalUtils; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; @Service public class CostCalculator { /** * 计算可用成本 * * @param rec 积分块 * @return 总成本 - 已用成本 - 冻结成本 */ public BigDecimal getAvailableCost(PointRecPo rec) { if (rec.getTotalCost() == null || DecimalUtils.lte(rec.getTotalCost(), DecimalUtils.ZERO)) { return DecimalUtils.ZERO; } BigDecimal ret = rec.getTotalCost().subtract(rec.getUsedCost()) .subtract(rec.getFrozenCost()) .subtract(rec.getRefundCost()); if (DecimalUtils.gt(ret, DecimalUtils.ZERO)) { return ret; } else { return DecimalUtils.ZERO; } } /** * 根据成本计算可用积分 * * @param rec 积分块 * @param cost 变动部分成本 * @return 对应的积分 */ public BigDecimal accountPoint(PointRecPo rec, BigDecimal cost) { BigDecimal point = DecimalUtils.ZERO; BigDecimal availableCost = this.getAvailableCost(rec); if (DecimalUtils.lte(availableCost, DecimalUtils.ZERO)) { point = DecimalUtils.ZERO; } else if (DecimalUtils.lte(availableCost, cost)) { point = rec.getAvailable(); } else { point = cost.multiply(rec.getTotal()).divide(rec.getTotalCost()) .setScale(DecimalUtils.SCALE_2, RoundingMode.HALF_UP); } return point; } /** * 计算delta(变动)部分在积分块中的所占成本 * * @param rec 积分块 * @param delta 变动部分 * @return 所占成本 */ public BigDecimal accountCost(PointRecPo rec, BigDecimal delta) { BigDecimal cost = DecimalUtils.ZERO; if (rec.getTotalCost() == null || DecimalUtils.lte(rec.getTotalCost(), DecimalUtils.ZERO)) { // 积分块没有成本时直接返回0 return cost; } else if (DecimalUtils.lte(rec.getAvailable(), delta)) { // 不够抵扣时返回剩余的全部 cost = this.getAvailableCost(rec); } else { // 按比例计算 cost = delta.multiply(rec.getTotalCost()).divide(rec.getTotal()) .setScale(DecimalUtils.SCALE_2, RoundingMode.HALF_UP); } return cost; } public BigDecimal accountCost4Unfreeze(PointRecPo rec, BigDecimal delta) { BigDecimal cost = DecimalUtils.ZERO; if (rec.getTotalCost() == null || DecimalUtils.lte(rec.getTotalCost(), DecimalUtils.ZERO)) { // 积分块没有成本时直接返回0 return cost; } else if (DecimalUtils.lte(rec.getFrozen(), delta)) { // 不够解冻时返回剩余的全部 cost = rec.getFrozenCost(); } else { // 按比例计算 cost = delta.multiply(rec.getTotalCost()).divide(rec.getTotal()) .setScale(DecimalUtils.SCALE_2, RoundingMode.HALF_UP); } return cost; } }