Skip to content

Commit

Permalink
Merge pull request #22 from hotungkhanh/kan-59/store-get-timetable
Browse files Browse the repository at this point in the history
KAN-59: setup to allow storage of timetable solutions
  • Loading branch information
hotungkhanh authored Sep 25, 2024
2 parents 032b94c + 96037a8 commit 3529c38
Show file tree
Hide file tree
Showing 13 changed files with 336 additions and 37 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"conventionalCommits.scopes": [
"database"
]
}
2 changes: 1 addition & 1 deletion backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ bin/
nb-configuration.xml

# Visual Studio Code
.vscode
.vscode/
.factorypath

# OSX
Expand Down
36 changes: 32 additions & 4 deletions backend/src/main/java/org/acme/TimetableResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ai.timefold.solver.core.api.solver.SolverManager;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
Expand Down Expand Up @@ -42,8 +43,16 @@ public Timetable handleRequest(Timetable problem) throws ExecutionException, Int
return solution;
}

@Path("/view")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Timetable> view() {
return Timetable.listAll();
}

@GET
@Transactional
@Produces(MediaType.APPLICATION_JSON)
public Timetable solveExample() throws ExecutionException, InterruptedException {

Student a = new Student("a");
Expand All @@ -60,12 +69,14 @@ public Timetable solveExample() throws ExecutionException, InterruptedException
Room r2 = new Room("Room2", 4, false);
Room r3 = new Room("Room3", 4, false);

Unit u1 = new Unit(1, "1", Duration.ofHours(2), List.of(a, b), true);
Unit u2 = new Unit(2, "2", Duration.ofHours(2), List.of(a, c, d, e), true);
Unit u3 = new Unit(3, "3", Duration.ofHours(2), List.of(f, g, h, i), false);
Unit u4 = new Unit(4, "4", Duration.ofHours(2), List.of(a, b), false);

var problem = new Timetable(
List.of(
new Unit(1, "1", Duration.ofHours(2), List.of(a, b), true),
new Unit(2, "2", Duration.ofHours(2), List.of(a, c, d, e), true),
new Unit(3, "3", Duration.ofHours(2), List.of(f, g, h, i), false),
new Unit(4, "4", Duration.ofHours(2), List.of(a, b), false)
u1, u2, u3, u4
// new Unit(5, "5", Duration.ofHours(2), List.of(c, d, e)),
// new Unit(6, "6", Duration.ofHours(2), List.of(f, g, h, i))
),
Expand All @@ -87,8 +98,25 @@ public Timetable solveExample() throws ExecutionException, InterruptedException
List.of(r1, r2, r3)
);

/*
* During this solving phase, new Unit objects will be created with the
* alloted date and Room assignment.
*
* Currently, the 'old' Unit objects in the 'problem' variable and the
* 'new' Unit objects in the 'solution' variable are stored as different
* Units in the database due to our inability to control the behaviour
* of solverManager.solve
*
* i.e. after solving, there will be 2 copies of each Unit in the
* database, where the 'old' Unit has the list of students but no
* timetable assignment, while the 'new' Unit does not have the list
* of students enrolled, but does have the assigned date and room
*/
Timetable solution = solverManager.solve("job 1", problem).getFinalBestSolution();

solution.persist();
// saves the solution timetable and all related entities to database

return solution;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.acme.schooltimetabling.domain;
package org.acme.domain;

// import java.util.List;
import jakarta.persistence.*;
Expand All @@ -9,11 +9,9 @@ public class Campus extends PanacheEntity {

public String name;

// empty constructor
public Campus() {
}

// constructor with name input
public Campus(String name) {
this.name = name;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.acme.schooltimetabling.domain;
package org.acme.domain;

import java.util.List;

Expand Down
53 changes: 44 additions & 9 deletions backend/src/main/java/org/acme/domain/Room.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,53 @@
package org.acme.domain;

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import ai.timefold.solver.core.api.domain.lookup.PlanningId;
import io.quarkus.hibernate.orm.panache.PanacheEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToMany;

/**
* Represents a room.
*
* @author Jet Edge
*/
public class Room {
@Entity
public class Room extends PanacheEntity {
@PlanningId
private String id;
public String roomCode;

public String buildingId;

public int capacity;

public boolean isLab;

private int capacity;
private boolean isLab;
/**
* A list of units that are taught in a Room
*/
@JsonIgnoreProperties("room")
@OneToMany(mappedBy = "room", orphanRemoval = false)
@JsonManagedReference
@JsonIgnore
public List<Unit> units = new ArrayList<Unit>();

/**
* A list of timetables that the Room is a part of
*/
@JsonIgnoreProperties("rooms")
@ManyToMany(mappedBy = "rooms", fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JsonManagedReference
@JsonIgnore
public List<Timetable> timetables = new ArrayList<Timetable>();

public Room() {
}
Expand All @@ -25,17 +60,17 @@ public Room() {
* @param isLab Whether the room is a laboratory.
*/
public Room(String id, int capacity, boolean isLab) {
this.id = id;
this.roomCode = id;
this.capacity = capacity;
this.isLab = isLab;
}

public String getId() {
return id;
public String getRoomCode() {
return roomCode;
}

public void setId(String id) {
this.id = id;
public void setRoomCode(String id) {
this.roomCode = id;
}

public int getCapacity() {
Expand Down
31 changes: 31 additions & 0 deletions backend/src/main/java/org/acme/domain/RoomResource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.acme.domain;

import java.util.List;

import jakarta.transaction.Transactional;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

@Path("/rooms")
public class RoomResource {

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Room> list() {
return Room.listAll();
}

@POST
@Transactional
@Consumes(MediaType.APPLICATION_JSON)
public Response createCampus(Room room) {
room.persist();
return Response.status(Response.Status.CREATED).entity(room).build();
}

}
30 changes: 28 additions & 2 deletions backend/src/main/java/org/acme/domain/Student.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
package org.acme.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import io.quarkus.hibernate.orm.panache.PanacheEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;

/**
* Represents a student.
*
* @author Jet Edge
*/
public class Student {
@Entity
public class Student extends PanacheEntity{

// String studentID;

String name;
public String name;

@JsonIgnoreProperties("students")
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinTable(
name = "student_unit",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "unit_id")
)
@JsonManagedReference
@JsonIgnore
public List<Unit> units = new ArrayList<Unit>();

public Student() {
}
Expand Down
29 changes: 29 additions & 0 deletions backend/src/main/java/org/acme/domain/StudentResource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.acme.domain;

import java.util.List;

import jakarta.transaction.Transactional;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

@Path("/students")
public class StudentResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Student> list() {
return Student.listAll();
}

@POST
@Transactional
@Consumes(MediaType.APPLICATION_JSON)
public Response createCampus(Student student) {
student.persist();
return Response.status(Response.Status.CREATED).entity(student).build();
}
}
Loading

0 comments on commit 3529c38

Please sign in to comment.