huminmin
昨天 ff09f8e85d51c5d127796bfbd097f5fad9267d4b
src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
@@ -158,13 +158,13 @@
     * 通过员工id计算社保方案
     * @param id
     */
    public void calculateByEmployeeId(Integer id,Map<String, Object> map,String date) {
    public void calculateByEmployeeId(Integer id, Map<String, Object> map, String date) {
        if (id == null || map == null) {
            return;
        }
        Long staffId = id.longValue();
        StaffOnJob staffOnJobDto = staffOnJobMapper.selectById(staffId);
        if(staffOnJobDto == null){
        if (staffOnJobDto == null) {
            return;
        }
        BigDecimal basicSalary = resolveBasicSalary(map, staffOnJobDto);
@@ -174,11 +174,12 @@
        BigDecimal socialSupplementAmount = resolveSocialSupplementAmount(map, staffOnJobDto);
        BigDecimal socialPersonal = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        BigDecimal fundPersonal = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        int monthWorkDays = calculateWorkDays(date);
        BigDecimal standardHours = calculateStandardHours(monthWorkDays);
        int monthWorkDays = resolveMonthWorkDays(map, date);
        BigDecimal workDays = resolveWorkDays(map, monthWorkDays);
        BigDecimal standardHours = resolveStandardHours(map, monthWorkDays);
        BigDecimal actualOutput = resolveActualOutput(map);
        BigDecimal standardQuantity = resolveStandardQuantity(map);
        BigDecimal conversionFactor = resolveConversionFactor(map);
        BigDecimal dailySalary = calculateDailySalary(basicSalary, workDays);
        Long sysUserId = getUidByStaffId(staffId);
        UserProductionAccountingDto userProductionAccountingDto = new UserProductionAccountingDto();
@@ -190,7 +191,6 @@
                map,
                actualOutput,
                standardQuantity,
                conversionFactor,
                repairWorkHour,
                byUserId
        );
@@ -201,21 +201,24 @@
        if (!CollectionUtils.isEmpty(schemeList)) {
            for (SchemeApplicableStaff scheme : schemeList) {
                List<SchemeInsuranceDetail> detailList = schemeApplicableStaffMapper.selectDetailBySchemeId(scheme.getId());
                if(CollectionUtils.isEmpty(detailList)){
                if (CollectionUtils.isEmpty(detailList)) {
                    continue;
                }
                for (SchemeInsuranceDetail detail : detailList) {
                    if("公积金".equals(detail.getInsuranceType())){
                    if ("公积金".equals(detail.getInsuranceType())) {
                        fundPersonal = calculateByEmployeeIdType(detail.getInsuranceType(), fundPersonal, basicSalary, staffOnJobDto, detail);
                    }else{
                    } else {
                        socialPersonal = calculateByEmployeeIdType(detail.getInsuranceType(), socialPersonal, basicSalary, staffOnJobDto, detail);
                    }
                }
            }
        }
        // 工资 = 全勤奖金 + 基本工资 * 折合倍数
        BigDecimal grossSalary = attendanceBonus.add(basicSalary.multiply(conversionRatio)).add(otherIncome);
        // 工资 = 全勤奖金 + 基本工资 * 折合倍数 + 其他收入 + 津贴
        BigDecimal grossSalary = attendanceBonus
                .add(basicSalary.multiply(conversionRatio))
                .add(otherIncome)
                .add(normalizeMoney(getBigDecimal(map, "allowance")));
        BigDecimal salaryTax = TaxCalculator.calculateMonthlyTax(
                grossSalary,
                socialPersonal.add(socialSupplementAmount),
@@ -236,14 +239,16 @@
        }
        map.put("basicSalary", basicSalary);
        map.put("attendanceBonus", attendanceBonus);
        map.put("workDays", workDays);
        map.put("monthWorkDays", monthWorkDays);
        map.put("dailySalary", dailySalary);
        map.put("standardHours", standardHours);
        map.put("actualOutput", actualOutput);
        map.put("standardQuantity", standardQuantity);
        map.put("conversionFactor", conversionFactor);
        map.put("convertedWorkHours", convertedWorkHours);
        map.put("monthTimeTotal", convertedWorkHours);
        map.put("conversionRatio", conversionRatio);
        map.put("benefit", conversionRatio);
        map.put("pieceSalary", convertedWorkHours);
        map.put("hourlySalary", BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP));
        map.put("otherIncome", otherIncome);
@@ -301,6 +306,20 @@
    }
    /**
     * 解析月标准工时。
     * 优先使用工资表传入的工作日计算,其次使用当月默认工作日。
     */
    private BigDecimal resolveStandardHours(Map<String, Object> map, int monthWorkDays) {
        if (hasValue(map, "standardHours")) {
            BigDecimal standardHours = normalizeMoney(getBigDecimal(map, "standardHours"));
            if (standardHours.compareTo(BigDecimal.ZERO) > 0) {
                return standardHours;
            }
        }
        return calculateStandardHours(monthWorkDays);
    }
    /**
     * 解析当月实际产量。
     */
    private BigDecimal resolveActualOutput(Map<String, Object> map) {
@@ -316,15 +335,6 @@
        return hasValue(map, "standardQuantity")
                ? normalizeMoney(getBigDecimal(map, "standardQuantity"))
                : BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
    }
    /**
     * 解析工序折算系数,未配置时默认 1。
     */
    private BigDecimal resolveConversionFactor(Map<String, Object> map) {
        return hasValue(map, "conversionFactor")
                ? normalizeMoney(getBigDecimal(map, "conversionFactor"))
                : BigDecimal.ONE.setScale(2, RoundingMode.HALF_UP);
    }
    /**
@@ -350,14 +360,13 @@
    /**
     * 计算月时间合计。
     * 计件场景使用实际产量、标准数量和折算系数换算;
     * 计件场景使用实际产量和标准数量换算;
     * 没有计件数据时,回落到生产核算汇总值;
     * 最后再叠加返工补修理工时。
     */
    private BigDecimal resolveConvertedWorkHours(Map<String, Object> map,
                                                 BigDecimal actualOutput,
                                                 BigDecimal standardQuantity,
                                                 BigDecimal conversionFactor,
                                                 BigDecimal repairWorkHour,
                                                 UserAccountDto byUserId) {
        if (hasValue(map, "monthTimeTotal")) {
@@ -367,12 +376,11 @@
            }
        }
        BigDecimal convertedWorkHours = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        // 计件折算工时 = 当月实际产量 / 工序标准数量 * 8 * 工序折算系数
        // 计件折算工时 = 当月实际产量 / 工序标准数量 * 8
        if (actualOutput.compareTo(BigDecimal.ZERO) > 0 && standardQuantity.compareTo(BigDecimal.ZERO) > 0) {
            convertedWorkHours = actualOutput
                    .divide(standardQuantity, 8, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal("8"))
                    .multiply(conversionFactor)
                    .setScale(2, RoundingMode.HALF_UP);
        } else if (byUserId != null) {
            convertedWorkHours = normalizeMoney(byUserId.getAccountBalance().add(byUserId.getAccount()));
@@ -386,9 +394,49 @@
     */
    private BigDecimal calculateConversionRatio(BigDecimal standardHours, BigDecimal convertedWorkHours) {
        return standardHours.compareTo(BigDecimal.ZERO) == 0
                ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
                ? BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP)
                : convertedWorkHours.divide(standardHours, 8, RoundingMode.HALF_UP)
                .setScale(2, RoundingMode.HALF_UP);
                .setScale(4, RoundingMode.HALF_UP);
    }
    /**
     * 计算日计工资。
     * 规则:基本工资 / 工作日天数。
     */
    private BigDecimal calculateDailySalary(BigDecimal basicSalary, BigDecimal workDays) {
        if (basicSalary == null || workDays == null || workDays.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
        }
        return basicSalary.divide(workDays, 3, RoundingMode.HALF_UP);
    }
    /**
     * 解析工资表工作日。
     * 优先使用页面传入的工作日,未传时才按自然月工作日计算。
     */
    private int resolveMonthWorkDays(Map<String, Object> map, String date) {
        if (hasValue(map, "monthWorkDays")) {
            BigDecimal monthWorkDays = normalizeMoney(getBigDecimal(map, "monthWorkDays"));
            if (monthWorkDays.compareTo(BigDecimal.ZERO) > 0) {
                return monthWorkDays.intValue();
            }
        }
        return calculateWorkDays(date);
    }
    /**
     * 解析工作日。
     * 如果工资表里已经填写了工作日,则优先使用人工填写值;
     * 否则默认使用当月工作日天数。
     */
    private BigDecimal resolveWorkDays(Map<String, Object> map, int monthWorkDays) {
        if (hasValue(map, "workDays")) {
            BigDecimal workDays = normalizeMoney(getBigDecimal(map, "workDays"));
            if (workDays.compareTo(BigDecimal.ZERO) > 0) {
                return workDays;
            }
        }
        return BigDecimal.valueOf(monthWorkDays).setScale(2, RoundingMode.HALF_UP);
    }
    /**