confirmation accepts deletion of revoked registrations

This commit is contained in:
Jottyfan 2024-10-26 11:37:46 +02:00
parent b5403ae20c
commit 2abb937725
26 changed files with 413 additions and 140 deletions

View File

@ -31,7 +31,7 @@ public class Main extends SpringBootServletInitializer {
Path path = Paths.get("");
String p = path.toAbsolutePath().toString();
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
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)
.orderBy(T_DOCUMENT.PK);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]> r = sql.fetchOne();
if (r != null) {
DocumentBean bean = new DocumentBean();
@ -129,7 +129,7 @@ public class AdminRepository {
.groupBy(T_DOCUMENT.PK, T_DOCUMENT.NAME, T_DOCUMENT.DOCTYPE, T_DOCUMENT.FILETYPE)
.orderBy(T_DOCUMENT.PK);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql.toString());
List<DocumentBean> list = new ArrayList<>();
Iterator<Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -162,7 +162,7 @@ public class AdminRepository {
.from(T_DOCUMENT)
.where(condition);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<DocumentBean> list = new ArrayList<>();
Iterator<Record4<Integer, String, EnumDocument, EnumFiletype>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -202,7 +202,7 @@ public class AdminRepository {
.set(T_DOCUMENT.FILETYPE, bean.getFiletype())
.where(T_DOCUMENT.PK.eq(bean.getPk()));
// @formatter:on
LOGGER.debug("{}", sql.toString());
LOGGER.trace(sql);
lrw.add(sql.execute());
} else {
InsertResultStep<TDocumentRecord> sql = DSL.using(c)
@ -215,7 +215,7 @@ public class AdminRepository {
.values(bean.getName(), bean.getDoctype(), bean.getDocument(), bean.getFiletype())
.returning(T_DOCUMENT.PK);
// @formatter:on
LOGGER.debug("{}", sql.toString());
LOGGER.trace(sql);
pk = sql.fetchOne().get(T_DOCUMENT.PK);
lrw.add(1);
}
@ -233,7 +233,7 @@ public class AdminRepository {
.onConflict(T_DOCUMENTROLE.FK_DOCUMENT, T_DOCUMENTROLE.CAMPROLE)
.doNothing();
// @formatter:on
LOGGER.debug("{}", sql.toString());
LOGGER.trace(sql);
lrw.add(sql.execute());
removeCandidates.remove(role);
} catch (IllegalArgumentException e) {
@ -246,7 +246,7 @@ public class AdminRepository {
.where(T_DOCUMENTROLE.FK_DOCUMENT.eq(pk))
.and(T_DOCUMENTROLE.CAMPROLE.in(removeCandidates));
// @formatter:on
LOGGER.debug("{}", sql.toString());
LOGGER.trace(sql);
lrw.add(sql.execute());
});
return lrw.getCounter();
@ -268,7 +268,7 @@ public class AdminRepository {
.set(T_CAMP.FK_DOCUMENT, (Integer) null)
.where(T_CAMP.FK_DOCUMENT.eq(pk));
// @formatter:on
LOGGER.debug("{}", sql.toString());
LOGGER.trace(sql);
lrw.add(sql.execute());
UpdateConditionStep<TLocationRecord> sql1 = DSL.using(t)
@ -277,7 +277,7 @@ public class AdminRepository {
.set(T_LOCATION.FK_DOCUMENT, (Integer) null)
.where(T_LOCATION.FK_DOCUMENT.eq(pk));
// @formatter:on
LOGGER.debug("{}", sql1.toString());
LOGGER.trace(sql1);
lrw.add(sql1.execute());
DeleteConditionStep<TDocumentroleRecord> sql2 = DSL.using(t)
@ -285,7 +285,7 @@ public class AdminRepository {
.deleteFrom(T_DOCUMENTROLE)
.where(T_DOCUMENTROLE.FK_DOCUMENT.eq(pk));
// @formatter:on
LOGGER.debug("{}", sql2.toString());
LOGGER.trace(sql2);
lrw.add(sql2.execute());
DeleteConditionStep<TDocumentRecord> sql3 = DSL.using(t)
@ -293,7 +293,7 @@ public class AdminRepository {
.deleteFrom(T_DOCUMENT)
.where(T_DOCUMENT.PK.eq(pk));
// @formatter:on
LOGGER.debug("{}", sql3.toString());
LOGGER.trace(sql3);
lrw.add(sql3.execute());
});
return lrw.getCounter();
@ -306,7 +306,7 @@ public class AdminRepository {
*/
public List<LocationBean> getLocations() {
SelectWhereStep<TLocationRecord> sql = jooq.selectFrom(T_LOCATION);
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<LocationBean> list = new ArrayList<>();
for (TLocationRecord r : sql.fetch()) {
list.add(LocationBean.of(r));
@ -322,7 +322,7 @@ public class AdminRepository {
*/
public LocationBean getLocation(Integer 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());
}
@ -334,7 +334,7 @@ public class AdminRepository {
*/
public Integer deleteLocation(Integer id) {
DeleteConditionStep<TLocationRecord> sql = jooq.deleteFrom(T_LOCATION).where(T_LOCATION.PK.eq(id));
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
return sql.execute();
}
@ -356,7 +356,7 @@ public class AdminRepository {
T_LOCATION.URL)
.values(bean.getName(), bean.getFkDocument(), bean.getUrl());
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
lrw.add(sql.execute());
} else {
UpdateConditionStep<TLocationRecord> sql = DSL.using(t)
@ -367,7 +367,7 @@ public class AdminRepository {
.set(T_LOCATION.URL, bean.getUrl())
.where(T_LOCATION.PK.eq(bean.getPk()));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
lrw.add(sql.execute());
}
});
@ -381,7 +381,7 @@ public class AdminRepository {
*/
public List<CampBean> getAllCamps() {
SelectWhereStep<TCampRecord> sql = jooq.selectFrom(T_CAMP);
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<CampBean> list = new ArrayList<>();
for (TCampRecord r : sql.fetch()) {
list.add(CampBean.of(r));
@ -397,7 +397,7 @@ public class AdminRepository {
*/
public CampBean getCamp(Integer 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());
}
@ -411,11 +411,11 @@ public class AdminRepository {
LambdaResultWrapper lrw = new LambdaResultWrapper();
jooq.transaction(t -> {
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();
if (registrations < 1) {
DeleteConditionStep<TCampRecord> sql2 = DSL.using(t).deleteFrom(T_CAMP).where(T_CAMP.PK.eq(id));
LOGGER.debug(sql2.toString());
LOGGER.trace(sql2);
sql2.execute();
} else {
lrw.putString("error", String
@ -464,7 +464,7 @@ public class AdminRepository {
bean.getLockSales() != null ? bean.getLockSales() : false, bean.getMaxAge(), bean.getMinAge(), bean.getName(), bean.getPrice(),
bean.getBedsFemale(), bean.getBedsMale(), bean.getBlockedBedsFemale(), bean.getBlockedBedsMale(), startBooking);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
sql.execute();
} else {
UpdateConditionStep<TCampRecord> sql = DSL.using(t)
@ -488,7 +488,7 @@ public class AdminRepository {
.set(T_CAMP.START_BOOKING, startBooking)
.where(T_CAMP.PK.eq(bean.getPk()));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
sql.execute();
}
});
@ -502,7 +502,7 @@ public class AdminRepository {
*/
public List<ProfileBean> getProfiles() {
SelectWhereStep<TProfileRecord> sql = jooq.selectFrom(T_PROFILE);
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<ProfileBean> list = new ArrayList<>();
for (TProfileRecord r : sql.fetch()) {
list.add(ProfileBean.of(r));
@ -542,7 +542,7 @@ public class AdminRepository {
.where(T_CAMPPROFILE.MODULE.eq(module))
.orderBy(T_CAMP.ARRIVE, T_PROFILE.PK);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
PrivilegesContainerBean pcb = new PrivilegesContainerBean();
Iterator<Record4<Integer, String, LocalDateTime, String>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -579,7 +579,7 @@ public class AdminRepository {
.where(T_CAMPPROFILE.FK_PROFILE.eq(user))
.orderBy(T_CAMP.ARRIVE);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
PrivilegesContainerBean pcb = new PrivilegesContainerBean();
Iterator<Record4<Integer, String, LocalDateTime, EnumModule>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -618,7 +618,7 @@ public class AdminRepository {
.where(T_CAMPPROFILE.FK_CAMP.eq(camp))
.orderBy(T_PROFILE.SURNAME, T_PROFILE.FORENAME);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
PrivilegesContainerBean pcb = new PrivilegesContainerBean();
Iterator<Record4<Integer, String, String, EnumModule>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -644,7 +644,7 @@ public class AdminRepository {
*/
public void deleteFromCampProfile(Integer id) {
DeleteConditionStep<TCampprofileRecord> sql = jooq.deleteFrom(T_CAMPPROFILE).where(T_CAMPPROFILE.PK.eq(id));
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
sql.execute();
}
@ -668,7 +668,7 @@ public class AdminRepository {
T_CAMPPROFILE.MODULE)
.doNothing();
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
sql.execute();
}
}

View File

@ -63,7 +63,7 @@ public class BookingsRepository {
.where(T_PROFILE.USERNAME.eq(username))
.orderBy(T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.SURNAME, T_PERSON.FORENAME);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<BookerBean> list = new ArrayList<>();
Iterator<Record10<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -119,7 +119,7 @@ public class BookingsRepository {
.where(T_PROFILE.USERNAME.eq(username))
.and(T_PERSON.PK.eq(id));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
Record r = sql.fetchOne();
if (r == null) {
return null;
@ -165,7 +165,7 @@ public class BookingsRepository {
.set(T_PERSON.PAID, value)
.where(T_PERSON.PK.eq(pk));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
return sql.execute();
}
}

View File

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

View File

@ -61,7 +61,7 @@ public class CampRepository {
.where(V_CAMP.PK.eq(pk))
.and(T_PROFILE.USERNAME.eq(username));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
CampBean bean = new CampBean();
Iterator<Record6<String, Double, LocalDateTime, LocalDateTime, String, String>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -95,7 +95,7 @@ public class CampRepository {
.and(T_PROFILE.USERNAME.eq(username))
.orderBy(T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.SURNAME, T_PERSON.FORENAME);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<PersonBean> list = new ArrayList<>();
Iterator<Record8<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) {

View File

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

View File

@ -55,7 +55,7 @@ public class CamplistRepository {
public Stream<VCampRecord> getAllCamps(Condition condition) {
SelectSeekStep1<VCampRecord, LocalDateTime> sql = jooq.selectFrom(V_CAMP).where(condition).orderBy(V_CAMP.ARRIVE);
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
return sql.fetchStream();
}
@ -100,7 +100,7 @@ public class CamplistRepository {
.and(T_PERSON.PK.isNotNull())
.orderBy(V_CAMP.ARRIVE.desc(), T_PERSON.CREATED);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<BookingBean> list = new ArrayList<>();
Iterator<Record> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -187,7 +187,7 @@ public class CamplistRepository {
.from(T_DOCUMENT)
.where(T_DOCUMENT.DOCTYPE.eq(EnumDocument.camppass)));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
Map<Integer, String> map = new HashMap<>(); // no duplicate on using a map
Iterator<Record2<String, Integer>> i = sql.fetch().iterator();
while (i.hasNext()) {

View File

@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import de.jottyfan.camporganizer.module.camplist.CommonController;
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 {
@Autowired
private ConfirmationService indexService;
private ConfirmationService service;
@GetMapping("/confirmation")
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");
for (CampOverviewBean bean : campoverview) {
campoverviewsummary.setApproved(bean.getApproved() + campoverviewsummary.getApproved());
campoverviewsummary.setRejected(bean.getRejected() + campoverviewsummary.getRejected());
campoverviewsummary.setUntouched(bean.getUntouched() + campoverviewsummary.getUntouched());
campoverviewsummary.setRevoked(bean.getRevoked() + campoverviewsummary.getRevoked());
}
model.addAttribute("campoverview", campoverview);
model.addAttribute("campoverviewsummary", campoverviewsummary);
model.addAttribute("untouched", indexService.getUntouched(super.getCurrentUser()));
model.addAttribute("approved", indexService.getApproved(super.getCurrentUser()));
model.addAttribute("rejected", indexService.getRejected(super.getCurrentUser()));
model.addAttribute("untouched", service.getUntouched(super.getCurrentUser()));
model.addAttribute("approved", service.getApproved(super.getCurrentUser()));
model.addAttribute("rejected", service.getRejected(super.getCurrentUser()));
model.addAttribute("revoked", service.getRevoked(super.getCurrentUser()));
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_CAMPPROFILE;
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_RSS;
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -18,12 +21,17 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.DeleteConditionStep;
import org.jooq.InsertValuesStep2;
import org.jooq.Name;
import org.jooq.Record4;
import org.jooq.Record5;
import org.jooq.Record7;
import org.jooq.Record8;
import org.jooq.SelectConditionStep;
import org.jooq.SelectHavingStep;
import org.jooq.SelectSeekStep1;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@ -32,6 +40,10 @@ import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
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.CampOverviewBean;
@ -71,7 +83,7 @@ public class ConfirmationRepository {
.and(T_PROFILE.USERNAME.eq(currentUser))
.groupBy(T_CAMP.NAME, T_CAMP.ARRIVE, T_PERSON.PROGRESS);
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
Map<LocalDateTime, CampOverviewBean> map = new HashMap<>();
Iterator<Record4<Integer, EnumProgress, String, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -91,6 +103,8 @@ public class ConfirmationRepository {
bean.setApproved(count);
} else if (EnumProgress.rejected.equals(progress)) {
bean.setRejected(count);
} else if (EnumProgress.revoked.equals(progress)) {
bean.setRevoked(count);
}
}
List<CampOverviewBean> list = new ArrayList<>(map.values());
@ -118,7 +132,7 @@ public class ConfirmationRepository {
.and(T_PROFILE.USERNAME.eq(currentUser))
.orderBy(T_PERSON.CREATED.desc());
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<BookingBean> list = new ArrayList<>();
Iterator<Record7<Integer, String, String, String, LocalDateTime, EnumCamprole, LocalDateTime>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -169,6 +183,16 @@ public class ConfirmationRepository {
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));
}
/**
* get the result of the search
*
@ -196,7 +220,7 @@ public class ConfirmationRepository {
.and(T_PROFILE.USERNAME.eq(currentUser))
.orderBy(T_PERSON.CREATED.desc());
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<BookingBean> list = new ArrayList<>();
Iterator<Record8<Integer, String, String, EnumCamprole, String, Double, String, EnumProgress>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -216,4 +240,62 @@ public class ConfirmationRepository {
}
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

@ -17,28 +17,32 @@ import de.jottyfan.camporganizer.module.confirmation.confirmation.model.CampOver
@Service
public class ConfirmationService {
@Autowired
private ConfirmationRepository gateway;
private ConfirmationRepository repository;
public List<CampOverviewBean> getCampOverview(String currentUser) {
return gateway.getCampOverviewBeans(currentUser);
return repository.getCampOverviewBeans(currentUser);
}
public List<BookingBean> getUntouched(String currentUser) {
return gateway.getUntouched(currentUser);
return repository.getUntouched(currentUser);
}
public List<BookingBean> getApproved(String currentUser) {
return gateway.getApproved(currentUser);
return repository.getApproved(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) {
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>");
for (BookingBean bean : gateway.getSearchResult(needle, currentUser)) {
for (BookingBean bean : repository.getSearchResult(needle, currentUser)) {
String acceptHtml = "";
if (EnumProgress.requested.equals(bean.getProgress())) {
acceptHtml = "<i class=\"fas fa-question framed framed-orange\"></i>";
@ -55,4 +59,14 @@ public class ConfirmationService {
buf.append("</tbody></table>");
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

@ -16,6 +16,7 @@ public class CampOverviewBean implements Serializable, Comparable<CampOverviewBe
private Integer approved;
private Integer rejected;
private Integer untouched;
private Integer revoked;
public CampOverviewBean(LocalDate date, String camp) {
this.date = date;
@ -23,6 +24,7 @@ public class CampOverviewBean implements Serializable, Comparable<CampOverviewBe
this.approved = 0;
this.rejected = 0;
this.untouched = 0;
this.revoked = 0;
}
@Override
@ -85,4 +87,18 @@ public class CampOverviewBean implements Serializable, Comparable<CampOverviewBe
public LocalDate getDate() {
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

@ -79,7 +79,7 @@ public class PersonRepository {
.and(T_PROFILE.USERNAME.eq(username))
.orderBy(T_CAMP.ARRIVE.desc());
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
List<CampBean> list = new ArrayList<>();
Iterator<Record4<Integer, String, LocalDateTime, String>> i = sql.fetch().iterator();
while (i.hasNext()) {
@ -113,7 +113,7 @@ public class PersonRepository {
.and(T_CAMPPROFILE.MODULE.eq(EnumModule.registration))
.and(T_PROFILE.USERNAME.eq(username));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
Iterator<Record> i = sql.fetch().iterator();
while (i.hasNext()) {
Record r = i.next();
@ -153,12 +153,12 @@ public class PersonRepository {
jooq.transaction(t -> {
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);
// get old accept value for comparison
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();
lrw.putBoolean("acceptOld", r == null ? null : EnumProgress.approved.equals(r.getProgress()));
lrw.putBoolean("acceptNew", EnumProgress.approved.getLiteral().equals(bean.getProgress()));
@ -167,7 +167,7 @@ public class PersonRepository {
lrw.putString("oldEmail", email);
SelectConditionStep<TCampRecord> sql2 = jooq.selectFrom(T_CAMP).where(T_CAMP.PK.eq(fkCamp));
LOGGER.debug(sql2.toString());
LOGGER.trace(sql2);
TCampRecord rc = sql2.fetchOne();
String campName = rc == null ? null : rc.getName();
LocalDateTime arrive = rc == null ? null : rc.getArrive();
@ -194,7 +194,7 @@ public class PersonRepository {
.set(T_PERSON.REQUIRED_PRICE, bean.getRequiredPrice())
.where(T_PERSON.PK.eq(bean.getPk()));
// @formatter:on
LOGGER.debug(sql3.toString());
LOGGER.trace(sql3);
lrw.add(sql3.execute());
// always
@ -210,7 +210,7 @@ public class PersonRepository {
T_RSS.RECIPIENT)
.values(buf.toString(), "registrator");
// @formatter:on
LOGGER.debug("{}", sql4.toString());
LOGGER.trace(sql4);
sql4.execute();
});
@ -303,7 +303,7 @@ public class PersonRepository {
.leftJoin(REGISTRATOR).on(REGISTRATOR.PK.eq(T_PERSON.FK_REGISTRATOR))
.where(T_PERSON.PK.eq(pk));
// @formatter:on
LOGGER.debug(sql.toString());
LOGGER.trace(sql);
StringBuilder buf = new StringBuilder();
Iterator<Record11<LocalDate, LocalDateTime, EnumCamprole, LocalDateTime, LocalDateTime, Integer, Integer, String, String, String, String>> i = sql
.fetch().iterator();

View File

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

View File

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

View File

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

View File

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

View File

@ -119,7 +119,7 @@ public class KeycloakRepository {
Response response = resource.create(user);
Boolean success = Status.CREATED.equals(response.getStatusInfo());
if (success) {
LOGGER.info("created new keycloak user {}", user.getUsername());
LOGGER.debug("created new keycloak user {}", user.getUsername());
} else {
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";
}
@GetMapping("/registration/remove/{id}")
public String remove(@PathVariable("id") Integer id, final Model model) {
service.removeBooking(id);
@GetMapping("/registration/revoke/{id}")
public String revoke(@PathVariable("id") Integer id, final Model model) {
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";
}

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_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_PROFILEROLE;
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 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.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.TRssRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord;
@ -147,7 +146,7 @@ public class RegistrationRepository {
T_RSS.RECIPIENT)
.values(new StringBuilder(bean.getFullname()).append(" hat sich als Nutzer im CampOrganizer2 registriert.").toString(), "admin");
// @formatter:on
LOGGER.debug("{}", sql2.toString());
LOGGER.trace(sql2);
sql2.execute();
} else {
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
* @return number of affected database rows, should be 1
* @param id the ID of the booking
*/
public Integer removeBooking(Integer id) {
LambdaResultWrapper lrw = new LambdaResultWrapper();
public void revokeBooking(Integer id) {
jooq.transaction(t -> {
SelectConditionStep<Record5<String, String, String, String, LocalDateTime>> sql0 = DSL.using(t)
// @formatter:off
@ -279,33 +276,32 @@ public class RegistrationRepository {
LocalDateTime arrive = r.get(T_CAMP.ARRIVE);
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(" an ");
rssMessage.append(campname).append(" ")
.append(arrive == null ? "" : arrive.format(DateTimeFormatter.ofPattern("YYYY")));
rssMessage.append(" storniert.");
rssMessage.append(" ausgelöst.");
DeleteConditionStep<TPersondocumentRecord> sql1 = DSL.using(t).deleteFrom(T_PERSONDOCUMENT)
.where(T_PERSONDOCUMENT.FK_PERSON.eq(id));
LOGGER.trace(sql1.toString());
UpdateConditionStep<TPersonRecord> sql1 = jooq
// @formatter:off
.update(T_PERSON)
.set(T_PERSON.PROGRESS, EnumProgress.revoked)
.where(T_PERSON.PK.eq(id));
// @formatter:on
LOGGER.trace(sql1);
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)
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("{}", sql3.toString());
sql3.execute();
LOGGER.trace("{}", sql2.toString());
sql2.execute();
});
return lrw.getCounter();
}
/**
@ -494,4 +490,59 @@ public class RegistrationRepository {
Iterator<Integer> i = sql.fetch(T_PERSON.PK).iterator();
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) {
return repository.removeBooking(id) > 0;
public void revokeBooking(Integer id, Boolean doRevoke) {
if (doRevoke) {
repository.revokeBooking(id);
} else {
repository.unrevokeBooking(id);
}
}
public void toggleConsent(Integer id) {

View File

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

View File

@ -121,19 +121,20 @@ div {
!important;
}
.acc_true {
background-image: linear-gradient(to bottom right, #cfc, #afa)
!important;
.acc_approved {
background: #aaffaa !important;
}
.acc_false {
background-image: linear-gradient(to bottom right, #fcc, #faa)
!important;
.acc_rejected {
background: #ffaaaa !important;
}
.acc_null {
background-image: linear-gradient(to bottom right, #fdb, #fca)
!important;
.acc_revoked {
background: rgb(220, 138, 221) !important;
}
.acc_requested {
background: rgb(255, 190, 111) !important;
}
.right-dist {
@ -303,6 +304,17 @@ div {
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 {
margin: 8px;
}
@ -333,19 +345,19 @@ div {
}
.framed-green {
background: linear-gradient(to bottom right, lime, darkgreen);
background: linear-gradient(to bottom right, darkgreen, lime);
color: white;
border: 1px solid green;
}
.framed-red {
background: linear-gradient(to bottom right, red, darkred);
background: linear-gradient(to bottom right, darkred, red);
color: white;
border: 1px solid red;
}
.framed-orange {
background: linear-gradient(to bottom right, orange, #bf6c06);
background: linear-gradient(to bottom right, #bf6c06, orange);
color: white;
border: 1px solid orange;
}
@ -357,9 +369,9 @@ div {
}
.framed-pink {
background: linear-gradient(to bottom right, #9141ac, #613583);
color: #9141ac;
border: 1px solid #613583;
background: linear-gradient(to bottom right, #3b115b, #d18be8);
color: #f8effb;
border: 1px solid #4a0084;
}
.nomaxwidth {

View File

@ -44,7 +44,7 @@
</div>
<div class="accordion-item">
<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>
</h2>
<div id="approveddiv" class="accordion-collapse collapse dist8" aria-labelled="approvedpanel" data-bs-parent="#mainacc">
@ -79,7 +79,7 @@
</div>
<div class="accordion-item">
<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>
</h2>
<div id="rejecteddiv" class="accordion-collapse collapse dist8" aria-labelled="rejectedpanel" data-bs-parent="#mainacc">
@ -112,6 +112,41 @@
</script>
</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">
<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>
@ -127,14 +162,14 @@
<tbody>
<tr th:each="o : ${campoverview}">
<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>
</tbody>
<tfoot>
<tr>
<td>Zusammenfassung</td>
<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>
</table>
<script type="text/javascript">
@ -146,7 +181,7 @@
});
});
</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 class="accordion-item">

View File

@ -112,11 +112,22 @@
</div>
<div class="row mb-2">
<label for="inputAccept" class="col-sm-2 col-form-label">Status</label>
<div class="col-sm-10">
<select th:field="*{progress}">
<option th:each="p : ${progresses}" value="${p}"><th:block th:text="${p}"></th:block></option>
<span class="col-sm-2 btn btn-outline-warning" th:if="${person.progress} == 'requested'">offen</span>
<span class="col-sm-2 btn btn-outline-success" th:if="${person.progress} == 'approved'">bestätigt</span>
<span class="col-sm-2 btn btn-outline-danger" th:if="${person.progress} == 'rejected'">abgelehnt</span>
<span class="col-sm-2 btn btn-outline-secondary" th:if="${person.progress} == 'revoked'">storniert</span>
<div class="col-sm-8" th:if="${#lists.contains({'requested', 'approved', 'rejected'}, person.progress)}">
<select th:field="*{progress}" class="form-select">
<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 class="row mb-2">
<label for="inputAccept" class="col-sm-2 col-form-label"></label>
@ -126,6 +137,26 @@
</div>
</div>
</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>
</div>

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-item" th:each="b : ${mybookings}">
<h2 class="accordion-header" th:id="'acc-head-' + ${b.pk}" th:if="${b.pk}">
<button th:class="'accordion-button collapsed acc_' + ${b.isOver ? 'over' : b.progress == 'approved'}" 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}">
<i class="fas fa-check framed framed-green" th:if="${b.progress} == 'approved'"></i> <i class="fas fa-ban framed framed-red" th:if="${b.progress} == 'rejected'"></i> <i
class="fas fa-question framed framed-orange" th:if="${b.progress} == 'requested'"></i>
<span th:text="${b.forename + ' ' + b.surname + ' für ' + b.campName + ' ' + #numbers.formatInteger(b.year, 4)}" class="headlinefont"></span>
<i class="fas fa-check framed framed-green" th:if="${b.progress} == 'approved'"></i>
<i class="fas fa-ban framed framed-red" th:if="${b.progress} == 'rejected'"></i>
<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>
</h2>
<div th:id="'acc-body-' + ${b.pk}" class="accordion-collapse collapse" th:aria-labelledby="'acc-head-' + ${b.pk}">
@ -139,8 +141,11 @@
<div class="col-sm-8">
<input type="submit" class="btn btn-primary" value="Änderungen übernehmen" />
</div>
<div class="col-sm-2">
<a th:href="@{/registration/cancel/{id}(id=${b.pk})}" class="btn btn-outline-danger" th:if="${!b.isOver}">stornieren</a>
<div class="col-sm-2" th:if="${b.progress != 'revoked'}">
<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>
@ -150,8 +155,12 @@
<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>
</div>
<div th:class="'alert ' + ${b.progress} == 'approved' ? 'alert-success' : 'alert-danger'}" th:if="${b.progress} != 'requested'}">
<span th:text="${b.progress} == 'approved'">bestätigt</span><span th:text="${b.progress} == 'rejected'">abgelehnt</span> von <span th:text="${b.registrator}"></span>
<div class="alert alert-danger" th:if="${b.progress == 'revoked'}">
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 class="alert alert-warning" th:if="${b.isOver}">Die Freizeit ist bereits vorbei.</div>
</div>

View File

@ -21,7 +21,7 @@
th:if="${bean.isDirector}">Leiter</span><span th:if="${bean.isFeeder}">Küchenhilfe</span>
</div>
<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>