This commit is contained in:
		| @@ -3,6 +3,8 @@ package de.jottyfan.camporganizer.module.camplist; | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; | ||||
| @@ -42,6 +44,12 @@ public class BookingBean implements Serializable { | ||||
| 	private Boolean accept; | ||||
| 	private String subscriber; | ||||
|  | ||||
| 	private List<DocumentBean> documents; | ||||
|  | ||||
| 	public BookingBean() { | ||||
| 		this.documents = new ArrayList<>(); | ||||
| 	} | ||||
|  | ||||
| 	public Boolean isFemale() { | ||||
| 		return EnumSex.female.equals(sex); | ||||
| 	} | ||||
| @@ -400,4 +408,8 @@ public class BookingBean implements Serializable { | ||||
| 		this.subscriber = subscriber; | ||||
| 	} | ||||
|  | ||||
| 	public List<DocumentBean> getDocuments() { | ||||
| 		return documents; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,8 @@ | ||||
| package de.jottyfan.camporganizer.module.camplist; | ||||
|  | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPDOCUMENT; | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENT; | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENTROLE; | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON; | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE; | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP; | ||||
| @@ -14,12 +17,15 @@ import org.apache.logging.log4j.Logger; | ||||
| import org.jooq.Condition; | ||||
| import org.jooq.DSLContext; | ||||
| import org.jooq.Record; | ||||
| import org.jooq.Record2; | ||||
| import org.jooq.SelectConditionStep; | ||||
| import org.jooq.SelectSeekStep1; | ||||
| import org.jooq.SelectSeekStep2; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Repository; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.TProfile; | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord; | ||||
|  | ||||
| @@ -61,6 +67,7 @@ public class CamplistGateway { | ||||
| 					    T_PERSON.EMAIL, | ||||
| 					    T_PERSON.SEX, | ||||
| 					    T_PERSON.ACCEPT, | ||||
| 					    T_PERSON.FK_CAMP, | ||||
| 					    T_PROFILE.FORENAME, | ||||
| 					    T_PROFILE.SURNAME, | ||||
| 					    REGISTRATOR.FORENAME, | ||||
| @@ -85,6 +92,7 @@ public class CamplistGateway { | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		List<BookingBean> list = new ArrayList<>(); | ||||
| 		for (Record r : sql.fetch()) { | ||||
| 			Integer fkCamp = r.get(T_PERSON.FK_CAMP); | ||||
| 			BookingBean bean = new BookingBean(); | ||||
| 			bean.setPk(r.get(T_PERSON.PK)); | ||||
| 			bean.setForename(r.get(T_PERSON.FORENAME)); | ||||
| @@ -126,6 +134,29 @@ public class CamplistGateway { | ||||
| 			} | ||||
| 			buf.append(regSurname != null ? regSurname : ""); | ||||
| 			bean.setSubscriber(buf.toString()); | ||||
| 			bean.getDocuments().addAll(getAllDocumentBeans(fkCamp, bean.getCamprole())); | ||||
| 			list.add(bean); | ||||
| 		} | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	private List<DocumentBean> getAllDocumentBeans(Integer fkCamp, EnumCamprole camprole) { | ||||
| 		SelectConditionStep<Record2<String, Integer>> sql = jooq | ||||
| 		// @formatter:off | ||||
| 			.select(T_DOCUMENT.NAME, | ||||
| 					    T_DOCUMENT.PK) | ||||
| 			.from(T_CAMPDOCUMENT) | ||||
| 			.leftJoin(T_DOCUMENT).on(T_DOCUMENT.PK.eq(T_CAMPDOCUMENT.FK_DOCUMENT)) | ||||
| 			.leftJoin(T_DOCUMENTROLE).on(T_DOCUMENTROLE.FK_DOCUMENT.eq(T_DOCUMENT.PK)) | ||||
| 			.where(T_CAMPDOCUMENT.FK_CAMP.eq(fkCamp)) | ||||
| 			.and(T_DOCUMENTROLE.CAMPROLE.eq(camprole)); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		List<DocumentBean> list = new ArrayList<>(); | ||||
| 		for (Record r : sql.fetch()) { | ||||
| 			DocumentBean bean = new DocumentBean(); | ||||
| 			bean.setPk(r.get(T_DOCUMENT.PK)); | ||||
| 			bean.setName(r.get(T_DOCUMENT.NAME)); | ||||
| 			list.add(bean); | ||||
| 		} | ||||
| 		return list; | ||||
|   | ||||
| @@ -0,0 +1,37 @@ | ||||
| package de.jottyfan.camporganizer.module.camplist; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| public class DocumentBean implements Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private Integer pk; | ||||
| 	private String name; | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the name | ||||
| 	 */ | ||||
| 	public String getName() { | ||||
| 		return name; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param name the name to set | ||||
| 	 */ | ||||
| 	public void setName(String name) { | ||||
| 		this.name = name; | ||||
| 	} | ||||
|  | ||||
| 	public Integer getPk() { | ||||
| 		return pk; | ||||
| 	} | ||||
|  | ||||
| 	public void setPk(Integer pk) { | ||||
| 		this.pk = pk; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,44 @@ | ||||
| package de.jottyfan.camporganizer.module.document; | ||||
|  | ||||
| import java.util.Base64; | ||||
|  | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.core.io.ByteArrayResource; | ||||
| import org.springframework.core.io.Resource; | ||||
| import org.springframework.http.HttpHeaders; | ||||
| import org.springframework.http.MediaType; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.web.bind.annotation.PathVariable; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMethod; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| @RestController | ||||
| public class DocumentController { | ||||
|  | ||||
| 	@Autowired | ||||
| 	private DocumentService service; | ||||
|  | ||||
| 	@RequestMapping(path = "/document/{id}", method = RequestMethod.GET) | ||||
| 	public ResponseEntity<Resource> getDocument(@PathVariable Integer id, HttpServletResponse response) { | ||||
| 		DownloadBean bean = service.getDocument(id); | ||||
| 		if (bean != null) { | ||||
| 			byte[] decoded = Base64.getDecoder().decode(bean.getContent()); | ||||
| 			HttpHeaders header = new HttpHeaders(); | ||||
| 			header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + bean.getName() + "." + bean.getFiletype()); | ||||
| 			MediaType contentType = MediaType.parseMediaType("application/octet-stream"); | ||||
| 			Integer length = decoded.length; | ||||
| 			ByteArrayResource resource = new ByteArrayResource(decoded); | ||||
| 			return ResponseEntity.ok().headers(header).contentLength(length).contentType(contentType).body(resource); | ||||
| 		} else { | ||||
| 			return ResponseEntity.notFound().build(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,52 @@ | ||||
| package de.jottyfan.camporganizer.module.document; | ||||
|  | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENT; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.jooq.DSLContext; | ||||
| import org.jooq.SelectConditionStep; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Repository; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.TDocumentRecord; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| @Repository | ||||
| @Transactional(transactionManager = "transactionManager") | ||||
| public class DocumentRepository { | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(DocumentRepository.class); | ||||
|  | ||||
| 	@Autowired | ||||
| 	private DSLContext jooq; | ||||
|  | ||||
| 	/** | ||||
| 	 * get the document or null | ||||
| 	 * | ||||
| 	 * @param id the id of the document | ||||
| 	 * @return the download bean or null (if not found) | ||||
| 	 */ | ||||
| 	public DownloadBean getDocument(Integer id) { | ||||
| 		SelectConditionStep<TDocumentRecord> sql = jooq | ||||
| 		// @formatter:off | ||||
| 			.selectFrom(T_DOCUMENT) | ||||
| 			.where(T_DOCUMENT.PK.eq(id)); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		TDocumentRecord r = sql.fetchOne(); | ||||
| 		if (r == null) { | ||||
| 			return null; | ||||
| 		} else { | ||||
| 			DownloadBean bean = new DownloadBean(); | ||||
| 			bean.setName(r.getName()); | ||||
| 			bean.setFiletype(r.getFiletype()); | ||||
| 			bean.setContent(r.getDocument()); | ||||
| 			return bean; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| package de.jottyfan.camporganizer.module.document; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| @Service | ||||
| public class DocumentService { | ||||
|  | ||||
| 	@Autowired | ||||
| 	private DocumentRepository repository; | ||||
|  | ||||
| 	/** | ||||
| 	 * get the document of id | ||||
| 	 * | ||||
| 	 * @param id the id of the document | ||||
| 	 */ | ||||
| 	public DownloadBean getDocument(Integer id) { | ||||
| 		return repository.getDocument(id); | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,60 @@ | ||||
| package de.jottyfan.camporganizer.module.document; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumFiletype; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| public class DownloadBean implements Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private String name; | ||||
| 	private EnumFiletype filetype; | ||||
| 	private String content; | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the filetype | ||||
| 	 */ | ||||
| 	public EnumFiletype getFiletype() { | ||||
| 		return filetype; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param filetype the filetype to set | ||||
| 	 */ | ||||
| 	public void setFiletype(EnumFiletype filetype) { | ||||
| 		this.filetype = filetype; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the content | ||||
| 	 */ | ||||
| 	public String getContent() { | ||||
| 		return content; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param content the content to set | ||||
| 	 */ | ||||
| 	public void setContent(String content) { | ||||
| 		this.content = content; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the name | ||||
| 	 */ | ||||
| 	public String getName() { | ||||
| 		return name; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param name the name to set | ||||
| 	 */ | ||||
| 	public void setName(String name) { | ||||
| 		this.name = name; | ||||
| 	} | ||||
| } | ||||
| @@ -83,8 +83,8 @@ | ||||
| 				} | ||||
| 			</script> | ||||
| 			<div class="alert alert-primary menufont" th:if="${mybookings.size() < 1}">Es wurden noch keine Anmeldungen für eine Freizeit hinterlegt.</div> | ||||
| 			<div th:if="${mybookings.size() > 0}" class="menufont">Deine bisherigen Anmeldungen:</div> | ||||
| 			<div class="accordion" id="acc" th:if="${mybookings.size() > 0}"> | ||||
| 			<div th:if="${mybookings.size() > 0}" class="menufont" style="text-align: center">Deine bisherigen Anmeldungen:</div> | ||||
| 			<div class="accordion" id="acc" th:if="${mybookings.size() > 0}" style="max-width: 800px; margin-left: auto; margin-right: auto"> | ||||
| 				<div class="accordion-item" th:each="b : ${mybookings}"> | ||||
| 					<h2 class="accordion-header" th:id="'acc-head-' + ${b.pk}" th:if="${b.pk}"> | ||||
| 						<button th:class="'accordion-button collapsed acc_' + ${b.isOver ? 'over' : b.accept}" type="button" data-bs-toggle="collapse" th:data-bs-target="'#acc-body-' + ${b.pk}" | ||||
| @@ -118,6 +118,18 @@ | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<div class="card" th:if="${b.accept}"> | ||||
| 								<div class="card-header">Dokumente</div> | ||||
| 								<div class="card-body"> | ||||
| 									<div class="container"> | ||||
| 										<div class="row"> | ||||
| 											<div class="col-sm-12 col-md-6 col-lg-4" th:each="d : ${b.documents}"> | ||||
| 												<a th:href="@{'/document/' + ${d.pk}}" th:text="${d.name}"></a> | ||||
| 											</div> | ||||
| 										</div> | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<div class="card"> | ||||
| 								<div class="card-header">Teilnehmerdaten</div> | ||||
| 								<div class="card-body"> | ||||
| @@ -169,8 +181,8 @@ | ||||
| 												<span class="col-sm-10"><input type="text" class="form-control" th:value="*{email}" name="email" onchange="mark(this)" /></span> | ||||
| 											</div> | ||||
| 											<div class="row mb-2"> | ||||
| 												<div class="col-sm-2">Foto-Einverständnis:</div> | ||||
| 												<span class="col-sm-10"><span th:text="${b.consentCatalogPhoto ? 'ja' : 'nein'}" th:if="${b.consentCatalogPhoto}"></span></span> | ||||
| 												<div class="col-sm-6">Foto-Einverständnis:</div> | ||||
| 												<span class="col-sm-6"><span th:text="${b.consentCatalogPhoto ? 'ja' : 'nein'}" th:if="${b.consentCatalogPhoto}"></span></span> | ||||
| 											</div> | ||||
| 											<div class="row mb-2"> | ||||
| 												<div class="col-sm-2">Kommentar:</div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user