package com.example.schedulerapp; import java.net.*; import java.io.*; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.concurrent.TimeUnit; public class Model { private PrintWriter writer; private Socket socket; protected ArrayList<String> shifts; protected ArrayList<String> employees; protected ArrayList<ModelSubscriber> subscribers; static LocalDate date; private boolean isManager; private int thisEmployee; private int selectedEmployee; public Model(String hostname, int port) { selectedEmployee = 1; //testing subscribers = new ArrayList<>(); if(date == null) { date = LocalDate.now(); } isManager = false; // changes if manager logs in this.shifts = new ArrayList<>(); this.employees = new ArrayList<>(); try { InetAddress ip = InetAddress.getByName(hostname); this.socket = new Socket(ip, port); System.out.println("Connected to the scheduling server"); new ReceiveThread(this.socket, this).start(); OutputStream output = this.socket.getOutputStream(); this.writer = new PrintWriter(output, true); } catch (UnknownHostException error) { System.out.println("Server not found: " + error.getMessage()); } catch (IOException error) { System.out.println("I/O Error: " + error.getMessage()); } } public void setIsManager(boolean aBool){ isManager = aBool; } public boolean getIsManager(){ return isManager; } public void setThisEmployee(int id){ thisEmployee = selectedEmployee = id; } public int getThisEmployee(){ return thisEmployee; } //for manager only, allows viewing of weekly schedule by employee public void setSelectedEmployee(int id){ selectedEmployee = id; notifySubscribers(); } public int getSelectedEmployee(){ return selectedEmployee; } public void dateNext(){ date = date.plusDays(1); notifySubscribers(); } public void datePrev(){ date = date.minusDays(1); notifySubscribers(); } //todo: add calender to fill jump field public void dateJump(LocalDate date){ this.date = date; notifySubscribers(); } //todo //Return void getAllEmployees() { } void updateAllShifts(){ writer.println("allShifts"); } void updateAllEmployees(){ writer.println("allEmployees"); } void addEmployee(String first_name, String last_name) { writer.println("addEmployee/" + first_name + "/" + last_name); } void removeEmployee(String employeeID) { writer.println("removeEmployee/" + employeeID); } void printAllEmployees(){ System.out.println(this.employees); } String getEmployeeByID(int id) { if (!this.employees.isEmpty()) { for(String e: this.employees){ if(!e.equals("allEmployees")){ String[] eSplit = e.split("\\."); try { if(Integer.parseInt(eSplit[0]) == id){ return eSplit[1] + " " + eSplit[2]; } } catch (NumberFormatException exception){ System.out.println("getEmployeeByID: string cannot be integer parsed"); } } } return "No Employee with that ID"; } return "No Employees"; } void addShift(int id, String date, int start, int end){ writer.println("addShift/"+id+"/"+date+"/"+start+"/"+end); notifySubscribers(); } void removeShift(int shiftID){ writer.println("removeShift/"+shiftID); notifySubscribers(); } void editShift(int shiftID, String day, int start, int end) { writer.println("editShift/"+shiftID+"/"+day+"/"+start+"/"+end); notifySubscribers(); } void printAllShifts() { System.out.println(this.shifts); } /* Parameters: - String date in format 2022-03-10. Return: ArrayList<String> where each string is a shift of format id.yyyy-mm-dd.start.end */ ArrayList<String> getShiftsByDay(String date){ String[] split = date.split("-"); ArrayList<String> output = new ArrayList<>(); for(String shift: this.shifts){ if(!shift.equals("allShifts")){ String[] shiftSplit = shift.split("\\."); String[] dateSplit = shiftSplit[1].split("-"); try { if(Integer.parseInt(split[0]) == Integer.parseInt(dateSplit[0]) && Integer.parseInt(split[1]) == Integer.parseInt(dateSplit[1]) && Integer.parseInt(split[2]) == Integer.parseInt(dateSplit[2])){ output.add(shift); } } catch (Exception e){ System.out.println("Error: Parsing string to int"); } } } return output; } /* Parameters: startOfWeek - The first day of the week in "yyyy-mm-dd" format endOfWeek - The last day of the week in "yyyy-mm-dd" format Return: ArrayList<String> */ ArrayList<String> getShiftsByWeek(String startOfWeek, String endOfWeek){ String[] startSplit = startOfWeek.split("-"); String[] endSplit = endOfWeek.split("-"); ArrayList<String> output = new ArrayList<>(); for(String shift: this.shifts){ if(!shift.equals("allShifts")){ String[] shiftSplit = shift.split("\\."); String[] dateSplit = shiftSplit[1].split("-"); try { if(Integer.parseInt(startSplit[0]) >= Integer.parseInt(dateSplit[0]) && Integer.parseInt(startSplit[1]) >= Integer.parseInt(dateSplit[1]) && Integer.parseInt(startSplit[2]) >= Integer.parseInt(dateSplit[2])){ if(Integer.parseInt(endSplit[0]) >= Integer.parseInt(dateSplit[0]) && Integer.parseInt(endSplit[1]) >= Integer.parseInt(dateSplit[1]) && Integer.parseInt(endSplit[2]) >= Integer.parseInt(dateSplit[2])){ output.add(shift); } } } catch (Exception e){ System.out.println("Error: Parsing string to int"); } } } return output; } //for view public ArrayList<Shift> getWeeklySchedule(){ String start; String end; // get start and end dates to pass along int today = date.getDayOfWeek().getValue(); // Mon is 1, Sun is 7 if (today == 7) { //this is the start date start = date.toString(); end = date.plusDays(6).toString(); } else { start = date.minusDays(today).toString(); end = date.plusDays(6 - today).toString(); } printAllShifts(); System.out.println("start: " + start + " end: " + end + " shifts returned " + getShiftsByWeek(start, end).size()); return convertToShift(getShiftsByWeek(start, end)); } //for view public ArrayList<Shift> getDailySchedule(){ return convertToShift(getShiftsByDay(date.toString())); } //format id.yyyy-mm-dd.start.end //convert ArrayList<String> to ArrayList<Shift> protected ArrayList<Shift> convertToShift(ArrayList<String> input){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-ddHHmm"); ArrayList<Shift> output = new ArrayList<>(); for (String dbShift : input){ String[] strings = dbShift.split("\\."); int id = Integer.parseInt(strings[0]); if (strings[2].length() == 3) strings[2] = "0" + strings[2]; if (strings[3].length() == 3) strings[3] = "0" + strings[3]; LocalDateTime start = LocalDateTime.parse(strings[1] + strings[2], formatter); LocalDateTime end = LocalDateTime.parse(strings[1] + strings[3], formatter); output.add(new Shift(id, start, end)); } return output; } ArrayList<String> getEmployeeShifts(String id){ ArrayList<String> output = new ArrayList<>(); for(String shift: this.shifts){ String[] shiftSplit = shift.split("\\."); if (shiftSplit[0].equals(id)) { output.add(shift); } } return output; } //todo void getEmployeeShiftsByWeek(){ } void logOut() { writer.println("logout"); try { this.socket.close(); } catch (IOException ex){ System.out.println("Error: Failed to close socket"); } } public static void main(String[] args) { String hostname = "localhost"; //"localhost if connecting to local server, or "172.16.1.99" connecting to Rafi's server int port = 8989; //Rafi's server port is 8989 Model client = new Model(hostname, port); System.out.print("Retrieving Data"); while(client.employees.isEmpty() && client.shifts.isEmpty()){ System.out.print("."); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { System.out.println("Error: ScheduleClient main. Interrupted while retrieving data "); } } System.out.println(); System.out.println("Data retrieved."); System.out.println("ScheduleClient is ready to use!"); } public ArrayList<String> returnFormattedEmployeeNames(){ ArrayList<String> result = new ArrayList<>(); ArrayList<String> temp = (ArrayList<String>) this.employees.clone(); String tempName = ""; temp.remove(0); for(int i = 0; i < temp.size(); i++){ String[] templist = temp.get(i).split("\\."); for(int j =0; j < 3; j++){ if(j == 1 || j == 2){ tempName += templist[j]; } if(j == 1){ tempName += " "; } } result.add(tempName); tempName = ""; } System.out.println(result); return result; } public int getIDbyIndex(int index) { ArrayList tempList = (ArrayList) this.employees.clone(); String tempEmployee = (String) tempList.get(index + 1); String[] splitString = tempEmployee.split("\\."); return Integer.parseInt(splitString[0]); } //for publish/subscribe public void addSubscriber(ModelSubscriber sub){ subscribers.add(sub); } public void notifySubscribers(){ for (ModelSubscriber sub : subscribers){ sub.modelChanged(); } } }