diff --git a/buisnesslogic/src/main/java/com/plannaplan/models/ExportData.java b/buisnesslogic/src/main/java/com/plannaplan/models/ExportData.java new file mode 100755 index 0000000..de3a7e3 --- /dev/null +++ b/buisnesslogic/src/main/java/com/plannaplan/models/ExportData.java @@ -0,0 +1,86 @@ +package com.plannaplan.models; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Container to keep data to export + */ +public class ExportData { + + private static final String GROUP_FIELD = "gr_nr"; + private static final String USER_FIELD = "user_id"; + private static final String CYKL_FIELD = "zaj_cykl_id"; + + private String userId; + private String zajCyklId; + private String grNr; + + /** + * @param userId usosid + * @param zajCyklId course cycle + * @param grNr group number + */ + public ExportData(String userId, String zajCyklId, String grNr) { + this.setUserId(userId); + this.setZajCyklId(zajCyklId); + this.setGrNr(grNr); + } + + /** + * @return group number + */ + public String getGrNr() { + return grNr; + } + + /** + * @param grNr group number + */ + public void setGrNr(String grNr) { + this.grNr = grNr; + } + + /** + * @return course cycle + */ + public String getZajCyklId() { + return zajCyklId; + } + + /** + * @param zajCyklId course cycle + */ + public void setZajCyklId(String zajCyklId) { + this.zajCyklId = zajCyklId; + } + + /** + * @return usosid + */ + public String getUserId() { + return userId; + } + + /** + * @param userId usosid + */ + public void setUserId(String userId) { + this.userId = userId; + } + + /** + * @return csv fromated line + */ + public String convertToCSVRecord() { + return Stream.of(this.userId, this.zajCyklId, this.grNr).collect(Collectors.joining(",")); + } + + /** + * @return csv formated first line + */ + public static String getCSVHeader() { + return USER_FIELD + ", " + CYKL_FIELD + ", " + GROUP_FIELD; + } + +} diff --git a/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java b/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java index 2f01a46..c7472fe 100755 --- a/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java +++ b/buisnesslogic/src/main/java/com/plannaplan/services/CommisionService.java @@ -1,10 +1,12 @@ package com.plannaplan.services; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import com.plannaplan.entities.Commision; import com.plannaplan.entities.User; +import com.plannaplan.models.ExportData; import com.plannaplan.repositories.AssignmentRepository; import com.plannaplan.repositories.CommisionRepository; @@ -22,6 +24,8 @@ public class CommisionService { private CommisionRepository repo; @Autowired private AssignmentRepository aRepository; + @Autowired + private UserService userService; public CommisionService() { } @@ -77,4 +81,21 @@ public class CommisionService { public long getCommisionsAmmount() { return this.repo.count(); } + + /** + * @return list of ExportData inmstancces keeping data to exprt to file + */ + public List getExportData() { + final List response = new ArrayList<>(); + + this.userService.getAllStudents().forEach(student -> { + student.getStudentRegisteredGrups().forEach(group -> { + response.add(new ExportData(student.getUsosId(), Integer.toString(group.getZajCykId()), + Integer.toString(group.getGrNr()))); + }); + }); + + return response; + } + } diff --git a/buisnesslogic/src/test/java/com/plannaplan/models/ExportDataTest.java b/buisnesslogic/src/test/java/com/plannaplan/models/ExportDataTest.java new file mode 100755 index 0000000..8314fd5 --- /dev/null +++ b/buisnesslogic/src/test/java/com/plannaplan/models/ExportDataTest.java @@ -0,0 +1,14 @@ +package com.plannaplan.models; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.Test; + +public class ExportDataTest { + + @Test + public void shouldConvertDataToCSVRecord() { + final ExportData data = new ExportData("4234", "242352", "12"); + assertTrue(data.convertToCSVRecord().equals("4234,242352,12")); + } +} diff --git a/restservice/pom.xml b/restservice/pom.xml index 4ba0b83..21d5dc0 100755 --- a/restservice/pom.xml +++ b/restservice/pom.xml @@ -62,6 +62,14 @@ 4.5.10 + + + commons-io + commons-io + 2.5 + + + org.springframework.boot spring-boot-starter-web diff --git a/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java b/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java index 7961630..4c9ded1 100755 --- a/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java +++ b/restservice/src/main/java/com/plannaplan/controllers/CommisionController.java @@ -12,12 +12,15 @@ import io.swagger.annotations.ApiParam; import java.util.List; import java.util.Optional; +import javax.servlet.http.HttpServletResponse; + import com.plannaplan.App; import com.plannaplan.entities.Assignment; import com.plannaplan.entities.Commision; import com.plannaplan.entities.Groups; import com.plannaplan.entities.User; import com.plannaplan.exceptions.UserNotFoundException; +import com.plannaplan.models.ExportData; import com.plannaplan.responses.mappers.CommisionResponseMappers; import com.plannaplan.responses.models.CommisionResponse; import com.plannaplan.services.AssignmentService; @@ -27,6 +30,8 @@ import com.plannaplan.services.GroupService; import com.plannaplan.types.AppState; import com.plannaplan.types.UserRoles; +import org.apache.commons.io.IOUtils; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -37,6 +42,8 @@ import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -259,4 +266,32 @@ public class CommisionController extends TokenBasedController { return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK); } + /** + * @param response spring response to set headers + */ + @GetMapping("/export/csv") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @ApiOperation(value = "Export acceptes assignmetns as csv file to import to usos. You need to provide ADMIN token in order to get access to this data.") + public void getFile(HttpServletResponse response) { + try { + String csvString = ExportData.getCSVHeader() + "\n"; + final Iterator it = this.commisionService.getExportData().iterator(); + while (it.hasNext()) { + final ExportData data = it.next(); + csvString += (data.convertToCSVRecord() + "\n"); + } + + final InputStream is = IOUtils.toInputStream(csvString, "UTF-8"); + + IOUtils.copy(is, response.getOutputStream()); + response.setContentType("application/csv"); + response.setHeader("Content-Disposition", "attachment; filename=\"export.csv\""); + response.flushBuffer(); + } catch (IOException ex) { + + throw new RuntimeException("IOError writing file to output stream"); + } + + } + } diff --git a/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java b/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java index 25990f5..f09a5e1 100755 --- a/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java +++ b/restservice/src/test/java/com/plannaplan/controllers/CommisionControllerTest.java @@ -18,6 +18,7 @@ import com.plannaplan.entities.User; import com.plannaplan.services.UserService; import com.plannaplan.types.UserRoles; +import static org.junit.Assert.assertTrue; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -31,11 +32,13 @@ public class CommisionControllerTest extends AbstractControllerTest { private UserService service; private static User user; + private static User admin; private static User otherUser; private static User asker; private static User otherAsker; private static final String TEST_COMMISIONS_STUDENT_EMAIL = "commisions.student@notexisting.domain"; + private static final String TEST_COMMISIONS_ADMIN_EMAIL = "commisions.admin@notexisiting,domain"; private static final String TEST_COMMISIONS_OTHER_STUDENT_EMAIL = "commisions.student2@notexisting.domain"; private static final String TEST_COMMISIONS_DEANERY_EMAIL = "commisions.deanery@notexisting.domain"; private static final String TEST_COMMISIONS_OTHER_DEANERY_EMAIL = "commisions.deanery2@notexisting.domain"; @@ -45,6 +48,8 @@ public class CommisionControllerTest extends AbstractControllerTest { private static final String GET_SOMEONE_COMMISIONS_ENDPOINT = "/api/v1/commisions/user"; private static final String GET_USER_SCHEDULE_ENDPOINT = "/api/v1/commisions/user/schedule"; + private static final String EXPORT_DATA = "/api/v1/commisions/export/csv"; + private static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); @@ -254,6 +259,10 @@ public class CommisionControllerTest extends AbstractControllerTest { UserRoles.STUDENT); this.service.save(otherUser); } + if (CommisionControllerTest.admin == null) { + CommisionControllerTest.admin = new User(null, null, TEST_COMMISIONS_ADMIN_EMAIL, UserRoles.ADMIN); + this.service.save(admin); + } if (CommisionControllerTest.asker == null) { CommisionControllerTest.asker = new User(null, null, TEST_COMMISIONS_DEANERY_EMAIL, UserRoles.DEANERY); this.service.save(asker); @@ -264,4 +273,38 @@ public class CommisionControllerTest extends AbstractControllerTest { this.service.save(otherAsker); } } + + @Test + public void shouldExportData() throws Exception { + this.checkUsers(); + final User admin = this.service.checkForUser(TEST_COMMISIONS_ADMIN_EMAIL, null); + final String token = this.service.login(admin).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(get(EXPORT_DATA).header("Authorization", "Bearer " + token)).andExpect(status().isOk()); + } + + @Test + public void shouldNotExportDataDueToWrongPermision() throws Exception { + this.checkUsers(); + final User student = this.service.checkForUser(TEST_COMMISIONS_STUDENT_EMAIL, null); + final String token = this.service.login(student).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + mockMvc.perform(get(EXPORT_DATA).header("Authorization", "Bearer " + token)) + .andExpect(status().is4xxClientError()); + } + + @Test + public void shouldExportDataBeCsvFile() throws Exception { + this.checkUsers(); + final User admin = this.service.checkForUser(TEST_COMMISIONS_ADMIN_EMAIL, null); + final String token = this.service.login(admin).getToken(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); + + assertTrue( + mockMvc.perform(get(EXPORT_DATA).header("Authorization", "Bearer " + token)).andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString().contains("user_id, zaj_cykl_id, gr_nr")); + } }