Advertisement
dzocesrce

[NP] Payroll System v2

Apr 27th, 2025
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.92 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3. import java.util.stream.Collectors;
  4. import java.util.Comparator;
  5. import java.util.List;
  6.  
  7. class HourlyEmployee extends Employee{
  8.     double hours;
  9.     EMPLOYEE_TYPE employeeType;
  10.     double hourlyRate;
  11.     public static int WEEK_HOURS=40;
  12.     public static double OVERTIME_RATE=1.5;
  13.     int bonus;
  14.     BONUS_TYPE bonusType;
  15.     public HourlyEmployee(String id, String level, double hours,EMPLOYEE_TYPE employeeType, int bonus, BONUS_TYPE bonusType) {
  16.         super(id,level);
  17.         this.hours= hours;
  18.         this.employeeType= employeeType;
  19.         this.hourlyRate=0;
  20.         this.bonus= bonus;
  21.         this.bonusType= bonusType;
  22.     }
  23.  
  24.     public void setRate(double hourlyRate){
  25.         this.hourlyRate= hourlyRate;
  26.     }
  27.     public double getOvertimeSalary(){
  28.         return Math.max(0,hours-WEEK_HOURS)*OVERTIME_RATE;
  29.     }
  30.     @Override
  31.     public double getBonus() {
  32.         if(bonusType.equals(BONUS_TYPE.FIXED))
  33.             return bonus;
  34.         else if(bonusType.equals(BONUS_TYPE.PROCENTUAL))
  35.             return getSalary()*bonus/100.00;
  36.         else
  37.             return 0;
  38.     }
  39.  
  40.     public EMPLOYEE_TYPE getEmployeeType() {
  41.         return employeeType;
  42.     }
  43.  
  44.  
  45.  
  46.     @Override
  47.     public double getSalary() {
  48.         return Math.min(WEEK_HOURS,hours)*hourlyRate+OVERTIME_RATE*Math.max(0,hours-WEEK_HOURS)*hourlyRate;
  49.     }
  50.  
  51.     @Override
  52.     public String toString() {
  53.         return String.format("Employee ID: %s Level: %s Salary: %.2f Regular hours: %.2f Overtime hours: %.2f  Bonus: %.2f",
  54.                 id,
  55.                 level,
  56.                 getSalary(),
  57.                 Math.min(WEEK_HOURS,hours),
  58.                 Math.max(0,hours-WEEK_HOURS),
  59.                 getBonus());
  60.     }
  61.  
  62.     @Override
  63.     public int compareTo(Employee o) {
  64.         return Comparator.comparing(Employee::getSalary).reversed().compare(this,o);
  65.     }
  66. }
  67. class FreelanceEmployee extends Employee {
  68.     List<Integer> tickets;
  69.     EMPLOYEE_TYPE employeeType;
  70.     double ratePerTicket;
  71.     int bonus;
  72.     BONUS_TYPE bonusType;
  73.     public FreelanceEmployee(String id, String level, List<Integer> tickets, EMPLOYEE_TYPE employeeType, int bonus, BONUS_TYPE bonusType) {
  74.         super(id, level);
  75.         this.tickets = tickets;
  76.         this.employeeType = employeeType;
  77.         this.ratePerTicket=0;
  78.         this.bonus= bonus;
  79.         this.bonusType= bonusType;
  80.     }
  81.  
  82.     public int getNumberOfTickets(){
  83.         return tickets.size();
  84.     }
  85.    
  86.     public int getTicketPoints() {
  87.         return tickets.stream().mapToInt(i -> i).sum();
  88.     }
  89.  
  90.     public void setRate(double ratePerTicket){
  91.         this.ratePerTicket= ratePerTicket;
  92.     }
  93.  
  94.  
  95.     public EMPLOYEE_TYPE getEmployeeType() {
  96.         return employeeType;
  97.     }
  98.  
  99.     @Override
  100.     public double getSalary() {
  101.         return ratePerTicket*getTicketPoints();
  102.     }
  103.  
  104.     @Override
  105.     public double getBonus() {
  106.         if(bonusType.equals(BONUS_TYPE.FIXED))
  107.             return bonus;
  108.         else if(bonusType.equals(BONUS_TYPE.PROCENTUAL))
  109.             return getSalary()*bonus/100.00;
  110.         else
  111.             return 0;
  112.     }
  113.  
  114.     @Override
  115.     public String toString() {
  116.         return String.format("Employee ID: %s Level: %s Salary: %.2f Tickets count: %d Tickets points: %d  Bonus: %.2f",
  117.                 id,
  118.                 level,
  119.                 getSalary(),
  120.                 tickets.size(),
  121.                 getTicketPoints(),
  122.                 getBonus());
  123.     }
  124.  
  125.     @Override
  126.     public int compareTo(Employee o) {
  127.         return Comparator.comparing(Employee::getSalary).reversed().compare(this,o);
  128.     }
  129. }
  130.  
  131.  
  132. enum BONUS_TYPE {
  133.  
  134.     FIXED,
  135.     NONE, PROCENTUAL
  136. }
  137.  
  138. class BonusNotAllowedException extends  Exception{
  139.  
  140.     public BonusNotAllowedException(String message) {
  141.         super(message);
  142.     }
  143. }
  144.  
  145. abstract class Employee implements Comparable<Employee> {
  146.     String id;
  147.     String level;
  148.  
  149.     public Employee(String id, String level) {
  150.         this.id = id;
  151.         this.level = level;
  152.     }
  153.  
  154.     public abstract void setRate(double rate);
  155.  
  156.     public String getId() {
  157.         return id;
  158.     }
  159.  
  160.     public String getLevel() {
  161.         return level;
  162.     }
  163.  
  164.     public abstract double getBonus();
  165.  
  166.     public abstract double getSalary();
  167.  
  168.     public abstract EMPLOYEE_TYPE getEmployeeType();
  169.  
  170. }
  171. enum EMPLOYEE_TYPE {
  172.     HOURLY,
  173.     FREELANCE
  174. }
  175.  
  176. class PayrollSystem {
  177.  
  178.     Map<String, List<Employee>> employees;
  179.     Map<String, Double> hourlyRateByLevel;
  180.     Map<String, Double> timeRateByLevel;
  181.  
  182.     PayrollSystem(Map<String, Double> hourlyRateByLevel, Map<String, Double> ticketRateByLevel) {
  183.         this.hourlyRateByLevel = hourlyRateByLevel;
  184.         this.timeRateByLevel = ticketRateByLevel;
  185.         this.employees = new HashMap<>();
  186.         this.employees.put("F", new ArrayList<>());
  187.         this.employees.put("H", new ArrayList<>());
  188.     }
  189.  
  190.     public Employee createEmployee(String line) throws BonusNotAllowedException {
  191.         String[] partsAndBonus = line.split("\\s+");
  192.         String bonus = "";
  193.         if (partsAndBonus.length > 1) {
  194.             bonus = partsAndBonus[1];
  195.         }
  196.         String[] parts = partsAndBonus[0].split(";");
  197.         String type = parts[0];
  198.         String id = parts[1];
  199.         String level = parts[2];
  200.         double hourlySalary;
  201.         List<Integer> tickets = new ArrayList<>();
  202.         if (!bonus.equals("")) {
  203.             if (bonus.contains("%") && Double.parseDouble(bonus.substring(0, bonus.length()-1)) > 20)
  204.                 throw new BonusNotAllowedException("E TOE");
  205.             if (!bonus.contains("%") && Double.parseDouble(bonus) > 1000)
  206.                 throw new BonusNotAllowedException("E TOE");
  207.         }
  208.         if (type.equals("H")) {
  209.             hourlySalary = Double.parseDouble(parts[3]);
  210.             if (bonus.equals("")) {
  211.                 employees.get("H").add(new HourlyEmployee(id, level, hourlySalary, EMPLOYEE_TYPE.HOURLY, 0, BONUS_TYPE.NONE));
  212.             } else {
  213.                 if (bonus.contains("%")) {
  214.                     employees.get("H").add(new HourlyEmployee(id, level, hourlySalary, EMPLOYEE_TYPE.HOURLY,
  215.                             Double.parseDouble(bonus.substring(0, bonus.length() - 1)), BONUS_TYPE.PROCENTUAL));
  216.                 } else {
  217.                     employees.get("H").add(new HourlyEmployee(id, level, hourlySalary, EMPLOYEE_TYPE.HOURLY,
  218.                             Double.parseDouble(bonus), BONUS_TYPE.FIXED));
  219.                 }
  220.             }
  221.             return employees.get("H").get(employees.size() - 1);
  222.         } else {
  223.             for (int i = 3; i < parts.length; i++) {
  224.                 tickets.add(Integer.parseInt(parts[i]));
  225.             }
  226.             if (bonus.equals("")) {
  227.                 employees.get("F").add(new FreelanceEmployee(id, level, tickets, EMPLOYEE_TYPE.HOURLY, 0, BONUS_TYPE.NONE));
  228.             } else {
  229.                 if (bonus.contains("%")) {
  230.                     employees.get("F").add(new FreelanceEmployee(id, level, tickets, EMPLOYEE_TYPE.HOURLY,
  231.                             Double.parseDouble(bonus.substring(0, bonus.length() - 1)), BONUS_TYPE.PROCENTUAL));
  232.  
  233.                 } else {
  234.                     employees.get("F").add(new FreelanceEmployee(id, level, tickets, EMPLOYEE_TYPE.HOURLY,
  235.                             Double.parseDouble(bonus), BONUS_TYPE.FIXED));
  236.                 }
  237.             }
  238.             return employees.get("F").get(employees.size() - 1);
  239.  
  240.         }
  241.     }
  242.  
  243.  
  244.     public void setRates() {
  245.  
  246.         for (Employee e : employees.get("H")) {
  247.             double hourlyRate = hourlyRateByLevel.get(e.getLevel());
  248.             e.setRate(hourlyRate);
  249.         }
  250.         for (Employee e : employees.get("F")) {
  251.             double ratePerTicket = timeRateByLevel.get(e.getLevel());
  252.             e.setRate(ratePerTicket);
  253.         }
  254.  
  255.     }
  256.  
  257. //    public Map<String, Set<Employee>> printEmployeesByLevels(PrintStream out, Set<String> levels) {
  258. //        PrintWriter printWriter = new PrintWriter(out);
  259. //        Map<String, Set<Employee>> employeesByLevels = employees.stream()
  260. //                .filter(i -> levels.contains(i.getLevel()))
  261. //                .collect(Collectors.groupingBy(
  262. //                        Employee::getLevel,
  263. //                        TreeMap::new, // map sorted by key
  264. //                        Collectors.toCollection(TreeSet::new) // values sorted too
  265. //                ));
  266. //        printWriter.flush();
  267. //        return employeesByLevels;
  268. //    }
  269.  
  270.  
  271.     Map<String, Double> getOvertimeSalaryForLevels() {
  272.         return employees.get("H").stream()
  273.                 .map(e -> (HourlyEmployee) e)
  274.                 .collect(Collectors.groupingBy(
  275.                 Employee::getLevel,
  276.                 Collectors.summingDouble(HourlyEmployee::getOvertimeSalary)
  277.         ));
  278.     }
  279.  
  280.     void printStatisticsForOvertimeSalary() {
  281.         DoubleSummaryStatistics doubleSummaryStatistics= employees.values().stream().flatMap(list -> list.stream()).mapToDouble(i->i.getBonus()).summaryStatistics();
  282.         System.out.println(String.format("Min: %.2f Max: %.2f Sum: %.2f Average: %.2f",doubleSummaryStatistics.getMin(),
  283.                 doubleSummaryStatistics.getMax(),
  284.                 doubleSummaryStatistics.getSum(),
  285.                 doubleSummaryStatistics.getAverage()));
  286.     }
  287.  
  288.     Map<String, Integer> ticketsDoneByLevel() {
  289.         return employees.get("F").stream()
  290.         .map(e -> (FreelanceEmployee) e)
  291.         .collect(Collectors.groupingBy(
  292.                 Employee::getLevel,
  293.                 Collectors.summingInt(FreelanceEmployee::getNumberOfTickets)
  294.         ));
  295.  
  296.     }
  297.  
  298.     Collection<Employee> getFirstNEmployeesByBonus(int n) {
  299.         return employees.values().stream().flatMap(list -> list.stream())
  300.                 .sorted(Comparator.comparing(Employee::getBonus).reversed())
  301.                 .limit(n).collect(Collectors.toList());
  302.     }
  303. }
  304. public class PayrollSystemTest2 {
  305.  
  306.     public static void main(String[] args) {
  307.  
  308.         Map<String, Double> hourlyRateByLevel = new LinkedHashMap<>();
  309.         Map<String, Double> ticketRateByLevel = new LinkedHashMap<>();
  310.         for (int i = 1; i <= 10; i++) {
  311.             hourlyRateByLevel.put("level" + i, 11 + i * 2.2);
  312.             ticketRateByLevel.put("level" + i, 5.5 + i * 2.5);
  313.         }
  314.  
  315.         Scanner sc = new Scanner(System.in);
  316.  
  317.         int employeesCount = Integer.parseInt(sc.nextLine());
  318.  
  319.         PayrollSystem ps = new PayrollSystem(hourlyRateByLevel, ticketRateByLevel);
  320.         Employee emp = null;
  321.         for (int i = 0; i < employeesCount; i++) {
  322.             try {
  323.                 emp = ps.createEmployee(sc.nextLine());
  324.             } catch (BonusNotAllowedException e) {
  325.                 System.out.println(e.getMessage());
  326.             }
  327.         }
  328.         ps.setRates();
  329.         int testCase = Integer.parseInt(sc.nextLine());
  330.  
  331.         switch (testCase) {
  332.             case 1: //Testing createEmployee
  333.                 if (emp != null)
  334.                     System.out.println(emp);
  335.                 break;
  336.             case 2: //Testing getOvertimeSalaryForLevels()
  337.                 ps.getOvertimeSalaryForLevels().forEach((level, overtimeSalary) -> {
  338.                     System.out.printf("Level: %s Overtime salary: %.2f\n", level, overtimeSalary);
  339.                 });
  340.                 break;
  341.             case 3: //Testing printStatisticsForOvertimeSalary()
  342.                 ps.printStatisticsForOvertimeSalary();
  343.                 break;
  344.             case 4: //Testing ticketsDoneByLevel
  345.                 ps.ticketsDoneByLevel().forEach((level, overtimeSalary) -> {
  346.                     System.out.printf("Level: %s Tickets by level: %d\n", level, overtimeSalary);
  347.               });
  348.                break;
  349.             case 5: //Testing getFirstNEmployeesByBonus (int n)
  350.                 ps.getFirstNEmployeesByBonus(Integer.parseInt(sc.nextLine())).forEach(System.out::println);
  351.                 break;
  352.         }
  353.  
  354.     }
  355. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement