工资计算系统设计实现

part1

XX 公司有三种类型的雇工, 不同类型的员工有不同的工资计算方式, 具体薪资计算规则如下。

• 小时工,每小时薪资为 40 元。

• 经理,每小时薪资为 60 元,每月工作满 150 小时就可以得到全额工资 10000 元。如果工作不满 150 小时,则按照 实际工作时间和时薪计算工资

• 销售人员, 基础工资为每月 3000,每月基础销售额应为 20000,如果销售额为 20000-30000,则超出部分(超出 20000 部分)提成率为 5%,如果销售额为 30000 及以上,则超出部分(超出 20000 部分)提成率为 8%。

• 加班工资计算规则。 对于小时工和经理,当他们每月工作超过 160 小时,则超出部分时长按照时薪 1.3 倍计算工资

请注意:

1. 员工的固定工资,时薪,提成率和底薪都可能会调整。

2. 员工类型可能会增加。

3. 加班规则和其适用的雇员规则都可能变化,比如小时工或者经理可能不再计算加班工资

公司现有雇员如下:

经理: Lisa 
小时工:Alex, Jack 
销售人员:Leo

解析以下 xml 数据,并计算 9 月和 10 月份,公司应支付员工工资总额。最终结果应该四舍五入为两位小 数。

<department>

<month value="9">

<employee name="Lisa" workingHours="145"/>

<employee name="Alex" workingHours="170.5"/>

<employee name="Leo" amount="34100.8"/>

</month>

<month value="10">

<employee name="Lisa" workingHours="165"/>

<employee name="Alex" workingHours="155.75"/>

<employee name="Jack" workingHours ="188.25"/>

<employee name="Leo" amount ="23500.7"/>

</month> 
</department>

part2

分析需求得出:

   1.解析xml数据

    2.计薪规则设计

   3.动态调整计薪规则

part3.设计实现

 采用策略模式实现计薪规则+  Dom4j xpath解析xml文件:

/**
 * 定义计薪规则接口
 */
public interface CalculateSalaryStrategy {
    BigDecimal CalculateSalary(Double workHours,BigDecimal amount,AdjustSalary adjustSalary);
}




/**
 * 小时工计薪规则
 */
public class HourCalSalaryStrategy implements  CalculateSalaryStrategy{
    @Override
    public BigDecimal CalculateSalary(Double workHours,BigDecimal amount,AdjustSalary adjustSalary) {
       BigDecimal workHoursTmp= new BigDecimal(workHours);
       if(workHours>160){
           BigDecimal FixedHours=new BigDecimal(160);

          //计算固定时间的薪资
           BigDecimal fixedSalary= FixedHours.multiply(adjustSalary.getHourSalary());

           //计算加班时间的薪资
           BigDecimal extraSalary=workHoursTmp.subtract(FixedHours).multiply(adjustSalary.getHourSalary().multiply(new BigDecimal(adjustSalary.getWorkExtra())));

           return fixedSalary.add(extraSalary);
       }else{
           return workHoursTmp.multiply(adjustSalary.getHourSalary());
       }
    }
}





/**
 * 经理记薪规则
 */
public class ManagerCalSalaryStrategy implements  CalculateSalaryStrategy{
    @Override
    public BigDecimal CalculateSalary(Double workHours,BigDecimal amount,AdjustSalary adjustSalary) {
        BigDecimal workHoursTmp= new BigDecimal(workHours);
        if(workHours>=150){
           if(workHours>160){
               BigDecimal FixedHours=new BigDecimal(160);
               //计算加班时间的薪资
               BigDecimal extraSalary=workHoursTmp.subtract(FixedHours).multiply(adjustSalary.getHourSalary().multiply(new BigDecimal(adjustSalary.getWorkExtra())));

               //固定工资+加班费
               return adjustSalary.getFixedSalary().add(extraSalary);
           }else{
               //只发固定薪资
               return adjustSalary.getFixedSalary();
           }
        }else{
          //实际工作时间和时薪计算工资
            return workHoursTmp.multiply(adjustSalary.getHourSalary());
        }
    }
}


import java.math.BigDecimal;

/**
 * 销售计薪规则
 */
public class SalesCalSalaryStrategy implements CalculateSalaryStrategy {
    @Override
    public BigDecimal CalculateSalary(Double workHours, BigDecimal amount, AdjustSalary adjustSalary) {
        if (amount.doubleValue() >= 30000) {
            //计算佣金
            BigDecimal commissionSalary = amount.subtract(new BigDecimal(20000)).multiply(new BigDecimal(adjustSalary.getCommissionRate().get("L2")));
            return adjustSalary.getBaseSalary().add(commissionSalary);
        } else if (amount.doubleValue()<=20000){
         return  adjustSalary.getBaseSalary();
        }else {
            //计算佣金
            BigDecimal commissionSalary = amount.subtract(new BigDecimal(20000)).multiply(new BigDecimal(adjustSalary.getCommissionRate().get("L1")));
            return adjustSalary.getBaseSalary().add(commissionSalary);
        }
    }
}





/**
 *创建计薪上下文
 */
public class CalculateSalaryContext {
    private CalculateSalaryStrategy calculateSalaryStrategy;
    public CalculateSalaryContext(CalculateSalaryStrategy calculateSalaryStrategy){
        this.calculateSalaryStrategy=calculateSalaryStrategy;
    }
    public BigDecimal callCalculateSalary(Double workHours,BigDecimal amount,AdjustSalary adjustSalary){
        return this.calculateSalaryStrategy.CalculateSalary(workHours,amount,adjustSalary);
    }
}





import lombok.Data;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 员工调薪
 */
@Data
public class AdjustSalary {
    /**
     * 固定工资
     */
    private BigDecimal fixedSalary;
    /**
     * 时薪
     */
    private BigDecimal hourSalary;

    /**
     * 提成率
     */
    private Map<String,Double> commissionRate=new HashMap<>();
    /**
     * 底薪
     */
    private BigDecimal baseSalary;

    /**
     * 加班计薪系数
     */
    private  Double workExtra;
}



import lombok.Data;

@Data
public class Employee {
    private String name;
    private String workingHours;
    private String amount;
}



import com.xx.calculaterule.*;
import com.xx.entity.Employee;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.math.BigDecimal;
import java.util.*;

/**
 * 计算公司应支付员工工资总额
 */
public class CalculateEmpTotalSalary {
    private static List<Employee> getEmployeeList() throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(CalculateEmpTotalSalary.class.getResourceAsStream("salary.xml"));
        //获取整个文档
        Element rootElement = document.getRootElement();
        System.out.println("整个文档:" + rootElement.asXML());
        List<Element> elements = rootElement.selectNodes("/department/month/employee");

        List<Employee> employees = new ArrayList<>();
        for(int i=0;i<elements.size();i++){
            Element element= elements.get(i);
            Employee employee = new Employee();
            employee.setName(element.attributeValue("name"));
            employee.setWorkingHours(element.attributeValue("workingHours"));
            employee.setAmount(element.attributeValue("amount"));
            employees.add(employee);
        }
        return employees;
    }

    public static void main(String[] args) throws DocumentException {
        /**
         * step0 构建员工与员工类型关系数据
         */
        Set<String> managers = new HashSet<>();
        managers.add("Lisa");
        Set<String> hours = new HashSet<>();
        hours.add("Alex");
        hours.add("Jack");
        Set<String> sales = new HashSet<>();
        sales.add("Leo");

        Map<String, Set<String>> storeEmployRSData = new HashMap<>();
        storeEmployRSData.put("manager", managers);
        storeEmployRSData.put("hours", hours);
        storeEmployRSData.put("sales", sales);

        /**
         * step1.获取解析xml数据成对象
         */
        List<Employee> employees = getEmployeeList();
        System.out.println("employees:"+employees.toString());

        /**
         *step2.计算公司支付员工总工资
         */
        BigDecimal payTotalSalary=new BigDecimal(0.00);
        for (Employee employee:employees){
            if(managers.contains(employee.getName())){
                CalculateSalaryContext managerCalSalary=new CalculateSalaryContext(new ManagerCalSalaryStrategy());

                //员工的固定工资,时薪,提成率和底薪调整配置
                AdjustSalary adjustSalary=new AdjustSalary();
                adjustSalary.setHourSalary(new BigDecimal(60));
                adjustSalary.setFixedSalary(new BigDecimal(10000));
                adjustSalary.setBaseSalary(new BigDecimal(0.00));
                adjustSalary.setCommissionRate(null);
                adjustSalary.setWorkExtra(1.3);

                Double workingHours=Double.parseDouble(employee.getWorkingHours());
                payTotalSalary=payTotalSalary.add(managerCalSalary.callCalculateSalary(workingHours,null,adjustSalary));
            }else if(hours.contains(employee.getName())){
                CalculateSalaryContext hourCalSalary=new CalculateSalaryContext(new HourCalSalaryStrategy());

                //员工的固定工资,时薪,提成率和底薪调整配置
                AdjustSalary adjustSalary=new AdjustSalary();
                adjustSalary.setHourSalary(new BigDecimal(40));
                adjustSalary.setFixedSalary(new BigDecimal(0.00));
                adjustSalary.setBaseSalary(new BigDecimal(0.00));
                adjustSalary.setCommissionRate(null);
                adjustSalary.setWorkExtra(1.3);

                Double workingHours=Double.parseDouble(employee.getWorkingHours());
                payTotalSalary=payTotalSalary.add(hourCalSalary.callCalculateSalary(workingHours,null,adjustSalary));
            }else if(sales.contains(employee.getName())){
                CalculateSalaryContext salesCalSalary=new CalculateSalaryContext(new SalesCalSalaryStrategy());

                //构建
                Map<String, Double> commissionRates=new HashMap<>();
                commissionRates.put("L1",0.05);
                commissionRates.put("L2",0.08);

                //员工的固定工资,时薪,提成率和底薪调整配置
                AdjustSalary adjustSalary=new AdjustSalary();
                adjustSalary.setHourSalary(new BigDecimal(0.00));
                adjustSalary.setFixedSalary(new BigDecimal(0.00));
                adjustSalary.setBaseSalary(new BigDecimal((3000)));
                adjustSalary.setCommissionRate(commissionRates);
                adjustSalary.setWorkExtra(0.00);

                BigDecimal amountTmp=new BigDecimal(employee.getAmount());
                //调用销售计薪规则
                payTotalSalary=payTotalSalary.add(salesCalSalary.callCalculateSalary(null,amountTmp,adjustSalary));
            }
        }

        System.out.println("公司应支付员工工资总额:"+payTotalSalary.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
    }
}

解析xml文件方法:

      1.采用dom4j

       2.xstream

需要注意的是解析的xml内容格式决定采用以上哪种更恰当。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本软件设计力求简单,用户一看就会。下面仅给大家做简单介绍。软件主界面如图所示: 1、 增加套改人员(2006-6-30时的非试用期人员) 菜单:增加参加工改人员(工改时非试用期): 如图,将人员工改时的基本信息及工改后的职级、级别、学历、年度考核情况填上后,点击【开始测算】按钮,即可测算出工改结果以及工资演变情况。 点击【保存】,即可将人员信息保存到数据中,方便查询、统计和输出打印。 选中人员后可以将信息输出到电子表格,打印存档,如图所示 工改后参加工作人员(包括工改时为试用期的人员)操作方法类似。菜单为: 增加工改后参加工作人员(含工改时试用期)。如图所示: 2、 由于每年存在正常晋升的情况,所有人员需要重新核定工资。检查是否需要正常晋升,在软件中可通过【全部重算】功能完成,如图所示: 选中要核算的截止日期,点击【开始核算】,所有人员的工资将重新核算到指定日期。所以您也可以通过该功能,测算人员若干年之后的工资情况。 3、 个别人员的测算或修改 已录入系统的人员,如果有新的变动或者信息有误,可以选中人员后,点击【编辑】按钮,修改信息后,重新测算后再保存信息即可。 4、 统计查询 点击工具栏【查询】按钮即可进行查询、统计和输出报表功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值