package com.exadel.controller;
import com.exadel.model.entity.feedback.TrainingFeedback;
import com.exadel.model.entity.training.Entry;
import com.exadel.model.entity.training.Training;
import com.exadel.model.entity.user.*;
import com.exadel.service.AbsenteeService;
import com.exadel.service.EntryService;
import com.exadel.service.UserService;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import static com.exadel.export.PdfExporter.*;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
@RestController
@RequestMapping("/user")
public class ExportStatController {
@Autowired
private UserService userService;
@Autowired
private EntryService entryService;
@Autowired
private AbsenteeService absenteeService;
private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HHmmss");
private static SimpleDateFormat prefaceFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
private static DecimalFormat doubleFormat = new DecimalFormat("#.##");
private static final String path = System.getProperty("user.dir");
@RequestMapping(value = "/stats", method = RequestMethod.GET)
public void getUserPdf(@RequestParam String userId, HttpServletResponse response) {
User user = userService.getUserById(userId);
long creatorId = userService.getCurrentId();
User creator = userService.getUserById(creatorId);
try {
Document document = new Document();
Date creatingDate = new Date();
String time = format.format(creatingDate);
String name = "Statistics of " + user.getName() + " " + user.getSurname();
String filePath = path + File.separator + name + " " + time + ".pdf";
File downloadFile = new File(filePath);
PdfWriter.getInstance(document, new FileOutputStream(downloadFile));
document.open();
addMetaDataAndTitlePage(document, creator, name, prefaceFormat.format(creatingDate));
addContent(document, user);
document.close();
FileUpDownLoadController.downloadFile(downloadFile, "application/pdf", response);
downloadFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
private void addContent(Document document, User user) throws DocumentException {
int chapterNumber = 1;
com.itextpdf.text.List summaryContent = new com.itextpdf.text.List(false, false, 15);
if (addVisitingTrainings(document, user, chapterNumber, summaryContent))
chapterNumber++;
if (addMentoringTrainings(document, user, chapterNumber, summaryContent))
chapterNumber++;
if (chapterNumber != 0)
addSummary(document, summaryContent, chapterNumber);
}
private boolean addVisitingTrainings(Document document, User user, int chapterNumber, com.itextpdf.text.List summaryContent) throws DocumentException {
List<Training> trainings;
if (user.getRole() == UserRole.EXTERNAL_VISITOR)
trainings = ((ExternalVisitor) user).getVisitingTrainings();
else if (user.getRole() == UserRole.EMPLOYEE)
trainings = ((Employee) user).getVisitingTrainings();
else
return false;
document.newPage();
Anchor anchor = new Anchor("Visiting trainings", catFont);
anchor.setName("Visiting trainings");
Chapter chapter = new Chapter(new Paragraph(anchor), chapterNumber);
Paragraph emptyLine = new Paragraph();
addEmptyLine(emptyLine, 1);
chapter.add(emptyLine);
List<String> headers = Arrays.asList("Name", "Absences", "All");
PdfPTable trainingsTable = createTableWithHeader(headers);
chapter.add(trainingsTable);
List<String> absenceHeaders = Arrays.asList("Day", "Absence reason");
int allAbsenceCount = 0;
int lecturesCount = 0;
for (Training training : trainings) {
List<String> trainingDays = new ArrayList<>();
List<String> trainingReasons = new ArrayList<>();
List<Entry> entries = entryService.getAllEntriesByTrainingId(training.getId());
int absentCount = 0;
for (Entry entry : entries) {
Absentee absentee = absenteeService.getAbsentee(user.getId(), entry.getId());
if (absentee != null) {
absentCount++;
trainingDays.add(dateFormat.format(entry.getBeginTime()));
trainingReasons.add(absentee.getReason());
}
}
lecturesCount += entries.size();
allAbsenceCount += absentCount;
if (absentCount > 0) {
Paragraph paragraph = new Paragraph(training.getName(), subFont);
addEmptyLine(paragraph, 1);
Section subSection = chapter.addSection(paragraph);
PdfPTable absenceTable = createTableWithHeader(absenceHeaders);
for (int j = 0; j < trainingDays.size(); j++) {
absenceTable.addCell(trainingDays.get(j));
absenceTable.addCell(trainingReasons.get(j));
}
subSection.add(absenceTable);
}
trainingsTable.addCell(training.getName());
trainingsTable.addCell(String.valueOf(absentCount));
trainingsTable.addCell(String.valueOf(entries.size()));
}
double percent = (double) allAbsenceCount / lecturesCount * 100;
summaryContent.add(new ListItem("Lectures attended: " + lecturesCount));
summaryContent.add(new ListItem("Lectures skipped: " + allAbsenceCount
+ " (" + doubleFormat.format(percent) + "%)"));
document.add(chapter);
return true;
}
private PdfPTable createTableWithHeader(List<String> headers) {
PdfPTable table = new PdfPTable(headers.size());
for (String header : headers) {
PdfPCell cell = new PdfPCell(new Phrase(header));
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
table.addCell(cell);
}
table.setHeaderRows(1);
return table;
}
private boolean addMentoringTrainings(Document document, User user, int chapterNumber, com.itextpdf.text.List summaryContent) throws DocumentException {
List<Training> mentoringTrainings;
if (user.getRole() != UserRole.EXTERNAL_VISITOR)
mentoringTrainings = ((ExternalTrainer) user).getMentoringTrainings();
else
return false;
document.newPage();
Anchor anchor = new Anchor("Mentoring trainings", catFont);
anchor.setName("Mentoring trainings");
Chapter chapter = new Chapter(new Paragraph(anchor), chapterNumber);
Paragraph emptyLine = new Paragraph();
addEmptyLine(emptyLine, 1);
chapter.add(emptyLine);
List<String> headers = Arrays.asList("Name", "Lectures mentored", "Responses");
PdfPTable trainingsTable = createTableWithHeader(headers);
chapter.add(trainingsTable);
List<String> feedbackHeaders = Arrays.asList("Day", "Feedback", "Positive");
int eventsSum = 0;
int feedbackSum = 0;
int positiveFeedbackSum = 0;
for (Training training : mentoringTrainings) {
trainingsTable.addCell(training.getName());
int eventsCount = training.getEntries().size();
eventsSum += eventsCount;
trainingsTable.addCell(String.valueOf(eventsCount));
int feedbackCount = training.getFeedbacks().size();
feedbackSum += feedbackCount;
trainingsTable.addCell(String.valueOf(feedbackCount));
if (feedbackCount > 0) {
Paragraph paragraph = new Paragraph(training.getName(), subFont);
addEmptyLine(paragraph, 1);
Section subSection = chapter.addSection(paragraph);
PdfPTable feedbackTable = createTableWithHeader(feedbackHeaders);
subSection.add(feedbackTable);
for (TrainingFeedback feedback : training.getFeedbacks()) {
feedbackTable.addCell(dateFormat.format(feedback.getDate()));
feedbackTable.addCell(feedback.getOtherInfo());
if (feedback.isStudyWithTrainer()) {
feedbackTable.addCell("+");
positiveFeedbackSum++;
}
else
feedbackTable.addCell("-");
}
}
}
summaryContent.add(new ListItem("Lectures mentored: " + eventsSum));
summaryContent.add(new ListItem("Feedbacks (as trainer) received: " + feedbackSum));
double percent = (double) positiveFeedbackSum / feedbackSum * 100;
summaryContent.add(new ListItem("Positive feedbacks (as trainer) received: "
+ positiveFeedbackSum + " (" + doubleFormat.format(percent) + "%)"));
document.add(chapter);
return true;
}
private void addSummary(Document document, com.itextpdf.text.List summaryContent, int chapterNumber) throws DocumentException {
document.newPage();
Anchor anchor = new Anchor("Summary", catFont);
anchor.setName("Summary");
Chapter chapter = new Chapter(new Paragraph(anchor), chapterNumber);
chapter.add(summaryContent);
document.add(chapter);
}
}