package com.example.schedulerapp; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.Event; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.input.MouseEvent; import javafx.scene.layout.*; import javafx.stage.Stage; import java.io.IOException; import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Controller { @FXML BorderPane myBorderPane; @FXML VBox leftSideButtons; @FXML public BorderPane rootBorderPane; @FXML TextArea employees; @FXML private TextField addFirstName; @FXML private TextField addLastName; @FXML private TextField removeID; @FXML Button addShiftSubmitButton; @FXML DatePicker addShiftDatePicker; @FXML TextField addShiftStartTime; @FXML TextField addShiftEndTime; @FXML ComboBox addShiftEmployeeBox; @FXML HBox addShiftEmployeeHBox; @FXML ComboBox removeEmployeeBox; @FXML ComboBox addShiftStartTimeBox; @FXML ComboBox addShiftEndTimeBox; @FXML Label currentDateText; @FXML TextField loginField; @FXML Label loggedIn; @FXML Label viewing; @FXML Label loginWarning; @FXML TextField editEmployeeFirstName; @FXML TextField editEmployeeLastName; @FXML TextField editEmployeeEmail; @FXML TextField editEmployeeWage; @FXML TextField editEmployeePhoneNumber; @FXML TextField editEmployeeAddress; @FXML ComboBox editEmployeeBox; @FXML CheckBox editEmployeeManager; @FXML DatePicker timeOffDatePicker; @FXML ChoiceBox<Employee> selectedEmployee; @FXML Label currentDateTextAvail; @FXML ComboBox<String> availabilityDayBox; @FXML ComboBox<String> editAvailabilityStartBox; @FXML ComboBox<String> editAvailabilityEndBox; @FXML Label availabilityResult; @FXML Label addShiftError; boolean isDaily; Stage popupStage; Scene popupScene; Stage popupAvailStage; Scene popupAvail; Stage popupTimeOffStage; Scene popupTimeOff; Model model; DailyView dailyView; WeeklyView weeklyView; EmployeeView employeeView; AvailabilityView availabilityView; BorderPane root; Parent header; Parent sideSchedulePanel; Parent bottomPanel; Parent paystubView; Parent editEmployeeView; Parent addEmployeeView; Parent staffPanel; Parent availabilityPanel; Parent removeEmployeeView; // login methods, initializes views too public void attemptLogin(Event e) throws Exception { if (!model.hasEmployee(Integer.parseInt(loginField.getText()))) { loginWarning.setText("Invalid id"); } else { login(e); } } public void login(Event e) throws Exception { //set this employee and manager privileges as appropriate int thisEmployee = Integer.parseInt(loginField.getText()); model.setThisEmployee(thisEmployee); model.setSelectedEmployee(thisEmployee); model.setIsManager(model.getEmployee(thisEmployee).isManager()); //load everything loadEverything(); //set up for initial daily schedule view root.setTop(header); viewSchedule(); Stage stage = (Stage)((Node)e.getSource()).getScene().getWindow(); Scene scene = new Scene(root, 800, 600); stage.setTitle("Scheduler App"); stage.setScene(scene); stage.show(); //set variable text updateCurrentDate(e); loggedIn.setText("Logged In: " + model.getEmployee(model.getThisEmployee()).toString()); //set manager specific text if (model.getIsManager()){ selectedEmployee.setItems(FXCollections.observableArrayList(model.getAllEmployees())); selectedEmployee.getSelectionModel().selectedItemProperty().addListener((observableValue, o, t1) -> model.setSelectedEmployee(selectedEmployee.getSelectionModel().getSelectedItem().getEmployeeID())); selectedEmployee.getSelectionModel().select(model.getEmployee(model.getSelectedEmployee())); } } // add components here to be loaded once public void loadEverything() throws IOException { root = new BorderPane(); dailyView = new DailyView(); dailyView.setModel(model); model.addSubscriber(dailyView); weeklyView = new WeeklyView(); weeklyView.setModel(model); model.addSubscriber(weeklyView); employeeView = new EmployeeView(); employeeView.setModel(model); model.addSubscriber(employeeView); availabilityView = new AvailabilityView(); availabilityView.setModel(model); model.addSubscriber(availabilityView); //fxml views loadHeader(); loadScheduleSide(); loadScheduleBottom(); loadPaystubView(); loadEditEmployee(); loadStaffPanel(); loadAvailabilityBottomPanel(); loadAddEmployee(); loadRemoveEmployee(); } /* load functions for individual views / panels all need to be called in loadEverything emp vs manager distinction made here, later can just load */ public void loadHeader() throws IOException { if (model.getIsManager()){ //load manager header FXMLLoader headerLoader = new FXMLLoader(this.getClass().getResource("headerManager.fxml")); headerLoader.setController(this); header = headerLoader.load(); } else { //load employee header FXMLLoader headerLoader = new FXMLLoader(this.getClass().getResource("employeeHeader.fxml")); //FXMLLoader headerLoader = new FXMLLoader(this.getClass().getResource("headerManager.fxml")); //for now headerLoader.setController(this); header = headerLoader.load(); } } public void loadScheduleSide() throws IOException { //same for both FXMLLoader sideLoader = new FXMLLoader(this.getClass().getResource("schedSidePanel.fxml")); sideLoader.setController(this); sideSchedulePanel = sideLoader.load(); } public void loadScheduleBottom() throws IOException { if (model.getIsManager()){ FXMLLoader bottomLoader = new FXMLLoader(this.getClass().getResource("schedBottomPanelManager.fxml")); bottomLoader.setController(this); bottomPanel = bottomLoader.load(); } else { FXMLLoader bottomLoader = new FXMLLoader(this.getClass().getResource("employeeSchedBottomPanel.fxml")); bottomLoader.setController(this); bottomPanel = bottomLoader.load(); } } public void loadAvailabilityBottomPanel() throws IOException { FXMLLoader sideLoader = new FXMLLoader(this.getClass().getResource("availabilityBottomPanel.fxml")); sideLoader.setController(this); availabilityPanel = sideLoader.load(); } public void loadPaystubView() throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(ScheduleApp.class.getResource("paystubView.fxml")); fxmlLoader.setController(this); paystubView = fxmlLoader.load(); } public void loadEditEmployee() throws IOException{ FXMLLoader gridLoader = new FXMLLoader(this.getClass().getResource("editEmployee.fxml")); gridLoader.setController(this); editEmployeeView = gridLoader.load(); } public void loadStaffPanel() throws IOException { FXMLLoader sideLoader = new FXMLLoader(this.getClass().getResource("staffManagerSidePanel.fxml")); sideLoader.setController(this); staffPanel = sideLoader.load(); } public void loadAddEmployee() throws IOException { FXMLLoader gridLoader = new FXMLLoader(this.getClass().getResource("addEmployee.fxml")); gridLoader.setController(this); addEmployeeView = gridLoader.load(); } public void loadRemoveEmployee() throws IOException { FXMLLoader gridLoader = new FXMLLoader(this.getClass().getResource("removeEmployee.fxml")); gridLoader.setController(this); removeEmployeeView = gridLoader.load(); } /* switch to the appropriate view same code for emp vs manager, distinction made in load functions */ // schedule tab (default daily view) public void viewSchedule(){ root.setLeft(sideSchedulePanel); root.setBottom(bottomPanel); root.setCenter(dailyView); isDaily = true; } // schedule -> weekly public void viewScheduleWeekly(){ root.setCenter(weeklyView); root.setBottom(bottomPanel); isDaily = false; } // schedule -> daily public void viewScheduleDaily(){ root.setCenter(dailyView); root.setBottom(bottomPanel); isDaily = true; } // schedule -> availability public void viewAvailability() { root.setCenter(availabilityView); root.setBottom(availabilityPanel); isDaily = false; } // schedule -> pickups todo public void viewPickups(){ root.setCenter(null); root.setBottom(bottomPanel); } //schedule popups public void editAvailability() throws IOException { FXMLLoader popupLoader = new FXMLLoader(this.getClass().getResource("availabilityPopup.fxml")); popupLoader.setController(this); popupAvail = new Scene(popupLoader.load(),500,500); popupAvailStage = new Stage(); popupAvailStage.setScene(popupAvail); popupAvailStage.show(); } public void requestTimeOff() throws IOException { FXMLLoader popupLoader = new FXMLLoader(this.getClass().getResource("timeOffPopup.fxml")); popupLoader.setController(this); popupTimeOff = new Scene(popupLoader.load(),500,500); popupTimeOffStage = new Stage(); popupTimeOffStage.setScene(popupTimeOff); popupTimeOffStage.show(); } //add shift popup (manager only) public void addShiftClicked() throws IOException { FXMLLoader popupLoader = new FXMLLoader(this.getClass().getResource("addShiftPopup.fxml")); popupLoader.setController(this); popupScene = new Scene(popupLoader.load(),500,500); popupStage = new Stage(); popupStage.setScene(popupScene); popupStage.show(); } // Paystub tab (employee only) public void viewPaystub() throws IOException { root.setCenter(paystubView); System.out.println("todo: display paystub"); root.setLeft(null); root.setBottom(null); } // Payroll tab (manager only) public void viewPayroll() { root.setCenter(null); //todo System.out.println("todo: display payroll"); root.setLeft(null); root.setBottom(null); } // Staff tab (default view staff, manager only) public void viewStaff(){ root.setLeft(staffPanel); root.setCenter(employeeView); root.setBottom(null); } // Staff -> edit employee public void viewEditEmployee(){ root.setCenter(editEmployeeView); } // Staff -> add employee public void viewAddEmployee(){ root.setCenter(addEmployeeView); } // Staff -> remove employee public void viewRemoveEmployee(){ root.setCenter(removeEmployeeView); } //Staff -> view employees public void viewViewEmployees(){ root.setCenter(employeeView); model.notifySubscribers(); } // Requests tab (manager only) public void viewRequests() { root.setCenter(null); System.out.println("todo: display requests"); root.setLeft(null); root.setBottom(null); } //methods for submitting data public void submitTimeOff(MouseEvent event){ System.out.println("todo"); } public void addShiftSubmitClicked(MouseEvent event){ String employee = (String) addShiftEmployeeBox.getValue(); int index = addShiftEmployeeBox.getSelectionModel().getSelectedIndex(); String startTime = (String) addShiftStartTimeBox.getValue(); String endTime = (String) addShiftEndTimeBox.getValue(); LocalDate date = addShiftDatePicker.getValue(); addShiftError.setText(model.addShift(model.getIDbyIndex(index),date.toString(),Integer.parseInt(startTime),Integer.parseInt(endTime))); //todo: show result to user? } public void submitNewAvailability(MouseEvent e){ availabilityResult.setText(model.editAvailability(model.getSelectedEmployee(), availabilityDayBox.getSelectionModel().getSelectedIndex(), Integer.parseInt(editAvailabilityStartBox.getValue()), Integer.parseInt(editAvailabilityEndBox.getValue()))); } public void addEmployeeClicked(MouseEvent mouseEvent) { String firstName = addFirstName.getText(); String lastName = addLastName.getText(); model.addEmployee(firstName, lastName); System.out.println("Employee " + firstName + " " + lastName + " added to Staff. Welcome " + firstName + "!"); model.notifySubscribers(); } public void editEmployeeClicked(MouseEvent mouseEvent) { int id = model.getIDbyIndex(editEmployeeBox.getSelectionModel().getSelectedIndex()); String newFirstName = editEmployeeFirstName.getText(); String newLastName = editEmployeeLastName.getText(); String newEmail = editEmployeeEmail.getText(); Float newWage = Float.parseFloat(editEmployeeWage.getText()); String newPhoneNumber = editEmployeePhoneNumber.getText(); boolean newIsManager = editEmployeeManager.isSelected(); model.editEmployee(id,newFirstName,newLastName,newIsManager,newEmail,newPhoneNumber,newWage); System.out.println("edit employee submit clicked"); } public void removeEmployeeClicked(MouseEvent mouseEvent) { int index = removeEmployeeBox.getSelectionModel().getSelectedIndex(); String id = String.valueOf(model.getIDbyIndex(index)); model.removeEmployee(id); removeEmployeeBox.getSelectionModel().clearSelection(); } public void prevButtonClicked (MouseEvent event) throws Exception { if (isDaily) model.datePrev(); else model.weekPrev(); updateCurrentDate(event); } public void jumpButtonClicked (MouseEvent event) throws Exception { System.out.println("jump button clicked"); //model.dateJump(); updateCurrentDate(event); } public void nextButtonClicked (MouseEvent event) throws Exception { if (isDaily) model.dateNext(); else model.weekNext(); updateCurrentDate(event); } public void cancelClicked(MouseEvent e){ ((Node)e.getSource()).getScene().getWindow().hide(); } public void logoutClicked(MouseEvent mouseEvent) throws IOException { FXMLLoader loginLoader = new FXMLLoader(this.getClass().getResource("login.fxml")); loginLoader.setController(this); Parent root = loginLoader.load(); Stage stage = (Stage)((Node)mouseEvent.getSource()).getScene().getWindow(); Scene scene = new Scene(root, 800, 600); stage.setTitle("Scheduler App"); stage.setScene(scene); stage.show(); } // helper methods for comboboxes public void populateEmployeeBox(MouseEvent event) { ArrayList<String> aList = model.returnFormattedEmployeeNames(); ObservableList<String> list = FXCollections.observableArrayList(); list.addAll(aList); ComboBox test = (ComboBox) event.getSource(); test.setItems(list); } public void populatePositionBox(MouseEvent event) { ArrayList<String> aList = model.returnPositions(); ObservableList<String> list = FXCollections.observableArrayList(); list.addAll(aList); ComboBox test = (ComboBox) event.getSource(); test.setItems(list); } public void removeEmployeeBoxClicked(MouseEvent event){ System.out.println("remove employee box clicked"); populateEmployeeBox(event); } public void populateDaysOfWeek(MouseEvent event){ List<String> times = Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"); ComboBox box = (ComboBox) event.getSource(); ObservableList<String> list = FXCollections.observableArrayList(times); box.setItems(list); } public void addShiftTimeBoxClicked(MouseEvent event){ ArrayList<String> times = new ArrayList<>(); for (int i = 8; i < 24; i++){ String j = i + "00"; String k = i + "30"; if (i < 10) { j = "0" + j; k = "0" + k; } times.add(j); times.add(k); } ComboBox box = (ComboBox) event.getSource(); ObservableList<String> list = FXCollections.observableArrayList(times); box.setItems(list); } public void availabilityTimeBoxClicked(MouseEvent event){ ArrayList<String> times = new ArrayList<>(); for (int i = 0; i < 24; i++){ String j = i + "00"; String k = i + "30"; if (i < 10) { j = "0" + j; k = "0" + k; } times.add(j); times.add(k); } ComboBox box = (ComboBox) event.getSource(); ObservableList<String> list = FXCollections.observableArrayList(times); box.setItems(list); } // other helper methods public void updateCurrentDate(Event event) throws Exception { currentDateText.setText("Current Date: " + model.date.toString()); currentDateTextAvail.setText("Current Date: " + model.date.toString()); } public void setModel(Model model) { this.model = model; } }