Newer
Older
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.*;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
@FXML
BorderPane myBorderPane;
@FXML
VBox leftSideButtons;
@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 addShiftStartTimeBox;
@FXML
ComboBox addShiftEndTimeBox;
Label loggedIn;
@FXML
Label viewing;
@FXML
Label loginWarning;
TextField editEmployeeFirstName;
@FXML
TextField editEmployeeLastName;
@FXML
TextField editEmployeeEmail;
@FXML
TextField editEmployeeWage;
@FXML
TextField editEmployeePhoneNumber;
@FXML
TextField editEmployeeAddress;
@FXML
ComboBox editEmployeeBox;
@FXML
CheckBox editEmployeeManager;
@FXML
ArktikHunter
committed
DatePicker timeOffDatePicker;
@FXML
@FXML
Label currentDateTextAvail;
@FXML
ComboBox<String> availabilityDayBox;
@FXML
ComboBox<String> editAvailabilityStartBox;
@FXML
ComboBox<String> editAvailabilityEndBox;
@FXML
Label availabilityResult;
Label addShiftError;
@FXML
ComboBox editEmployeePositions;
@FXML
ComboBox<String> addShiftPositionBox;
@FXML
TextArea timeOffReasonBox;
@FXML
DatePicker timeOffDateStart;
@FXML
DatePicker timeOffDateEnd;
@FXML
Label timeOffLabel;
boolean isDaily;
ArktikHunter
committed
Stage popupAvailStage;
Scene popupAvail;
Stage popupTimeOffStage;
Scene popupTimeOff;
ArktikHunter
committed
DailyView dailyView;
WeeklyView weeklyView;
EmployeeView employeeView;
ArktikHunter
committed
BorderPane root;
Parent header;
Parent sideSchedulePanel;
ArktikHunter
committed
Parent bottomPanel;
Parent paystubView;
Parent editEmployeeView;
Parent addEmployeeView;
Parent staffPanel;
ArktikHunter
committed
Parent availabilityPanel;
Parent removeEmployeeView;
DatePicker jumpDatePicker;
// 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
ArktikHunter
committed
root.setTop(header);
Stage stage = (Stage)((Node)e.getSource()).getScene().getWindow();
Scene scene = new Scene(root, 800, 600);
stage.setTitle("Scheduler App");
stage.setScene(scene);
stage.show();
updateCurrentDate(e);
loggedIn.setText("Logged In: " + model.getEmployee(model.getThisEmployee()).toString());
//set manager specific text
if (model.getIsManager()){
ArktikHunter
committed
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);
//pickupView = new PickupView();
//pickupView.setModel(model);
//fxml views
loadHeader();
loadScheduleSide();
loadScheduleBottom();
loadPaystubView();
loadEditEmployee();
loadStaffPanel();
ArktikHunter
committed
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.setCenter(dailyView);
isDaily = true;
// schedule -> weekly
public void viewScheduleWeekly(){
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);
//schedule popups
ArktikHunter
committed
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(LocalDate start, LocalDate end) throws IOException {
String[][] payrollInfo = getPayrollInfo(model.getSelectedEmployee(),start,end);
double grossPay = 0;
double totalHours = 0;
for(int i = 0; i < payrollInfo.length; i++){
HBox tempHBox = new HBox();
tempHBox.setSpacing(50);
tempHBox.setBorder(new Border(new BorderStroke(Color.BLACK,
BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
Label position = new Label("Position: " + payrollInfo[i][0]);
Label hours = new Label("Hours Worked: " + payrollInfo[i][1]);
Label wage = new Label("Wage: " + payrollInfo[i][2]);
Label totalPay = new Label("Total Pay: " + payrollInfo[i][3]);
tempHBox.getChildren().addAll(position,hours,wage,totalPay);
paystubVBox.getChildren().add(tempHBox);
grossPay += Double.parseDouble(payrollInfo[i][3]);
totalHours += Double.parseDouble(payrollInfo[i][1]);
}
HBox totalHBox = new HBox();
totalHBox.setSpacing(50);
totalHBox.getChildren().add(new Label("Total Hours Worked: " + totalHours));
totalHBox.getChildren().add(new Label("Gross Pay: " + grossPay));
paystubVBox.getChildren().add(totalHBox);
root.setCenter(paystubVBox);
public void showPaystubDatePicker(){
DatePicker startDatePicker = new DatePicker();
DatePicker endDatePicker = new DatePicker();
Button confirmButton = new Button("Confirm");
VBox tempVBox = new VBox(new Label("Choose Start Date Of Pay Period"),startDatePicker,
new Label("Choose End Date of Pay Period"),endDatePicker,confirmButton);
Scene tempScene = new Scene(tempVBox,400,400);
Stage tempStage = new Stage();
tempStage.setScene(tempScene);
tempStage.show();
confirmButton.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
try {
viewPaystub(startDatePicker.getValue(),endDatePicker.getValue());
} catch (IOException e) {
e.printStackTrace();
}
tempStage.close();
}
});
}
private String[][] getPayrollInfo(int selectedEmployee,LocalDate start,LocalDate end) {
LocalDateTime startDate = LocalDateTime.of(start, LocalTime.MIN);
LocalDateTime endDate = LocalDateTime.of(end,LocalTime.MAX);
ArrayList<Shift> shiftsThisWeek = model.getEmployeeShiftsByWeek(selectedEmployee,startDate,endDate);
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
HashMap<String , Double> hoursWorked = new HashMap<String, Double>();
DecimalFormat df = new DecimalFormat("0.00");
for(int i = 0; i < shiftsThisWeek.size(); i++){
Shift tempShift = shiftsThisWeek.get(i);
LocalDateTime startTime = tempShift.getStart();
LocalDateTime endTime = tempShift.getEnd();
String position = tempShift.getPosition();
int startHour = startTime.getHour();
int startMin = startTime.getMinute();
int endHour = endTime.getHour();
int endMin = endTime.getMinute();;
double newHours = endHour - startHour;
double minRemainder;
if(!hoursWorked.containsKey(position)){
hoursWorked.put(position,newHours);
}
else{
double oldHours = hoursWorked.get(position);
if(endMin - startMin == 0){
minRemainder = 0;
}
else{
minRemainder = 0.5;
}
hoursWorked.replace(position,oldHours + newHours + minRemainder);
}
}
String [][] result = new String[hoursWorked.size()][4];
int index = 0;
for (Map.Entry<String, Double> entry : hoursWorked.entrySet()) {
String position = entry.getKey();
double hours = entry.getValue();
Float wage = model.getWage(position);
result[index][0] = position;
result[index][1] = String.valueOf(hours);
result[index][2] = String.valueOf(wage);
result[index][3] = String.valueOf(df.format(wage * hours));
index++;
}
return result;
// Payroll tab (manager only)
// 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);
// Requests tab (manager only)
public void viewRequests() {
System.out.println("todo: display requests");
//methods for submitting data
ArktikHunter
committed
public void submitTimeOff(MouseEvent event){
timeOffLabel.setText(model.addTimeOff(model.getSelectedEmployee(), timeOffDateStart.getValue().toString(),
timeOffDateEnd.getValue().toString(), timeOffReasonBox.getText()));
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();
String position = addShiftPositionBox.getValue();
addShiftError.setText(model.addShift(model.getIDbyIndex(index),date.toString(),Integer.parseInt(startTime),
Integer.parseInt(endTime), position));
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 + "!");
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();
public void jumpButtonClicked (MouseEvent event) throws Exception {
System.out.println("jump button clicked");
jumpDatePicker = new DatePicker();
Scene tempScene = new Scene(jumpDatePicker);
Stage tempStage = new Stage();
tempStage.setScene(tempScene);
tempStage.show();
jumpDatePicker.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
model.dateJump(jumpDatePicker.getValue());
try {
updateCurrentDate(actionEvent);
} catch (Exception e) {
e.printStackTrace();
}
}
});
ArktikHunter
committed
//model.dateJump();
public void jumpDatePicked(){
model.dateJump(jumpDatePicker.getValue());
}
public void nextButtonClicked (MouseEvent event) throws Exception {
if (isDaily) model.dateNext();
else model.weekNext();
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) {
ObservableList<String> list = FXCollections.observableArrayList();
ComboBox temp = (ComboBox) event.getSource();
if(event.getSource() == editEmployeeBox){
System.out.println("test");
}
temp.setItems(list);
public void populatePositionBox(MouseEvent event) {
ComboBox test = (ComboBox) event.getSource();
test.setItems(FXCollections.observableArrayList(model.returnPositions()));
ArktikHunter
committed
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;
}
public void fillEditEmployee(){
int boxIndex = editEmployeeBox.getSelectionModel().getSelectedIndex();
if(boxIndex >= 0){
int index = model.getIDbyIndex(boxIndex);
Employee currentEmployee = model.getEmployee(index);
editEmployeeFirstName.setText(currentEmployee.getFirstName());
editEmployeeLastName.setText(currentEmployee.getLastName());
editEmployeeManager.setSelected(currentEmployee.isManager());
editEmployeeEmail.setText(currentEmployee.getEmail());
editEmployeePhoneNumber.setText(currentEmployee.getPhoneNumber());
System.out.println(currentEmployee.getPositions());
}
}
public void addRemovePosition(){
VBox tempBox = new VBox();
tempBox.setPadding(new Insets(20));
tempBox.setSpacing(20);
ComboBox tempCombo = new ComboBox();
Button addPosition = new Button("Add Position");
Button removePosition = new Button("Remove Position");
Label result = new Label("");
tempBox.getChildren().addAll(tempCombo,addPosition,removePosition, result);
tempCombo.setOnMouseClicked(this::populatePositionBox);
addPosition.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
VBox tempVBox = new VBox();
tempVBox.setSpacing(20);
tempVBox.setPadding(new Insets(30));
TextField tempPositionText = new TextField("Enter Position Here");
TextField tempWageText = new TextField("Enter Wage Here");
Button addPositionSubmit = new Button("Submit");
tempVBox.getChildren().addAll(tempPositionText,tempWageText,addPositionSubmit);
Scene tempScene = new Scene(tempVBox);
Stage tempStage = new Stage();
tempStage.setScene(tempScene);
tempStage.show();
addPositionSubmit.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
System.out.println("add position submit clicked");
System.out.println(model.addPosition(tempPositionText.getText(),Float.parseFloat(tempWageText.getText())));
tempStage.close();
}
});
}
});
removePosition.setOnMouseClicked(e -> {
if (tempCombo.getValue() == null) result.setText("No position selected.");
else result.setText(model.removePosition(tempCombo.getSelectionModel().getSelectedItem().toString()));
});
root.setCenter(tempBox);
}