20 Commits

Author SHA1 Message Date
27c1669ed3 make scrolling work again 2025-06-07 19:42:49 +02:00
3bb68aff1f last finetuning 2025-06-07 18:45:01 +02:00
4c32a12d2d slide of thumbnails experiments 2025-05-31 10:25:38 +02:00
485a222be4 stock images description properties file 2025-05-29 17:53:18 +02:00
82ce501f39 start page final changes 2025-05-29 16:51:55 +02:00
d3389e4813 more welcome page gimmicks 2025-05-13 23:06:17 +02:00
bdfe54a148 some progress on landing page 2025-05-05 22:17:02 +02:00
1d67aefa4d redesign of the landing page, see #20 2025-04-05 17:48:18 +02:00
a801d3178a changed menu, see #19 2025-04-03 22:45:26 +02:00
15a4388490 transition on logo hover 2025-03-30 22:25:47 +02:00
5a891c085d login icon hover effect 2025-03-27 22:29:39 +01:00
8cf1857c24 logo as button, see #18 2025-03-27 22:14:47 +01:00
890d46dcdd added image of lars 2025-03-24 21:45:40 +01:00
b26b014225 added lars 2025-03-23 22:44:35 +01:00
2b2246f2de start booking with time now 2025-03-23 22:32:26 +01:00
92970d8c63 src/main/resources/templates/fragments/camplist.html aktualisiert
added registration start time info
2025-03-23 08:21:24 +01:00
be4b75eef4 merged progress 2024-11-30 17:35:31 +01:00
31727e23ac removed ok button on revoked, see #9 2024-11-30 17:33:50 +01:00
2abb937725 confirmation accepts deletion of revoked registrations 2024-10-26 16:44:26 +02:00
b5403ae20c still buggy on rejecting people and loading old bookings 2024-10-23 22:42:15 +02:00
59 changed files with 1077 additions and 518 deletions

View File

@ -6,13 +6,6 @@
<attribute name="gradle_used_by_scope" value="main,test"/> <attribute name="gradle_used_by_scope" value="main,test"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources"> <classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes> <attributes>
<attribute name="gradle_scope" value="main"/> <attribute name="gradle_scope" value="main"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>camporganizer2</name> <name>CampOrganizer2</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>

View File

@ -1,5 +1,5 @@
plugins { plugins {
id 'org.springframework.boot' version '3.2.4' id 'org.springframework.boot' version '3.3.4'
id "io.spring.dependency-management" version "1.1.4" id "io.spring.dependency-management" version "1.1.4"
id 'java' id 'java'
id 'war' id 'war'
@ -8,7 +8,7 @@ plugins {
} }
group = 'de.jottyfan.camporganizer' group = 'de.jottyfan.camporganizer'
version = '0.8.6' version = '0.9.7'
description = """CampOrganizer2""" description = """CampOrganizer2"""
@ -40,19 +40,20 @@ war {
} }
dependencies { dependencies {
implementation 'org.jooq:jooq:3.19.6' implementation 'org.jooq:jooq:3.19.14'
implementation 'de.jottyfan:COJooq:2024.03.16c' implementation 'de.jottyfan:COJooq:2024.10.24'
implementation 'org.apache.logging.log4j:log4j-api:2.23.1' implementation 'org.apache.logging.log4j:log4j-api:2.24.1'
implementation 'org.apache.logging.log4j:log4j-core:2.23.1' implementation 'org.apache.logging.log4j:log4j-core:2.24.1'
implementation 'org.apache.logging.log4j:log4j-to-slf4j:2.23.1' implementation 'org.apache.logging.log4j:log4j-to-slf4j:2.24.1'
implementation 'org.webjars:bootstrap:5.3.2' implementation 'org.webjars:bootstrap:5.3.3'
implementation 'org.webjars:font-awesome:6.5.1' implementation 'org.webjars:font-awesome:6.5.2'
implementation 'org.webjars:jquery:3.7.1' implementation 'org.webjars:jquery:3.7.1'
implementation 'org.webjars:popper.js:2.11.7' implementation 'org.webjars:popper.js:2.11.7'
implementation 'org.webjars:datatables:1.13.5' implementation 'org.webjars:datatables:1.13.5'
implementation 'org.webjars:select2:4.0.13' implementation 'org.webjars:select2:4.0.13'
implementation 'org.webjars.npm:fancyapps__fancybox:3.5.7'
implementation 'net.sf.biweekly:biweekly:0.6.7' implementation 'net.sf.biweekly:biweekly:0.6.7'
@ -74,12 +75,12 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jooq' implementation 'org.springframework.boot:spring-boot-starter-jooq'
implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-security'
implementation "org.springframework.boot:spring-boot-starter-oauth2-client" implementation "org.springframework.boot:spring-boot-starter-oauth2-client"
implementation 'org.springframework.security:spring-security-oauth2-authorization-server:1.2.1' implementation 'org.springframework.security:spring-security-oauth2-authorization-server:1.3.3'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.3.0' implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.4.0'
implementation 'commons-io:commons-io:2.15.1' implementation 'commons-io:commons-io:2.15.1'

View File

@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class Main extends SpringBootServletInitializer { public class Main extends SpringBootServletInitializer {
private static final Logger LOGGER = LogManager.getLogger(Main.class); public static final Logger LOGGER = LogManager.getLogger(Main.class);
@Override @Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
@ -31,7 +31,7 @@ public class Main extends SpringBootServletInitializer {
Path path = Paths.get(""); Path path = Paths.get("");
String p = path.toAbsolutePath().toString(); String p = path.toAbsolutePath().toString();
p = p.substring(p.lastIndexOf("/") + 1); p = p.substring(p.lastIndexOf("/") + 1);
LOGGER.info("running in {}", p); LOGGER.debug("running in {}", p);
// TODO: put p + "properties" somehow into consideration to load the application.properties // TODO: put p + "properties" somehow into consideration to load the application.properties
SpringApplication.run(Main.class, args); SpringApplication.run(Main.class, args);
} }

View File

@ -96,7 +96,7 @@ public class AdminRepository {
.groupBy(T_DOCUMENT.PK, T_DOCUMENT.NAME, T_DOCUMENT.DOCTYPE, T_DOCUMENT.FILETYPE) .groupBy(T_DOCUMENT.PK, T_DOCUMENT.NAME, T_DOCUMENT.DOCTYPE, T_DOCUMENT.FILETYPE)
.orderBy(T_DOCUMENT.PK); .orderBy(T_DOCUMENT.PK);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]> r = sql.fetchOne(); Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]> r = sql.fetchOne();
if (r != null) { if (r != null) {
DocumentBean bean = new DocumentBean(); DocumentBean bean = new DocumentBean();
@ -129,7 +129,7 @@ public class AdminRepository {
.groupBy(T_DOCUMENT.PK, T_DOCUMENT.NAME, T_DOCUMENT.DOCTYPE, T_DOCUMENT.FILETYPE) .groupBy(T_DOCUMENT.PK, T_DOCUMENT.NAME, T_DOCUMENT.DOCTYPE, T_DOCUMENT.FILETYPE)
.orderBy(T_DOCUMENT.PK); .orderBy(T_DOCUMENT.PK);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql.toString());
List<DocumentBean> list = new ArrayList<>(); List<DocumentBean> list = new ArrayList<>();
Iterator<Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]>> i = sql.fetch().iterator(); Iterator<Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -162,7 +162,7 @@ public class AdminRepository {
.from(T_DOCUMENT) .from(T_DOCUMENT)
.where(condition); .where(condition);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<DocumentBean> list = new ArrayList<>(); List<DocumentBean> list = new ArrayList<>();
Iterator<Record4<Integer, String, EnumDocument, EnumFiletype>> i = sql.fetch().iterator(); Iterator<Record4<Integer, String, EnumDocument, EnumFiletype>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -202,7 +202,7 @@ public class AdminRepository {
.set(T_DOCUMENT.FILETYPE, bean.getFiletype()) .set(T_DOCUMENT.FILETYPE, bean.getFiletype())
.where(T_DOCUMENT.PK.eq(bean.getPk())); .where(T_DOCUMENT.PK.eq(bean.getPk()));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
lrw.add(sql.execute()); lrw.add(sql.execute());
} else { } else {
InsertResultStep<TDocumentRecord> sql = DSL.using(c) InsertResultStep<TDocumentRecord> sql = DSL.using(c)
@ -215,7 +215,7 @@ public class AdminRepository {
.values(bean.getName(), bean.getDoctype(), bean.getDocument(), bean.getFiletype()) .values(bean.getName(), bean.getDoctype(), bean.getDocument(), bean.getFiletype())
.returning(T_DOCUMENT.PK); .returning(T_DOCUMENT.PK);
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
pk = sql.fetchOne().get(T_DOCUMENT.PK); pk = sql.fetchOne().get(T_DOCUMENT.PK);
lrw.add(1); lrw.add(1);
} }
@ -233,7 +233,7 @@ public class AdminRepository {
.onConflict(T_DOCUMENTROLE.FK_DOCUMENT, T_DOCUMENTROLE.CAMPROLE) .onConflict(T_DOCUMENTROLE.FK_DOCUMENT, T_DOCUMENTROLE.CAMPROLE)
.doNothing(); .doNothing();
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
lrw.add(sql.execute()); lrw.add(sql.execute());
removeCandidates.remove(role); removeCandidates.remove(role);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -246,7 +246,7 @@ public class AdminRepository {
.where(T_DOCUMENTROLE.FK_DOCUMENT.eq(pk)) .where(T_DOCUMENTROLE.FK_DOCUMENT.eq(pk))
.and(T_DOCUMENTROLE.CAMPROLE.in(removeCandidates)); .and(T_DOCUMENTROLE.CAMPROLE.in(removeCandidates));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
lrw.add(sql.execute()); lrw.add(sql.execute());
}); });
return lrw.getCounter(); return lrw.getCounter();
@ -268,7 +268,7 @@ public class AdminRepository {
.set(T_CAMP.FK_DOCUMENT, (Integer) null) .set(T_CAMP.FK_DOCUMENT, (Integer) null)
.where(T_CAMP.FK_DOCUMENT.eq(pk)); .where(T_CAMP.FK_DOCUMENT.eq(pk));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
lrw.add(sql.execute()); lrw.add(sql.execute());
UpdateConditionStep<TLocationRecord> sql1 = DSL.using(t) UpdateConditionStep<TLocationRecord> sql1 = DSL.using(t)
@ -277,7 +277,7 @@ public class AdminRepository {
.set(T_LOCATION.FK_DOCUMENT, (Integer) null) .set(T_LOCATION.FK_DOCUMENT, (Integer) null)
.where(T_LOCATION.FK_DOCUMENT.eq(pk)); .where(T_LOCATION.FK_DOCUMENT.eq(pk));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql1.toString()); LOGGER.trace(sql1);
lrw.add(sql1.execute()); lrw.add(sql1.execute());
DeleteConditionStep<TDocumentroleRecord> sql2 = DSL.using(t) DeleteConditionStep<TDocumentroleRecord> sql2 = DSL.using(t)
@ -285,7 +285,7 @@ public class AdminRepository {
.deleteFrom(T_DOCUMENTROLE) .deleteFrom(T_DOCUMENTROLE)
.where(T_DOCUMENTROLE.FK_DOCUMENT.eq(pk)); .where(T_DOCUMENTROLE.FK_DOCUMENT.eq(pk));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql2.toString()); LOGGER.trace(sql2);
lrw.add(sql2.execute()); lrw.add(sql2.execute());
DeleteConditionStep<TDocumentRecord> sql3 = DSL.using(t) DeleteConditionStep<TDocumentRecord> sql3 = DSL.using(t)
@ -293,7 +293,7 @@ public class AdminRepository {
.deleteFrom(T_DOCUMENT) .deleteFrom(T_DOCUMENT)
.where(T_DOCUMENT.PK.eq(pk)); .where(T_DOCUMENT.PK.eq(pk));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql3.toString()); LOGGER.trace(sql3);
lrw.add(sql3.execute()); lrw.add(sql3.execute());
}); });
return lrw.getCounter(); return lrw.getCounter();
@ -306,7 +306,7 @@ public class AdminRepository {
*/ */
public List<LocationBean> getLocations() { public List<LocationBean> getLocations() {
SelectWhereStep<TLocationRecord> sql = jooq.selectFrom(T_LOCATION); SelectWhereStep<TLocationRecord> sql = jooq.selectFrom(T_LOCATION);
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<LocationBean> list = new ArrayList<>(); List<LocationBean> list = new ArrayList<>();
for (TLocationRecord r : sql.fetch()) { for (TLocationRecord r : sql.fetch()) {
list.add(LocationBean.of(r)); list.add(LocationBean.of(r));
@ -322,7 +322,7 @@ public class AdminRepository {
*/ */
public LocationBean getLocation(Integer id) { public LocationBean getLocation(Integer id) {
SelectConditionStep<TLocationRecord> sql = jooq.selectFrom(T_LOCATION).where(T_LOCATION.PK.eq(id)); SelectConditionStep<TLocationRecord> sql = jooq.selectFrom(T_LOCATION).where(T_LOCATION.PK.eq(id));
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return LocationBean.of(sql.fetchOne()); return LocationBean.of(sql.fetchOne());
} }
@ -334,7 +334,7 @@ public class AdminRepository {
*/ */
public Integer deleteLocation(Integer id) { public Integer deleteLocation(Integer id) {
DeleteConditionStep<TLocationRecord> sql = jooq.deleteFrom(T_LOCATION).where(T_LOCATION.PK.eq(id)); DeleteConditionStep<TLocationRecord> sql = jooq.deleteFrom(T_LOCATION).where(T_LOCATION.PK.eq(id));
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return sql.execute(); return sql.execute();
} }
@ -356,7 +356,7 @@ public class AdminRepository {
T_LOCATION.URL) T_LOCATION.URL)
.values(bean.getName(), bean.getFkDocument(), bean.getUrl()); .values(bean.getName(), bean.getFkDocument(), bean.getUrl());
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
lrw.add(sql.execute()); lrw.add(sql.execute());
} else { } else {
UpdateConditionStep<TLocationRecord> sql = DSL.using(t) UpdateConditionStep<TLocationRecord> sql = DSL.using(t)
@ -367,7 +367,7 @@ public class AdminRepository {
.set(T_LOCATION.URL, bean.getUrl()) .set(T_LOCATION.URL, bean.getUrl())
.where(T_LOCATION.PK.eq(bean.getPk())); .where(T_LOCATION.PK.eq(bean.getPk()));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
lrw.add(sql.execute()); lrw.add(sql.execute());
} }
}); });
@ -381,7 +381,7 @@ public class AdminRepository {
*/ */
public List<CampBean> getAllCamps() { public List<CampBean> getAllCamps() {
SelectWhereStep<TCampRecord> sql = jooq.selectFrom(T_CAMP); SelectWhereStep<TCampRecord> sql = jooq.selectFrom(T_CAMP);
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<CampBean> list = new ArrayList<>(); List<CampBean> list = new ArrayList<>();
for (TCampRecord r : sql.fetch()) { for (TCampRecord r : sql.fetch()) {
list.add(CampBean.of(r)); list.add(CampBean.of(r));
@ -397,7 +397,7 @@ public class AdminRepository {
*/ */
public CampBean getCamp(Integer id) { public CampBean getCamp(Integer id) {
SelectConditionStep<TCampRecord> sql = jooq.selectFrom(T_CAMP).where(T_CAMP.PK.eq(id)); SelectConditionStep<TCampRecord> sql = jooq.selectFrom(T_CAMP).where(T_CAMP.PK.eq(id));
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return CampBean.of(sql.fetchOne()); return CampBean.of(sql.fetchOne());
} }
@ -411,11 +411,11 @@ public class AdminRepository {
LambdaResultWrapper lrw = new LambdaResultWrapper(); LambdaResultWrapper lrw = new LambdaResultWrapper();
jooq.transaction(t -> { jooq.transaction(t -> {
SelectConditionStep<TPersonRecord> sql1 = DSL.using(t).selectFrom(T_PERSON).where(T_PERSON.FK_CAMP.eq(id)); SelectConditionStep<TPersonRecord> sql1 = DSL.using(t).selectFrom(T_PERSON).where(T_PERSON.FK_CAMP.eq(id));
LOGGER.debug(sql1.toString()); LOGGER.trace(sql1);
Integer registrations = sql1.fetch().size(); Integer registrations = sql1.fetch().size();
if (registrations < 1) { if (registrations < 1) {
DeleteConditionStep<TCampRecord> sql2 = DSL.using(t).deleteFrom(T_CAMP).where(T_CAMP.PK.eq(id)); DeleteConditionStep<TCampRecord> sql2 = DSL.using(t).deleteFrom(T_CAMP).where(T_CAMP.PK.eq(id));
LOGGER.debug(sql2.toString()); LOGGER.trace(sql2);
sql2.execute(); sql2.execute();
} else { } else {
lrw.putString("error", String lrw.putString("error", String
@ -435,10 +435,8 @@ public class AdminRepository {
jooq.transaction(t -> { jooq.transaction(t -> {
LocalDate arriveDate = bean.getArrive(); LocalDate arriveDate = bean.getArrive();
LocalDate departDate = bean.getDepart(); LocalDate departDate = bean.getDepart();
LocalDate startBookingDate = bean.getStartBooking();
LocalDateTime arrive = arriveDate == null ? null : arriveDate.atStartOfDay(); LocalDateTime arrive = arriveDate == null ? null : arriveDate.atStartOfDay();
LocalDateTime depart = departDate == null ? null : departDate.atStartOfDay(); LocalDateTime depart = departDate == null ? null : departDate.atStartOfDay();
LocalDateTime startBooking = startBookingDate == null ? null : startBookingDate.atStartOfDay();
if (bean.getPk() == null) { if (bean.getPk() == null) {
InsertValuesStep16<TCampRecord, LocalDateTime, String, LocalDateTime, Integer, Integer, Integer, Boolean, Integer, Integer, String, String, Integer, Integer, Integer, Integer, LocalDateTime> sql = DSL InsertValuesStep16<TCampRecord, LocalDateTime, String, LocalDateTime, Integer, Integer, Integer, Boolean, Integer, Integer, String, String, Integer, Integer, Integer, Integer, LocalDateTime> sql = DSL
.using(t) .using(t)
@ -462,9 +460,9 @@ public class AdminRepository {
T_CAMP.START_BOOKING) T_CAMP.START_BOOKING)
.values(arrive, bean.getCountries(), depart, bean.getFkDocument(), bean.getFkLocation(), bean.getFkProfile(), .values(arrive, bean.getCountries(), depart, bean.getFkDocument(), bean.getFkLocation(), bean.getFkProfile(),
bean.getLockSales() != null ? bean.getLockSales() : false, bean.getMaxAge(), bean.getMinAge(), bean.getName(), bean.getPrice(), bean.getLockSales() != null ? bean.getLockSales() : false, bean.getMaxAge(), bean.getMinAge(), bean.getName(), bean.getPrice(),
bean.getBedsFemale(), bean.getBedsMale(), bean.getBlockedBedsFemale(), bean.getBlockedBedsMale(), startBooking); bean.getBedsFemale(), bean.getBedsMale(), bean.getBlockedBedsFemale(), bean.getBlockedBedsMale(), bean.getStartBooking());
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
sql.execute(); sql.execute();
} else { } else {
UpdateConditionStep<TCampRecord> sql = DSL.using(t) UpdateConditionStep<TCampRecord> sql = DSL.using(t)
@ -485,10 +483,10 @@ public class AdminRepository {
.set(T_CAMP.BEDS_MALE, bean.getBedsMale()) .set(T_CAMP.BEDS_MALE, bean.getBedsMale())
.set(T_CAMP.BLOCKED_BEDS_FEMALE, bean.getBlockedBedsFemale()) .set(T_CAMP.BLOCKED_BEDS_FEMALE, bean.getBlockedBedsFemale())
.set(T_CAMP.BLOCKED_BEDS_MALE, bean.getBlockedBedsMale()) .set(T_CAMP.BLOCKED_BEDS_MALE, bean.getBlockedBedsMale())
.set(T_CAMP.START_BOOKING, startBooking) .set(T_CAMP.START_BOOKING, bean.getStartBooking())
.where(T_CAMP.PK.eq(bean.getPk())); .where(T_CAMP.PK.eq(bean.getPk()));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
sql.execute(); sql.execute();
} }
}); });
@ -502,7 +500,7 @@ public class AdminRepository {
*/ */
public List<ProfileBean> getProfiles() { public List<ProfileBean> getProfiles() {
SelectWhereStep<TProfileRecord> sql = jooq.selectFrom(T_PROFILE); SelectWhereStep<TProfileRecord> sql = jooq.selectFrom(T_PROFILE);
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<ProfileBean> list = new ArrayList<>(); List<ProfileBean> list = new ArrayList<>();
for (TProfileRecord r : sql.fetch()) { for (TProfileRecord r : sql.fetch()) {
list.add(ProfileBean.of(r)); list.add(ProfileBean.of(r));
@ -542,7 +540,7 @@ public class AdminRepository {
.where(T_CAMPPROFILE.MODULE.eq(module)) .where(T_CAMPPROFILE.MODULE.eq(module))
.orderBy(T_CAMP.ARRIVE, T_PROFILE.PK); .orderBy(T_CAMP.ARRIVE, T_PROFILE.PK);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
PrivilegesContainerBean pcb = new PrivilegesContainerBean(); PrivilegesContainerBean pcb = new PrivilegesContainerBean();
Iterator<Record4<Integer, String, LocalDateTime, String>> i = sql.fetch().iterator(); Iterator<Record4<Integer, String, LocalDateTime, String>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -579,7 +577,7 @@ public class AdminRepository {
.where(T_CAMPPROFILE.FK_PROFILE.eq(user)) .where(T_CAMPPROFILE.FK_PROFILE.eq(user))
.orderBy(T_CAMP.ARRIVE); .orderBy(T_CAMP.ARRIVE);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
PrivilegesContainerBean pcb = new PrivilegesContainerBean(); PrivilegesContainerBean pcb = new PrivilegesContainerBean();
Iterator<Record4<Integer, String, LocalDateTime, EnumModule>> i = sql.fetch().iterator(); Iterator<Record4<Integer, String, LocalDateTime, EnumModule>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -618,7 +616,7 @@ public class AdminRepository {
.where(T_CAMPPROFILE.FK_CAMP.eq(camp)) .where(T_CAMPPROFILE.FK_CAMP.eq(camp))
.orderBy(T_PROFILE.SURNAME, T_PROFILE.FORENAME); .orderBy(T_PROFILE.SURNAME, T_PROFILE.FORENAME);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
PrivilegesContainerBean pcb = new PrivilegesContainerBean(); PrivilegesContainerBean pcb = new PrivilegesContainerBean();
Iterator<Record4<Integer, String, String, EnumModule>> i = sql.fetch().iterator(); Iterator<Record4<Integer, String, String, EnumModule>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -644,7 +642,7 @@ public class AdminRepository {
*/ */
public void deleteFromCampProfile(Integer id) { public void deleteFromCampProfile(Integer id) {
DeleteConditionStep<TCampprofileRecord> sql = jooq.deleteFrom(T_CAMPPROFILE).where(T_CAMPPROFILE.PK.eq(id)); DeleteConditionStep<TCampprofileRecord> sql = jooq.deleteFrom(T_CAMPPROFILE).where(T_CAMPPROFILE.PK.eq(id));
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
sql.execute(); sql.execute();
} }
@ -668,7 +666,7 @@ public class AdminRepository {
T_CAMPPROFILE.MODULE) T_CAMPPROFILE.MODULE)
.doNothing(); .doNothing();
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
sql.execute(); sql.execute();
} }
} }

View File

@ -58,8 +58,8 @@ public class CampBean implements Serializable {
@Min(value = 0) @Min(value = 0)
private Integer blockedBedsMale; private Integer blockedBedsMale;
@NotNull @NotNull
@DateTimeFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDate startBooking; private LocalDateTime startBooking;
/** /**
* generate a camp bean out of r * generate a camp bean out of r
@ -74,7 +74,6 @@ public class CampBean implements Serializable {
CampBean bean = new CampBean(); CampBean bean = new CampBean();
LocalDateTime arrive = r.getArrive(); LocalDateTime arrive = r.getArrive();
LocalDateTime depart = r.getDepart(); LocalDateTime depart = r.getDepart();
LocalDateTime startBooking = r.getStartBooking();
bean.setArrive(arrive == null ? null : arrive.toLocalDate()); bean.setArrive(arrive == null ? null : arrive.toLocalDate());
bean.setCountries(r.getCountries()); bean.setCountries(r.getCountries());
bean.setDepart(depart == null ? null : depart.toLocalDate()); bean.setDepart(depart == null ? null : depart.toLocalDate());
@ -91,7 +90,7 @@ public class CampBean implements Serializable {
bean.setBedsMale(r.getBedsMale()); bean.setBedsMale(r.getBedsMale());
bean.setBlockedBedsFemale(r.getBlockedBedsFemale()); bean.setBlockedBedsFemale(r.getBlockedBedsFemale());
bean.setBlockedBedsMale(r.getBlockedBedsMale()); bean.setBlockedBedsMale(r.getBlockedBedsMale());
bean.setStartBooking(startBooking == null ? null : startBooking.toLocalDate()); bean.setStartBooking(r.getStartBooking());
return bean; return bean;
} }
@ -353,14 +352,14 @@ public class CampBean implements Serializable {
/** /**
* @return the startBooking * @return the startBooking
*/ */
public LocalDate getStartBooking() { public LocalDateTime getStartBooking() {
return startBooking; return startBooking;
} }
/** /**
* @param startBooking the startBooking to set * @param startBooking the startBooking to set
*/ */
public void setStartBooking(LocalDate startBooking) { public void setStartBooking(LocalDateTime startBooking) {
this.startBooking = startBooking; this.startBooking = startBooking;
} }
} }

View File

@ -1,8 +1,8 @@
package de.jottyfan.camporganizer.module.business.bookings; package de.jottyfan.camporganizer.module.business.bookings;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPPROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON; 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.T_PROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPPROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP; import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -27,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.camporganizer.db.EnumConverter; import de.jottyfan.camporganizer.db.EnumConverter;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule; import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
import de.jottyfan.camporganizer.module.business.bookings.model.BookerBean; import de.jottyfan.camporganizer.module.business.bookings.model.BookerBean;
@ -52,9 +53,9 @@ public class BookingsRepository {
* @return a list of bookings; an empty one at least * @return a list of bookings; an empty one at least
*/ */
public List<BookerBean> getBookings(String username) { public List<BookerBean> getBookings(String username) {
SelectSeekStep4<Record10<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double>, EnumCamprole, EnumSex, String, String> sql = jooq SelectSeekStep4<Record10<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double>, EnumCamprole, EnumSex, String, String> sql = jooq
// @formatter:off // @formatter:off
.select(T_PERSON.PK, T_PERSON.ACCEPT, T_PERSON.PAID, T_PERSON.FORENAME, T_PERSON.SURNAME, T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.CREATED, V_CAMP.NAME, V_CAMP.YEAR) .select(T_PERSON.PK, T_PERSON.PROGRESS, T_PERSON.PAID, T_PERSON.FORENAME, T_PERSON.SURNAME, T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.CREATED, V_CAMP.NAME, V_CAMP.YEAR)
.from(T_PERSON) .from(T_PERSON)
.leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_PERSON.FK_CAMP)) .leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_PERSON.FK_CAMP))
.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.business)) .leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.business))
@ -62,15 +63,16 @@ public class BookingsRepository {
.where(T_PROFILE.USERNAME.eq(username)) .where(T_PROFILE.USERNAME.eq(username))
.orderBy(T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.SURNAME, T_PERSON.FORENAME); .orderBy(T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.SURNAME, T_PERSON.FORENAME);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<BookerBean> list = new ArrayList<>(); List<BookerBean> list = new ArrayList<>();
Iterator<Record10<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double>> i = sql.fetch().iterator(); Iterator<Record10<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
Record10<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double> r = i.next(); Record10<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double> r = i.next();
String forename = r.get(T_PERSON.FORENAME); String forename = r.get(T_PERSON.FORENAME);
String surname = r.get(T_PERSON.SURNAME); String surname = r.get(T_PERSON.SURNAME);
EnumCamprole role = r.get(T_PERSON.CAMPROLE); EnumCamprole role = r.get(T_PERSON.CAMPROLE);
EnumSex sex = r.get(T_PERSON.SEX); EnumSex sex = r.get(T_PERSON.SEX);
EnumProgress progress = r.get(T_PERSON.PROGRESS);
String campName = r.get(V_CAMP.NAME); String campName = r.get(V_CAMP.NAME);
Double campYear = r.get(V_CAMP.YEAR); Double campYear = r.get(V_CAMP.YEAR);
BookerBean bean = new BookerBean(); BookerBean bean = new BookerBean();
@ -79,7 +81,7 @@ public class BookingsRepository {
bean.setRole(EnumConverter.role2GermanNames(role)); bean.setRole(EnumConverter.role2GermanNames(role));
bean.setSex(EnumConverter.sex2GermanNames(sex)); bean.setSex(EnumConverter.sex2GermanNames(sex));
bean.setBookingDate(r.get(T_PERSON.CREATED)); bean.setBookingDate(r.get(T_PERSON.CREATED));
bean.setAccept(r.get(T_PERSON.ACCEPT)); bean.setProgress(progress == null ? null : progress.getLiteral());
bean.setPaid(r.get(T_PERSON.PAID)); bean.setPaid(r.get(T_PERSON.PAID));
bean.setCamp(String.format("%s %4.0f", campName, campYear)); bean.setCamp(String.format("%s %4.0f", campName, campYear));
list.add(bean); list.add(bean);
@ -95,10 +97,10 @@ public class BookingsRepository {
* @return the booker bean or null * @return the booker bean or null
*/ */
public BookerBean getBooking(Integer id, String username) { public BookerBean getBooking(Integer id, String username) {
SelectConditionStep<Record13<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, BigDecimal, String, Double, String, Integer>> sql = jooq SelectConditionStep<Record13<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, BigDecimal, String, Double, String, Integer>> sql = jooq
// @formatter:off // @formatter:off
.select(T_PERSON.PK, .select(T_PERSON.PK,
T_PERSON.ACCEPT, T_PERSON.PROGRESS,
T_PERSON.PAID, T_PERSON.PAID,
T_PERSON.FORENAME, T_PERSON.FORENAME,
T_PERSON.SURNAME, T_PERSON.SURNAME,
@ -117,7 +119,7 @@ public class BookingsRepository {
.where(T_PROFILE.USERNAME.eq(username)) .where(T_PROFILE.USERNAME.eq(username))
.and(T_PERSON.PK.eq(id)); .and(T_PERSON.PK.eq(id));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
Record r = sql.fetchOne(); Record r = sql.fetchOne();
if (r == null) { if (r == null) {
return null; return null;
@ -126,6 +128,7 @@ public class BookingsRepository {
String surname = r.get(T_PERSON.SURNAME); String surname = r.get(T_PERSON.SURNAME);
EnumCamprole role = r.get(T_PERSON.CAMPROLE); EnumCamprole role = r.get(T_PERSON.CAMPROLE);
EnumSex sex = r.get(T_PERSON.SEX); EnumSex sex = r.get(T_PERSON.SEX);
EnumProgress progress = r.get(T_PERSON.PROGRESS);
BigDecimal requiredPrice = r.get(T_PERSON.REQUIRED_PRICE); BigDecimal requiredPrice = r.get(T_PERSON.REQUIRED_PRICE);
String campName = r.get(V_CAMP.NAME); String campName = r.get(V_CAMP.NAME);
Double campYear = r.get(V_CAMP.YEAR); Double campYear = r.get(V_CAMP.YEAR);
@ -136,7 +139,7 @@ public class BookingsRepository {
bean.setRole(EnumConverter.role2GermanNames(role)); bean.setRole(EnumConverter.role2GermanNames(role));
bean.setSex(EnumConverter.sex2GermanNames(sex)); bean.setSex(EnumConverter.sex2GermanNames(sex));
bean.setBookingDate(r.get(T_PERSON.CREATED)); bean.setBookingDate(r.get(T_PERSON.CREATED));
bean.setAccept(r.get(T_PERSON.ACCEPT)); bean.setProgress(progress == null ? null : progress.getLiteral());
bean.setPaid(r.get(T_PERSON.PAID)); bean.setPaid(r.get(T_PERSON.PAID));
bean.setCamp(String.format("%s %4.0f", campName, campYear)); bean.setCamp(String.format("%s %4.0f", campName, campYear));
bean.setCampId(campId); bean.setCampId(campId);
@ -162,7 +165,7 @@ public class BookingsRepository {
.set(T_PERSON.PAID, value) .set(T_PERSON.PAID, value)
.where(T_PERSON.PK.eq(pk)); .where(T_PERSON.PK.eq(pk));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return sql.execute(); return sql.execute();
} }
} }

View File

@ -10,13 +10,13 @@ import java.time.LocalDateTime;
* *
*/ */
public class BookerBean implements Serializable { public class BookerBean implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 2L;
private Integer pk; private Integer pk;
private String name; private String name;
private String role; private String role;
private String sex; private String sex;
private Boolean accept; private String progress;
private LocalDateTime bookingDate; private LocalDateTime bookingDate;
private BigDecimal paid; private BigDecimal paid;
private String camp; private String camp;
@ -24,20 +24,6 @@ public class BookerBean implements Serializable {
private Integer campId; private Integer campId;
private BigDecimal requiredPrice; private BigDecimal requiredPrice;
/**
* @return the accept
*/
public Boolean getAccept() {
return accept;
}
/**
* @param accept the accept to set
*/
public void setAccept(Boolean accept) {
this.accept = accept;
}
/** /**
* @return the paid * @return the paid
*/ */
@ -141,4 +127,18 @@ public class BookerBean implements Serializable {
public void setRequiredPrice(BigDecimal requiredPrice) { public void setRequiredPrice(BigDecimal requiredPrice) {
this.requiredPrice = requiredPrice; this.requiredPrice = requiredPrice;
} }
/**
* @return the progress
*/
public String getProgress() {
return progress;
}
/**
* @param progress the progress to set
*/
public void setProgress(String progress) {
this.progress = progress;
}
} }

View File

@ -65,7 +65,7 @@ public class BusinessRepository {
.where(T_PROFILE.USERNAME.eq(username)) .where(T_PROFILE.USERNAME.eq(username))
.orderBy(T_CAMP.ARRIVE); .orderBy(T_CAMP.ARRIVE);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<CampBudgetBean> list = new ArrayList<>(); List<CampBudgetBean> list = new ArrayList<>();
Iterator<Record4<BigDecimal, String, Double, Integer>> i = sql.fetch().iterator(); Iterator<Record4<BigDecimal, String, Double, Integer>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -105,7 +105,7 @@ public class BusinessRepository {
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE)) .leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE))
.where(T_PROFILE.USERNAME.eq(username)); .where(T_PROFILE.USERNAME.eq(username));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<BusinessBean> list = new ArrayList<>(); List<BusinessBean> list = new ArrayList<>();
Iterator<Record9<Integer, String, String, String, String, LocalDateTime, String, BigDecimal, BigDecimal>> i = sql.fetch().iterator(); Iterator<Record9<Integer, String, String, String, String, LocalDateTime, String, BigDecimal, BigDecimal>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -140,7 +140,7 @@ public class BusinessRepository {
.set(T_PERSON.PAID, bean.getPaid()) .set(T_PERSON.PAID, bean.getPaid())
.where(T_PERSON.PK.eq(bean.getFkPerson())); .where(T_PERSON.PK.eq(bean.getFkPerson()));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
count += sql.execute(); count += sql.execute();
} }
} }

View File

@ -25,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.camporganizer.db.EnumConverter; import de.jottyfan.camporganizer.db.EnumConverter;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule; import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
import de.jottyfan.camporganizer.module.business.camp.model.CampBean; import de.jottyfan.camporganizer.module.business.camp.model.CampBean;
import de.jottyfan.camporganizer.module.business.camp.model.PersonBean; import de.jottyfan.camporganizer.module.business.camp.model.PersonBean;
@ -60,7 +61,7 @@ public class CampRepository {
.where(V_CAMP.PK.eq(pk)) .where(V_CAMP.PK.eq(pk))
.and(T_PROFILE.USERNAME.eq(username)); .and(T_PROFILE.USERNAME.eq(username));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
CampBean bean = new CampBean(); CampBean bean = new CampBean();
Iterator<Record6<String, Double, LocalDateTime, LocalDateTime, String, String>> i = sql.fetch().iterator(); Iterator<Record6<String, Double, LocalDateTime, LocalDateTime, String, String>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -84,9 +85,9 @@ public class CampRepository {
* @return a list of bookings; an empty one at least * @return a list of bookings; an empty one at least
*/ */
public List<PersonBean> getBookings(Integer pk, String username) { public List<PersonBean> getBookings(Integer pk, String username) {
SelectSeekStep4<Record8<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>, EnumCamprole, EnumSex, String, String> sql = jooq SelectSeekStep4<Record8<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>, EnumCamprole, EnumSex, String, String> sql = jooq
// @formatter:off // @formatter:off
.select(T_PERSON.PK, T_PERSON.ACCEPT, T_PERSON.PAID, T_PERSON.FORENAME, T_PERSON.SURNAME, T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.CREATED) .select(T_PERSON.PK, T_PERSON.PROGRESS, T_PERSON.PAID, T_PERSON.FORENAME, T_PERSON.SURNAME, T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.CREATED)
.from(T_PERSON) .from(T_PERSON)
.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.business)) .leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.business))
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE)) .leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE))
@ -94,22 +95,23 @@ public class CampRepository {
.and(T_PROFILE.USERNAME.eq(username)) .and(T_PROFILE.USERNAME.eq(username))
.orderBy(T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.SURNAME, T_PERSON.FORENAME); .orderBy(T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.SURNAME, T_PERSON.FORENAME);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<PersonBean> list = new ArrayList<>(); List<PersonBean> list = new ArrayList<>();
Iterator<Record8<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>> i = sql.fetch().iterator(); Iterator<Record8<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
Record8<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime> r = i.next(); Record8<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime> r = i.next();
String forename = r.get(T_PERSON.FORENAME); String forename = r.get(T_PERSON.FORENAME);
String surname = r.get(T_PERSON.SURNAME); String surname = r.get(T_PERSON.SURNAME);
EnumCamprole role = r.get(T_PERSON.CAMPROLE); EnumCamprole role = r.get(T_PERSON.CAMPROLE);
EnumSex sex = r.get(T_PERSON.SEX); EnumSex sex = r.get(T_PERSON.SEX);
EnumProgress progress = r.get(T_PERSON.PROGRESS);
PersonBean bean = new PersonBean(); PersonBean bean = new PersonBean();
bean.setPk(r.get(T_PERSON.PK)); bean.setPk(r.get(T_PERSON.PK));
bean.setName(String.format("%s %s", forename, surname)); bean.setName(String.format("%s %s", forename, surname));
bean.setRole(EnumConverter.role2GermanNames(role)); bean.setRole(EnumConverter.role2GermanNames(role));
bean.setSex(EnumConverter.sex2GermanNames(sex)); bean.setSex(EnumConverter.sex2GermanNames(sex));
bean.setBookingDate(r.get(T_PERSON.CREATED)); bean.setBookingDate(r.get(T_PERSON.CREATED));
bean.setAccept(r.get(T_PERSON.ACCEPT)); bean.setProgress(progress == null ? null : progress.getLiteral());
bean.setPaid(r.get(T_PERSON.PAID)); bean.setPaid(r.get(T_PERSON.PAID));
list.add(bean); list.add(bean);
} }

View File

@ -6,6 +6,7 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.module.business.camp.model.BookingBean; import de.jottyfan.camporganizer.module.business.camp.model.BookingBean;
import de.jottyfan.camporganizer.module.business.camp.model.CampBean; import de.jottyfan.camporganizer.module.business.camp.model.CampBean;
import de.jottyfan.camporganizer.module.business.camp.model.PersonBean; import de.jottyfan.camporganizer.module.business.camp.model.PersonBean;
@ -31,12 +32,12 @@ public class CampService {
Integer rejected = 0; Integer rejected = 0;
BigDecimal paid = new BigDecimal(0); BigDecimal paid = new BigDecimal(0);
for (PersonBean p : campGateway.getBookings(id, username)) { for (PersonBean p : campGateway.getBookings(id, username)) {
Boolean acceptence = p.getAccept(); String progress = p.getProgress();
if (acceptence == null) { if (EnumProgress.requested.getLiteral().equals(progress)) {
open += 1; open += 1;
} else if (acceptence) { } else if (EnumProgress.approved.getLiteral().equals(progress)) {
approved += 1; approved += 1;
} else { } else if (EnumProgress.rejected.getLiteral().equals(progress)) {
rejected += 1; rejected += 1;
} }
paid = paid.add(p.getPaid() == null ? new BigDecimal(0) : p.getPaid()); paid = paid.add(p.getPaid() == null ? new BigDecimal(0) : p.getPaid());

View File

@ -16,24 +16,10 @@ public class PersonBean implements Serializable {
private String name; private String name;
private String role; private String role;
private String sex; private String sex;
private Boolean accept; private String progress;
private LocalDateTime bookingDate; private LocalDateTime bookingDate;
private BigDecimal paid; private BigDecimal paid;
/**
* @return the accept
*/
public Boolean getAccept() {
return accept;
}
/**
* @param accept the accept to set
*/
public void setAccept(Boolean accept) {
this.accept = accept;
}
/** /**
* @return the paid * @return the paid
*/ */
@ -99,4 +85,18 @@ public class PersonBean implements Serializable {
public void setBookingDate(LocalDateTime bookingDate) { public void setBookingDate(LocalDateTime bookingDate) {
this.bookingDate = bookingDate; this.bookingDate = bookingDate;
} }
/**
* @return the progress
*/
public String getProgress() {
return progress;
}
/**
* @param progress the progress to set
*/
public void setProgress(String progress) {
this.progress = progress;
}
} }

View File

@ -50,7 +50,7 @@ public class BusinessPrivilegesRepository {
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE)) .leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE))
.orderBy(V_CAMP.ARRIVE, T_PROFILE.SURNAME, T_PROFILE.FORENAME); .orderBy(V_CAMP.ARRIVE, T_PROFILE.SURNAME, T_PROFILE.FORENAME);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<BusinessPrivilegesBean> list = new ArrayList<>(); List<BusinessPrivilegesBean> list = new ArrayList<>();
for (Record8<String, String, LocalDateTime, String, Integer, Integer, String, Double> r : sql.fetch()) { for (Record8<String, String, LocalDateTime, String, Integer, Integer, String, Double> r : sql.fetch()) {
BusinessPrivilegesBean bean = new BusinessPrivilegesBean(); BusinessPrivilegesBean bean = new BusinessPrivilegesBean();
@ -80,7 +80,7 @@ public class BusinessPrivilegesRepository {
.where((allowed == null || allowed.size() < 1) ? DSL.trueCondition() : T_PERSON.CAMPROLE.in(allowed)) .where((allowed == null || allowed.size() < 1) ? DSL.trueCondition() : T_PERSON.CAMPROLE.in(allowed))
.orderBy(T_PROFILE.SURNAME, T_PROFILE.FORENAME, T_PROFILE.DUEDATE); .orderBy(T_PROFILE.SURNAME, T_PROFILE.FORENAME, T_PROFILE.DUEDATE);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<ProfileBean> list = new ArrayList<>(); List<ProfileBean> list = new ArrayList<>();
for (Record5<Integer, String, String, LocalDateTime, String> r : sql.fetch()) { for (Record5<Integer, String, String, LocalDateTime, String> r : sql.fetch()) {
ProfileBean bean = new ProfileBean(); ProfileBean bean = new ProfileBean();
@ -102,7 +102,7 @@ public class BusinessPrivilegesRepository {
.onConflict(T_CAMPPROFILE.FK_CAMP, T_CAMPPROFILE.FK_PROFILE, T_CAMPPROFILE.MODULE) .onConflict(T_CAMPPROFILE.FK_CAMP, T_CAMPPROFILE.FK_PROFILE, T_CAMPPROFILE.MODULE)
.doNothing(); .doNothing();
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return sql.execute(); return sql.execute();
} }
@ -118,7 +118,7 @@ public class BusinessPrivilegesRepository {
.from(T_PROFILE) .from(T_PROFILE)
.where(T_PROFILE.USERNAME.eq(currentUser)))); .where(T_PROFILE.USERNAME.eq(currentUser))));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return sql.execute(); return sql.execute();
} }
} }

View File

@ -34,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumDocument; import de.jottyfan.camporganizer.db.jooq.enums.EnumDocument;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.tables.TProfile; import de.jottyfan.camporganizer.db.jooq.tables.TProfile;
import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord;
import de.jottyfan.camporganizer.module.camplist.model.BookingBean; import de.jottyfan.camporganizer.module.camplist.model.BookingBean;
@ -54,7 +55,7 @@ public class CamplistRepository {
public Stream<VCampRecord> getAllCamps(Condition condition) { public Stream<VCampRecord> getAllCamps(Condition condition) {
SelectSeekStep1<VCampRecord, LocalDateTime> sql = jooq.selectFrom(V_CAMP).where(condition).orderBy(V_CAMP.ARRIVE); SelectSeekStep1<VCampRecord, LocalDateTime> sql = jooq.selectFrom(V_CAMP).where(condition).orderBy(V_CAMP.ARRIVE);
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return sql.fetchStream(); return sql.fetchStream();
} }
@ -76,7 +77,7 @@ public class CamplistRepository {
T_PERSON.CREATED, T_PERSON.CREATED,
T_PERSON.EMAIL, T_PERSON.EMAIL,
T_PERSON.SEX, T_PERSON.SEX,
T_PERSON.ACCEPT, T_PERSON.PROGRESS,
T_PERSON.FK_CAMP, T_PERSON.FK_CAMP,
T_PROFILE.FORENAME, T_PROFILE.FORENAME,
T_PROFILE.SURNAME, T_PROFILE.SURNAME,
@ -99,13 +100,15 @@ public class CamplistRepository {
.and(T_PERSON.PK.isNotNull()) .and(T_PERSON.PK.isNotNull())
.orderBy(V_CAMP.ARRIVE.desc(), T_PERSON.CREATED); .orderBy(V_CAMP.ARRIVE.desc(), T_PERSON.CREATED);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<BookingBean> list = new ArrayList<>(); List<BookingBean> list = new ArrayList<>();
Iterator<Record> i = sql.fetch().iterator(); Iterator<Record> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
Record r = i.next(); Record r = i.next();
Integer fkCamp = r.get(T_PERSON.FK_CAMP); Integer fkCamp = r.get(T_PERSON.FK_CAMP);
BookingBean bean = new BookingBean(); BookingBean bean = new BookingBean();
EnumProgress progress = r.get(T_PERSON.PROGRESS);
bean.setProgress(progress == null ? null : progress.getLiteral());
bean.setPk(r.get(T_PERSON.PK)); bean.setPk(r.get(T_PERSON.PK));
bean.setForename(r.get(T_PERSON.FORENAME)); bean.setForename(r.get(T_PERSON.FORENAME));
bean.setSurname(r.get(T_PERSON.SURNAME)); bean.setSurname(r.get(T_PERSON.SURNAME));
@ -129,7 +132,6 @@ public class CamplistRepository {
bean.setUrl(r.get(V_CAMP.URL)); bean.setUrl(r.get(V_CAMP.URL));
bean.setIsOver(r.get(V_CAMP.IS_OVER)); bean.setIsOver(r.get(V_CAMP.IS_OVER));
bean.setCampName(r.get(V_CAMP.NAME)); bean.setCampName(r.get(V_CAMP.NAME));
bean.setAccept(r.get(T_PERSON.ACCEPT));
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
String forename = r.get(REGISTRATOR.FORENAME); String forename = r.get(REGISTRATOR.FORENAME);
String surname = r.get(REGISTRATOR.SURNAME); String surname = r.get(REGISTRATOR.SURNAME);
@ -185,7 +187,7 @@ public class CamplistRepository {
.from(T_DOCUMENT) .from(T_DOCUMENT)
.where(T_DOCUMENT.DOCTYPE.eq(EnumDocument.camppass))); .where(T_DOCUMENT.DOCTYPE.eq(EnumDocument.camppass)));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
Map<Integer, String> map = new HashMap<>(); // no duplicate on using a map Map<Integer, String> map = new HashMap<>(); // no duplicate on using a map
Iterator<Record2<String, Integer>> i = sql.fetch().iterator(); Iterator<Record2<String, Integer>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {

View File

@ -41,7 +41,7 @@ public class BookingBean implements Serializable {
private Boolean isOver; private Boolean isOver;
private String campName; private String campName;
private String registrator; private String registrator;
private Boolean accept; private String progress;
private String subscriber; private String subscriber;
private List<DocumentBean> documents; private List<DocumentBean> documents;
@ -396,14 +396,6 @@ public class BookingBean implements Serializable {
this.registrator = registrator; this.registrator = registrator;
} }
public Boolean getAccept() {
return accept;
}
public void setAccept(Boolean accept) {
this.accept = accept;
}
public String getSubscriber() { public String getSubscriber() {
return subscriber; return subscriber;
} }
@ -416,4 +408,18 @@ public class BookingBean implements Serializable {
return documents; return documents;
} }
/**
* @return the progress
*/
public String getProgress() {
return progress;
}
/**
* @param progress the progress to set
*/
public void setProgress(String progress) {
this.progress = progress;
}
} }

View File

@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule; import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
import de.jottyfan.camporganizer.module.confirmation.board.model.CampBean; import de.jottyfan.camporganizer.module.confirmation.board.model.CampBean;
import de.jottyfan.camporganizer.module.confirmation.board.model.PersonBean; import de.jottyfan.camporganizer.module.confirmation.board.model.PersonBean;
@ -93,7 +94,8 @@ public class ConfirmationBoardRepository {
while (i.hasNext()) { while (i.hasNext()) {
Record r = i.next(); Record r = i.next();
PersonBean bean = new PersonBean(); PersonBean bean = new PersonBean();
bean.setAccept(r.get(T_PERSON.ACCEPT)); EnumProgress progress = r.get(T_PERSON.PROGRESS);
bean.setProgress(progress == null ? null : progress.getLiteral());
bean.setBirthDate(r.get(T_PERSON.BIRTHDATE)); bean.setBirthDate(r.get(T_PERSON.BIRTHDATE));
bean.setCamprole(r.get(T_PERSON.CAMPROLE) == null ? null : r.get(T_PERSON.CAMPROLE).getLiteral()); bean.setCamprole(r.get(T_PERSON.CAMPROLE) == null ? null : r.get(T_PERSON.CAMPROLE).getLiteral());
bean.setCity(r.get(T_PERSON.CITY)); bean.setCity(r.get(T_PERSON.CITY));

View File

@ -61,7 +61,7 @@ public class List2CSVService {
append(buf, bean.getSex()); append(buf, bean.getSex());
append(buf, bean.getCamprolle()); append(buf, bean.getCamprolle());
append(buf, bean.getBirthDate()); append(buf, bean.getBirthDate());
append(buf, bean.getAccept()); append(buf, bean.getProgress());
append(buf, bean.getCreated()); append(buf, bean.getCreated());
append(buf, bean.getConsentCatalogPhoto()); append(buf, bean.getConsentCatalogPhoto());
append(buf, bean.getComment()); append(buf, bean.getComment());

View File

@ -22,7 +22,7 @@ public class PersonBean implements Serializable {
private String email; private String email;
private LocalDate birthDate; private LocalDate birthDate;
private String camprole; private String camprole;
private Boolean accept; private String progress;
private LocalDateTime created; private LocalDateTime created;
private String sex; private String sex;
private Double paid; private Double paid;
@ -181,20 +181,6 @@ public class PersonBean implements Serializable {
this.camprole = camprole; this.camprole = camprole;
} }
/**
* @return the accept
*/
public Boolean getAccept() {
return accept;
}
/**
* @param accept the accept to set
*/
public void setAccept(Boolean accept) {
this.accept = accept;
}
/** /**
* @return the created * @return the created
*/ */
@ -264,4 +250,18 @@ public class PersonBean implements Serializable {
public void setConsentCatalogPhoto(Boolean consentCatalogPhoto) { public void setConsentCatalogPhoto(Boolean consentCatalogPhoto) {
this.consentCatalogPhoto = consentCatalogPhoto; this.consentCatalogPhoto = consentCatalogPhoto;
} }
/**
* @return the progress
*/
public String getProgress() {
return progress;
}
/**
* @param progress the progress to set
*/
public void setProgress(String progress) {
this.progress = progress;
}
} }

View File

@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import de.jottyfan.camporganizer.module.camplist.CommonController; import de.jottyfan.camporganizer.module.camplist.CommonController;
import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOverviewBean; import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOverviewBean;
@ -20,22 +21,32 @@ import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOver
public class ConfirmationController extends CommonController { public class ConfirmationController extends CommonController {
@Autowired @Autowired
private ConfirmationService indexService; private ConfirmationService service;
@GetMapping("/confirmation") @GetMapping("/confirmation")
public String getIndex(Model model) { public String getIndex(Model model) {
List<CampOverviewBean> campoverview = indexService.getCampOverview(super.getCurrentUser()); List<CampOverviewBean> campoverview = service.getCampOverview(super.getCurrentUser());
CampOverviewBean campoverviewsummary = new CampOverviewBean(LocalDate.now(), "summary"); CampOverviewBean campoverviewsummary = new CampOverviewBean(LocalDate.now(), "summary");
for (CampOverviewBean bean : campoverview) { for (CampOverviewBean bean : campoverview) {
campoverviewsummary.setApproved(bean.getApproved() + campoverviewsummary.getApproved()); campoverviewsummary.setApproved(bean.getApproved() + campoverviewsummary.getApproved());
campoverviewsummary.setRejected(bean.getRejected() + campoverviewsummary.getRejected()); campoverviewsummary.setRejected(bean.getRejected() + campoverviewsummary.getRejected());
campoverviewsummary.setUntouched(bean.getUntouched() + campoverviewsummary.getUntouched()); campoverviewsummary.setUntouched(bean.getUntouched() + campoverviewsummary.getUntouched());
campoverviewsummary.setRevoked(bean.getRevoked() + campoverviewsummary.getRevoked());
} }
model.addAttribute("campoverview", campoverview); model.addAttribute("campoverview", campoverview);
model.addAttribute("campoverviewsummary", campoverviewsummary); model.addAttribute("campoverviewsummary", campoverviewsummary);
model.addAttribute("untouched", indexService.getUntouched(super.getCurrentUser())); model.addAttribute("untouched", service.getUntouched(super.getCurrentUser()));
model.addAttribute("approved", indexService.getApproved(super.getCurrentUser())); model.addAttribute("approved", service.getApproved(super.getCurrentUser()));
model.addAttribute("rejected", indexService.getRejected(super.getCurrentUser())); model.addAttribute("rejected", service.getRejected(super.getCurrentUser()));
model.addAttribute("revoked", service.getRevoked(super.getCurrentUser()));
return "confirmation/confirmation"; return "confirmation/confirmation";
} }
@GetMapping("/registration/remove/{id}")
public String revoke(@PathVariable("id") Integer id, final Model model) {
service.removeBooking(id);
return "redirect:/confirmation";
}
} }

View File

@ -3,10 +3,13 @@ package de.jottyfan.camporganizer.module.confirmation.confirmation;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP; import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPPROFILE; import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPPROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON; import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSONDOCUMENT;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE; import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_RSS;
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP; import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -18,12 +21,17 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.jooq.Condition; import org.jooq.Condition;
import org.jooq.DSLContext; import org.jooq.DSLContext;
import org.jooq.DeleteConditionStep;
import org.jooq.InsertValuesStep2;
import org.jooq.Name; import org.jooq.Name;
import org.jooq.Record4; import org.jooq.Record4;
import org.jooq.Record5;
import org.jooq.Record7; import org.jooq.Record7;
import org.jooq.Record8; import org.jooq.Record8;
import org.jooq.SelectConditionStep;
import org.jooq.SelectHavingStep; import org.jooq.SelectHavingStep;
import org.jooq.SelectSeekStep1; import org.jooq.SelectSeekStep1;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL; import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@ -31,6 +39,11 @@ import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule; import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersondocumentRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TRssRecord;
import de.jottyfan.camporganizer.module.camplist.model.LambdaResultWrapper;
import de.jottyfan.camporganizer.module.confirmation.confirmation.model.BookingBean; import de.jottyfan.camporganizer.module.confirmation.confirmation.model.BookingBean;
import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOverviewBean; import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOverviewBean;
@ -55,10 +68,10 @@ public class ConfirmationRepository {
*/ */
public List<CampOverviewBean> getCampOverviewBeans(String currentUser) { public List<CampOverviewBean> getCampOverviewBeans(String currentUser) {
Name COUNT = DSL.name("count"); Name COUNT = DSL.name("count");
SelectHavingStep<Record4<Integer, Boolean, String, LocalDateTime>> sql = jooq SelectHavingStep<Record4<Integer, EnumProgress, String, LocalDateTime>> sql = jooq
// @formatter:off // @formatter:off
.select(DSL.count(T_PERSON.PK).as(COUNT), .select(DSL.count(T_PERSON.PK).as(COUNT),
T_PERSON.ACCEPT, T_PERSON.PROGRESS,
T_CAMP.NAME, T_CAMP.NAME,
T_CAMP.ARRIVE) T_CAMP.ARRIVE)
.from(T_PERSON) .from(T_PERSON)
@ -68,15 +81,15 @@ public class ConfirmationRepository {
.where(T_CAMP.ARRIVE.isNotNull()) .where(T_CAMP.ARRIVE.isNotNull())
.and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration)) .and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration))
.and(T_PROFILE.USERNAME.eq(currentUser)) .and(T_PROFILE.USERNAME.eq(currentUser))
.groupBy(T_CAMP.NAME, T_CAMP.ARRIVE, T_PERSON.ACCEPT); .groupBy(T_CAMP.NAME, T_CAMP.ARRIVE, T_PERSON.PROGRESS);
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
Map<LocalDateTime, CampOverviewBean> map = new HashMap<>(); Map<LocalDateTime, CampOverviewBean> map = new HashMap<>();
Iterator<Record4<Integer, Boolean, String, LocalDateTime>> i = sql.fetch().iterator(); Iterator<Record4<Integer, EnumProgress, String, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
Record4<Integer, Boolean, String, LocalDateTime> r = i.next(); Record4<Integer, EnumProgress, String, LocalDateTime> r = i.next();
Integer count = r.get(COUNT, Integer.class); Integer count = r.get(COUNT, Integer.class);
Boolean accept = r.get(T_PERSON.ACCEPT); EnumProgress progress = r.get(T_PERSON.PROGRESS);
String campname = r.get(T_CAMP.NAME); String campname = r.get(T_CAMP.NAME);
LocalDateTime arrive = r.get(T_CAMP.ARRIVE); LocalDateTime arrive = r.get(T_CAMP.ARRIVE);
CampOverviewBean bean = map.get(arrive); CampOverviewBean bean = map.get(arrive);
@ -84,12 +97,14 @@ public class ConfirmationRepository {
bean = new CampOverviewBean(arrive.toLocalDate(), campname); bean = new CampOverviewBean(arrive.toLocalDate(), campname);
map.put(arrive, bean); map.put(arrive, bean);
} }
if (accept == null) { if (progress == null || EnumProgress.requested.equals(progress)) {
bean.setUntouched(count); bean.setUntouched(count);
} else if (accept) { } else if (EnumProgress.approved.equals(progress)) {
bean.setApproved(count); bean.setApproved(count);
} else { } else if (EnumProgress.rejected.equals(progress)) {
bean.setRejected(count); bean.setRejected(count);
} else if (EnumProgress.revoked.equals(progress)) {
bean.setRevoked(count);
} }
} }
List<CampOverviewBean> list = new ArrayList<>(map.values()); List<CampOverviewBean> list = new ArrayList<>(map.values());
@ -117,7 +132,7 @@ public class ConfirmationRepository {
.and(T_PROFILE.USERNAME.eq(currentUser)) .and(T_PROFILE.USERNAME.eq(currentUser))
.orderBy(T_PERSON.CREATED.desc()); .orderBy(T_PERSON.CREATED.desc());
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<BookingBean> list = new ArrayList<>(); List<BookingBean> list = new ArrayList<>();
Iterator<Record7<Integer, String, String, String, LocalDateTime, EnumCamprole, LocalDateTime>> i = sql.fetch().iterator(); Iterator<Record7<Integer, String, String, String, LocalDateTime, EnumCamprole, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -145,7 +160,7 @@ public class ConfirmationRepository {
* @return a list of booking beans; an empty one at least * @return a list of booking beans; an empty one at least
*/ */
public List<BookingBean> getUntouched(String currentUser) { public List<BookingBean> getUntouched(String currentUser) {
return getListWithCondition(currentUser, T_PERSON.ACCEPT.isNull()); return getListWithCondition(currentUser, T_PERSON.PROGRESS.eq(EnumProgress.requested));
} }
/** /**
@ -155,7 +170,7 @@ public class ConfirmationRepository {
* @return a list of booking beans; an empty one at least * @return a list of booking beans; an empty one at least
*/ */
public List<BookingBean> getApproved(String currentUser) { public List<BookingBean> getApproved(String currentUser) {
return getListWithCondition(currentUser, T_PERSON.ACCEPT.isTrue()); return getListWithCondition(currentUser, T_PERSON.PROGRESS.eq(EnumProgress.approved));
} }
/** /**
@ -165,7 +180,17 @@ public class ConfirmationRepository {
* @return a list of booking beans; an empty one at least * @return a list of booking beans; an empty one at least
*/ */
public List<BookingBean> getRejected(String currentUser) { public List<BookingBean> getRejected(String currentUser) {
return getListWithCondition(currentUser, T_PERSON.ACCEPT.isFalse()); return getListWithCondition(currentUser, T_PERSON.PROGRESS.eq(EnumProgress.rejected));
}
/**
* get all revoked bookings that this user can manage
*
* @param currentUser the current user
* @return a list of booking beans; an empty one at least
*/
public List<BookingBean> getRevoked(String currentUser) {
return getListWithCondition(currentUser, T_PERSON.PROGRESS.eq(EnumProgress.revoked));
} }
/** /**
@ -183,9 +208,9 @@ public class ConfirmationRepository {
.or(V_CAMP.YEAR.cast(String.class).containsIgnoreCase(needle)); .or(V_CAMP.YEAR.cast(String.class).containsIgnoreCase(needle));
// @formatter:on // @formatter:on
SelectSeekStep1<Record8<Integer, String, String, EnumCamprole, String, Double, String, Boolean>, LocalDateTime> sql = jooq SelectSeekStep1<Record8<Integer, String, String, EnumCamprole, String, Double, String, EnumProgress>, LocalDateTime> sql = jooq
// @formatter:off // @formatter:off
.select(T_PERSON.PK, T_PERSON.FORENAME, T_PERSON.SURNAME, T_PERSON.CAMPROLE, V_CAMP.NAME, V_CAMP.YEAR, V_CAMP.LOCATION_NAME, T_PERSON.ACCEPT) .select(T_PERSON.PK, T_PERSON.FORENAME, T_PERSON.SURNAME, T_PERSON.CAMPROLE, V_CAMP.NAME, V_CAMP.YEAR, V_CAMP.LOCATION_NAME, T_PERSON.PROGRESS)
.from(T_PERSON) .from(T_PERSON)
.leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_PERSON.FK_CAMP)) .leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_PERSON.FK_CAMP))
.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP)) .leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP))
@ -195,24 +220,82 @@ public class ConfirmationRepository {
.and(T_PROFILE.USERNAME.eq(currentUser)) .and(T_PROFILE.USERNAME.eq(currentUser))
.orderBy(T_PERSON.CREATED.desc()); .orderBy(T_PERSON.CREATED.desc());
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<BookingBean> list = new ArrayList<>(); List<BookingBean> list = new ArrayList<>();
Iterator<Record8<Integer, String, String, EnumCamprole, String, Double, String, Boolean>> i = sql.fetch().iterator(); Iterator<Record8<Integer, String, String, EnumCamprole, String, Double, String, EnumProgress>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
Record8<Integer, String, String, EnumCamprole, String, Double, String, Boolean> r = i.next(); Record8<Integer, String, String, EnumCamprole, String, Double, String, EnumProgress> r = i.next();
Integer pkPerson = r.get(T_PERSON.PK); Integer pkPerson = r.get(T_PERSON.PK);
String forename = r.get(T_PERSON.FORENAME); String forename = r.get(T_PERSON.FORENAME);
String surname = r.get(T_PERSON.SURNAME); String surname = r.get(T_PERSON.SURNAME);
EnumCamprole role = r.get(T_PERSON.CAMPROLE); EnumCamprole role = r.get(T_PERSON.CAMPROLE);
String campname = r.get(V_CAMP.NAME); String campname = r.get(V_CAMP.NAME);
Double year = r.get(V_CAMP.YEAR); Double year = r.get(V_CAMP.YEAR);
Boolean accept = r.get(T_PERSON.ACCEPT); EnumProgress progress = r.get(T_PERSON.PROGRESS);
BookingBean bean = new BookingBean(pkPerson, null, String.format("%s %4.0f", campname, year)); BookingBean bean = new BookingBean(pkPerson, null, String.format("%s %4.0f", campname, year));
bean.setRole(role == null ? null : role.getLiteral()); bean.setRole(role == null ? null : role.getLiteral());
bean.setFullname(new StringBuilder().append(forename).append(" ").append(surname).toString()); bean.setFullname(new StringBuilder().append(forename).append(" ").append(surname).toString());
bean.setAccept(accept); bean.setProgress(progress == null ? null : progress.getLiteral());
list.add(bean); list.add(bean);
} }
return list; return list;
} }
/**
* remove the booking and all of its dependencies
*
* @param id the pk of t_person
* @return number of affected database rows, should be 1
*/
public Integer removeBooking(Integer id) {
LambdaResultWrapper lrw = new LambdaResultWrapper();
jooq.transaction(t -> {
SelectConditionStep<Record5<String, String, String, String, LocalDateTime>> sql0 = DSL.using(t)
// @formatter:off
.select(T_PROFILE.USERNAME, T_PERSON.FORENAME, T_PERSON.SURNAME, T_CAMP.NAME, T_CAMP.ARRIVE)
.from(T_PERSON)
.leftJoin(T_CAMP).on(T_CAMP.PK.eq(T_PERSON.FK_CAMP))
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_PERSON.FK_PROFILE))
.where(T_PERSON.PK.eq(id));
// @formatter:on
LOGGER.trace(sql0.toString());
Record5<String, String, String, String, LocalDateTime> r = sql0.fetchOne();
if (r == null) {
throw new DataAccessException("no such entry in t_person with id = " + id);
}
String username = r.get(T_PROFILE.USERNAME);
String forename = r.get(T_PERSON.FORENAME);
String surname = r.get(T_PERSON.SURNAME);
String campname = r.get(T_CAMP.NAME);
LocalDateTime arrive = r.get(T_CAMP.ARRIVE);
StringBuilder rssMessage = new StringBuilder(username);
rssMessage.append(" hat die Stornierung der Buchung von ");
rssMessage.append(forename).append(" ").append(surname);
rssMessage.append(" an ");
rssMessage.append(campname).append(" ")
.append(arrive == null ? "" : arrive.format(DateTimeFormatter.ofPattern("YYYY")));
rssMessage.append(" bestätigt und den Datensatz gelöscht.");
DeleteConditionStep<TPersondocumentRecord> sql1 = DSL.using(t).deleteFrom(T_PERSONDOCUMENT)
.where(T_PERSONDOCUMENT.FK_PERSON.eq(id));
LOGGER.trace(sql1.toString());
sql1.execute();
DeleteConditionStep<TPersonRecord> sql2 = DSL.using(t).deleteFrom(T_PERSON).where(T_PERSON.PK.eq(id));
LOGGER.trace(sql2.toString());
lrw.add(sql2.execute());
InsertValuesStep2<TRssRecord, String, String> sql3 = DSL.using(t)
// @formatter:off
.insertInto(T_RSS,
T_RSS.MSG,
T_RSS.RECIPIENT)
.values(rssMessage.toString(), "registrator");
// @formatter:on
LOGGER.trace("{}", sql3.toString());
sql3.execute();
});
return lrw.getCounter();
}
} }

View File

@ -5,6 +5,7 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.module.confirmation.confirmation.model.BookingBean; import de.jottyfan.camporganizer.module.confirmation.confirmation.model.BookingBean;
import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOverviewBean; import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOverviewBean;
@ -16,35 +17,41 @@ import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOver
@Service @Service
public class ConfirmationService { public class ConfirmationService {
@Autowired @Autowired
private ConfirmationRepository gateway; private ConfirmationRepository repository;
public List<CampOverviewBean> getCampOverview(String currentUser) { public List<CampOverviewBean> getCampOverview(String currentUser) {
return gateway.getCampOverviewBeans(currentUser); return repository.getCampOverviewBeans(currentUser);
} }
public List<BookingBean> getUntouched(String currentUser) { public List<BookingBean> getUntouched(String currentUser) {
return gateway.getUntouched(currentUser); return repository.getUntouched(currentUser);
} }
public List<BookingBean> getApproved(String currentUser) { public List<BookingBean> getApproved(String currentUser) {
return gateway.getApproved(currentUser); return repository.getApproved(currentUser);
} }
public List<BookingBean> getRejected(String currentUser) { public List<BookingBean> getRejected(String currentUser) {
return gateway.getRejected(currentUser); return repository.getRejected(currentUser);
}
public List<BookingBean> getRevoked(String currentUser) {
return repository.getRevoked(currentUser);
} }
public String search(String needle, String linkURL, String currentUser) { public String search(String needle, String linkURL, String currentUser) {
StringBuilder buf = new StringBuilder( StringBuilder buf = new StringBuilder(
"<table class=\"table table-striped\"><thead><tr><th>Dabei</th><th>Name</th><th>Freizeit</th><th>Rolle</th></tr><tbody>"); "<table class=\"table table-striped\"><thead><tr><th>Dabei</th><th>Name</th><th>Freizeit</th><th>Rolle</th></tr><tbody>");
for (BookingBean bean : gateway.getSearchResult(needle, currentUser)) { for (BookingBean bean : repository.getSearchResult(needle, currentUser)) {
String acceptHtml = ""; String acceptHtml = "";
if (bean.getAccept() == null) { if (EnumProgress.requested.equals(bean.getProgress())) {
acceptHtml = "<i class=\"fas fa-question framed framed-orange\"></i>"; acceptHtml = "<i class=\"fas fa-question framed framed-orange\"></i>";
} else if (bean.getAccept()) { } else if (EnumProgress.approved.equals(bean.getProgress())) {
acceptHtml = "<i class=\"fas fa-check framed framed-green\"></i>"; acceptHtml = "<i class=\"fas fa-check framed framed-green\"></i>";
} else { } else if (EnumProgress.rejected.equals(bean.getProgress())) {
acceptHtml = "<i class=\"fas fa-ban framed framed-red\"></i>"; acceptHtml = "<i class=\"fas fa-ban framed framed-red\"></i>";
} else if (EnumProgress.revoked.equals(bean.getProgress())) {
acceptHtml = "<i class=\"fas fa-skull framed framed-pink\"></i>";
} }
buf.append(String.format("<tr><td>%s</td><td><a href=\"%s/%d\">%s</a></td><td>%s</td><td>%s</td></tr>", buf.append(String.format("<tr><td>%s</td><td><a href=\"%s/%d\">%s</a></td><td>%s</td><td>%s</td></tr>",
acceptHtml, linkURL, bean.getPkPerson(), bean.getFullname(), bean.getCamp(), bean.getRolename())); acceptHtml, linkURL, bean.getPkPerson(), bean.getFullname(), bean.getCamp(), bean.getRolename()));
@ -52,4 +59,14 @@ public class ConfirmationService {
buf.append("</tbody></table>"); buf.append("</tbody></table>");
return buf.toString(); return buf.toString();
} }
/**
* remove the booking and all of its dependencies
*
* @param id the id of the booking (t_person.pk)
*/
public Boolean removeBooking(Integer id) {
return repository.removeBooking(id) > 0;
}
} }

View File

@ -20,7 +20,7 @@ public class BookingBean implements Serializable, Comparable<BookingBean> {
private String fullname; private String fullname;
private String role; private String role;
private LocalDateTime registered; private LocalDateTime registered;
private Boolean accept; private String progress;
public BookingBean(Integer pkPerson, LocalDate date, String camp) { public BookingBean(Integer pkPerson, LocalDate date, String camp) {
this.pkPerson = pkPerson; this.pkPerson = pkPerson;
@ -114,11 +114,17 @@ public class BookingBean implements Serializable, Comparable<BookingBean> {
return pkPerson; return pkPerson;
} }
public Boolean getAccept() { /**
return accept; * @return the progress
*/
public String getProgress() {
return progress;
} }
public void setAccept(Boolean accept) { /**
this.accept = accept; * @param progress the progress to set
*/
public void setProgress(String progress) {
this.progress = progress;
} }
} }

View File

@ -16,6 +16,7 @@ public class CampOverviewBean implements Serializable, Comparable<CampOverviewBe
private Integer approved; private Integer approved;
private Integer rejected; private Integer rejected;
private Integer untouched; private Integer untouched;
private Integer revoked;
public CampOverviewBean(LocalDate date, String camp) { public CampOverviewBean(LocalDate date, String camp) {
this.date = date; this.date = date;
@ -23,6 +24,7 @@ public class CampOverviewBean implements Serializable, Comparable<CampOverviewBe
this.approved = 0; this.approved = 0;
this.rejected = 0; this.rejected = 0;
this.untouched = 0; this.untouched = 0;
this.revoked = 0;
} }
@Override @Override
@ -85,4 +87,18 @@ public class CampOverviewBean implements Serializable, Comparable<CampOverviewBe
public LocalDate getDate() { public LocalDate getDate() {
return date; return date;
} }
/**
* @return the revoked
*/
public Integer getRevoked() {
return revoked;
}
/**
* @param revoked the revoked to set
*/
public void setRevoked(Integer revoked) {
this.revoked = revoked;
}
} }

View File

@ -32,6 +32,7 @@ public class PersonController extends CommonController {
model.addAttribute("camps", personService.getCamps(username)); model.addAttribute("camps", personService.getCamps(username));
model.addAttribute("annotations", personService.getAnnotations(pk)); model.addAttribute("annotations", personService.getAnnotations(pk));
model.addAttribute("campPrice", personService.getCampPrice(pk)); model.addAttribute("campPrice", personService.getCampPrice(pk));
model.addAttribute("progresses", personService.getProgresses());
return "confirmation/person"; return "confirmation/person";
} }
@ -43,6 +44,7 @@ public class PersonController extends CommonController {
model.addAttribute("camps", personService.getCamps(username)); model.addAttribute("camps", personService.getCamps(username));
model.addAttribute("annotations", personService.getAnnotations(bean.getPk())); model.addAttribute("annotations", personService.getAnnotations(bean.getPk()));
model.addAttribute("campPrice", personService.getCampPrice(bean.getPk())); model.addAttribute("campPrice", personService.getCampPrice(bean.getPk()));
model.addAttribute("progresses", personService.getProgresses());
return "confirmation/person"; return "confirmation/person";
} }
personService.updatePerson(bean, username); personService.updatePerson(bean, username);

View File

@ -33,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule; import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.tables.TProfile; import de.jottyfan.camporganizer.db.jooq.tables.TProfile;
import de.jottyfan.camporganizer.db.jooq.tables.records.TCampRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.TCampRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
@ -78,7 +79,7 @@ public class PersonRepository {
.and(T_PROFILE.USERNAME.eq(username)) .and(T_PROFILE.USERNAME.eq(username))
.orderBy(T_CAMP.ARRIVE.desc()); .orderBy(T_CAMP.ARRIVE.desc());
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
List<CampBean> list = new ArrayList<>(); List<CampBean> list = new ArrayList<>();
Iterator<Record4<Integer, String, LocalDateTime, String>> i = sql.fetch().iterator(); Iterator<Record4<Integer, String, LocalDateTime, String>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -112,13 +113,14 @@ public class PersonRepository {
.and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration)) .and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration))
.and(T_PROFILE.USERNAME.eq(username)); .and(T_PROFILE.USERNAME.eq(username));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
Iterator<Record> i = sql.fetch().iterator(); Iterator<Record> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
Record r = i.next(); Record r = i.next();
PersonBean bean = new PersonBean(); PersonBean bean = new PersonBean();
bean.setPk(pk); bean.setPk(pk);
bean.setAccept(r.get(T_PERSON.ACCEPT)); EnumProgress progress = r.get(T_PERSON.PROGRESS);
bean.setProgress(progress == null ? null : progress.getLiteral());
bean.setBirthdate(r.get(T_PERSON.BIRTHDATE)); bean.setBirthdate(r.get(T_PERSON.BIRTHDATE));
bean.setCamprole(r.get(T_PERSON.CAMPROLE)); bean.setCamprole(r.get(T_PERSON.CAMPROLE));
bean.setCity(r.get(T_PERSON.CITY)); bean.setCity(r.get(T_PERSON.CITY));
@ -151,21 +153,21 @@ public class PersonRepository {
jooq.transaction(t -> { jooq.transaction(t -> {
SelectConditionStep<TProfileRecord> sql0 = jooq.selectFrom(T_PROFILE).where(T_PROFILE.USERNAME.eq(registrator)); SelectConditionStep<TProfileRecord> sql0 = jooq.selectFrom(T_PROFILE).where(T_PROFILE.USERNAME.eq(registrator));
LOGGER.debug(sql0.toString()); LOGGER.trace(sql0);
Integer fkRegistrator = sql0.fetchOne(T_PROFILE.PK); Integer fkRegistrator = sql0.fetchOne(T_PROFILE.PK);
// get old accept value for comparison // get old accept value for comparison
SelectConditionStep<TPersonRecord> sql1 = jooq.selectFrom(T_PERSON).where(T_PERSON.PK.eq(bean.getPk())); SelectConditionStep<TPersonRecord> sql1 = jooq.selectFrom(T_PERSON).where(T_PERSON.PK.eq(bean.getPk()));
LOGGER.debug(sql1.toString()); LOGGER.trace(sql1);
TPersonRecord r = sql1.fetchOne(); TPersonRecord r = sql1.fetchOne();
lrw.putBoolean("acceptOld", r == null ? null : r.getAccept()); lrw.putBoolean("acceptOld", r == null ? null : EnumProgress.approved.equals(r.getProgress()));
lrw.putBoolean("acceptNew", bean.getAccept()); lrw.putBoolean("acceptNew", EnumProgress.approved.getLiteral().equals(bean.getProgress()));
Integer fkCamp = r == null ? null : r.getFkCamp(); Integer fkCamp = r == null ? null : r.getFkCamp();
String email = r.getEmail(); // use the old one, too String email = r.getEmail(); // use the old one, too
lrw.putString("oldEmail", email); lrw.putString("oldEmail", email);
SelectConditionStep<TCampRecord> sql2 = jooq.selectFrom(T_CAMP).where(T_CAMP.PK.eq(fkCamp)); SelectConditionStep<TCampRecord> sql2 = jooq.selectFrom(T_CAMP).where(T_CAMP.PK.eq(fkCamp));
LOGGER.debug(sql2.toString()); LOGGER.trace(sql2);
TCampRecord rc = sql2.fetchOne(); TCampRecord rc = sql2.fetchOne();
String campName = rc == null ? null : rc.getName(); String campName = rc == null ? null : rc.getName();
LocalDateTime arrive = rc == null ? null : rc.getArrive(); LocalDateTime arrive = rc == null ? null : rc.getArrive();
@ -186,13 +188,13 @@ public class PersonRepository {
.set(T_PERSON.PHONE, bean.getPhone()) .set(T_PERSON.PHONE, bean.getPhone())
.set(T_PERSON.EMAIL, bean.getEmail()) .set(T_PERSON.EMAIL, bean.getEmail())
.set(T_PERSON.COMMENT, bean.getComment()) .set(T_PERSON.COMMENT, bean.getComment())
.set(T_PERSON.ACCEPT, bean.getAccept()) .set(T_PERSON.PROGRESS, EnumProgress.lookupLiteral(bean.getProgress()))
.set(T_PERSON.CAMPROLE, bean.getCamprole()) .set(T_PERSON.CAMPROLE, bean.getCamprole())
.set(T_PERSON.FK_REGISTRATOR, fkRegistrator) .set(T_PERSON.FK_REGISTRATOR, fkRegistrator)
.set(T_PERSON.REQUIRED_PRICE, bean.getRequiredPrice()) .set(T_PERSON.REQUIRED_PRICE, bean.getRequiredPrice())
.where(T_PERSON.PK.eq(bean.getPk())); .where(T_PERSON.PK.eq(bean.getPk()));
// @formatter:on // @formatter:on
LOGGER.debug(sql3.toString()); LOGGER.trace(sql3);
lrw.add(sql3.execute()); lrw.add(sql3.execute());
// always // always
@ -208,7 +210,7 @@ public class PersonRepository {
T_RSS.RECIPIENT) T_RSS.RECIPIENT)
.values(buf.toString(), "registrator"); .values(buf.toString(), "registrator");
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql4.toString()); LOGGER.trace(sql4);
sql4.execute(); sql4.execute();
}); });
@ -301,7 +303,7 @@ public class PersonRepository {
.leftJoin(REGISTRATOR).on(REGISTRATOR.PK.eq(T_PERSON.FK_REGISTRATOR)) .leftJoin(REGISTRATOR).on(REGISTRATOR.PK.eq(T_PERSON.FK_REGISTRATOR))
.where(T_PERSON.PK.eq(pk)); .where(T_PERSON.PK.eq(pk));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
Iterator<Record11<LocalDate, LocalDateTime, EnumCamprole, LocalDateTime, LocalDateTime, Integer, Integer, String, String, String, String>> i = sql Iterator<Record11<LocalDate, LocalDateTime, EnumCamprole, LocalDateTime, LocalDateTime, Integer, Integer, String, String, String, String>> i = sql
.fetch().iterator(); .fetch().iterator();

View File

@ -1,10 +1,12 @@
package de.jottyfan.camporganizer.module.confirmation.person; package de.jottyfan.camporganizer.module.confirmation.person;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.module.confirmation.person.model.CampBean; import de.jottyfan.camporganizer.module.confirmation.person.model.CampBean;
import de.jottyfan.camporganizer.module.confirmation.person.model.PersonBean; import de.jottyfan.camporganizer.module.confirmation.person.model.PersonBean;
@ -43,4 +45,12 @@ public class PersonService {
public String getCampPrice(Integer pk) { public String getCampPrice(Integer pk) {
return gateway.getCampprice(pk); return gateway.getCampprice(pk);
} }
public List<String> getProgresses() {
List<String> list = new ArrayList<>();
for (EnumProgress p : EnumProgress.values()) {
list.add(p.getLiteral());
}
return list;
}
} }

View File

@ -32,7 +32,7 @@ public class PersonBean implements Serializable {
private String email; private String email;
private Integer fkCamp; private Integer fkCamp;
private Integer fkProfile; private Integer fkProfile;
private Boolean accept; private String progress;
private LocalDateTime created; private LocalDateTime created;
private EnumSex sex; private EnumSex sex;
private Integer fkRegistrator; private Integer fkRegistrator;
@ -194,20 +194,6 @@ public class PersonBean implements Serializable {
this.fkProfile = fkProfile; this.fkProfile = fkProfile;
} }
/**
* @return the accept
*/
public Boolean getAccept() {
return accept;
}
/**
* @param accept the accept to set
*/
public void setAccept(Boolean accept) {
this.accept = accept;
}
/** /**
* @return the created * @return the created
*/ */
@ -291,4 +277,18 @@ public class PersonBean implements Serializable {
public void setRequiredPrice(BigDecimal requiredPrice) { public void setRequiredPrice(BigDecimal requiredPrice) {
this.requiredPrice = requiredPrice; this.requiredPrice = requiredPrice;
} }
/**
* @return the progress
*/
public String getProgress() {
return progress;
}
/**
* @param progress the progress to set
*/
public void setProgress(String progress) {
this.progress = progress;
}
} }

View File

@ -79,7 +79,7 @@ public class DashboardRepository {
.deleteFrom(T_PERSONDOCUMENT) .deleteFrom(T_PERSONDOCUMENT)
.where(T_PERSONDOCUMENT.PK.eq(bean.getPk())); .where(T_PERSONDOCUMENT.PK.eq(bean.getPk()));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
lrw.add(sql.execute()); lrw.add(sql.execute());
StringBuilder buf = new StringBuilder("Dokument "); StringBuilder buf = new StringBuilder("Dokument ");
@ -92,7 +92,7 @@ public class DashboardRepository {
T_RSS.RECIPIENT) T_RSS.RECIPIENT)
.values(buf.toString(), "registrator"); .values(buf.toString(), "registrator");
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql2.toString()); LOGGER.trace(sql);
sql2.execute(); sql2.execute();
}); });
return lrw.getCounter(); return lrw.getCounter();
@ -117,7 +117,7 @@ public class DashboardRepository {
) )
.values(bean.getName(), bean.getFiletype(), bean.getFkPerson(), bean.getDocument()); .values(bean.getName(), bean.getFiletype(), bean.getFkPerson(), bean.getDocument());
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
sql.execute(); sql.execute();
StringBuilder buf = new StringBuilder("Dokument "); StringBuilder buf = new StringBuilder("Dokument ");
@ -130,7 +130,7 @@ public class DashboardRepository {
T_RSS.RECIPIENT) T_RSS.RECIPIENT)
.values(buf.toString(), "registrator"); .values(buf.toString(), "registrator");
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql2.toString()); LOGGER.trace(sql2);
sql2.execute(); sql2.execute();
}); });
} }

View File

@ -37,7 +37,7 @@ public class DocumentRepository {
.selectFrom(T_DOCUMENT) .selectFrom(T_DOCUMENT)
.where(T_DOCUMENT.PK.eq(id)); .where(T_DOCUMENT.PK.eq(id));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
TDocumentRecord r = sql.fetchOne(); TDocumentRecord r = sql.fetchOne();
if (r == null) { if (r == null) {
return null; return null;

View File

@ -54,7 +54,7 @@ public class ICalRepository {
.from(T_CAMP) .from(T_CAMP)
.leftJoin(T_LOCATION).on(T_LOCATION.PK.eq(T_CAMP.FK_LOCATION)); .leftJoin(T_LOCATION).on(T_LOCATION.PK.eq(T_CAMP.FK_LOCATION));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
ICalendar ical = new ICalendar(); ICalendar ical = new ICalendar();
ical.getTimezoneInfo().setDefaultTimezone(TimezoneAssignment.download(TimeZone.getTimeZone("Europe/Berlin"), false)); ical.getTimezoneInfo().setDefaultTimezone(TimezoneAssignment.download(TimeZone.getTimeZone("Europe/Berlin"), false));
Iterator<Record5<String, LocalDateTime, LocalDateTime, String, String>> i = sql.fetch().iterator(); Iterator<Record5<String, LocalDateTime, LocalDateTime, String, String>> i = sql.fetch().iterator();

View File

@ -37,7 +37,7 @@ public class MigrationRepository {
.from(T_PROFILE) .from(T_PROFILE)
.where(T_PROFILE.USERNAME.eq(username)); .where(T_PROFILE.USERNAME.eq(username));
// @formatter:on // @formatter:on
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return sql.fetchOne(T_PROFILE.PASSWORD); return sql.fetchOne(T_PROFILE.PASSWORD);
} }
} }

View File

@ -119,7 +119,7 @@ public class KeycloakRepository {
Response response = resource.create(user); Response response = resource.create(user);
Boolean success = Status.CREATED.equals(response.getStatusInfo()); Boolean success = Status.CREATED.equals(response.getStatusInfo());
if (success) { if (success) {
LOGGER.info("created new keycloak user {}", user.getUsername()); LOGGER.debug("created new keycloak user {}", user.getUsername());
} else { } else {
LOGGER.error("error on creating keycloak user {}: {}", user.getUsername(), response.getStatus()); LOGGER.error("error on creating keycloak user {}: {}", user.getUsername(), response.getStatus());
} }

View File

@ -99,9 +99,15 @@ public class RegistrationController extends CommonController {
return "/registration/cancellation"; return "/registration/cancellation";
} }
@GetMapping("/registration/remove/{id}") @GetMapping("/registration/revoke/{id}")
public String remove(@PathVariable("id") Integer id, final Model model) { public String revoke(@PathVariable("id") Integer id, final Model model) {
service.removeBooking(id); service.revokeBooking(id, true);
return "redirect:/dashboard";
}
@GetMapping("/registration/unrevoke/{id}")
public String unrevoke(@PathVariable("id") Integer id, final Model model) {
service.revokeBooking(id, false);
return "redirect:/dashboard"; return "redirect:/dashboard";
} }

View File

@ -2,7 +2,6 @@ package de.jottyfan.camporganizer.module.registration;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP; import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON; import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSONDOCUMENT;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE; import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILEROLE; import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILEROLE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_RSS; import static de.jottyfan.camporganizer.db.jooq.Tables.T_RSS;
@ -41,9 +40,9 @@ import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersondocumentRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TProfileRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.TProfileRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TRssRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.TRssRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord; import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord;
@ -147,7 +146,7 @@ public class RegistrationRepository {
T_RSS.RECIPIENT) T_RSS.RECIPIENT)
.values(new StringBuilder(bean.getFullname()).append(" hat sich als Nutzer im CampOrganizer2 registriert.").toString(), "admin"); .values(new StringBuilder(bean.getFullname()).append(" hat sich als Nutzer im CampOrganizer2 registriert.").toString(), "admin");
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql2.toString()); LOGGER.trace(sql2);
sql2.execute(); sql2.execute();
} else { } else {
SelectConditionStep<Record1<Integer>> sql1 = DSL.using(t) SelectConditionStep<Record1<Integer>> sql1 = DSL.using(t)
@ -251,13 +250,11 @@ public class RegistrationRepository {
} }
/** /**
* remove the booking and all of its dependencies * set the revoke state of a booking
* *
* @param id the pk of t_person * @param id the ID of the booking
* @return number of affected database rows, should be 1
*/ */
public Integer removeBooking(Integer id) { public void revokeBooking(Integer id) {
LambdaResultWrapper lrw = new LambdaResultWrapper();
jooq.transaction(t -> { jooq.transaction(t -> {
SelectConditionStep<Record5<String, String, String, String, LocalDateTime>> sql0 = DSL.using(t) SelectConditionStep<Record5<String, String, String, String, LocalDateTime>> sql0 = DSL.using(t)
// @formatter:off // @formatter:off
@ -279,33 +276,32 @@ public class RegistrationRepository {
LocalDateTime arrive = r.get(T_CAMP.ARRIVE); LocalDateTime arrive = r.get(T_CAMP.ARRIVE);
StringBuilder rssMessage = new StringBuilder(username); StringBuilder rssMessage = new StringBuilder(username);
rssMessage.append(" hat die Buchung von "); rssMessage.append(" hat die Stornierung der Buchung von ");
rssMessage.append(forename).append(" ").append(surname); rssMessage.append(forename).append(" ").append(surname);
rssMessage.append(" an "); rssMessage.append(" an ");
rssMessage.append(campname).append(" ") rssMessage.append(campname).append(" ")
.append(arrive == null ? "" : arrive.format(DateTimeFormatter.ofPattern("YYYY"))); .append(arrive == null ? "" : arrive.format(DateTimeFormatter.ofPattern("YYYY")));
rssMessage.append(" storniert."); rssMessage.append(" ausgelöst.");
DeleteConditionStep<TPersondocumentRecord> sql1 = DSL.using(t).deleteFrom(T_PERSONDOCUMENT) UpdateConditionStep<TPersonRecord> sql1 = jooq
.where(T_PERSONDOCUMENT.FK_PERSON.eq(id)); // @formatter:off
LOGGER.trace(sql1.toString()); .update(T_PERSON)
.set(T_PERSON.PROGRESS, EnumProgress.revoked)
.where(T_PERSON.PK.eq(id));
// @formatter:on
LOGGER.trace(sql1);
sql1.execute(); sql1.execute();
DeleteConditionStep<TPersonRecord> sql2 = DSL.using(t).deleteFrom(T_PERSON).where(T_PERSON.PK.eq(id)); InsertValuesStep2<TRssRecord, String, String> sql2 = DSL.using(t)
LOGGER.trace(sql2.toString());
lrw.add(sql2.execute());
InsertValuesStep2<TRssRecord, String, String> sql3 = DSL.using(t)
// @formatter:off // @formatter:off
.insertInto(T_RSS, .insertInto(T_RSS,
T_RSS.MSG, T_RSS.MSG,
T_RSS.RECIPIENT) T_RSS.RECIPIENT)
.values(rssMessage.toString(), "registrator"); .values(rssMessage.toString(), "registrator");
// @formatter:on // @formatter:on
LOGGER.trace("{}", sql3.toString()); LOGGER.trace("{}", sql2.toString());
sql3.execute(); sql2.execute();
}); });
return lrw.getCounter();
} }
/** /**
@ -494,4 +490,59 @@ public class RegistrationRepository {
Iterator<Integer> i = sql.fetch(T_PERSON.PK).iterator(); Iterator<Integer> i = sql.fetch(T_PERSON.PK).iterator();
return i.hasNext(); return i.hasNext();
} }
/**
* turn back the revocation and set state to requested
*
* @param id
*/
public void unrevokeBooking(Integer id) {
jooq.transaction(t -> {
SelectConditionStep<Record5<String, String, String, String, LocalDateTime>> sql0 = DSL.using(t)
// @formatter:off
.select(T_PROFILE.USERNAME, T_PERSON.FORENAME, T_PERSON.SURNAME, T_CAMP.NAME, T_CAMP.ARRIVE)
.from(T_PERSON)
.leftJoin(T_CAMP).on(T_CAMP.PK.eq(T_PERSON.FK_CAMP))
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_PERSON.FK_PROFILE))
.where(T_PERSON.PK.eq(id));
// @formatter:on
LOGGER.trace(sql0.toString());
Record5<String, String, String, String, LocalDateTime> r = sql0.fetchOne();
if (r == null) {
throw new DataAccessException("no such entry in t_person with id = " + id);
}
String username = r.get(T_PROFILE.USERNAME);
String forename = r.get(T_PERSON.FORENAME);
String surname = r.get(T_PERSON.SURNAME);
String campname = r.get(T_CAMP.NAME);
LocalDateTime arrive = r.get(T_CAMP.ARRIVE);
StringBuilder rssMessage = new StringBuilder(username);
rssMessage.append(" hat die Stornierung der Buchung von ");
rssMessage.append(forename).append(" ").append(surname);
rssMessage.append(" an ");
rssMessage.append(campname).append(" ")
.append(arrive == null ? "" : arrive.format(DateTimeFormatter.ofPattern("YYYY")));
rssMessage.append(" rückgängig gemacht.");
UpdateConditionStep<TPersonRecord> sql1 = jooq
// @formatter:off
.update(T_PERSON)
.set(T_PERSON.PROGRESS, EnumProgress.requested)
.where(T_PERSON.PK.eq(id));
// @formatter:on
LOGGER.trace(sql1);
sql1.execute();
InsertValuesStep2<TRssRecord, String, String> sql2 = DSL.using(t)
// @formatter:off
.insertInto(T_RSS,
T_RSS.MSG,
T_RSS.RECIPIENT)
.values(rssMessage.toString(), "registrator");
// @formatter:on
LOGGER.trace("{}", sql2.toString());
sql2.execute();
});
}
} }

View File

@ -75,12 +75,18 @@ public class RegistrationService {
} }
/** /**
* remove the booking and all of its dependencies * revoke a booking
* *
* @param id the id of the booking (t_person.pk) * @param id the ID of the booking
* @parem doRevoke if true, revoke the booking; if false, unrevoke and set it to
* requested again
*/ */
public Boolean removeBooking(Integer id) { public void revokeBooking(Integer id, Boolean doRevoke) {
return repository.removeBooking(id) > 0; if (doRevoke) {
repository.revokeBooking(id);
} else {
repository.unrevokeBooking(id);
}
} }
public void toggleConsent(Integer id) { public void toggleConsent(Integer id) {

View File

@ -47,7 +47,7 @@ public class RssRepository {
.from(T_RSS) .from(T_RSS)
.where(T_RSS.RECIPIENT.eq(recipientCode)); .where(T_RSS.RECIPIENT.eq(recipientCode));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
List<RssBean> list = new ArrayList<>(); List<RssBean> list = new ArrayList<>();
Iterator<Record3<Integer, String, LocalDateTime>> i = sql.fetch().iterator(); Iterator<Record3<Integer, String, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -63,7 +63,7 @@ public class RssRepository {
public List<String> getAllFeeds() { public List<String> getAllFeeds() {
SelectJoinStep<Record1<String>> sql = jooq.selectDistinct(T_RSS.RECIPIENT).from(T_RSS); SelectJoinStep<Record1<String>> sql = jooq.selectDistinct(T_RSS.RECIPIENT).from(T_RSS);
LOGGER.debug(sql.toString()); LOGGER.trace(sql);
return sql.fetch(T_RSS.RECIPIENT); return sql.fetch(T_RSS.RECIPIENT);
} }
@ -76,7 +76,7 @@ public class RssRepository {
T_RSS.REGDATE) T_RSS.REGDATE)
.from(T_RSS); .from(T_RSS);
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
List<RssBean> list = new ArrayList<>(); List<RssBean> list = new ArrayList<>();
Iterator<Record4<Integer, String, String, LocalDateTime>> i = sql.fetch().iterator(); Iterator<Record4<Integer, String, String, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -96,7 +96,7 @@ public class RssRepository {
.deleteFrom(T_RSS) .deleteFrom(T_RSS)
.where(T_RSS.PK.eq(bean.getPk())); .where(T_RSS.PK.eq(bean.getPk()));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
sql.execute(); sql.execute();
} }
@ -107,7 +107,7 @@ public class RssRepository {
.set(T_RSS.MSG, bean.getMessage()) .set(T_RSS.MSG, bean.getMessage())
.where(T_RSS.PK.eq(bean.getPk())); .where(T_RSS.PK.eq(bean.getPk()));
// @formatter:on // @formatter:on
LOGGER.debug("{}", sql.toString()); LOGGER.trace(sql);
sql.execute(); sql.execute();
} }
} }

View File

@ -1,6 +1,8 @@
package de.jottyfan.camporganizer.module.staticpages; package de.jottyfan.camporganizer.module.staticpages;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -14,6 +16,9 @@ import de.jottyfan.camporganizer.module.camplist.CommonController;
@Controller @Controller
public class StaticPagesController extends CommonController { public class StaticPagesController extends CommonController {
@Autowired
private StaticPagesService service;
/** /**
* load the index page * load the index page
* *
@ -21,7 +26,7 @@ public class StaticPagesController extends CommonController {
*/ */
@GetMapping("/") @GetMapping("/")
public String getIndex() { public String getIndex() {
return "/index"; return "redirect:/allgemeines";
} }
/** /**
@ -44,6 +49,16 @@ public class StaticPagesController extends CommonController {
return "/verein"; return "/verein";
} }
/**
* load the vereinsmitglieder page
*
* @return the vereinsmitglieder page
*/
@GetMapping("/vereinsmitglieder")
public String getVereinsmitglieder() {
return "/vereinsmitglieder";
}
/** /**
* load the kontakt page * load the kontakt page
* *
@ -60,7 +75,8 @@ public class StaticPagesController extends CommonController {
* @return the allgemeines page * @return the allgemeines page
*/ */
@GetMapping("/allgemeines") @GetMapping("/allgemeines")
public String getAllgemeines() { public String getAllgemeines(final Model model) {
model.addAttribute("title", service.getStockDescription());
return "/allgemeines"; return "/allgemeines";
} }

View File

@ -0,0 +1,37 @@
package de.jottyfan.camporganizer.module.staticpages;
import java.io.IOException;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import de.jottyfan.camporganizer.Main;
/**
*
* @author jotty
*
*/
@Service
public class StaticPagesService {
@Autowired
private ResourceLoader resourceLoader;
public Properties getStockDescription() {
Resource resource = resourceLoader.getResource(
"classpath:/static/images/stock.properties"
);
Properties properties = new Properties();
try {
properties.load(resource.getInputStream());
} catch (IOException e) {
Main.LOGGER.error(e.getMessage());
}
return properties;
}
}

View File

@ -49,6 +49,48 @@ body {
background-repeat: no-repeat; background-repeat: no-repeat;
} }
.logo {
width: 128px;
height: 55px;
background-size: 128px;
background-repeat: no-repeat;
background-image: url('../images/logo.png');
margin-left: 8px;
display: inline-block;
position: relative;
overflow: hidden;
}
.logo::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('../images/logo_hover.png');
background-size: cover;
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
.logo:hover::before {
opacity: 1;
}
.icon_profile {
width: 32px;
height: 32px;
background-size: 32px;
background-repeat: no-repeat;
background-image: url('../images/Icon_Profil.svg');
display: inline-block;
}
.icon_profile:hover {
background-image: url('../images/Icon_Profil_hover.svg');
}
a { a {
font-family: 'Fira Sans'; font-family: 'Fira Sans';
} }
@ -121,19 +163,20 @@ div {
!important; !important;
} }
.acc_true { .acc_approved {
background-image: linear-gradient(to bottom right, #cfc, #afa) background: #aaffaa !important;
!important;
} }
.acc_false { .acc_rejected {
background-image: linear-gradient(to bottom right, #fcc, #faa) background: #ffaaaa !important;
!important;
} }
.acc_null { .acc_revoked {
background-image: linear-gradient(to bottom right, #fdb, #fca) background: rgb(220, 138, 221) !important;
!important; }
.acc_requested {
background: rgb(255, 190, 111) !important;
} }
.right-dist { .right-dist {
@ -303,6 +346,17 @@ div {
margin: 0px 2px 0px 2px; margin: 0px 2px 0px 2px;
} }
.badgeerror {
border-radius: 8px;
border: 1px solid black;
color: white;
font-weight: bolder;
background-image: linear-gradient(to right bottom, rgb(246, 97, 81),
rgb(165, 29, 45));
padding: 2px 4px 2px 4px;
margin: 0px 2px 0px 2px;
}
.dist8 { .dist8 {
margin: 8px; margin: 8px;
} }
@ -333,19 +387,19 @@ div {
} }
.framed-green { .framed-green {
background: linear-gradient(to bottom right, lime, darkgreen); background: linear-gradient(to bottom right, darkgreen, lime);
color: white; color: white;
border: 1px solid green; border: 1px solid green;
} }
.framed-red { .framed-red {
background: linear-gradient(to bottom right, red, darkred); background: linear-gradient(to bottom right, darkred, red);
color: white; color: white;
border: 1px solid red; border: 1px solid red;
} }
.framed-orange { .framed-orange {
background: linear-gradient(to bottom right, orange, #bf6c06); background: linear-gradient(to bottom right, #bf6c06, orange);
color: white; color: white;
border: 1px solid orange; border: 1px solid orange;
} }
@ -356,6 +410,12 @@ div {
border: 1px solid black; border: 1px solid black;
} }
.framed-pink {
background: linear-gradient(to bottom right, #3b115b, #d18be8);
color: #f8effb;
border: 1px solid #4a0084;
}
.nomaxwidth { .nomaxwidth {
max-width: none !important; max-width: none !important;
} }
@ -457,3 +517,25 @@ div {
margin: 0px !important; margin: 0px !important;
padding: 100px; padding: 100px;
} }
.hoverlink {
color: #333333;
text-decoration: none;
}
.hoverlink:hover {
color: #0d6efd;
text-decoration: underline;
}
.thumbswipe {
-webkit-overflow-scrolling: touch;
max-height: 100px;
overflow-x: scroll;
overflow-y: hidden;
scrollbar-width: none;
}
.thumbswipe::-webkit-scrollbar {
display: none;
}

View File

@ -148,3 +148,13 @@ h4 {
h5 { h5 {
font-size: 14px; font-size: 14px;
} }
.preview-content {
min-height: 200px;
max-height: 200px;
overflow-y: auto;
}
.accordion-collapse:not(.show) {
height: 200px !important;
}

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_2" data-name="Ebene 2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 71.44 71.44">
<defs>
<style>
.cls-1 {
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: .5px;
}
.cls-1, .cls-2 {
stroke: #008b8b;
}
.cls-1, .cls-2, .cls-3 {
fill: none;
}
.cls-4 {
clip-path: url(#clippath);
}
.cls-2 {
stroke-miterlimit: 10;
}
</style>
<clipPath id="clippath">
<circle class="cls-3" cx="35.72" cy="35.72" r="35.22"/>
</clipPath>
</defs>
<g id="Ebene_1-2" data-name="Ebene 1">
<circle class="cls-2" cx="35.72" cy="35.72" r="35.22"/>
<g class="cls-4">
<g>
<path class="cls-1" d="m26.52,40.74c.1.18,2.36-1.36,2.36-1.36.7,1.22-8.38,7.81-7.67,9.05,1.64,2.84,16.71-10.45,17.06-9.85,0,0-19.7,11.6-17.8,14.89,1.1,1.91,23.09-13.33,23.09-13.33.64,1.11-24.96,17.34-24.23,18.61l27.74-16.02c1.97,3.41-28.1,17.71-26.74,20.06,1.11,1.92,28.55-18.65,29.48-17.02l-29.78,21.81,31.45-18.16c1.78,3.08-31.55,21.22-30.85,22.43.13.22,31.02-17.91,31.02-17.91,2.48,4.3-28.57,20.86-28.46,21.05l27.99-16.16c1.06,1.84-18.76,15.45-18.76,15.45.49.85,18.85-10.88,18.85-10.88l-10.45,10.65s9.95-7.97,10.91-6.3c.39.68-4.82,5.99-4.21,7.05.28.48,3.6-2.08,3.6-2.08"/>
<path class="cls-1" d="m27.35,10.64c.22.37,2.8-2.3,3.09-1.79l-9.63,10.18c.69,1.2,18.44-11.86,18.96-10.95,0,0-19,13.93-18.28,15.17.99,1.71,20.42-16.02,22.25-12.85,1.25,2.16-24.58,13.41-22.24,17.46,2.06,3.57,26.29-15.18,26.29-15.18,2.08,3.6-27.69,14.43-25.02,19.06l25.92-14.96s-23.11,17.33-22.84,17.8c2.55,4.41,24.69-14.25,24.69-14.25,0,0-19.83,14.92-19.34,15.78.46.79,18.25-14.34,19.9-11.49,0,0-15.86,10.69-14.52,13l11.54-6.66"/>
<path class="cls-2" d="m35.72,37.67h0c8.62,0,15.61,6.99,15.61,15.61v21.27h-31.22v-21.27c0-8.62,6.99-15.61,15.61-15.61Z"/>
<circle class="cls-2" cx="35.72" cy="22.8" r="14.87"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,10 @@
stock02 = Heimfreizeit - Spiele im Wertwiesenpark
stock25 = Olfen - Gutes Essen
stock27 = Olfen - Miniaturdorf im Wald
stock29 = Olfen - Die Frohe Stunde am Morgen
stock52 = Rehe 2 - Kreative Ideen
stock63 = Schweiz - Blaue Bergseen
stock71 = Heimfreizeit - Kreuzkirche ECG Heilbronn
stock83 = Schweiz - Aufstieg in die Berge
stock84 = Hohenhaslach - Mitten in den Weinbergen
stock85 = Rehe 2 - Gemeinsame Andacht

View File

@ -120,7 +120,8 @@
</div> </div>
<label for="startBooking" class="col-sm-2 col-form-label mb-2">Buchungsbeginn</label> <label for="startBooking" class="col-sm-2 col-form-label mb-2">Buchungsbeginn</label>
<div class="col-sm-4 mb-2"> <div class="col-sm-4 mb-2">
<span class="error" th:each="error : ${#fields.errors('startBooking')}">[[${error}]]<br /></span> <input id="startBooking" type="date" th:field="*{startBooking}" <span class="error" th:each="error : ${#fields.errors('startBooking')}">[[${error}]]<br /></span>
<input id="startBooking" type="datetime-local" th:field="*{startBooking}"
th:class="${'form-control ' + (#fields.hasErrors('startBooking') ? 'inputerror' : '')}" /> th:class="${'form-control ' + (#fields.hasErrors('startBooking') ? 'inputerror' : '')}" />
</div> </div>
<label for="inputBedsFemale" class="col-sm-2 col-form-label mb-2">Anzahl Betten für Mädchen</label> <label for="inputBedsFemale" class="col-sm-2 col-form-label mb-2">Anzahl Betten für Mädchen</label>

View File

@ -7,140 +7,174 @@
<body> <body>
<th:block layout:fragment="content"> <th:block layout:fragment="content">
<div class="container"> <div class="container">
<div class="row"> <div id="welcomeblock" class="row displayblock">
<div class="col"> <div class="col-12">
<div class="blocktext"> <h2 class="headlinefont center">Willkommen bei den</h2>
<h1 class="titlefont">Statt Langeweile zu Hause Action auf einer Freizeit!</h1> <h1 class="titlefont center">Mittelpunkt<br />Freizeiten</h1>
<p> </div>
Ferien sind cool! Das steht auf jeden Fall fest. Doch wenn die Freunde alle im Urlaub sind und du alleine zu Hause bleibst, <div class="col-12 center">
kommt schnell Langeweile auf. <strong>Warum also nicht einfach die Ferien mit vielen anderen Gleichaltrigen <a th:href="@{/camplist}" class="btn btn-outline-danger">zur Anmeldung</a>
verbringen und jede Menge Spaß erleben?</strong> Genau dafür stehen <strong>Onkel Werner Freizeiten!</strong> </div>
</p> <div class="col-12 center mt-3">
<h2 class="headlinefont">Das sind Onkel Werner Freizeiten</h2> <a href="#" onclick="$('#welcomeblock').slideUp('slow'); $('#fotoblock').fadeIn(1000);" class="btn btn-outline-secondary"><i class="fas fa-arrow-down"></i>&nbsp;weitere Informationen</a>
<p> </div>
<strong>Onkel Werner Freizeiten sind immer ein Erlebnis der besonderen Art.</strong> Je nach Freizeit verbringst du entweder </div>
ein verlängertes Wochenende, eine Woche oder sogar zwei Wochen zusammen mit einer Hand voll Mitarbeitern und jeder Menge <div id="fotoblock" class="row displayblock" style="display: none">
Kindern oder Teenies. <div class="col-12 center mb-3">
</p> <a href="#" onclick="$('#fotoblock').fadeOut(1000); $('#welcomeblock').slideDown('slow');" class="btn btn-outline-secondary"><i class="fas fa-arrow-up"></i>&nbsp;Startseite</a>
<p>Im Freizeitheim angekommen, wirst du erst einmal ordentlich begrüßt und beziehst zusammen mit deinen (neuen) Freunden </div>
dein Zimmer. Und dann kann die Freizeit auch schon starten. Hier erlebst du jede Menge Spaß, knüpfst neue Freundschaften, <div class="col-12 thumbswipe">
bekommst ein tolles Programm geboten, hörst spannende Geschichten aus der Bibel und noch viel mehr.</p> <div style="min-width: 13000px"><!-- omits line break -->
<p> <th:block th:each="n : ${#numbers.sequence(1, 85)}" th:with="i=${#strings.toString(n < 10 ? '0' + n : n)}">
<strong>Preise, Termine und weitere Infos findest du in unserem Buchungsportal.</strong> <a th:href="'https://www.onkelwernerfreizeiten.de/stock/stock' + ${i} + '.jpg'" data-fancybox="gallery" th:data-caption="${title['stock' + i]}"><img th:src="'https://www.onkelwernerfreizeiten.de/stock/thumb_stock' + ${i} + '.jpg'" height="96px" class="m-1" th:title="${title['stock' + i]}" /></a>
</p> </th:block>
<p> </div>
<a th:href="@{/camplist}">Jetzt Freizeiten entdecken</a> <script th:inline="javascript">
</p> Fancybox.bind('[data-fancybox="gallery"]', {
<h2 class="headlinefont">Kinderfreizeiten in Olfen</h2> });
<p>Jede Menge Kinder in deinem Alter, viele coole Spiele, Sommerrodeln und spannende biblische Geschichten…</p>
<p>…das und noch viel mehr erwartet dich auf den Kinderfreizeiten in Olfen in den Oster- und Herbstferien. Olfen ist ein function selectCamp(name) {
kleines Dorf in Hessen. Im großen Freizeitheim mit noch größerem Gelände drumherum erlebst du eine Woche voller Action, $('#fotoblock').slideUp('slow');
Zusammenhalt und Gottes Wort.</p> $('#infoblock').fadeIn(1000);
<p>Der Tag startet mit einer Stillen Zeit zusammen mit deiner Zimmergruppe und einem Mitarbeiter. Gemeinsam nehmt ihr $('.description').hide();
Abschnitte aus der Bibel unter die Lupe.</p> $('.campbtn').removeClass('btn-secondary').removeClass('text-white').addClass("btn-secondary-outline");
<p>Nach dem Frühstück kannst du in der “Frohen Stunde” Lieder singen, eine spannende Geschichte aus der Bibel hören und $('#camp_' + name).show();
Bibelverse lernen. Das kann dir in deinem Leben eine große Hilfe sein.</p> $('#btn_' + name).addClass('btn-secondary').removeClass("btn-secondary-outline").addClass('text-white');
<p>Am Nachmittag gibt es immer etwas zu Erleben. Zum Beispiel bei Geländespielen, in verschiedenen AGs oder Spielen im }
Dorf. Mit Sicherheit ist auch etwas Interessantes für dich dabei! Würdest du zum Beispiel verkleidete Mitarbeiter im Dorf </script>
direkt erkennen? Bist du bereit, dich den Aufgaben zu stellen?</p> </div>
<p>Am Abend erwarten dich Spiele- oder Themenabende, tolle Filme oder auch mal ein spannender Bericht von einem Missionar. <div class="col-12 center">
Und ja, manchmal sind wir sogar nachts unterwegs…auf Nachtwanderungen oder bei aufregenden Geländespielen im Dunkeln.</p> <h2 class="headlinefont">Unsere Freizeiten</h2>
<p>Ein besonderer Höhepunkt ist die Wanderung zur Sommerrodelbahn. Und natürlich das anschließende Rodeln! Wer traut sich, </div>
mit voller Geschwindigkeit zu fahren? Oder wer hat es lieber etwas langsamer und macht dabei ein entspanntes Gesicht auf dem <div class="col-12 center">
Foto, das geschossen wird?</p> <!-- waiting for content from Jan
<p>Sei dabei und lerne neue Freunde kennen, die du bestimmt auch in der nächsten Freizeit wieder treffen wirst!</p> <button class="btn btn-outline-secondary" onclick="selectCamp('rehe')">Rehe</button>
<h2 class="headlinefont">Jugendfreizeit Grow Up</h2> -->
<p>Grow Up kann man mit heranwachsen übersetzen und genau darum geht es auf dieser Freizeit! Möchtest du im Glauben <button class="btn btn-outline-secondary" onclick="selectCamp('olfen')">Olfen</button>
heranwachsen, Gottes Wort begierig studieren und Gott noch tiefer erkennen? Dann bist du auf dieser Freizeit genau richtig!</p> <button class="btn btn-outline-secondary" onclick="selectCamp('growup')">Grow Up</button>
<p>Auf der Grow Up möchten wir dir unter anderem folgende Möglichkeiten bieten:</p> <button class="btn btn-outline-secondary" onclick="selectCamp('schweiz')">Schweiz</button>
<ul> <button class="btn btn-outline-secondary" onclick="selectCamp('heimfreizeit')">Heimfreizeit</button>
<li>Selbstständiges Arbeiten mit deiner Bibel</li> <button class="btn btn-outline-secondary" onclick="selectCamp('hohenhaslach')">Hohenhaslach</button>
<li>Austausch mit anderen Teilnehmern und Mitarbeitern</li> </div>
<li>Jede Menge Gedanken, um im Glauben zu wachsen</li> <div class="col-12 center mt-3">
</ul> <a th:href="@{/camplist}" class="btn btn-outline-danger">zur Anmeldung</a>
<p>Und natürlich Jugendliche und junge Erwachsene kennenzulernen, die das gleiche Anliegen haben wie du. Nämlich Jesus </div>
Christus immer ähnlicher zu werden und ein treuer Nachfolger zu sein.</p> </div>
<p>Den Tag startest du erstmal ganz alleine mit Gott, deiner Bibel und deinem Freizeit-Heft. Hier geht es um ein Bibelbuch <div id="infoblock" class="row displayblock" style="display: none">
oder biblisches Thema, das du anhand von Fragen tiefergehend studieren kannst.</p> <div class="col-12 center mb-3">
<p>Nach dem Frühstück treffen wir uns in kleinen Gruppen. &nbsp;Hier kannst du dich über die Dinge austauschen, die du im <a href="#" onclick="$('#infoblock').fadeOut(1000); $('#fotoblock').slideDown('slow');" class="btn btn-outline-secondary"><i class="fas fa-arrow-up"></i>&nbsp;Bilder</a>
Bibeltext gelernt hast. Welche Fragen sind bei dir aufgetaucht? Was verstehst du überhaupt nicht? Was ist dir besonders </div>
wichtig geworden? Und wie kannst du es im Alltag anwenden? Der Austausch bereichert dich durch Gedanken von Anderen, auf die <div class="col-12 center">
du selber vielleicht gar nicht gekommen wärst.</p> <h2 class="headlinefont">Unsere Freizeiten</h2>
<p>Am Nachmittag erwarten dich interessante Seminare zu relevanten Themen, Workshops, Geländespiele. Aber auch besondere </div>
Aktionen, wie ein Missionseinsatz oder ein stiller Nachmittag.</p> <div class="col-12 center">
<p>Abends kannst du dich auf Vorträge freuen, die dich in deinem Glaubensleben herausfordern und zum Wachstum anspornen <!-- waiting for content from Jan
sollen. Oder wir verbringen gemütliche Zeiten am Lagerfeuer und führen interessante Gespräche bei einer Nachtwanderung. Denn <button id="btn_rehe" class="btn btn-outline-secondary campbtn" onclick="selectCamp('rehe')">Rehe</button>
neben der intensiver Beschäftigung mit Gottes Wort wirst du auf der Grow Up auch die Möglichkeit haben, intensive -->
Freundschaften zu starten oder von Anderen zu lernen.</p> <button id="btn_olfen" class="btn btn-outline-secondary campbtn" onclick="selectCamp('olfen')">Olfen</button>
<p> <button id="btn_growup" class="btn btn-outline-secondary campbtn" onclick="selectCamp('growup')">Grow Up</button>
Zwischen den Programmpunkten bleibt viel Zeit, um sich kennenzulernen, zusammen <em>Nacht in Palermo</em>, Volleyball oder <em>Capture <button id="btn_schweiz" class="btn btn-outline-secondary campbtn" onclick="selectCamp('schweiz')">Schweiz</button>
the Flag </em>zu spielen oder auch ein Gespräch mit einem Mitarbeiter zu suchen, wenn dich etwas total beschäftigt oder du <button id="btn_heimfreizeit" class="btn btn-outline-secondary campbtn" onclick="selectCamp('heimfreizeit')">Heimfreizeit</button>
Hilfe und Rat brauchst. <button id="btn_hohenhaslach" class="btn btn-outline-secondary campbtn" onclick="selectCamp('hohenhaslach')">Hohenhaslach</button>
</p> </div>
<p>Du möchtest im Glauben herausgefordert werden, die Bibel und deinen Herrn besser kennenlernen und wirklich wachsen? <div id="camp_rehe" class="col-12 description" style="display: none">
Dann komm zur Grow Up und sei bereit, dich von Gott verändern zu lassen!</p> <h2 class="headlinefont">Wochenendfreizeit in Rehe</h2>
<h2 class="headlinefont">Teeniefreizeit Schweiz</h2> <p>TODO: Jan & Melanie</p>
<p>Ab in die Berge zwei Wochen Schweiz: mit Bergen, Seen, Kühen und allem, was das Herz begehrt. Mit Sicherheit wirst du </div>
dort eine ganze Menge erleben, denn das Programm ist vielfältig und voller Action!</p> <div id="camp_olfen" class="col-12 description" style="display: none">
<p>Du wirst in diesen zwei Wochen die Möglichkeit haben, spannende Bibelarbeiten und gute Gemeinschaft mit Gott zu <h2 class="headlinefont">Kinderfreizeiten in Olfen</h2>
erleben. Wir beginnen jeden Morgen in kleinen Gruppen mit gemeinsamer Stillen Zeit das bedeutet, dass wir über <p>Jede Menge Kinder in deinem Alter, viele coole Spiele, Sommerrodeln und spannende biblische Geschichten…</p>
verschiedene Bibelstellen nachdenken und uns über unsere Leben und die Erfahrungen, die wir mit Gott gemacht haben, <p>…das und noch viel mehr erwartet dich auf den Kinderfreizeiten in Olfen in den Oster- und Herbstferien. Olfen ist ein kleines Dorf in Hessen. Im großen Freizeitheim mit noch
austauschen.</p> größerem Gelände drumherum erlebst du eine Woche voller Action, Zusammenhalt und Gottes Wort.</p>
<p>Nach dem Frühstück folgt die „Frohe Stunde“ mit einer Bibelarbeit. In dieser Zeit konzentrieren wir uns gemeinsam <p>Der Tag startet mit einer Stillen Zeit zusammen mit deiner Zimmergruppe und einem Mitarbeiter. Gemeinsam nehmt ihr Abschnitte aus der Bibel unter die Lupe.</p>
darauf, was uns verschiedene Mitarbeiter über Gott und die Bibel mitteilen werden. Es gibt viel zu lernen.</p> <p>Nach dem Frühstück kannst du in der “Frohen Stunde” Lieder singen, eine spannende Geschichte aus der Bibel hören und Bibelverse lernen. Das kann dir in deinem Leben eine große
<p>In einer langen Mittagspause hast du Zeit für Fußball und Volleyball, Halli Galli oder andere Gesellschaftsspiele.</p> Hilfe sein.</p>
<p>Später am Nachmittag gibt es ein abwechslungsreiches Programm, beispielsweise Geländespiele vor Ort oder im Wald, <p>Am Nachmittag gibt es immer etwas zu Erleben. Zum Beispiel bei Geländespielen, in verschiedenen AGs oder Spielen im Dorf. Mit Sicherheit ist auch etwas Interessantes für dich
Wasserspiele, Workshops und verschiedene AG's.</p> dabei! Würdest du zum Beispiel verkleidete Mitarbeiter im Dorf direkt erkennen? Bist du bereit, dich den Aufgaben zu stellen?</p>
<p>Den Abend verbringen wir mit coolen kreativen Spielen wie z.B. einem Kochduell, Kiental sucht die Superband, Wetten <p>Am Abend erwarten dich Spiele- oder Themenabende, tolle Filme oder auch mal ein spannender Bericht von einem Missionar. Und ja, manchmal sind wir sogar nachts unterwegs…auf
Dass…?, und Die perfekte Minute. Oder aber wir sehen uns nach einem anstrengenden Tag ganz entspannt einen Film an und Nachtwanderungen oder bei aufregenden Geländespielen im Dunkeln.</p>
lassen den Abend mit angeregten Gesprächen ausklingen.</p> <p>Ein besonderer Höhepunkt ist die Wanderung zur Sommerrodelbahn. Und natürlich das anschließende Rodeln! Wer traut sich, mit voller Geschwindigkeit zu fahren? Oder wer hat es lieber
<p>Außerdem gibt es noch etwas ganz Besonderes: Unse Tagestouren! Die Mitarbeiter wecken dich bereits im frühen etwas langsamer und macht dabei ein entspanntes Gesicht auf dem Foto, das geschossen wird?</p>
Morgengrauen und dann wird der Gipfel auf 2820 Metern Höhe gestürmt. Oder wir fahren an den wunderschönen Thunersee. Hier <p>Sei dabei und lerne neue Freunde kennen, die du bestimmt auch in der nächsten Freizeit wieder treffen wirst!</p>
kannst du nicht nur Schwimmen, sondern auch aus zehn Metern Höhe ins Wasser springen, Beachvolleyball spielen und viele </div>
andere coole Dinge machen.</p> <div id="camp_growup" class="col-12 description" style="display: none">
<p>Bist du bereit, auf eine Woche voller Spaß und Action? Bist du bereit, dich verändern zu lassen? Bist du neugierig <h2 class="headlinefont">Jugendfreizeit Grow Up</h2>
geworden? Dann sehen wir uns in der Schweiz!</p> <p>Grow Up kann man mit heranwachsen übersetzen und genau darum geht es auf dieser Freizeit! Möchtest du im Glauben heranwachsen, Gottes Wort begierig studieren und Gott noch
<h2 class="headlinefont">Heimfreizeit für Kinder in Heilbronn</h2> tiefer erkennen? Dann bist du auf dieser Freizeit genau richtig!</p>
<p>Du hast noch zwei Wochen Sommerferien, wohnst in Heilbronn und hast noch nichts vor? Wie wäre es mit einem coolen und <p>Auf der Grow Up möchten wir dir unter anderem folgende Möglichkeiten bieten:</p>
abwechslungsreichen Tagesprogramm zusammen mit vielen anderen Kindern in deinem Alter?</p> <ul>
<p>Auf der Heimfreizeit hast du die Möglichkeit schon einmal ein bisschen hineinzuschnuppern, wie es sich anfühlt, auf <li>Selbstständiges Arbeiten mit deiner Bibel</li>
einer Freizeit dabei zu sein. Denn du übernachtest zwar zu Hause, aber zwei Wochen lang verbringst du den Tag mit vielen <li>Austausch mit anderen Teilnehmern und Mitarbeitern</li>
anderen Kindern und Mitarbeitern bei einem tollen Programm.</p> <li>Jede Menge Gedanken, um im Glauben zu wachsen</li>
<p>Wir starten mit Liedern und einer spannenden Geschichte aus der Bibel in den Tag. Natürlich gibts auch gemeinsames </ul>
Mittagessen. Auch Zeit zum spielen gibt es genug. Zum Beispiel auf dem Spielplatz oder beim Völkerball auf dem Alten <p>Und natürlich Jugendliche und junge Erwachsene kennenzulernen, die das gleiche Anliegen haben wie du. Nämlich Jesus Christus immer ähnlicher zu werden und ein treuer Nachfolger zu
Friedhof. Nachmittags erwarten dich viele coole Aktionen. Wie wäre es zum Beispiel mit einer Schnitzeljagd? Oder einer sein.</p>
kleinen Wanderung auf den Wartberg? Mit vielen tollen Spielen im Pfühlpark? Oder mit einer schönen Abkühlung und viel Spaß <p>Den Tag startest du erstmal ganz alleine mit Gott, deiner Bibel und deinem Freizeit-Heft. Hier geht es um ein Bibelbuch oder biblisches Thema, das du anhand von Fragen tiefergehend
im Freibad?</p> studieren kannst.</p>
<p>Nach einem kleinen Nachmittagssnack verabschieden wir uns bis zum nächsten Morgen.</p> <p>Nach dem Frühstück treffen wir uns in kleinen Gruppen. &nbsp;Hier kannst du dich über die Dinge austauschen, die du im Bibeltext gelernt hast. Welche Fragen sind bei dir
<p>Besondere Höhepunkte sind ein Besuch im Indoor-Spielplatz oder der Experimenta. Manchmal lässt Axel (Erlebnispädagoge) aufgetaucht? Was verstehst du überhaupt nicht? Was ist dir besonders wichtig geworden? Und wie kannst du es im Alltag anwenden? Der Austausch bereichert dich durch Gedanken von Anderen,
sich auch etwas ganz Besonderes einfallen, wie zum Beispiel Flag-Football.</p> auf die du selber vielleicht gar nicht gekommen wärst.</p>
<p>Das klingt doch viel besser, als sich zu Hause zu langweilen, oder?</p> <p>Am Nachmittag erwarten dich interessante Seminare zu relevanten Themen, Workshops, Geländespiele. Aber auch besondere Aktionen, wie ein Missionseinsatz oder ein stiller Nachmittag.</p>
<h2 class="headlinefont">Teeniefreizeit Hohenhaslach</h2> <p>Abends kannst du dich auf Vorträge freuen, die dich in deinem Glaubensleben herausfordern und zum Wachstum anspornen sollen. Oder wir verbringen gemütliche Zeiten am Lagerfeuer und
<p>Eine Woche Herbstferien und das hast keine Lust, sie zu verschwenden oder alleine zu Hause zu sitzen? Wie wärs mit führen interessante Gespräche bei einer Nachtwanderung. Denn neben der intensiver Beschäftigung mit Gottes Wort wirst du auf der Grow Up auch die Möglichkeit haben, intensive
einer herausfordernden Woche zusammen mit anderen Jugendlichen in den schönen Weinbergen von Baden-Württemberg?</p> Freundschaften zu starten oder von Anderen zu lernen.</p>
<p>Das Freizeitheim in Hohenhaslach liegt tatsächlich mitten in den Weinbergen, die natürlich im Herbst am schönsten <p>
aussehen. Hier lassen sich wunderbar Geländespiele oder Spaziergänge erleben.</p> Zwischen den Programmpunkten bleibt viel Zeit, um sich kennenzulernen, zusammen <em>Nacht in Palermo</em>, Volleyball oder <em>Capture the Flag </em>zu spielen oder auch ein Gespräch mit
<p>Aber nicht die schöne Landschaft allein macht die gute Atmosphäre aus. In dieser Woche hast du die Möglichkeit, Leute einem Mitarbeiter zu suchen, wenn dich etwas total beschäftigt oder du Hilfe und Rat brauchst.
in deinem Alter kennenzulernen, die mit Jesus leben wollen und dir zu guten Freunden werden können. Außerdem kannst du durch </p>
tiefgehende Bibelarbeiten und Stille Zeiten mit deiner Zimmergruppe und einem Mitarbeiter auch Gott besser kennenlernen oder <p>Du möchtest im Glauben herausgefordert werden, die Bibel und deinen Herrn besser kennenlernen und wirklich wachsen? Dann komm zur Grow Up und sei bereit, dich von Gott verändern zu
Fragen stellen, die du dir schon lange gestellt hast.</p> lassen!</p>
<p>Der Morgen ist gefüllt mit der Beschäftigung mit Gottes Wort, was es uns für unser Leben zu sagen hat und wie wir für </div>
Gott leben können. Du wirst herausgefordert, ganz persönlich darüber nachzudenken, wo du in Bezug auf Gott stehst und was du <div id="camp_schweiz" class="col-12 description" style="display: none">
gerne ändern oder auch fördern möchtest. Durch das Lernen von wichtigen Bibelversen bekommst du einen guten Schutz, wenn du <h2 class="headlinefont">Teeniefreizeit Schweiz</h2>
im Alltag mit Problemen zu kämpfen hast.</p> <p>Ab in die Berge zwei Wochen Schweiz: mit Bergen, Seen, Kühen und allem, was das Herz begehrt. Mit Sicherheit wirst du dort eine ganze Menge erleben, denn das Programm ist
<p>Am Nachmittag bleibt viel Zeit für tolle Spiele, Herausforderungen beim Sport, Taktieren im Geländespiel oder Erkunden vielfältig und voller Action!</p>
des Dorfes und der Weinberge.</p> <p>Du wirst in diesen zwei Wochen die Möglichkeit haben, spannende Bibelarbeiten und gute Gemeinschaft mit Gott zu erleben. Wir beginnen jeden Morgen in kleinen Gruppen mit
<p>Abends erwarten dich Gameshows, ein Film oder auch mal ein gemütliches Dinner. Auch nachts sind die Weinberge nicht gemeinsamer Stillen Zeit das bedeutet, dass wir über verschiedene Bibelstellen nachdenken und uns über unsere Leben und die Erfahrungen, die wir mit Gott gemacht haben, austauschen.</p>
immer sicher vor uns, egal ob es sich um eine Nachtwanderung oder ein spannendes Nachtspiel handelt.</p> <p>Nach dem Frühstück folgt die „Frohe Stunde“ mit einer Bibelarbeit. In dieser Zeit konzentrieren wir uns gemeinsam darauf, was uns verschiedene Mitarbeiter über Gott und die Bibel
<p>Gemeinschaft und Spaß kommen auf jeden Fall nicht zu kurz und auch im Glauben bietet dir die Hohenhaslach-Freizeit mitteilen werden. Es gibt viel zu lernen.</p>
Herausforderung, wenn du dazu bereit bist!</p> <p>In einer langen Mittagspause hast du Zeit für Fußball und Volleyball, Halli Galli oder andere Gesellschaftsspiele.</p>
<p> <p>Später am Nachmittag gibt es ein abwechslungsreiches Programm, beispielsweise Geländespiele vor Ort oder im Wald, Wasserspiele, Workshops und verschiedene AG's.</p>
<strong>Preise, Termine und weitere Infos findest du in unserem Buchungsportal.</strong> <p>Den Abend verbringen wir mit coolen kreativen Spielen wie z.B. einem Kochduell, Kiental sucht die Superband, Wetten Dass…?, und Die perfekte Minute. Oder aber wir sehen uns nach
</p> einem anstrengenden Tag ganz entspannt einen Film an und lassen den Abend mit angeregten Gesprächen ausklingen.</p>
<p> <p>Außerdem gibt es noch etwas ganz Besonderes: Unse Tagestouren! Die Mitarbeiter wecken dich bereits im frühen Morgengrauen und dann wird der Gipfel auf 2820 Metern Höhe gestürmt.
<a th:href="@{/camplist}">Jetzt Freizeiten entdecken</a> Oder wir fahren an den wunderschönen Thunersee. Hier kannst du nicht nur Schwimmen, sondern auch aus zehn Metern Höhe ins Wasser springen, Beachvolleyball spielen und viele andere coole
</p> Dinge machen.</p>
</div> <p>Bist du bereit, auf eine Woche voller Spaß und Action? Bist du bereit, dich verändern zu lassen? Bist du neugierig geworden? Dann sehen wir uns in der Schweiz!</p>
</div>
<div id="camp_heimfreizeit" class="col-12 description" style="display: none">
<h2 class="headlinefont">Heimfreizeit für Kinder in Heilbronn</h2>
<p>Du hast noch zwei Wochen Sommerferien, wohnst in Heilbronn und hast noch nichts vor? Wie wäre es mit einem coolen und abwechslungsreichen Tagesprogramm zusammen mit vielen anderen
Kindern in deinem Alter?</p>
<p>Auf der Heimfreizeit hast du die Möglichkeit schon einmal ein bisschen hineinzuschnuppern, wie es sich anfühlt, auf einer Freizeit dabei zu sein. Denn du übernachtest zwar zu Hause,
aber zwei Wochen lang verbringst du den Tag mit vielen anderen Kindern und Mitarbeitern bei einem tollen Programm.</p>
<p>Wir starten mit Liedern und einer spannenden Geschichte aus der Bibel in den Tag. Natürlich gibts auch gemeinsames Mittagessen. Auch Zeit zum spielen gibt es genug. Zum Beispiel
auf dem Spielplatz oder beim Völkerball auf dem Alten Friedhof. Nachmittags erwarten dich viele coole Aktionen. Wie wäre es zum Beispiel mit einer Schnitzeljagd? Oder einer kleinen
Wanderung auf den Wartberg? Mit vielen tollen Spielen im Pfühlpark? Oder mit einer schönen Abkühlung und viel Spaß im Freibad?</p>
<p>Nach einem kleinen Nachmittagssnack verabschieden wir uns bis zum nächsten Morgen.</p>
<p>Besondere Höhepunkte sind ein Besuch im Indoor-Spielplatz oder der Experimenta. Manchmal lässt Axel (Erlebnispädagoge) sich auch etwas ganz Besonderes einfallen, wie zum Beispiel
Flag-Football.</p>
<p>Das klingt doch viel besser, als sich zu Hause zu langweilen, oder?</p>
</div>
<div id="camp_hohenhaslach" class="col-12 description" style="display: none">
<h2 class="headlinefont">Teeniefreizeit Hohenhaslach</h2>
<p>Eine Woche Herbstferien und das hast keine Lust, sie zu verschwenden oder alleine zu Hause zu sitzen? Wie wärs mit einer herausfordernden Woche zusammen mit anderen Jugendlichen in
den schönen Weinbergen von Baden-Württemberg?</p>
<p>Das Freizeitheim in Hohenhaslach liegt tatsächlich mitten in den Weinbergen, die natürlich im Herbst am schönsten aussehen. Hier lassen sich wunderbar Geländespiele oder
Spaziergänge erleben.</p>
<p>Aber nicht die schöne Landschaft allein macht die gute Atmosphäre aus. In dieser Woche hast du die Möglichkeit, Leute in deinem Alter kennenzulernen, die mit Jesus leben wollen und
dir zu guten Freunden werden können. Außerdem kannst du durch tiefgehende Bibelarbeiten und Stille Zeiten mit deiner Zimmergruppe und einem Mitarbeiter auch Gott besser kennenlernen oder
Fragen stellen, die du dir schon lange gestellt hast.</p>
<p>Der Morgen ist gefüllt mit der Beschäftigung mit Gottes Wort, was es uns für unser Leben zu sagen hat und wie wir für Gott leben können. Du wirst herausgefordert, ganz persönlich
darüber nachzudenken, wo du in Bezug auf Gott stehst und was du gerne ändern oder auch fördern möchtest. Durch das Lernen von wichtigen Bibelversen bekommst du einen guten Schutz, wenn du
im Alltag mit Problemen zu kämpfen hast.</p>
<p>Am Nachmittag bleibt viel Zeit für tolle Spiele, Herausforderungen beim Sport, Taktieren im Geländespiel oder Erkunden des Dorfes und der Weinberge.</p>
<p>Abends erwarten dich Gameshows, ein Film oder auch mal ein gemütliches Dinner. Auch nachts sind die Weinberge nicht immer sicher vor uns, egal ob es sich um eine Nachtwanderung oder
ein spannendes Nachtspiel handelt.</p>
<p>Gemeinschaft und Spaß kommen auf jeden Fall nicht zu kurz und auch im Glauben bietet dir die Hohenhaslach-Freizeit Herausforderung, wenn du dazu bereit bist!</p>
</div>
<div class="col-12 center mt-3">
<a th:href="@{/camplist}" class="btn btn-outline-danger">zur Anmeldung</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -36,8 +36,8 @@
<td th:text="${#temporals.format(booker.bookingDate, 'dd.MM.yyyy')}"></td> <td th:text="${#temporals.format(booker.bookingDate, 'dd.MM.yyyy')}"></td>
</tr> </tr>
<tr> <tr>
<th>Bestätigt</th> <th>Status</th>
<td th:text="${booker.accept == null ? '' : (booker.accept ? 'Ja' : 'abgelehnt')}"></td> <td th:text="${booker.progress}"></td>
</tr> </tr>
<tr> <tr>
<th>Freizeitpreis</th> <th>Freizeitpreis</th>

View File

@ -18,7 +18,7 @@
<th>Freizeit</th> <th>Freizeit</th>
<th>Rolle</th> <th>Rolle</th>
<th>Kontostand</th> <th>Kontostand</th>
<th>Angemeldet</th> <th>Status</th>
<th>Bestätigt</th> <th>Bestätigt</th>
</tr> </tr>
</thead> </thead>
@ -48,7 +48,7 @@
</form> </form>
</td> </td>
<td class="middled" th:text="${#temporals.format(b.bookingDate, 'dd.MM.yyyy')}"></td> <td class="middled" th:text="${#temporals.format(b.bookingDate, 'dd.MM.yyyy')}"></td>
<td class="middled" th:text="${b.accept == null ? '' : (b.accept ? 'Ja' : 'abgelehnt')}"></td> <td class="middled" th:text="${b.progress}"></td>
</tr> </tr>
</th:block> </th:block>
</tbody> </tbody>

View File

@ -63,7 +63,7 @@
<th>Geschlecht</th> <th>Geschlecht</th>
<th>Rolle</th> <th>Rolle</th>
<th>Kontostand</th> <th>Kontostand</th>
<th>Angemeldet</th> <th>Status</th>
<th>Bestätigt</th> <th>Bestätigt</th>
</tr> </tr>
</thead> </thead>
@ -75,7 +75,7 @@
<td th:text="${b.role}"></td> <td th:text="${b.role}"></td>
<td><span th:text="${#numbers.formatDecimal(b.paid, 1, 2) + ' €'}" th:if="${b.paid != null}"></span></td> <td><span th:text="${#numbers.formatDecimal(b.paid, 1, 2) + ' €'}" th:if="${b.paid != null}"></span></td>
<td th:text="${#temporals.format(b.bookingDate, 'dd.MM.yyyy')}"></td> <td th:text="${#temporals.format(b.bookingDate, 'dd.MM.yyyy')}"></td>
<td th:text="${b.accept == null ? '' : (b.accept ? 'Ja' : 'abgelehnt')}"></td> <td th:text="${b.progress}"></td>
</tr> </tr>
</th:block> </th:block>
</tbody> </tbody>

View File

@ -39,7 +39,7 @@
<div th:text="${p.camprolle}"></div></td> <div th:text="${p.camprolle}"></div></td>
<td><div th:text="${#temporals.format(p.birthDate, 'dd.MM.yyyy')}"></div> <td><div th:text="${#temporals.format(p.birthDate, 'dd.MM.yyyy')}"></div>
<div th:text="${p.getAge(campStartDate)} + ' Jahre'"></div></td> <div th:text="${p.getAge(campStartDate)} + ' Jahre'"></div></td>
<td th:text="${p.accept}"></td> <td th:text="${p.progress}"></td>
<td th:text="${#temporals.format(p.created, 'dd.MM.yyyy HH:mm')}"></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> <td><span th:text="${p.consentCatalogPhoto ? 'ja' : 'nein'}" th:if="${p.consentCatalogPhoto}"></span></td>
<td th:text="${p.comment}"></td> <td th:text="${p.comment}"></td>

View File

@ -44,7 +44,7 @@
</div> </div>
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header" id="approvedpanel"> <h2 class="accordion-header" id="approvedpanel">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#approveddiv" aria-expanded="true" aria-control="approveddiv">kürzlich bestätigte <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#approveddiv" aria-expanded="true" aria-control="approveddiv">bestätigte
Anmeldungen</button> Anmeldungen</button>
</h2> </h2>
<div id="approveddiv" class="accordion-collapse collapse dist8" aria-labelled="approvedpanel" data-bs-parent="#mainacc"> <div id="approveddiv" class="accordion-collapse collapse dist8" aria-labelled="approvedpanel" data-bs-parent="#mainacc">
@ -79,7 +79,7 @@
</div> </div>
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header" id="rejectedpanel"> <h2 class="accordion-header" id="rejectedpanel">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#rejecteddiv" aria-expanded="true" aria-control="rejecteddiv">kürzlich abgelehnte <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#rejecteddiv" aria-expanded="true" aria-control="rejecteddiv">abgelehnte
Anmeldungen</button> Anmeldungen</button>
</h2> </h2>
<div id="rejecteddiv" class="accordion-collapse collapse dist8" aria-labelled="rejectedpanel" data-bs-parent="#mainacc"> <div id="rejecteddiv" class="accordion-collapse collapse dist8" aria-labelled="rejectedpanel" data-bs-parent="#mainacc">
@ -112,6 +112,41 @@
</script> </script>
</div> </div>
</div> </div>
<div class="accordion-item">
<h2 class="accordion-header" id="revokedpanel">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#revokeddiv" aria-expanded="true" aria-control="revokeddiv">stornierte
Anmeldungen</button>
</h2>
<div id="revokeddiv" class="accordion-collapse collapse dist8" aria-labelled="revokedpanel" data-bs-parent="#mainacc">
<table id="revoked">
<thead>
<tr>
<th>Freizeit</th>
<th>Name</th>
<th>Rolle</th>
<th>Anmeldedatum</th>
</tr>
</thead>
<tbody>
<tr th:each="u : ${revoked}">
<td><a th:href="@{'/confirmation/person/' + ${u.pkPerson}}" th:text="${u.camp} + ' ' + ${#temporals.format(u.date, 'yyyy')}"></a></td>
<td><a th:href="@{'/confirmation/person/' + ${u.pkPerson}}" th:text="${u.fullname}"></a></td>
<td><a th:href="@{'/confirmation/person/' + ${u.pkPerson}}" th:text="${u.rolename}"></a></td>
<td><a th:href="@{'/confirmation/person/' + ${u.pkPerson}}" th:text="${#temporals.format(u.registered, 'yyyy-MM-dd')}"></a></td>
</tr>
</tbody>
</table>
<script type="text/javascript">
$(document).ready(function() {
$("#revoked").DataTable({
language : locale_de,
pageLength : 5,
lengthMenu : [ [ 5, 25, 50, -1 ], [ 5, 25, 50, "Alle" ] ]
});
});
</script>
</div>
</div>
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header" id="overviewpanel"> <h2 class="accordion-header" id="overviewpanel">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#overviewdiv" aria-expanded="true" aria-control="overviewdiv">Freizeitenübersicht</button> <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#overviewdiv" aria-expanded="true" aria-control="overviewdiv">Freizeitenübersicht</button>
@ -127,14 +162,14 @@
<tbody> <tbody>
<tr th:each="o : ${campoverview}"> <tr th:each="o : ${campoverview}">
<td th:text="${o.camp} + ' ' + ${#temporals.format(o.date, 'yyyy')}"></td> <td th:text="${o.camp} + ' ' + ${#temporals.format(o.date, 'yyyy')}"></td>
<td><span th:text="${o.untouched}" class="badgetodo"></span> / <span th:text="${o.rejected}" class="badgewarn"></span> / <span th:text="${o.approved}" class="badgeinfo"></span></td> <td><span th:text="${o.untouched}" class="badgetodo"></span> / <span th:text="${o.rejected}" class="badgewarn"></span> / <span th:text="${o.approved}" class="badgeinfo"></span> / <span th:text="${o.revoked}" class="badgeerror"></span></td>
</tr> </tr>
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td>Zusammenfassung</td> <td>Zusammenfassung</td>
<td><span th:text="${campoverviewsummary.untouched}" class="badgetodo"></span> / <span th:text="${campoverviewsummary.rejected}" class="badgewarn"></span> / <span <td><span th:text="${campoverviewsummary.untouched}" class="badgetodo"></span> / <span th:text="${campoverviewsummary.rejected}" class="badgewarn"></span> / <span
th:text="${campoverviewsummary.approved}" class="badgeinfo"></span></td> th:text="${campoverviewsummary.approved}" class="badgeinfo"></span> / <span th:text="${campoverviewsummary.revoked}" class="badgeerror"></span></td>
</tfoot> </tfoot>
</table> </table>
<script type="text/javascript"> <script type="text/javascript">
@ -146,7 +181,7 @@
}); });
}); });
</script> </script>
<span>Legende:</span><span class="badgetodo">unbearbeitet</span><span class="badgewarn">abgelehnt</span><span class="badgeinfo">bestätigt</span> <span>Legende:</span><span class="badgetodo">unbearbeitet</span><span class="badgewarn">abgelehnt</span><span class="badgeinfo">bestätigt</span><span class="badgeerror">storniert</span>
</div> </div>
</div> </div>
<div class="accordion-item"> <div class="accordion-item">

View File

@ -8,7 +8,7 @@
<th:block layout:fragment="content"> <th:block layout:fragment="content">
<div class="mainpage"> <div class="mainpage">
<div class="container" style="max-width: 100%" sec:authorize="hasRole('registrator')"> <div class="container" style="max-width: 100%" sec:authorize="hasRole('registrator')">
<form action="#" th:action="@{/confirmation/person/update}" th:object="${person}" method="post" th:if="${person != null}"> <form id="form" action="#" th:action="@{/confirmation/person/update}" th:object="${person}" method="post" th:if="${person != null}">
<div class="row mb-2"> <div class="row mb-2">
<label for="outputPk" class="col-sm-2 col-form-label">ID</label> <label for="outputPk" class="col-sm-2 col-form-label">ID</label>
<div class="col-sm-10"> <div class="col-sm-10">
@ -112,26 +112,65 @@
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label for="inputAccept" class="col-sm-2 col-form-label">Status</label> <label for="inputAccept" class="col-sm-2 col-form-label">Status</label>
<div class="col-sm-10"> <span class="col-sm-2 btn btn-outline-warning" th:if="${person.progress} == 'requested'">offen</span>
<div class="form-group"> <span class="col-sm-2 btn btn-outline-success" th:if="${person.progress} == 'approved'">bestätigt</span>
<input type="radio" class="btn-check" id="accept1" name="accept1" value="" th:field="*{accept}" /> <label class="btn btn-outline-primary" for="accept1"><i <span class="col-sm-2 btn btn-outline-danger" th:if="${person.progress} == 'rejected'">abgelehnt</span>
class="fas fa-question"></i>&nbsp;offen</label> <input type="radio" class="btn-check" id="accept2" name="accept2" value="true" th:field="*{accept}" /> <label class="btn btn-outline-success" <span class="col-sm-2 btn btn-outline-secondary" th:if="${person.progress} == 'revoked'">storniert</span>
for="accept2"><i class="fas fa-check"></i>&nbsp;bestätigt</label> <input type="radio" class="btn-check" id="accept3" name="accept3" value="false" th:field="*{accept}" /> <label <div class="col-sm-8" th:if="${#lists.contains({'requested', 'approved', 'rejected'}, person.progress)}">
class="btn btn-outline-danger" for="accept3"><i class="fas fa-ban"></i>&nbsp;abgelehnt</label> <select th:field="*{progress}" class="form-select">
</div> <option value="requested">offen</option>
<option value="approved">bestätigt</option>
<option value="rejected">abgelehnt</option>
</select>
</div>
<div class="col-sm-8" th:if="${person.progress} == 'revoked'">
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
<i class="fas fa-trash"></i>&nbsp;endgültig löschen
</button>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<label for="inputAccept" class="col-sm-2 col-form-label"></label> <label for="inputAccept" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10"> <div class="col-sm-10">
<button type="submit" class="btn btn-primary" onclick="progress.start()">Ok</button> <button type="submit" class="btn btn-primary" onclick="progress.start()" th:if="${person.progress} != 'revoked'">Ok</button>
<a th:href="@{/confirmation}" class="btn btn-secondary">Abbrechen</a> <a th:href="@{/confirmation}" class="btn btn-secondary">Abbrechen</a>
</div> </div>
</div> </div>
</form> </form>
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-danger">
<h1 class="modal-title fs-5" id="deleteModalLabel">Löschen der Anmeldung</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Willst du wirklich die Anmeldung von <span th:text="${person.forename}" class="text-danger"></span>&nbsp;<span th:text="${person.surname}" class="text-danger"></span> an der Freizeit
<select class="form-select locked" th:field="${person.fkCamp}" disabled="disabled">
<option th:each="c : ${camps}" th:value="${c.pk}" th:text="${c.name} + ' ' + ${#temporals.format(c.arrive, 'yyyy')} + ' in ' + ${c.location}"></option>
</select> löschen? Sie geht damit unwiederbringlich verloren.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Abbrechen</button>
<a th:href="@{/registration/remove/{id}(id=${person.pk})}" class="btn btn-danger">ja, wirklich löschen</a>
</div>
</div>
</div>
</div>
<div th:if="${person == null}" class="error">In der Datenbank wurde keine Person mit entsprechender ID gefunden.</div> <div th:if="${person == null}" class="error">In der Datenbank wurde keine Person mit entsprechender ID gefunden.</div>
</div> </div>
</div> </div>
</th:block> <script type="text/javascript">
/**
* forbid enter in form to allow disabling the ok button for revoked bookings
*/
$(document).on('keyup keypress', 'form', function(e) {
if (e.keyCode == 13) {
e.preventDefault();
return false;
}
});
</script>
</th:block>
</body> </body>
</html> </html>

View File

@ -32,11 +32,13 @@
<div class="accordion" id="acc" th:if="${mybookings.size() > 0}" style="max-width: 800px; margin-left: auto; margin-right: auto"> <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}"> <div class="accordion-item" th:each="b : ${mybookings}">
<h2 class="accordion-header" th:id="'acc-head-' + ${b.pk}" th:if="${b.pk}"> <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}" <button th:class="'accordion-button collapsed acc_' + ${b.isOver ? 'over' : b.progress}" type="button" data-bs-toggle="collapse" th:data-bs-target="'#acc-body-' + ${b.pk}"
aria-expanded="true" th:aria-controls="'#acc-body-' + ${b.pk}"> aria-expanded="true" th:aria-controls="'#acc-body-' + ${b.pk}">
<i class="fas fa-check framed framed-green" th:if="${b.accept}"></i> <i class="fas fa-ban framed framed-red" th:if="${b.accept} == false"></i> <i <i class="fas fa-check framed framed-green" th:if="${b.progress} == 'approved'"></i>
class="fas fa-question framed framed-orange" th:if="${b.accept} == null"></i> <i class="fas fa-ban framed framed-red" th:if="${b.progress} == 'rejected'"></i>
<span th:text="${b.forename + ' ' + b.surname + ' für ' + b.campName + ' ' + #numbers.formatInteger(b.year, 4)}" class="headlinefont"></span> <i class="fas fa-question framed framed-orange" th:if="${b.progress} == 'requested'"></i>
<i class="fas fa-trash framed framed-pink" th:if="${b.progress} == 'revoked'"></i>
<span th:text="${b.forename + ' ' + b.surname + ' @ ' + b.campName + ' ' + #numbers.formatInteger(b.year, 4)}" class="headlinefont"></span>
</button> </button>
</h2> </h2>
<div th:id="'acc-body-' + ${b.pk}" class="accordion-collapse collapse" th:aria-labelledby="'acc-head-' + ${b.pk}"> <div th:id="'acc-body-' + ${b.pk}" class="accordion-collapse collapse" th:aria-labelledby="'acc-head-' + ${b.pk}">
@ -62,7 +64,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="card" th:if="${b.accept}"> <div class="card" th:if="${b.progress} == 'approved'">
<div class="card-header">Dokumente</div> <div class="card-header">Dokumente</div>
<div class="card-body"> <div class="card-body">
<div class="container"> <div class="container">
@ -139,8 +141,11 @@
<div class="col-sm-8"> <div class="col-sm-8">
<input type="submit" class="btn btn-primary" value="Änderungen übernehmen" /> <input type="submit" class="btn btn-primary" value="Änderungen übernehmen" />
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2" th:if="${b.progress != 'revoked'}">
<a th:href="@{/registration/cancel/{id}(id=${b.pk})}" class="btn btn-outline-danger" th:if="${!b.isOver}">stornieren</a> <a th:href="@{/registration/revoke/{id}(id=${b.pk})}" class="btn btn-outline-danger" th:if="${!b.isOver}">stornieren</a>
</div>
<div class="col-sm-2" th:if="${b.progress == 'revoked'}">
<a th:href="@{/registration/unrevoke/{id}(id=${b.pk})}" class="btn btn-outline-success" th:if="${!b.isOver}">Stornierung aufheben</a>
</div> </div>
</div> </div>
</div> </div>
@ -150,8 +155,12 @@
<div class="alert alert-primary" th:if="${b.created != null}"> <div class="alert alert-primary" th:if="${b.created != null}">
angemeldet am <span th:text="${#temporals.format(b.created, 'dd.MM.yyyy')}"></span> von <span th:text="${b.subscriber}"></span> angemeldet am <span th:text="${#temporals.format(b.created, 'dd.MM.yyyy')}"></span> von <span th:text="${b.subscriber}"></span>
</div> </div>
<div th:class="'alert ' + ${b.accept ? 'alert-success' : 'alert-danger'}" th:if="${b.accept != null}"> <div class="alert alert-danger" th:if="${b.progress == 'revoked'}">
<span th:text="${b.accept ? 'bestätigt' : 'abgelehnt'}"></span> von <span th:text="${b.registrator}"></span> storniert von <span th:text="${b.subscriber}"></span>
</div>
<div th:class="'alert alert-' + (${b.progress} == 'approved' ? 'success' : 'danger')" th:if="${#lists.contains({'approved', 'rejected'}, b.progress)}">
<span th:if="${b.progress} == 'approved'">bestätigt</span>
<span th:if="${b.progress} == 'rejected'">abgelehnt</span> von <span th:text="${b.registrator}"></span>
</div> </div>
<div class="alert alert-warning" th:if="${b.isOver}">Die Freizeit ist bereits vorbei.</div> <div class="alert alert-warning" th:if="${b.isOver}">Die Freizeit ist bereits vorbei.</div>
</div> </div>

View File

@ -47,7 +47,7 @@
</div> </div>
<div class="row g-5" th:unless="${c.bookingHasStarted}"> <div class="row g-5" th:unless="${c.bookingHasStarted}">
<div class="col-12 alert alert-info" role="alert"> <div class="col-12 alert alert-info" role="alert">
Die Anmeldung wird erst am <span th:text="${#temporals.format(c.startBooking, 'dd.MM.yyyy')}"></span> freigeschaltet. Die Anmeldung wird erst am <span th:text="${#temporals.format(c.startBooking, 'dd.MM.yyyy, HH:mm')}"></span> Uhr, freigeschaltet.
</div> </div>
</div> </div>
</div> </div>

View File

@ -17,23 +17,6 @@
<p>Einen Tag vor seinem Tod sagte er dazu: „Ich will mir dafür nicht auf die Schulter klopfen. Es ist Gottes Werk.“</p> <p>Einen Tag vor seinem Tod sagte er dazu: „Ich will mir dafür nicht auf die Schulter klopfen. Es ist Gottes Werk.“</p>
<p>Wir dürfen dankbar sein, für das, was er durch Gottes Gnade aufgebaut hat und bitten euch herzlich um Gebet, um diese große Arbeit der Freizeiten so weiterzuführen, wie es dem Herrn gefällt und wie es sich auch Onkel Werner gewünscht hat. Er sagte, dass er sich wünscht und dafür betet, dass wir noch doppelt so viel Segen erleben dürften, ähnlich wie Elisa, der sich das doppelte des Geistes Elias erbat.</p> <p>Wir dürfen dankbar sein, für das, was er durch Gottes Gnade aufgebaut hat und bitten euch herzlich um Gebet, um diese große Arbeit der Freizeiten so weiterzuführen, wie es dem Herrn gefällt und wie es sich auch Onkel Werner gewünscht hat. Er sagte, dass er sich wünscht und dafür betet, dass wir noch doppelt so viel Segen erleben dürften, ähnlich wie Elisa, der sich das doppelte des Geistes Elias erbat.</p>
<p>Onkel Werner wird uns fehlen, aber wir freuen uns, dass er nach einem erfüllten Leben sein Ziel erreichen durfte!</p> <p>Onkel Werner wird uns fehlen, aber wir freuen uns, dass er nach einem erfüllten Leben sein Ziel erreichen durfte!</p>
<!--
<img class="img-fluid rounded" th:src="@{/images/start-banner-2019.jpg}" alt=""><br />
<br />
<div class="blocktext">
<h1 style="text-align: left">Ferien, die in Erinnerung bleiben persönlich, echt, erlebnisreich</h1>
<p style="text-align: left">Du willst nicht einfach deine Zeit totschlagen, sondern Ferien erleben, die dein Leben prägen,
sinnvoll sind und dazu Spaß machen? Dann bist du hier genau richtig! Bei den Freizeiten geht es um Freundschaften, Spaß und
vor allem Gottes Wort. Genau dafür stehen Onkel Werner Freizeiten!</p>
<p></p>
<h2 style="text-align: left">Unsere Freizeiten</h2>
<h4 style="text-align: left">Erfahre hier, welche Freizeiten wir anbieten und was da so abgeht.</h4>
<p style="text-align: left">Preise, Termine und weitere Infos findest du in unserem Buchungsportal.</p>
<p style="text-align: left">
<a th:href="@{/camplist}">Jetzt Freizeiten entdecken</a>
</p>
</div>
-->
</div> </div>
</div> </div>
</div> </div>

View File

@ -21,7 +21,7 @@
th:if="${bean.isDirector}">Leiter</span><span th:if="${bean.isFeeder}">Küchenhilfe</span> th:if="${bean.isDirector}">Leiter</span><span th:if="${bean.isFeeder}">Küchenhilfe</span>
</div> </div>
<div class="card-footer"> <div class="card-footer">
<a th:href="@{/registration/remove/{id}(id=${bean.pk})}" class="btn btn-danger">Ja, stornieren</a> &nbsp;<a th:href="@{/dashboard}" class="btn btn-outline-success">Stornierung abbrechen</a> <a th:href="@{/registration/revoke/{id}(id=${bean.pk})}" class="btn btn-danger">Ja, stornieren</a> &nbsp;<a th:href="@{/dashboard}" class="btn btn-outline-success">Stornierung abbrechen</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,17 +1,19 @@
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" data-bs-theme="light">
<head> <head>
<title>Camp Organizer 2</title> <title>Camp Organizer 2</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/bootstrap/5.3.2/css/bootstrap.min.css} " /> <link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/bootstrap/5.3.3/css/bootstrap.min.css} " />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/font-awesome/6.5.1/css/all.min.css} " /> <link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/font-awesome/6.5.2/css/all.min.css} " />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/datatables/1.13.5/css/jquery.dataTables.min.css}" /> <link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/datatables/1.13.5/css/jquery.dataTables.min.css}" />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/select2/4.0.13/css/select2.min.css}" /> <link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/select2/4.0.13/css/select2.min.css}" />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/css/style.css}" />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/css/select2-bootstrap-5-theme.min.css}" /> <link th:rel="stylesheet" type="text/css" media="all" th:href="@{/css/select2-bootstrap-5-theme.min.css}" />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/css/style.css}" />
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/fancyapps__fancybox/3.5.7/dist/jquery.fancybox.min.css}">
<script th:src="@{/webjars/jquery/3.7.1/jquery.min.js}"></script> <script th:src="@{/webjars/jquery/3.7.1/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/5.3.2/js/bootstrap.bundle.min.js}"></script> <script th:src="@{/webjars/fancyapps__fancybox/3.5.7/dist/jquery.fancybox.min.js}"></script>
<script th:src="@{/webjars/bootstrap/5.3.3/js/bootstrap.bundle.min.js}"></script>
<script th:src="@{/webjars/datatables/1.13.5/js/jquery.dataTables.min.js}"></script> <script th:src="@{/webjars/datatables/1.13.5/js/jquery.dataTables.min.js}"></script>
<script th:src="@{/webjars/select2/4.0.13/js/select2.full.min.js}"></script> <script th:src="@{/webjars/select2/4.0.13/js/select2.full.min.js}"></script>
<script th:src="@{/js/dataTables.de.js}"></script> <script th:src="@{/js/dataTables.de.js}"></script>
@ -21,7 +23,7 @@
</head> </head>
<body> <body>
<nav class="navbar sticky-top navbar-expand-lg navbar-light bg-light headerlayout navbar-background"> <nav class="navbar sticky-top navbar-expand-lg navbar-light bg-light headerlayout navbar-background">
<span class="navbar-brand"><img th:src="@{/images/logo.png}" width="128px" style="margin-left: 8px" /></span> <span class="navbar-brand"><a th:href="@{/allgemeines}"><span class="logo"></span></a></span>
<button class="navbar-toggler" style="margin-right: 40px" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" <button class="navbar-toggler" style="margin-right: 40px" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false"> aria-expanded="false">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
@ -29,13 +31,8 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent" style="margin-right: 20px"> <div class="collapse navbar-collapse" id="navbarSupportedContent" style="margin-right: 20px">
<ul class="navbar-nav mb-2 mb-lg-0"> <ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item"><a th:href="@{/ical}" class="btn btn-secondary btn-icon-silent" target="_blank" title="Freizeitdaten als ical herunterladen"><i class="far fa-calendar-alt"></i></a></li> <li class="nav-item"><a th:href="@{/ical}" class="btn btn-secondary btn-icon-silent" target="_blank" title="Freizeitdaten als ical herunterladen"><i class="far fa-calendar-alt"></i></a></li>
<li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/}">Startseite</a></li> <li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/camplist}">Anmeldung</a></li>
<li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/nachruf}">Nachruf</a></li> <li class="nav-item dropdown"><a class="nav-link dropdown-toggle btn-icon-silent menufont" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">Berichte</a>
<li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/allgemeines}">Allgemeines</a></li>
<li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/camplist}">Freizeiten</a></li>
<li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/verein}">Verein</a></li>
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle btn-icon-silent menufont" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Tagebuch </a>
<ul class="dropdown-menu visibledropdown" aria-labelledby="navbarDropdown"> <ul class="dropdown-menu visibledropdown" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item menufont" th:href="@{/reports/olfenostern2023}">Osterfreizeit 2023 in Olfen</a></li> <li><a class="dropdown-item menufont" th:href="@{/reports/olfenostern2023}">Osterfreizeit 2023 in Olfen</a></li>
<li><hr class="dropdown-divider"></li> <li><hr class="dropdown-divider"></li>
@ -65,7 +62,15 @@
<li><a class="dropdown-item menufont" th:href="@{/reports/schweiz2014}">Schweiz 2014</a></li> <li><a class="dropdown-item menufont" th:href="@{/reports/schweiz2014}">Schweiz 2014</a></li>
<li><hr class="dropdown-divider"></li> <li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item menufont" th:href="@{/reports/history}">Über 30 Jahre Onkel Werner Freizeiten Ein Rückblick ...</a></li> <li><a class="dropdown-item menufont" th:href="@{/reports/history}">Über 30 Jahre Onkel Werner Freizeiten Ein Rückblick ...</a></li>
</ul></li> </ul>
</li>
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle btn-icon-silent menufont" href="#" id="navbarDropdownClub" role="button" data-bs-toggle="dropdown" aria-expannded="false">Verein</a>
<ul class="dropdown-menu visibledropdown" aria-labelledby="navbarDropdownClub">
<li><a class="dropdown-item menufont" th:href="@{/nachruf}">Onkel Werner</a></li>
<li><a class="dropdown-item menufont" th:href="@{/verein}">Vereinsbeschreibung</a></li>
<li><a class="dropdown-item menufont" th:href="@{/vereinsmitglieder}">Vereinsmitglieder</a></li>
</ul>
</li>
<li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/kontakt}">Kontakt</a></li> <li class="nav-item"><a class="btn btn-icon-silent menufont" th:href="@{/kontakt}">Kontakt</a></li>
</ul> </ul>
<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('business')"> <ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('business')">
@ -127,7 +132,7 @@
<li class="nav-item"> <li class="nav-item">
<div class="dropdown"> <div class="dropdown">
<button class="btn btn-hoverborder navbar-collapse" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <button class="btn btn-hoverborder navbar-collapse" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<img th:src="@{/images/Icon_Profil.svg}" width="24px" height="24px" /> <span class="icon_profile"></span>
</button> </button>
<ul class="dropdown-menu dropdown-menu-end" th:if="${#strings.isEmpty(currentUser)}"> <ul class="dropdown-menu dropdown-menu-end" th:if="${#strings.isEmpty(currentUser)}">
<li><a class="dropdown-item" th:href="@{/dashboard}">einloggen</a></li> <li><a class="dropdown-item" th:href="@{/dashboard}">einloggen</a></li>

View File

@ -31,50 +31,7 @@
<h3 class="headlinefont">Der Verein</h3> <h3 class="headlinefont">Der Verein</h3>
<p>Und unser Verein? Der ist eben aus genau diesen Kindern und Jugendlichen entstanden, die selbst Onkel Werners Freizeiten besucht haben und später dort Mitarbeiter geworden sind. <p>Und unser Verein? Der ist eben aus genau diesen Kindern und Jugendlichen entstanden, die selbst Onkel Werners Freizeiten besucht haben und später dort Mitarbeiter geworden sind.
Wir möchten, dass seine Arbeit weitergeführt wird. Aber vor allem wollen wir, dass noch viele Kinder und Jugendliche den Herrn Jesus kennen lernen können und mit ihm leben wollen.</p> Wir möchten, dass seine Arbeit weitergeführt wird. Aber vor allem wollen wir, dass noch viele Kinder und Jugendliche den Herrn Jesus kennen lernen können und mit ihm leben wollen.</p>
<p> <p></p>
<h3 class="headlinefont">Die Vereinsmitglieder</h3>
<p>In unserem Verein arbeiten verschiedene Freizeitbegeisterte mit, von denen sich hier ein paar vorstellen:</p>
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/simeon.velleuer.jpg}" align="left" class="rounded" style="margin-right: 8px" /> Simeon Velleuer, 41 Jahre, verheiratet mit Anja und Vater von zwei wunderbaren
Kindern, Sophie und Kaleb. Für alle „Süddeutschen“ meine Heimat liegt „im Norden“ in Mettmann.<br /> <br /> Ich darf mittlerweile auf eine über zwanzigjährige Zeit in der Mitarbeit
mit Kids und Teens zurückblicken und bin unserem gnädigen Gott und Vater dafür sehr dankbar. Er hat mich errettet und aus der Finsternis in sein wunderbares Licht berufen (1.Petr. 2,9).
Diese Botschaft möchte ich gerne weitergeben - auf Freizeiten durch die froh machende Botschaft der Bibel und durch das ganz praktische und tägliche Leben.<br /> <br /> Ich erhoffe mir
von den Freizeiten, dass wir auf ein Leben mit Gott aufmerksam machen können. Das ist spannend und herausfordernd zugleich. Durch zahlreiche Erfahrungen in meinem Leben habe ich
feststellen können, dass Gott immer den richtigen Plan für jeden ganz persönlich längst fertig hat. Wir dürfen uns ihm ganz anvertrauen.<br /> <br /> (Es ist schon ein paar Jahre her,
als ich selber noch Teilnehmer auf der wunderschönen Griesalp war. Heutzutage fahren wir ins Kiental. Großartig gelegen inmitten der faszinierenden Bergwelt des Schweizer Berner
Oberlandes. Die Kombination aus Wanderungen und Andachten ist genau das Richtige für mich...und mit Sicherheit auch für dich.)<br />
<hr />
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/joerg.henke.jpg}" align="left" class="rounded" style="margin-right: 8px" /> Jörg Henke, Vater von zwei atemberaubenden Töchtern. Aus Dresden unterstütze ich die
Freizeitarbeit v.a. im Bereich der Homepage und den Abrechnungen. Wenn ich es mal wieder schaffe, auch an einer Freizeit teilzunehmen, spiele ich gerne Gitarre und singe viele Lieder mit
den Teilnehmern.<br /> <br /> Als einer von Onkel Werners "Erben" darf ich mich an meine Bekehrung erinnern, die ich am 31.10.1993 erlebt habe. Details dazu gibt es auch hier: <a
href="https://www.jottyfan.de/bekehrung/" target="_blank">https://www.jottyfan.de/bekehrung/</a>.<br /> <br /> Gerade deswegen ist es mir wichtig, dass unsere Freizeiten stattfinden,
offen für finanziell schwächere Familien sind und wir durch die uns anvertrauten Spenden unterstützen können. Jedes Kind / jeder Teenie soll die rettende Botschaft vom Kreuz hören: dass
Jesus Christus gerade für dich gestorben und auferstanden ist, um dich von deinen Sünden zu befreien und dir damit ewiges Leben in der Gemeinschaft mit Gott schenkt. Sehr wertvoll finde
ich daher auch die Abendandachten, die es ermöglichen, genau diese Wahrheit zu verdeutlichen.<br />
<hr />
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/anna.weiser.png}" align="left" class="rounded" style="margin-right: 8px" /> Mein Name ist Anna Weiser, ich bin Ehefrau und Mutter und arbeite seit ich 18 Jahre alt
bin auf den Freizeiten mit. Schnell habe ich gemerkt, dass der Herr mir das Anliegen für die Freizeitarbeit stärker aufs Herz legt und so habe ich mit der Zeit mehr Verantwortung übernehmen
und in den Verein eintreten dürfen.<br /><br />Mir liegt es stark am Herzen, Kindern, Jugendlichen und jungen Erwachsenen vom Evangelium zu erzählen, ihnen das Gottes Wort groß zu machen,
sie in der Nachfolge von Jesus Christus zu fördern und ihnen auch über die Freizeiten hinaus in ihrem Glaubensleben und ihrer Charakterentwicklung zu helfen.<br /><br />
Seit 2020 darf ich mit einem Minijob im Verein angestellt sein und übernehme neben der Freizeitarbeit (Schwerpunkt Teenie- und Jugendfreizeiten) vor allem Aufgaben im organisatorischen
Bereich und in der Nacharbeit mit Mädels und jungen Frauen.
<br />
<hr />
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/linda.lang.png}" align="left" class="rounded" style="margin-right: 8px" /> Ich bin Linda und 22 Jahre alt. In meiner Freizeit fahre ich Inliner, reise und habe gerne
eine Kamera in der Hand. Schon als Kind durfte ich die Onkel Werner Freizeiten (vor allem die Heimfreizeiten) besuchen und auch da immer mehr über Gottes Wort lernen und nach meiner Bekehrung
weiter erkennen. Nachdem die Teilnehmer-Zeit vorbei war, durfte ich auch als Mitarbeiter auf Freizeiten unterstützen, bin aber im Verein hauptsächlich im Bereich der Website und Design tätig.<br /><br />
Das Besondere an den Onkel Werner Freizeiten ist, dass Kinder und Jugendliche nicht nur gemeinsam Spiel und Spaß haben, sondern auch hören und sehen, wie das Wort Gottes im Alltag angewandt
und erlebt werden kann. Der Mittelpunkt der Freizeiten ist Jesus Christus, der jedes einzelne Kind liebt und zu sich ruft, egal aus welchen Umständen es kommt. Wir möchten diese Gelegenheit
deshalb nutzen und sein Evangelium in den Freizeiten weitergeben.
<br />
<hr />
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,82 @@
<!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 - Vereinsmitglieder</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<th:block layout:fragment="content">
<div class="container">
<div class="row">
<div class="col-12">
<h3 class="headlinefont">Die Vereinsmitglieder</h3>
<p>In unserem Verein arbeiten verschiedene Freizeitbegeisterte mit, von denen sich hier ein paar vorstellen:</p>
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/simeon.velleuer.jpg}" align="left" class="rounded" style="margin-right: 8px" /> Simeon Velleuer, 41 Jahre, verheiratet mit Anja und Vater von zwei wunderbaren
Kindern, Sophie und Kaleb. Für alle „Süddeutschen“ meine Heimat liegt „im Norden“ in Mettmann.<br /> <br /> Ich darf mittlerweile auf eine über zwanzigjährige Zeit in der Mitarbeit
mit Kids und Teens zurückblicken und bin unserem gnädigen Gott und Vater dafür sehr dankbar. Er hat mich errettet und aus der Finsternis in sein wunderbares Licht berufen (1.Petr. 2,9).
Diese Botschaft möchte ich gerne weitergeben - auf Freizeiten durch die froh machende Botschaft der Bibel und durch das ganz praktische und tägliche Leben.<br /> <br /> Ich erhoffe mir
von den Freizeiten, dass wir auf ein Leben mit Gott aufmerksam machen können. Das ist spannend und herausfordernd zugleich. Durch zahlreiche Erfahrungen in meinem Leben habe ich
feststellen können, dass Gott immer den richtigen Plan für jeden ganz persönlich längst fertig hat. Wir dürfen uns ihm ganz anvertrauen.<br /> <br /> (Es ist schon ein paar Jahre her,
als ich selber noch Teilnehmer auf der wunderschönen Griesalp war. Heutzutage fahren wir ins Kiental. Großartig gelegen inmitten der faszinierenden Bergwelt des Schweizer Berner
Oberlandes. Die Kombination aus Wanderungen und Andachten ist genau das Richtige für mich...und mit Sicherheit auch für dich.)<br />
<hr />
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/joerg.henke.jpg}" align="left" class="rounded" style="margin-right: 8px" /> Jörg Henke, Vater von zwei atemberaubenden Töchtern. Aus Dresden unterstütze ich die
Freizeitarbeit v.a. im Bereich der Homepage und den Abrechnungen. Wenn ich es mal wieder schaffe, auch an einer Freizeit teilzunehmen, spiele ich gerne Gitarre und singe viele Lieder mit
den Teilnehmern.<br /> <br /> Als einer von Onkel Werners "Erben" darf ich mich an meine Bekehrung erinnern, die ich am 31.10.1993 erlebt habe. Details dazu gibt es auch hier: <a
href="https://www.jottyfan.de/bekehrung/" target="_blank">https://www.jottyfan.de/bekehrung/</a>.<br /> <br /> Gerade deswegen ist es mir wichtig, dass unsere Freizeiten stattfinden,
offen für finanziell schwächere Familien sind und wir durch die uns anvertrauten Spenden unterstützen können. Jedes Kind / jeder Teenie soll die rettende Botschaft vom Kreuz hören: dass
Jesus Christus gerade für dich gestorben und auferstanden ist, um dich von deinen Sünden zu befreien und dir damit ewiges Leben in der Gemeinschaft mit Gott schenkt. Sehr wertvoll finde
ich daher auch die Abendandachten, die es ermöglichen, genau diese Wahrheit zu verdeutlichen.<br />
<hr />
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/anna.weiser.png}" align="left" class="rounded" style="margin-right: 8px" /> Mein Name ist Anna Weiser, ich bin Ehefrau und Mutter und arbeite seit ich 18 Jahre alt
bin auf den Freizeiten mit. Schnell habe ich gemerkt, dass der Herr mir das Anliegen für die Freizeitarbeit stärker aufs Herz legt und so habe ich mit der Zeit mehr Verantwortung übernehmen
und in den Verein eintreten dürfen.<br /><br />Mir liegt es stark am Herzen, Kindern, Jugendlichen und jungen Erwachsenen vom Evangelium zu erzählen, ihnen das Gottes Wort groß zu machen,
sie in der Nachfolge von Jesus Christus zu fördern und ihnen auch über die Freizeiten hinaus in ihrem Glaubensleben und ihrer Charakterentwicklung zu helfen.<br /><br />
Seit 2020 darf ich mit einem Minijob im Verein angestellt sein und übernehme neben der Freizeitarbeit (Schwerpunkt Teenie- und Jugendfreizeiten) vor allem Aufgaben im organisatorischen
Bereich und in der Nacharbeit mit Mädels und jungen Frauen.
<br />
<hr />
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/lars.dell.png}" align="left" class="rounded" style="margin-right: 8px" /> Würdest du lieber die Victoriafälle besuchen oder die Sahara Wüste?<br />
Hallöchen, ich bin Lars; auch wenn du mit der Frage am Anfang nichts verbinden kannst, lies ruhig weiter. Man hat mich kürzlich gefragt, warum ich denn eigentlich Mitarbeiter sein möchte,
„was motiviert dich denn?“ fragt man da. Nun, um ehrlich zu sein: Oft scheinbar sehr wenig. Sehr oft einfach der Drang, das tun zu müssen, was man schon immer getan hat.
Manche vermuten ja, dass der Strohhut auf Freizeitfotos einem immer wiederkehrenden Landstreicher zuzuschreiben ist, tatsächlich ist es aber meiner. Warum aber komme ich
immer wieder? Nun, manchmal weiß ich es nicht anders zu beschreiben als ein Drängen, ein Pflichtgefühl, das mich zieht, eine Last, die man einfach nicht loskriegt, wenn man
stehenbleibt. Ich kann mich daran erinnern, dass es früher nicht so war: Als Mitarbeiter mit Ende 15 sah die Welt anders aus: Man hat sich auf die Gemeinschaft, den Spaß, die
Spiele, allgemein die Mega Gaudi auf den Freizeiten gefreut. Da waren die Freunde, die Leute, die man gern hat, vielleicht gerade deshalb, weil man sie nur ein paar Mal im
Jahr sieht. Aber wenn die ersten Weggefährten und Freunde nicht mehr kommen, stellt sich die Frage: Warum kommst du?<br />
Ich habe vorhin den Drang beschreiben, kommen zu müssen. Es ist eine Last, die in der Vorbereitung auf die Freizeiten immer leichter wird und auf den Freizeiten irgendwann
ganz verschwindet. Ich glaube, dass es daran liegt, dass man merkt, dass Gott wirken möchte. Man sieht, dass Er durch die gute Botschaft von Jesus Christus Leben verändert
und durch Sein Wort die dicksten, stursten und selbstmitleidigsten Kinder, Teens, Jugendlichen und Erwachsenen knackt. Das ist wie der freie, ungetrübte Blick auf einen
gewaltigen Wasserfall. Ich erlebe Freizeiten als solche Wasserfälle der Gnade Gottes, wo Er wirkt und wir staunend zusehen, was Er Gewaltiges tut. Und da kann ich ein
Werkzeug sein. Die Frage, die sich mir dann stellt, ist nicht mehr: Warum komme ich eigentlich? Sondern: Wo wirkt die gewaltige Gnade Gottes?<br />
Und so drängt es mich immer wieder in die Ferne: Hohenhaslach, Schweiz, Olfen egal wo, egal wer, egal wie viele - Hauptsache, es gibt dort Wasserfälle zu besichtigen.
<br />
<hr />
</div>
</div>
<div>
<h3 class="headlinefont">Ehemalige Vereinsmitglieder</h3>
<p>Leider verlassen unseren Verein auch ab und zu Mitarbeiter, bei denen sich die Lebensumstände verändert haben. Wie sie sich einst vorgestellt haben, kann hier nachgelesen werden:</p>
</div>
<div class="col-sm-12 col-md-6">
<img th:src="@{/images/linda.lang.png}" align="left" class="rounded" style="margin-right: 8px" /> Ich bin Linda und 22 Jahre alt. In meiner Freizeit fahre ich Inliner, reise und habe gerne
eine Kamera in der Hand. Schon als Kind durfte ich die Onkel Werner Freizeiten (vor allem die Heimfreizeiten) besuchen und auch da immer mehr über Gottes Wort lernen und nach meiner Bekehrung
weiter erkennen. Nachdem die Teilnehmer-Zeit vorbei war, durfte ich auch als Mitarbeiter auf Freizeiten unterstützen, bin aber im Verein hauptsächlich im Bereich der Website und Design tätig.<br /><br />
Das Besondere an den Onkel Werner Freizeiten ist, dass Kinder und Jugendliche nicht nur gemeinsam Spiel und Spaß haben, sondern auch hören und sehen, wie das Wort Gottes im Alltag angewandt
und erlebt werden kann. Der Mittelpunkt der Freizeiten ist Jesus Christus, der jedes einzelne Kind liebt und zu sich ruft, egal aus welchen Umständen es kommt. Wir möchten diese Gelegenheit
deshalb nutzen und sein Evangelium in den Freizeiten weitergeben.
<br />
<hr />
</div>
</div>
</th:block>
</body>
</html>