# ItemCommonService.java

    package cloud.wconnect.workperformance.service.hkinventory;

    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.workperformance.entity.hkinventory.HkInventoryItem;
    import com.google.common.collect.Lists;
    import jakarta.annotation.Nullable;
    import org.apache.commons.lang3.StringUtils;

    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.List;
    import java.util.Objects;

    /**
     * item 计算服务类
     *
     * @author lichen
     * @date 2025/4/24
     */
    public class ItemCommonService {

        /**
         * 计算item的指标
         *
         * @param item                   对象
         * @param totalRooms             指定房型的总房间数
         * @param previousInventoryCount 当前item的上期库存数量
         * @param roundingMode           保留位数
         * @return void
         * @author lichen
         * @date 2025/4/24
         */
        public static void calculate(HkInventoryItem item, int totalRooms, @Nullable Integer previousInventoryCount, RoundingMode roundingMode) {
            //库存数量
            Integer inventory = item.getInventory();
            if (Objects.isNull(inventory)) return;

            //每个房间最少需要的数量
            Integer minPerRoom = item.getMinPerRoom();
            //单价
            BigDecimal unitCost = item.getUnitCost();
            //目标PAR
            BigDecimal parTarget = item.getParTarget();
            //购买数量
            Integer purchaseCount = item.getPurchase();
            //所有房间小最小需要的数量
            int allRoomMinNeedCount = minPerRoom * totalRooms;

            /*
             * 开始计算指标
             */
            if(Objects.nonNull(previousInventoryCount)){
                //设置使用数量
                int usage = previousInventoryCount + purchaseCount - item.getInventory();
                item.setUsage(usage);
                //设置补货费用，公式Usage * Unit Cost
                item.setReplenishmentCost(unitCost.multiply(new BigDecimal(usage)));
            }

            //设置现有的PAR，公式inventory/minPerRoom*totalRooms
            BigDecimal existingPar = new BigDecimal(inventory).divide(new BigDecimal(allRoomMinNeedCount),
                    BaseConstant.DATA_PRECISION, roundingMode);
            item.setExistingPar(existingPar);
            //设置PAR差值，公式existingPar - parTarget
            BigDecimal diffPar = existingPar.subtract(parTarget);
            item.setDiffPar(diffPar);
            //设置总余额，公式unitCost * inventory
            item.setTotalBalance(unitCost.multiply(new BigDecimal(inventory)));
            //设置需要购买的数量，公式(PAR Target - Existing PAR) * Min. Per Room * Total Rooms
            int requiredPurchaseCount = (parTarget.subtract(existingPar)).multiply(new BigDecimal(allRoomMinNeedCount))
                    .setScale(0, roundingMode).intValueExact();
            if(requiredPurchaseCount <= 0){
                item.setRequiredPurchaseCount(0);
                //设置需要购买的金额
                item.setRequiredPurchaseAmount(BigDecimal.ZERO);
            }else{
                item.setRequiredPurchaseCount(requiredPurchaseCount);
                //设置需要购买的金额
                item.setRequiredPurchaseAmount(unitCost.multiply(new BigDecimal(requiredPurchaseCount)));
            }
            /*
             * 结束计算指标
             */
        }

        /**
         * 生成key
         *
         * @param categoryId 分类id
         * @param roomTypeId 房型id
         * @param itemId     item id
         * @return String
         * @author lichen
         * @date 2025/4/25
         */
        public static String generateKey(Integer categoryId, Integer roomTypeId, Integer itemId) {
            List<String> list = Lists.newArrayList(categoryId, roomTypeId, itemId)
                    .stream().map(Object::toString).toList();
            return StringUtils.join(list, "_");
        }

    }