工资计算系统设计实现
Posted mask哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工资计算系统设计实现相关的知识,希望对你有一定的参考价值。
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内容格式决定采用以上哪种更恰当。
以上是关于工资计算系统设计实现的主要内容,如果未能解决你的问题,请参考以下文章