Skip to content

Commit

Permalink
wip: float courses
Browse files Browse the repository at this point in the history
  • Loading branch information
iamareebjamal committed Nov 23, 2018
1 parent e1c2df0 commit 12e850e
Show file tree
Hide file tree
Showing 33 changed files with 730 additions and 23 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"datatables.net-buttons": "^1.5.4",
"datatables.net-buttons-bs4": "^1.5.4",
"datatables.net-select": "^1.2.7",
"datatables.net-select-bs4": "^1.2.7"
"datatables.net-select-bs4": "^1.2.7",
"hyperapp": "^1.2.9"
}
}
7 changes: 6 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@ async function getConfig() {
minimize: isProdBuild,
plugins: []
}),
buble({
objectAssign: 'Object.assign',
jsx: 'h'
}),
resolve()
];
const plugins = isProdBuild ?
[
...commonPlugins,
buble({
objectAssign: 'Object.assign'
objectAssign: 'Object.assign',
jsx: 'h'
}),
terser()
] :
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package amu.zhcet.core.admin.dean.registration.course.floated;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/admin/dean/float")
public class FloatCoursesController {

@GetMapping
public String floatCourse(Model model) {
model.addAttribute("page_title", "Float Courses");
model.addAttribute("page_subtitle", "Float courses using CSV");
model.addAttribute("page_description", "Upload courses CSV to float courses in current session");

return "dean/float-course";
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
package amu.zhcet.core.admin.dean.registration.course.floated;

import amu.zhcet.storage.csv.neo.Confirmation;
import amu.zhcet.storage.csv.neo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@Slf4j
@RestController
@RequestMapping("/api/test")
public class FloatedCourseRegistrationController {

private final FloatedCourseRegistrationService floatedCourseRegistrationService;

public FloatedCourseRegistrationController(FloatedCourseRegistrationService floatedCourseRegistrationService) {
this.floatedCourseRegistrationService = floatedCourseRegistrationService;
}

@PostMapping
public Result<FloatedCourseUpload> test(@RequestParam(required = false) MultipartFile file) throws IOException {
return floatedCourseRegistrationService.parse(file);
}

@PostMapping("confirm")
public Confirmation testConfirm(@RequestBody ItemState itemState) throws IOException {
return floatedCourseRegistrationService.confirm(itemState);
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,161 @@
package amu.zhcet.core.admin.dean.registration.course.floated;

import amu.zhcet.data.config.ConfigurationService;
import amu.zhcet.data.course.Course;
import amu.zhcet.data.course.CourseLite;
import amu.zhcet.data.course.CourseRepository;
import amu.zhcet.data.course.floated.FloatedCourse;
import amu.zhcet.data.course.floated.FloatedCourseLite;
import amu.zhcet.data.course.floated.FloatedCourseLiteImpl;
import amu.zhcet.data.course.floated.FloatedCourseRepository;
import amu.zhcet.storage.csv.neo.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.transaction.Transactional;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FloatedCourseRegistrationService {

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CourseResponse {
private String code;
private String title;
private String department;
}

private final FloatedCourseRepository floatedCourseRepository;
private final CourseRepository courseRepository;

private final FileStorageCsvParser floatedCourseCsvParser;

private final ModelMapper modelMapper;

public FloatedCourseRegistrationService(FloatedCourseRepository floatedCourseRepository, CourseRepository courseRepository, FileStorageCsvParser floatedCourseCsvParser, ModelMapper modelMapper) {
this.floatedCourseRepository = floatedCourseRepository;
this.courseRepository = courseRepository;
this.floatedCourseCsvParser = floatedCourseCsvParser;
this.modelMapper = modelMapper;
}

public List<FloatedCourseLite> get(Collection<String> codes) {
String defaultSessionCode = ConfigurationService.getDefaultSessionCode();

return floatedCourseRepository.getBySessionAndCourse_CodeIn(defaultSessionCode, codes);
}

public Result<FloatedCourseUpload> parse(MultipartFile file) throws IOException {
Result<FloatedCourseUpload> uploadResult = floatedCourseCsvParser.parse(FloatedCourseUpload.class, file);

if (uploadResult.isParsed() && uploadResult.getCsv().isSuccessful()) {
return getWrappedResult(uploadResult);
}

return uploadResult;
}

@Data
@EqualsAndHashCode(callSuper = true)
public static class FloatedCourseConfirmation extends Confirmation {
private Collection<FloatedCourseLite> floated;

public FloatedCourseConfirmation(boolean success, String message, Collection<FloatedCourseLite> floated) {
super(success, message);
this.floated = floated;
}
}

@Transactional
public Confirmation confirm(ItemState itemState) {
List<Wrapper<CourseResponse>> wrappers = getWrappedCourses(new LinkedHashSet<>(itemState.getItems()));
State newState = State.fromWrappers(wrappers);

boolean matchingState = newState.isMatching(itemState.getState());
log.debug("Is new state same as old state? {}", matchingState);

if (!matchingState) {
return new Confirmation(false, "Something went wrong! Please try again");
} else {
log.debug("Floating course requests {}", wrappers);
Set<String> validCodes = wrappers.stream()
.filter(item -> item.getMessage() == null || item.getMessage().getType() == Type.SUCCESS)
.map(item -> item.getItem().getCode())
.collect(Collectors.toCollection(LinkedHashSet::new));

log.debug("Floating courses {}", validCodes);
List<Course> courses = courseRepository.findAllByCodeIn(validCodes);
List<FloatedCourse> floatedCourses = courses.stream()
.map(course -> new FloatedCourse(ConfigurationService.getDefaultSessionCode(), course))
.collect(Collectors.toList());
Iterable<FloatedCourse> floated = floatedCourseRepository.saveAll(floatedCourses);

List<FloatedCourseLite> floatedCourseLites = new ArrayList<>();
floated.forEach(floatedCourse -> {
floatedCourseLites.add(modelMapper.map(floatedCourse, FloatedCourseLiteImpl.class));
});

return new FloatedCourseConfirmation(true, "Courses floated successfully", floatedCourseLites);
}
}

private WrappedResult<FloatedCourseUpload, CourseResponse> getWrappedResult(Result<FloatedCourseUpload> uploadResult) {
Set<String> codes = uploadResult.getCsv().getItems().stream()
.map(FloatedCourseUpload::getCourse)
.collect(Collectors.toCollection(LinkedHashSet::new));

List<Wrapper<CourseResponse>> wrappers = getWrappedCourses(codes);

State state = State.fromWrappers(wrappers);
log.debug("Floated Course State {}", state);
log.debug("Is valid state? {}", state.isValid());
return new WrappedResult<>(uploadResult, wrappers, state);
}

private List<Wrapper<CourseResponse>> getWrappedCourses(Set<String> codes) {
List<FloatedCourseLite> floatedCourseLites = get(codes);
List<CourseLite> courses = courseRepository.getByCodeIn(codes);

return codes.stream().map(item -> {
Optional<FloatedCourseLite> floatedCourseLiteOptional = floatedCourseLites.stream()
.filter(floatedCourse -> floatedCourse.getCourse().getCode().equals(item))
.findAny();

if (floatedCourseLiteOptional.isPresent()) {
FloatedCourseLite floatedCourseLite = floatedCourseLiteOptional.get();
CourseResponse courseResponse = new CourseResponse(floatedCourseLite.getCourse().getCode(), floatedCourseLite.getCourse().getTitle(), floatedCourseLite.getCourse().getDepartment().getName());
return new Wrapper<>(courseResponse, Message.warning("Course is already floated"));
}

Optional<CourseLite> courseLiteOptional = courses.stream()
.filter(courseLite -> courseLite.getCode().equals(item))
.findAny();

if (courseLiteOptional.isPresent()) {
CourseLite courseLite = courseLiteOptional.get();


CourseResponse courseResponse = new CourseResponse(courseLite.getCode(), courseLite.getTitle(), courseLite.getDepartment().getName());
if (!courseLite.isActive()) {
return new Wrapper<>(courseResponse, Message.error("Course is inactive"));
} else {
return new Wrapper<>(courseResponse);
}
} else {
return new Wrapper<>(new CourseResponse(item, null, null), Message.error("Course does not exist"));
}
}).collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package amu.zhcet.core.admin.dean.registration.course.floated;

import com.j256.simplecsv.common.CsvColumn;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class FloatedCourseUpload {
@CsvColumn
private String course;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package amu.zhcet.core.admin.dean.registration.course.floated;

import amu.zhcet.storage.csv.neo.State;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
public class ItemState {
private List<String> items;
private State state;
}
8 changes: 7 additions & 1 deletion src/main/java/amu/zhcet/data/course/CourseLite.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
package amu.zhcet.data.course;

public class CourseLite {
import amu.zhcet.data.department.DepartmentLite;

public interface CourseLite {
String getCode();
String getTitle();
boolean isActive();
DepartmentLite getDepartment();
}
12 changes: 12 additions & 0 deletions src/main/java/amu/zhcet/data/course/CourseLiteImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package amu.zhcet.data.course;

import amu.zhcet.data.department.DepartmentLiteImpl;
import lombok.Data;

@Data
public class CourseLiteImpl implements CourseLite {
private String code;
private String title;
private boolean active;
private DepartmentLiteImpl department;
}
6 changes: 6 additions & 0 deletions src/main/java/amu/zhcet/data/course/CourseRepository.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package amu.zhcet.data.course;

import amu.zhcet.data.course.floated.FloatedCourseLite;
import amu.zhcet.data.department.Department;
import org.springframework.data.repository.CrudRepository;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

Expand All @@ -14,4 +16,8 @@ public interface CourseRepository extends CrudRepository<Course, String> {

List<Course> findByDepartmentAndActive(Department department, Boolean active);

List<Course> findAllByCodeIn(Collection<String> ids);

List<CourseLite> getByCodeIn(Collection<String> ids);

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
package amu.zhcet.data.course.floated;

public class FloatedCourseLite {
import amu.zhcet.data.course.CourseLite;

public interface FloatedCourseLite {
String getSession();
CourseLite getCourse();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package amu.zhcet.data.course.floated;

import amu.zhcet.data.course.CourseLiteImpl;
import lombok.Data;

@Data
public class FloatedCourseLiteImpl implements FloatedCourseLite {
private String session;
private CourseLiteImpl course;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import amu.zhcet.data.department.Department;
import org.springframework.data.jpa.datatables.repository.DataTablesRepository;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

Expand All @@ -17,4 +18,8 @@ public interface FloatedCourseRepository extends DataTablesRepository<FloatedCou

List<FloatedCourse> getBySession(String session);

List<FloatedCourseLite> getLightBySession(String session);

List<FloatedCourseLite> getBySessionAndCourse_CodeIn(String session, Collection<String> ids);

}
4 changes: 3 additions & 1 deletion src/main/java/amu/zhcet/data/department/DepartmentLite.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package amu.zhcet.data.department;

public class LightDepartment {
public interface DepartmentLite {
String getCode();
String getName();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package amu.zhcet.data.department;

import lombok.Data;

@Data
public class DepartmentLiteImpl implements DepartmentLite {
private String code;
private String name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

//@Order(1)
//@Configuration
@Order(1)
@Configuration
public class ApiSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**")
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/test/**").permitAll()
.antMatchers("/api/auth").permitAll()
.antMatchers("/api/v1/admin/**").hasRole("DEAN_ADMIN")
.antMatchers("/api/v1/dev/**").hasRole("DEVELOPMENT_ADMIN")
Expand Down
Loading

0 comments on commit 12e850e

Please sign in to comment.