Skip to content

Commit

Permalink
Add academic context to chosen schedule date. (nusCS2113-AY1920S1#83)
Browse files Browse the repository at this point in the history
* Add schedule command

* Yellow flag handling

* Add ui to show schedule

* Add ViewSchedule command

* Add view schedule message

* Add command allowing user to view time specific tasks

* Change Date states to public

* Change Date states to public

* Add test for ViewScheduleCommand

* Add ViewScheduleCommand

* Change back to private states

* Change back to private states

* Add test for ViewScheduleCommand

* Add overload showSearchResult method

* Add ViewScheduleCommand

* ViewScheduleCommand displays separate events and deadlines for any given time period

* ViewScheduleCommand displays separate events and deadlines for any given time period

* Add getDate methods

* Add getDate methods

* Add ViewScheduleCommand

* Add javadoc

* Add javadoc

* Add javadoc

* Organise imports

* Expand imports for checkstyle :(

* Bug fix

* Add abstract boolean isWithinTimeFrame

* Change schedule ui

* Add abstract method isWithinTimeFrame

* Add abstract method isWithinTimeFrame

* Add abstract method isWithinTimeFrame

* Test ViewScheduleCommand

* Add new abtract method isWithinTimeFrame

* Add new abtract method isWithinTimeFrame

* Add new abtract method isWithinTimeFrame

* Add Schedule for printing time table

* Add ViewScheduleCommand

* Add timetable interface

* Add abstract Schedule method

* Add abstract Schedule method

* Add abstract Schedule method

* Add abstract Schedule method

* Organise imports

* Update with ui image, features and commands

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Update

* Add javadoc and format code

* Change nested loop

* Add javadoc

* Organise imports

* Organise imports

* im so technically challenged

* Add test for Schedule

* Add test for Schedule

* Update features and commands

* update link to Ui.png

* test

* test

* test

* test

* test

* test

* test

* test

* image

* image

* image

* image

* update

* update

* update

* update

* update

* update

* refactor Schedule to TimeFrame

* Add implements Comparable<TimeFrame>

* 092919 ui fix (nusCS2113-AY1920S1#2)

* udate

* udate

* refactor Schedule to TimeFrame

* update

* update

* update change in schedule command

* fix merge conflict and bug

* minor code change

* merge to latest (nusCS2113-AY1920S1#3)

* refactor Schedule to TimeFrame

* Add implements Comparable<TimeFrame>

* 092919 ui fix (nusCS2113-AY1920S1#2)

* udate

* udate

* refactor Schedule to TimeFrame

* Refactor Schedule class to TimeFrame  (nusCS2113-AY1920S1#40)

* Refactor TimeFrame class (nusCS2113-AY1920S1#42)

* Reimplement TimeFrameClass

* Refactor ViewScheduleCommand

* Allow for instantaneous tasks

* Implement printing of schedule

* update

* update

* update change in schedule command

* fix merge conflict and bug

* minor code change

* add academic context to date

* modify ViewScheduleCommand to accept date range

* add academic context to date

* Add date context (nusCS2113-AY1920S1#4)

* refactor Schedule to TimeFrame

* Add implements Comparable<TimeFrame>

* 092919 ui fix (nusCS2113-AY1920S1#2)

* udate

* udate

* refactor Schedule to TimeFrame

* Refactor Schedule class to TimeFrame  (nusCS2113-AY1920S1#40)

* Refactor TimeFrame class (nusCS2113-AY1920S1#42)

* Reimplement TimeFrameClass

* Refactor ViewScheduleCommand

* Allow for instantaneous tasks

* Implement printing of schedule

* update

* update

* update change in schedule command

* fix merge conflict and bug

* minor code change

* add academic context to date

* modify ViewScheduleCommand to accept date range

* add academic context to date

* update to latest (nusCS2113-AY1920S1#5)

* merge to latest (nusCS2113-AY1920S1#3)

* refactor Schedule to TimeFrame

* Add implements Comparable<TimeFrame>

* 092919 ui fix (nusCS2113-AY1920S1#2)

* udate

* udate

* refactor Schedule to TimeFrame

* Refactor Schedule class to TimeFrame  (nusCS2113-AY1920S1#40)

* Refactor TimeFrame class (nusCS2113-AY1920S1#42)

* Reimplement TimeFrameClass

* Refactor ViewScheduleCommand

* Allow for instantaneous tasks

* Implement printing of schedule

* update

* update

* update change in schedule command

* fix merge conflict and bug

* minor code change

* Add date context (nusCS2113-AY1920S1#4)

* refactor Schedule to TimeFrame

* Add implements Comparable<TimeFrame>

* 092919 ui fix (nusCS2113-AY1920S1#2)

* udate

* udate

* refactor Schedule to TimeFrame

* Refactor Schedule class to TimeFrame  (nusCS2113-AY1920S1#40)

* Refactor TimeFrame class (nusCS2113-AY1920S1#42)

* Reimplement TimeFrameClass

* Refactor ViewScheduleCommand

* Allow for instantaneous tasks

* Implement printing of schedule

* update

* update

* update change in schedule command

* fix merge conflict and bug

* minor code change

* add academic context to date

* modify ViewScheduleCommand to accept date range

* add academic context to date

* add week view

* update with V2.0 features

* update with V2.0 features

* improve code quality

* refactor Date to LocalDateTime, fix bug causing incorrect date resets

* Add week view

* Update javadoc

* remove time run

* remove time run

* Merge branch 'master' of https://github.com/AY1920S1-CS2113T-T09-2/main into add_weekView

# Conflicts:
#	src/main/java/Duke.java
#	src/main/java/duchess/logic/commands/ViewScheduleCommand.java

* fix checkstyle indentation

* add academic context to date

* update

* update

* update

* update

* update

* update

* update

* update

* add junit tests

* fix checkstyle

* fix checkstyle

* edit according to review

* change according to requested changes
  • Loading branch information
limsiying authored Oct 8, 2019
1 parent 134798b commit adfc845
Show file tree
Hide file tree
Showing 19 changed files with 310 additions and 78 deletions.
7 changes: 5 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
= Duchess
![alt text](https://github.com/AY1920S1-CS2113T-T09-2/main/blob/master/docs/images/Ui.PNG)

image::https://travis-ci.org/AY1920S1-CS2113T-T09-2/main.svg?branch=master[]

image::docs/images/Ui.png[]

* Duchess is a calendar application tailor-made for NUS students.
* It provides an interface for students to manage both their school and extra-curriculum commitments while providing academic contextual information.
Expand All @@ -13,4 +16,4 @@

== Acknowledgements
* This application is a morph of the CS2113 Duke application.
* Libraries used:
* Libraries used: https://github.com/FasterXML/jackson[Jackson]
31 changes: 29 additions & 2 deletions docs/UserGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Duchess is a calendar application tailor-made for NUS students. Duchess closes t
. Copy the file to the folder you want to use as the home folder for your Calendar.
. Double-click the file to start the app.
+
image::Ui.PNG[]
image::Ui.png[]
+
. Type a command in the input field and press kbd:[Enter] to execute it.
. Refer to <<Features>> for details of all commands.
Expand Down Expand Up @@ -227,10 +227,37 @@ Noted. I've snoozed this task:
[D][✘] health and wellness transcript (by: 26/09/2019 0800)
```

=== Saving the data

Duchess data are saved in the hard disk automatically after any command that changes the data.

=== Add recurring task: `[coming in V2.0]`

Add recurring task to task list.

* Recurring task can be tagged by user. eg `tutorial`, `lab`, `lecture`
* Recurring task will be repeated on a time basis as defined by user.

=== Auto-scheduling: `[coming in V2.0]`

Adds task to timetable according to user-defined time constraints.

=== Display task list as timetable: `[coming in V2.0]`

Displays task list as timetable instead of list format.

=== Export task list and timetable: `[coming in V2.0]`

Save task list and timetable view of task list in text file on local hard disk.

=== Undo command: `[coming in V2.0]`

Undoes the most recent command entered.

== FAQ

*Q*: Am I able to export my schedule from command line? +
*A*: All schedules are saved in a text file which can be accessed outside of CLI.
*A*: `[coming in V2.0]` All schedules are saved in a text file which can be accessed outside of CLI.

== Command Summary

Expand Down
Binary file removed docs/images/Ui.PNG
Binary file not shown.
Binary file added docs/images/Ui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/main/java/duchess/logic/commands/AddModuleCommand.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package duchess.logic.commands;

import duchess.exceptions.DuchessException;
import duchess.model.Module;
import duchess.storage.Storage;
import duchess.storage.Store;
import duchess.ui.Ui;
import duchess.model.Module;

import java.util.List;

Expand Down
33 changes: 13 additions & 20 deletions src/main/java/duchess/logic/commands/ViewScheduleCommand.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package duchess.logic.commands;

import duchess.exceptions.DuchessException;
import duchess.model.AcademicContext;
import duchess.model.TimeFrame;
import duchess.model.task.Task;
import duchess.storage.Storage;
Expand All @@ -18,44 +19,34 @@
import java.util.stream.Collectors;

public class ViewScheduleCommand extends Command {
private List<String> words;
private String date;
private String view;
private TimeFrame timeFrame;
private AcademicContext academicContext;

/**
* Constructor for class.
*
* @param words User input with start and end date time
* @param date Date
* @param view Either week or day
* @throws DuchessException Exception thrown for invalid or missing date time
*/
public ViewScheduleCommand(List<String> words) throws DuchessException {
this.words = words;
this.date = processString("/for");
this.view = processString("view");
if (!view.equals("day") && !view.equals("week")) {
throw new DuchessException("Invalid view. Please choose either day or week view.");
}
public ViewScheduleCommand(String date, String view) throws DuchessException {
this.date = date;
this.view = view;
LocalDateTime start = processDate(" 0000");
LocalDateTime end = processDate(" 2359");
this.academicContext = new AcademicContext(start);
this.timeFrame = new TimeFrame(start, end);
}

private String processString(String keyword) throws DuchessException {
int index = words.indexOf(keyword);
if (index == -1) {
throw new DuchessException("Format for viewing schedule: schedule /for <date> view <view>");
}
return words.get(index + 1);
}

/**
* Process date by setting time of LocalDateTime to either 0000 or 2359.
* Also sets LocalDateTime to nearest previous or same Monday date/ nearest
* next or same Friday date if user desires week view.
*
* @param time either " 0000" or " 2359" to indicate timeframe
* @return the LocalDateTime instance
* @return LocalDateTime
* @throws DuchessException Thrown for invalid or missing date time and command format
*/
private LocalDateTime processDate(String time) throws DuchessException {
Expand All @@ -64,6 +55,7 @@ private LocalDateTime processDate(String time) throws DuchessException {
boolean isStartOfDay = time.equals(" 0000");
boolean isStartOfWeek = isWeek && isStartOfDay;
boolean isEndOfWeek = isWeek && !isStartOfDay;

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HHmm")
.withResolverStyle(ResolverStyle.STRICT);
LocalDateTime localDateTime = LocalDateTime.parse(date + time, formatter);
Expand Down Expand Up @@ -91,9 +83,10 @@ public void execute(Store store, Ui ui, Storage storage) throws DuchessException
if (tasksForToday.size() <= 0) {
throw new DuchessException("There are no tasks in the schedule.");
} else if (view.equals("week")) {
date = "the week with " + date;
date = "the week of " + date;
}
Collections.sort(tasksForToday);
ui.showScheduleResult(tasksForToday, date);
ui.showScheduleResult(tasksForToday, date, academicContext.getAcademicContext()
);
}
}
13 changes: 12 additions & 1 deletion src/main/java/duchess/logic/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,18 @@ public static Command parse(String input) throws DuchessException {
case "snooze":
return new SnoozeCommand(arguments);
case "schedule":
return new ViewScheduleCommand(arguments);
try {
String view = words.get(2);
boolean isInvalidView = !view.equals("day") && !view.equals("week");
boolean isIllegalArgument = isInvalidView && (words.size() > 3);
if (isIllegalArgument) {
throw new IllegalArgumentException();
}
String date = words.get(1);
return new ViewScheduleCommand(date, view);
} catch (IndexOutOfBoundsException e) {
throw new DuchessException("Usage: schedule <date> (day | week)");
}
case "bye":
return new ByeCommand();
case "log":
Expand Down
126 changes: 126 additions & 0 deletions src/main/java/duchess/model/AcademicContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package duchess.model;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;

public class AcademicContext {
private LocalDate localDate;
private LocalDate startDate;
private LocalDate endDate;
private String academicYear;
private String academicWeek;
private String semester;
private static final double week = 7.0;

/**
* Set academic context based on given date.
*
* @param localDateTime date
*/
public AcademicContext(LocalDateTime localDateTime) {
this.localDate = localDateTime.toLocalDate();
this.startDate = localDate;
this.endDate = localDate;
this.semester = processSemester();
this.academicWeek = processAcademicWeek();
this.academicYear = processAcademicYear();
}

/**
* Returns start or end date of a semester.
*
* @param month Month semester starts in
* @param end Start or end of semester
* @return LocalDate with year corresponding to constructor parameter localDateTime
*/
private LocalDate processDate(Month month, boolean end) {
LocalDate temp = localDate.with(month).with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));
if (end) {
temp = temp.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)).plusWeeks(16);
}
return temp;
}

private String processSemester() {
LocalDate semOneStart = processDate(Month.AUGUST, false);
LocalDate semOneEnd = processDate(Month.AUGUST, true);
LocalDate semTwoStart = processDate(Month.JANUARY, false);
LocalDate semTwoEnd = processDate(Month.JANUARY, true);
boolean isSemesterOne = localDate.compareTo(semOneStart) >= 0 && localDate.compareTo(semOneEnd) <= 0;
boolean isSemesterTwo = localDate.compareTo(semTwoStart) >= 0 && localDate.compareTo(semTwoEnd) <= 0;
boolean isSummerBreak = localDate.isAfter(semTwoEnd) && localDate.isBefore(semOneStart);

if (isSemesterOne) {
this.startDate = semOneStart;
return "Semester 1";
} else if (isSemesterTwo) {
this.startDate = semTwoStart;
return "Semester 2";
} else if (isSummerBreak) {
this.endDate = semOneStart;
return "Summer Break";
}
if (localDate.getMonth() == Month.DECEMBER) {
this.endDate = semTwoStart.plusYears(1).with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));
} else {
this.endDate = semTwoStart;
}
return "Winter Break";
}

private String processAcademicWeek() {
boolean isSchoolTerm = semester.equals("Semester 1") || semester.equals("Semester 2");

long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
if (isSchoolTerm) {
daysBetween++;
}
int currWeek = (int) Math.ceil(daysBetween / week);
if (isSchoolTerm) {
switch (currWeek) {
case 7:
return "Recess Week";
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
return "W" + (currWeek - 1);
case 15:
return "Reading Week";
case 16:
case 17:
return "Examinations";
default:
return "W" + currWeek;
}
}
if (currWeek == 1) {
return "last week of break before a new semester starts";
} else {
return currWeek + " weeks left to the next semester";
}
}

private String processAcademicYear() {
int currYear = localDate.getYear();
boolean isFirstHalf = semester.equals("Semester 1")
|| (semester.equals("Winter Break") && localDate.getMonth() == Month.DECEMBER);

if (isFirstHalf) {
return "AY" + currYear + "/" + (currYear + 1);
} else {
return "AY" + (currYear - 1) + "/" + currYear;
}
}

public String getAcademicContext() {
return academicYear + ", " + semester + ", " + academicWeek;
}
}
2 changes: 1 addition & 1 deletion src/main/java/duchess/storage/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonSetter;
import duchess.model.task.Task;
import duchess.model.Module;
import duchess.model.task.Task;

import java.util.ArrayList;
import java.util.List;
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/duchess/ui/Ui.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

package duchess.ui;

import duchess.model.task.Task;
import duchess.model.Module;
import duchess.model.task.Task;

import java.util.List;
import java.util.Scanner;
Expand Down Expand Up @@ -63,7 +63,7 @@ public void showError(String message) {
/**
* Displays the newly added module as well as other modules.
*
* @param module newly added module
* @param module newly added module
* @param modules existing modules
*/
public void showModuleAdded(Module module, List<Module> modules) {
Expand Down Expand Up @@ -127,7 +127,8 @@ public void showSearchResult(List<Task> tasks) {
* @param tasks List of tasks to show
* @param date Date
*/
public void showScheduleResult(List<Task> tasks, String date) {
public void showScheduleResult(List<Task> tasks, String date, String academicContext) {
printIndented(academicContext);
printIndented("Here is your schedule for " + date + ":");
int counter = 1;
for (Task t : tasks) {
Expand Down
Loading

0 comments on commit adfc845

Please sign in to comment.