added download csv file feature
This commit is contained in:
parent
b3a089d6b3
commit
e0e972cfe8
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = 'de.jottyfan.camporganizer'
|
||||
version = '0.6.0'
|
||||
version = '0.6.1'
|
||||
|
||||
description = """CampOrganizer2"""
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
package de.jottyfan.camporganizer.module.confirmation.board;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@ -9,6 +12,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import de.jottyfan.camporganizer.module.camplist.CommonController;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -29,7 +33,20 @@ public class ConfirmationBoardController extends CommonController {
|
||||
|
||||
@GetMapping("/confirmation/board/camp/{id}")
|
||||
public String getCamplist(Model model, @PathVariable Integer id, Principal principal) {
|
||||
model.addAttribute("campId", id);
|
||||
model.addAttribute("campStartDate", service.getCampStartDate(super.getCurrentUser(principal), id));
|
||||
model.addAttribute("persons", service.loadPersonList(super.getCurrentUser(principal), id));
|
||||
return "/confirmation/camplist";
|
||||
}
|
||||
|
||||
@GetMapping("/confirmation/board/download/{id}")
|
||||
public void getCsvOfAll(@PathVariable Integer id, Principal principal, HttpServletResponse response)
|
||||
throws IOException {
|
||||
response.setContentType("text/csv");
|
||||
String filename = String.format("camplist_%d_%s.csv", id,
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")));
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
|
||||
response.getWriter().write(service.getDownloadCsvOfAll(super.getCurrentUser(principal), id));
|
||||
response.flushBuffer();
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,14 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Record2;
|
||||
import org.jooq.Record6;
|
||||
import org.jooq.SelectConditionStep;
|
||||
import org.jooq.SelectSeekStep1;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
|
||||
import de.jottyfan.camporganizer.module.confirmation.board.model.CampBean;
|
||||
import de.jottyfan.camporganizer.module.confirmation.board.model.PersonBean;
|
||||
import de.jottyfan.camporganizer.module.confirmation.confirmation.ConfirmationRepository;
|
||||
@ -46,7 +48,7 @@ public class ConfirmationBoardRepository {
|
||||
// @formatter:off
|
||||
.select(V_CAMP.NAME, V_CAMP.YEAR, V_CAMP.IS_OVER, V_CAMP.LOCATION_NAME, V_CAMP.PK, V_CAMP.ARRIVE)
|
||||
.from(T_PROFILE)
|
||||
.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_PROFILE.eq(T_PROFILE.PK))
|
||||
.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_PROFILE.eq(T_PROFILE.PK)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration))
|
||||
.leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_CAMPPROFILE.FK_CAMP))
|
||||
.where(T_PROFILE.USERNAME.eq(username))
|
||||
.orderBy(V_CAMP.ARRIVE);
|
||||
@ -77,7 +79,7 @@ public class ConfirmationBoardRepository {
|
||||
// @formatter:off
|
||||
.select(T_PERSON.fields())
|
||||
.from(T_PERSON)
|
||||
.innerJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP))
|
||||
.innerJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration))
|
||||
.innerJoin(T_PROFILE).on(T_PROFILE.USERNAME.eq(username)).and(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE))
|
||||
.where(T_PERSON.FK_CAMP.eq(campId));
|
||||
// @formatter:on
|
||||
@ -104,4 +106,28 @@ public class ConfirmationBoardRepository {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the camp start date of campId if username is allowed to
|
||||
*
|
||||
* @param username the user
|
||||
* @param campId the ID of the camp
|
||||
* @return the camp start time or null
|
||||
*/
|
||||
public LocalDateTime getCampStartDate(String username, Integer campId) {
|
||||
SelectConditionStep<Record2<String, LocalDateTime>> sql = jooq
|
||||
// @formatter:off
|
||||
.select(V_CAMP.NAME, V_CAMP.ARRIVE)
|
||||
.from(T_PROFILE)
|
||||
.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_PROFILE.eq(T_PROFILE.PK)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration))
|
||||
.leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_CAMPPROFILE.FK_CAMP))
|
||||
.where(T_PROFILE.USERNAME.eq(username))
|
||||
.and(V_CAMP.PK.eq(campId));
|
||||
// @formatter:on
|
||||
LOGGER.trace(sql);
|
||||
for (Record2<String, LocalDateTime> r : sql.fetch()) {
|
||||
return r.get(V_CAMP.ARRIVE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,9 @@ public class ConfirmationBoardService {
|
||||
@Autowired
|
||||
private ConfirmationBoardRepository repository;
|
||||
|
||||
@Autowired
|
||||
private List2CSVService csvService;
|
||||
|
||||
public List<CampBean> loadCampList(String username) {
|
||||
return repository.getCamps(username);
|
||||
}
|
||||
@ -26,4 +29,13 @@ public class ConfirmationBoardService {
|
||||
public List<PersonBean> loadPersonList(String username, Integer campId) {
|
||||
return repository.getPersons(username, campId);
|
||||
}
|
||||
|
||||
public String getDownloadCsvOfAll(String username, Integer campId) {
|
||||
List<PersonBean> list = repository.getPersons(username, campId);
|
||||
return csvService.toCsv(list);
|
||||
}
|
||||
|
||||
public Object getCampStartDate(String username, Integer campId) {
|
||||
return repository.getCampStartDate(username, campId);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
package de.jottyfan.camporganizer.module.confirmation.board;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import de.jottyfan.camporganizer.module.confirmation.board.model.PersonBean;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class List2CSVService {
|
||||
private static final String QUOTE = "\"";
|
||||
private static final String SEP = ",";
|
||||
|
||||
private StringBuilder append(StringBuilder buf, String s) {
|
||||
return buf.append(s == null || s.isEmpty() ? SEP : String.format("%s%s%s%s", QUOTE, s, QUOTE, SEP));
|
||||
}
|
||||
|
||||
private StringBuilder append(StringBuilder buf, Double d) {
|
||||
return buf.append(d == null ? SEP : String.format("%s%s%s%s", QUOTE, d.toString(), QUOTE, SEP));
|
||||
}
|
||||
|
||||
private StringBuilder append(StringBuilder buf, Boolean b) {
|
||||
return buf.append(b == null ? SEP : String.format("%s%s%s%s", QUOTE, b ? "ja" : "nein", QUOTE, SEP));
|
||||
}
|
||||
|
||||
private StringBuilder append(StringBuilder buf, LocalDateTime l) {
|
||||
return buf.append(l == null ? SEP : String.format("%s%s%s%s", QUOTE, l.format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")), QUOTE, SEP));
|
||||
}
|
||||
|
||||
private StringBuilder append(StringBuilder buf, LocalDate l) {
|
||||
return buf.append(l == null ? SEP : String.format("%s%s%s%s", QUOTE, l.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")), QUOTE, SEP));
|
||||
}
|
||||
|
||||
public String toCsv(List<PersonBean> list) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("Bezahlt,Vorname,Nachname,Strasse,PLZ,Ort,Telefon,Email,Geschlecht,Rolle,Geburtsdatum,Anmeldestatus,Anmeldedatum,Fotoeinverständnis,Kommentar\n");
|
||||
for (PersonBean bean : list) {
|
||||
append(buf, bean.getPaid());
|
||||
append(buf, bean.getForename());
|
||||
append(buf, bean.getSurname());
|
||||
append(buf, bean.getStreet());
|
||||
append(buf, bean.getZip());
|
||||
append(buf, bean.getCity());
|
||||
append(buf, bean.getPhone());
|
||||
append(buf, bean.getEmail());
|
||||
append(buf, bean.getSex());
|
||||
append(buf, bean.getCamprole());
|
||||
append(buf, bean.getBirthDate());
|
||||
append(buf, bean.getAccept());
|
||||
append(buf, bean.getCreated());
|
||||
append(buf, bean.getConsentCatalogPhoto());
|
||||
append(buf, bean.getComment());
|
||||
buf.append("\n");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package de.jottyfan.camporganizer.module.confirmation.board.model;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Period;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -29,7 +30,13 @@ public class PersonBean implements Serializable {
|
||||
private Boolean consentCatalogPhoto;
|
||||
|
||||
public String getAge(LocalDate relation) {
|
||||
return "?"; // TODO: calculate age in relation to the camp start.
|
||||
if (relation == null) {
|
||||
return "?";
|
||||
} else {
|
||||
Period period = Period.between(birthDate, relation);
|
||||
Integer years = period == null ? null : period.getYears();
|
||||
return years == null ? "?" : years.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public String getCamprolle() {
|
||||
|
@ -2,10 +2,6 @@ package de.jottyfan.camporganizer.module.confirmation.confirmation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
@ -9,9 +9,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import de.jottyfan.camporganizer.module.camplist.CommonController;
|
||||
import de.jottyfan.camporganizer.module.confirmation.confirmation.ConfirmationService;
|
||||
import de.jottyfan.camporganizer.module.confirmation.person.model.PersonBean;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -7,6 +7,10 @@
|
||||
<body>
|
||||
<th:block layout:fragment="content">
|
||||
<div sec:authorize="hasRole('registrator')" style="margin: 8px">
|
||||
<div class="btn-group" role="group">
|
||||
<a class="btn btn-outline-primary" role="button" th:href="@{/confirmation/board/download/{id}(id=${campId})}"><i class="fas fa-download"></i> alles als CSV exportieren</a>
|
||||
</div>
|
||||
<br />
|
||||
<table id="table" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -25,20 +29,16 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="p : ${persons}">
|
||||
<td th:text="${p.paid}"></td>
|
||||
<td th:text="${#strings.replace(#numbers.formatCurrency(p.paid), '¤', '€')}"></td>
|
||||
<td th:text="${p.forename}"></td>
|
||||
<td th:text="${p.surname}"></td>
|
||||
<td><div th:text="${p.street}"></div>
|
||||
<span th:text="${p.zip}"></span> <span th:text="${p.city}"></span>
|
||||
</td>
|
||||
<td><div th:text="${p.street}"></div> <span th:text="${p.zip}"></span> <span th:text="${p.city}"></span></td>
|
||||
<td><div th:text="'Tel.: ' + ${p.phone}"></div>
|
||||
<div th:text="${p.email}"></div>
|
||||
</td>
|
||||
<div th:text="${p.email}"></div></td>
|
||||
<td><div th:text="${p.sex == 'male' ? 'männlich' : 'weiblich'}"></div>
|
||||
<div th:text="${p.camprolle}"></div></td>
|
||||
<td><div th:text="${#temporals.format(p.birthDate, 'dd.MM.yyyy')}"></div>
|
||||
<div th:text="${p.getAge(p.birthDate)} + ' Jahre'"></div>
|
||||
</td>
|
||||
<div th:text="${p.getAge(campStartDate)} + ' Jahre'"></div></td>
|
||||
<td th:text="${p.accept}"></td>
|
||||
<td th:text="${#temporals.format(p.created, 'dd.MM.yyyy HH:mm')}"></td>
|
||||
<td><span th:text="${p.consentCatalogPhoto ? 'ja' : 'nein'}" th:if="${p.consentCatalogPhoto}"></span></td>
|
||||
|
Loading…
x
Reference in New Issue
Block a user