preparations for online camp planning tool
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = 'de.jottyfan.camporganizer'
|
group = 'de.jottyfan.camporganizer'
|
||||||
version = '1.0.3'
|
version = '1.0.4'
|
||||||
|
|
||||||
description = """CampOrganizer2"""
|
description = """CampOrganizer2"""
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.campside;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.camplist.CommonController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class CampsideController extends CommonController {
|
||||||
|
@Autowired
|
||||||
|
CampsideService service;
|
||||||
|
|
||||||
|
@GetMapping("/campside")
|
||||||
|
public String getCampside(final Model model) {
|
||||||
|
model.addAttribute("myCampBookings", service.getCampBookingsOf(super.getCurrentUser()));
|
||||||
|
return "/campside/list";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/campside/{id}")
|
||||||
|
public String getCampDetails(@PathVariable("id") Integer fkCamp, final Model model) {
|
||||||
|
// TODO: load content for the camp with fkCamp
|
||||||
|
return "/campside/camp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/campside/{id}/plan")
|
||||||
|
public String getCampPlan(@PathVariable("id") Integer fkCamp, final Model model) {
|
||||||
|
// TODO: load camp plan from database
|
||||||
|
return "/campside/plan";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.campside;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.Record;
|
||||||
|
import org.jooq.Record9;
|
||||||
|
import org.jooq.SelectSeekStep1;
|
||||||
|
import org.jooq.impl.DSL;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.tables.TProfile;
|
||||||
|
import de.jottyfan.camporganizer.module.campside.model.MyCampBookingBean;
|
||||||
|
import de.jottyfan.camporganizer.module.campside.model.MyPersonBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public class CampsideRepository {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(CampsideRepository.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext jooq;
|
||||||
|
|
||||||
|
public List<MyCampBookingBean> getMyCampBookings(String username) {
|
||||||
|
TProfile REGISTRATOR = TProfile.T_PROFILE.as("registrator");
|
||||||
|
SelectSeekStep1<Record9<String, String, Double, Boolean, LocalDateTime, LocalDateTime, Integer, String, String>, LocalDateTime> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.select(V_CAMP.NAME,
|
||||||
|
V_CAMP.LOCATION_NAME,
|
||||||
|
V_CAMP.YEAR,
|
||||||
|
V_CAMP.IS_OVER,
|
||||||
|
V_CAMP.ARRIVE,
|
||||||
|
V_CAMP.DEPART,
|
||||||
|
V_CAMP.PK,
|
||||||
|
T_PERSON.FORENAME,
|
||||||
|
T_PERSON.SURNAME)
|
||||||
|
.from(T_PROFILE)
|
||||||
|
.leftJoin(T_PERSON).on(T_PERSON.FK_PROFILE.eq(T_PROFILE.PK))
|
||||||
|
.leftJoin(REGISTRATOR).on(REGISTRATOR.PK.eq(T_PERSON.FK_REGISTRATOR))
|
||||||
|
.leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_PERSON.FK_CAMP))
|
||||||
|
.where(DSL.trim(T_PROFILE.USERNAME).eq(username == null ? null : username.trim()))
|
||||||
|
.and(T_PERSON.PK.isNotNull())
|
||||||
|
.orderBy(V_CAMP.ARRIVE.desc());
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.trace(sql);
|
||||||
|
Map<Integer, MyCampBookingBean> map = new HashMap<>();
|
||||||
|
Iterator<Record9<String, String, Double, Boolean, LocalDateTime, LocalDateTime, Integer, String, String>> i = sql.fetch().iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
Record r = i.next();
|
||||||
|
Integer fkCamp = r.get(V_CAMP.PK);
|
||||||
|
MyCampBookingBean bean = map.get(fkCamp);
|
||||||
|
if (bean == null) {
|
||||||
|
bean = new MyCampBookingBean();
|
||||||
|
map.put(fkCamp, bean);
|
||||||
|
}
|
||||||
|
bean.setFkCamp(fkCamp);
|
||||||
|
bean.setLocationName(r.get(V_CAMP.LOCATION_NAME));
|
||||||
|
bean.setCampName(String.format("%s %4.0f", r.get(V_CAMP.NAME), r.get(V_CAMP.YEAR)).trim());
|
||||||
|
bean.setIsOver(r.get(V_CAMP.IS_OVER));
|
||||||
|
bean.setArrive(r.get(V_CAMP.ARRIVE));
|
||||||
|
bean.setDepart(r.get(V_CAMP.DEPART));
|
||||||
|
bean.getPerson().add(MyPersonBean.of(null, r.get(T_PERSON.FORENAME), r.get(T_PERSON.SURNAME)));
|
||||||
|
}
|
||||||
|
List<MyCampBookingBean> list = new ArrayList<>(map.values());
|
||||||
|
list.sort((o1, o2) -> (o1 == null || o1.getArrive() == null || o2 == null) ? 0 : o1.getArrive().compareTo(o2.getArrive()));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.campside;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.campside.model.MyCampBookingBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CampsideService {
|
||||||
|
@Autowired
|
||||||
|
private CampsideRepository repository;
|
||||||
|
|
||||||
|
public List<MyCampBookingBean> getCampBookingsOf(String currentUser) {
|
||||||
|
return repository.getMyCampBookings(currentUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.campside.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MyCampBookingBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer fkCamp;
|
||||||
|
private String locationName;
|
||||||
|
private String campName;
|
||||||
|
private Boolean isOver;
|
||||||
|
private LocalDateTime arrive;
|
||||||
|
private LocalDateTime depart;
|
||||||
|
private final List<MyPersonBean> person;
|
||||||
|
|
||||||
|
public MyCampBookingBean() {
|
||||||
|
person = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fkCamp
|
||||||
|
*/
|
||||||
|
public Integer getFkCamp() {
|
||||||
|
return fkCamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fkCamp the fkCamp to set
|
||||||
|
*/
|
||||||
|
public void setFkCamp(Integer fkCamp) {
|
||||||
|
this.fkCamp = fkCamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the locationName
|
||||||
|
*/
|
||||||
|
public String getLocationName() {
|
||||||
|
return locationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param locationName the locationName to set
|
||||||
|
*/
|
||||||
|
public void setLocationName(String locationName) {
|
||||||
|
this.locationName = locationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campName
|
||||||
|
*/
|
||||||
|
public String getCampName() {
|
||||||
|
return campName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param campName the campName to set
|
||||||
|
*/
|
||||||
|
public void setCampName(String campName) {
|
||||||
|
this.campName = campName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the isOver
|
||||||
|
*/
|
||||||
|
public Boolean getIsOver() {
|
||||||
|
return isOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isOver the isOver to set
|
||||||
|
*/
|
||||||
|
public void setIsOver(Boolean isOver) {
|
||||||
|
this.isOver = isOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the person
|
||||||
|
*/
|
||||||
|
public List<MyPersonBean> getPerson() {
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the arrive
|
||||||
|
*/
|
||||||
|
public LocalDateTime getArrive() {
|
||||||
|
return arrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param arrive the arrive to set
|
||||||
|
*/
|
||||||
|
public void setArrive(LocalDateTime arrive) {
|
||||||
|
this.arrive = arrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the depart
|
||||||
|
*/
|
||||||
|
public LocalDateTime getDepart() {
|
||||||
|
return depart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param depart the depart to set
|
||||||
|
*/
|
||||||
|
public void setDepart(LocalDateTime depart) {
|
||||||
|
this.depart = depart;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.campside.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MyPersonBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer pkPerson;
|
||||||
|
private String forename;
|
||||||
|
private String surname;
|
||||||
|
|
||||||
|
public static final MyPersonBean of(Integer pkPerson, String forename, String surname) {
|
||||||
|
MyPersonBean bean = new MyPersonBean();
|
||||||
|
bean.setPkPerson(pkPerson);
|
||||||
|
bean.setForename(forename);
|
||||||
|
bean.setSurname(surname);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the forename
|
||||||
|
*/
|
||||||
|
public String getForename() {
|
||||||
|
return forename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param forename the forename to set
|
||||||
|
*/
|
||||||
|
public void setForename(String forename) {
|
||||||
|
this.forename = forename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pkPerson
|
||||||
|
*/
|
||||||
|
public Integer getPkPerson() {
|
||||||
|
return pkPerson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pkPerson the pkPerson to set
|
||||||
|
*/
|
||||||
|
public void setPkPerson(Integer pkPerson) {
|
||||||
|
this.pkPerson = pkPerson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the surname
|
||||||
|
*/
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param surname the surname to set
|
||||||
|
*/
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
<th:block layout:fragment="content">
|
<th:block layout:fragment="content">
|
||||||
<div class="mainpage">
|
<div class="mainpage">
|
||||||
<div th:replace="~{/fragments/camplist.html::camplist(camps=${camps})}"></div>
|
<div th:replace="~{/fragments/camplist.html::camplist(camps=${camps})}"></div>
|
||||||
|
<br />
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="btn btn-outline-secondary titlefont d-inline-block" th:href="@{/campside}">Zu meinen Freizeiten</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</th:block>
|
</th:block>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer 2</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<th:block layout:fragment="content">
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
Diese Übersicht wurde noch nicht entwickelt.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer 2</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<th:block layout:fragment="content">
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
Diese Seite befindet sich noch im Aufbau. Nutze vorübergehend besser <a th:href="@{/camplist}">die Freizeitübersicht</a>.
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-primary menufont" th:if="${myCampBookings.size() < 1}">Für diese Freizeit hast du keine Anmeldedaten.</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row g-2">
|
||||||
|
<div class="col" th:each="b : ${myCampBookings}">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="headlinefont" th:text="${b.campName}"></div>
|
||||||
|
<div class="menufont" th:text="${#temporals.format(b.arrive, 'dd.MM.') + ' - ' + #temporals.format(b.depart, 'dd.MM.')}"></div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<span class="menufont">von dir angemeldet:</span><br />
|
||||||
|
<div th:each="p : ${b.person}">
|
||||||
|
<span th:text="${p.forename}"></span> <span th:text="${p.surname}"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<a class="btn btn-outline-secondary" th:href="@{/campside/{id}(id=${b.fkCamp})}">Freizeitdetails</a>
|
||||||
|
<a class="btn btn-outline-secondary" th:href="@{/campside/{id}/plan(id=${b.fkCamp})}">Freizeitplan</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer 2</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<th:block layout:fragment="content">
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="alert alert-info">
|
||||||
|
Diese Übersicht wurde noch nicht entwickelt. Sie wird nur für Mitarbeiter verfügbar sein.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user