integrated the business module
This commit is contained in:
parent
8e8fc13efa
commit
6b6b37f3ea
@ -12,6 +12,13 @@
|
|||||||
<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="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
|
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||||
|
@ -1,13 +1,2 @@
|
|||||||
arguments=
|
|
||||||
auto.sync=false
|
|
||||||
build.scans.enabled=false
|
|
||||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
|
||||||
connection.project.dir=
|
connection.project.dir=
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
gradle.user.home=
|
|
||||||
java.home=
|
|
||||||
jvm.arguments=
|
|
||||||
offline.mode=false
|
|
||||||
override.workspace.settings=false
|
|
||||||
show.console.view=false
|
|
||||||
show.executions.view=false
|
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||||
<project-modules id="moduleCoreId" project-version="1.5.0">
|
|
||||||
<wb-module deploy-name="camporganizer2">
|
<wb-module deploy-name="CampOrganizer2">
|
||||||
<property name="context-root" value="camporganizer2"/>
|
|
||||||
|
<property name="context-root" value="CampOrganizer2"/>
|
||||||
|
|
||||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/>
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/>
|
||||||
|
|
||||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
|
||||||
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
|
||||||
|
|
||||||
</wb-module>
|
</wb-module>
|
||||||
|
|
||||||
</project-modules>
|
</project-modules>
|
||||||
|
@ -57,7 +57,7 @@ public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
|
|||||||
super.configure(http);
|
super.configure(http);
|
||||||
http.authorizeRequests()
|
http.authorizeRequests()
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
.antMatchers("/user/**", "/business/**").authenticated()
|
.antMatchers("/dashboard/**", "/business/**").authenticated()
|
||||||
.anyRequest().permitAll();
|
.anyRequest().permitAll();
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
// http.anonymous().disable();
|
// http.anonymous().disable();
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.bookings;
|
||||||
|
|
||||||
|
import javax.annotation.security.RolesAllowed;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
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.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.bookings.impl.BookerBean;
|
||||||
|
import de.jottyfan.camporganizer.module.business.business.IBusinessService;
|
||||||
|
import de.jottyfan.camporganizer.module.business.bookings.impl.AddPaymentBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class BookingsController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBusinessService indexService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBookingsService bookingsService;
|
||||||
|
|
||||||
|
@GetMapping("/business/bookings")
|
||||||
|
@RolesAllowed({"business_booking"})
|
||||||
|
public String getBookings(Model model) {
|
||||||
|
String username = indexService.getCurrentUser(request);
|
||||||
|
model.addAttribute("currentUser", username);
|
||||||
|
model.addAttribute("bookers", bookingsService.getBookers(username));
|
||||||
|
return "business/bookings";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/business/bookings/{id}")
|
||||||
|
@RolesAllowed({"business_booking"})
|
||||||
|
public String getBooking(Model model, @PathVariable Integer id) {
|
||||||
|
String username = indexService.getCurrentUser(request);
|
||||||
|
model.addAttribute("currentUser", username);
|
||||||
|
BookerBean bean = bookingsService.getBooker(id, username);
|
||||||
|
model.addAttribute("booker", bean);
|
||||||
|
model.addAttribute("addBean", new AddPaymentBean());
|
||||||
|
return bean == null ? getBookings(model) : "business/booker";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/business/bookings/payment/{id}")
|
||||||
|
@RolesAllowed({"business_booking"})
|
||||||
|
public String addBooking(Model model, @ModelAttribute AddPaymentBean bean, @PathVariable Integer id) {
|
||||||
|
Double payment = bean.getPayment();
|
||||||
|
bookingsService.addPayment(id, payment);
|
||||||
|
return getBooking(model, id);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.bookings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.bookings.impl.BookerBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IBookingsService {
|
||||||
|
/**
|
||||||
|
* get the bookers information
|
||||||
|
*
|
||||||
|
* @param username the name of the user in this session
|
||||||
|
* @return the list of bookers; an empty one at least
|
||||||
|
*/
|
||||||
|
public List<BookerBean> getBookers(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the booker referenced by id
|
||||||
|
*
|
||||||
|
* @param id the ID of the booker
|
||||||
|
* @param username the name of the user in this session
|
||||||
|
* @return the booker if found; null otherwise
|
||||||
|
*/
|
||||||
|
public BookerBean getBooker(Integer id, String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add payment to the paid values of user with id
|
||||||
|
*
|
||||||
|
* @param id the ID of the booker
|
||||||
|
* @param payment the payment (additional value)
|
||||||
|
* @return number of affected database rows, should be 1
|
||||||
|
*/
|
||||||
|
public Integer addPayment(Integer id, Double payment);
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.bookings.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AddPaymentBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private Double payment;
|
||||||
|
|
||||||
|
public Double getPayment() {
|
||||||
|
return payment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayment(Double payment) {
|
||||||
|
this.payment = payment;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.bookings.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BookerBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer pk;
|
||||||
|
private String name;
|
||||||
|
private String role;
|
||||||
|
private String sex;
|
||||||
|
private Boolean accept;
|
||||||
|
private LocalDateTime bookingDate;
|
||||||
|
private BigDecimal paid;
|
||||||
|
private String camp;
|
||||||
|
private String price;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
public BigDecimal getPaid() {
|
||||||
|
return paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paid the paid to set
|
||||||
|
*/
|
||||||
|
public void setPaid(BigDecimal paid) {
|
||||||
|
this.paid = paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pk
|
||||||
|
*/
|
||||||
|
public Integer getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pk the pk to set
|
||||||
|
*/
|
||||||
|
public void setPk(Integer pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(String role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSex() {
|
||||||
|
return sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSex(String sex) {
|
||||||
|
this.sex = sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getBookingDate() {
|
||||||
|
return bookingDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBookingDate(LocalDateTime bookingDate) {
|
||||||
|
this.bookingDate = bookingDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCamp() {
|
||||||
|
return camp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCamp(String camp) {
|
||||||
|
this.camp = camp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(String price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.bookings.impl;
|
||||||
|
|
||||||
|
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_SALESPROFILE;
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.Record;
|
||||||
|
import org.jooq.Record10;
|
||||||
|
import org.jooq.Record11;
|
||||||
|
import org.jooq.SelectConditionStep;
|
||||||
|
import org.jooq.SelectSeekStep4;
|
||||||
|
import org.jooq.UpdateConditionStep;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@Transactional(transactionManager = "transactionManager")
|
||||||
|
public class BookingsGateway {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(BookingsGateway.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext jooq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a list of all registered persons that have booked the camp
|
||||||
|
*
|
||||||
|
* @param username the name of the current user in this session
|
||||||
|
*
|
||||||
|
* @return a list of bookings; an empty one at least
|
||||||
|
*/
|
||||||
|
public List<BookerBean> getBookings(String username) {
|
||||||
|
SelectSeekStep4<Record10<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double>, EnumCamprole, EnumSex, String, String> sql = jooq
|
||||||
|
// @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)
|
||||||
|
.from(T_PERSON)
|
||||||
|
.leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_PERSON.FK_CAMP))
|
||||||
|
.leftJoin(T_SALESPROFILE).on(T_SALESPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP))
|
||||||
|
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_SALESPROFILE.FK_PROFILE))
|
||||||
|
.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());
|
||||||
|
List<BookerBean> list = new ArrayList<>();
|
||||||
|
for (Record r : sql.fetch()) {
|
||||||
|
String forename = r.get(T_PERSON.FORENAME);
|
||||||
|
String surname = r.get(T_PERSON.SURNAME);
|
||||||
|
EnumCamprole role = r.get(T_PERSON.CAMPROLE);
|
||||||
|
EnumSex sex = r.get(T_PERSON.SEX);
|
||||||
|
String campName = r.get(V_CAMP.NAME);
|
||||||
|
Double campYear = r.get(V_CAMP.YEAR);
|
||||||
|
BookerBean bean = new BookerBean();
|
||||||
|
bean.setPk(r.get(T_PERSON.PK));
|
||||||
|
bean.setName(String.format("%s %s", forename, surname));
|
||||||
|
bean.setRole(EnumCamprole.student.equals(role) ? "Teilnehmer" : "Mitarbeiter");
|
||||||
|
bean.setSex(EnumSex.female.equals(sex) ? "weiblich" : "männlich");
|
||||||
|
bean.setBookingDate(r.get(T_PERSON.CREATED));
|
||||||
|
bean.setAccept(r.get(T_PERSON.ACCEPT));
|
||||||
|
bean.setPaid(r.get(T_PERSON.PAID));
|
||||||
|
bean.setCamp(String.format("%s %4.0f", campName, campYear));
|
||||||
|
list.add(bean);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the booking payment information of the user referenced by id
|
||||||
|
*
|
||||||
|
* @param id the id of the user
|
||||||
|
* @param username the name of the current's session user
|
||||||
|
* @return the booker bean or null
|
||||||
|
*/
|
||||||
|
public BookerBean getBooking(Integer id, String username) {
|
||||||
|
SelectConditionStep<Record11<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime, String, Double, String>> sql = jooq
|
||||||
|
// @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, V_CAMP.PRICE)
|
||||||
|
.from(T_PERSON)
|
||||||
|
.leftJoin(V_CAMP).on(V_CAMP.PK.eq(T_PERSON.FK_CAMP))
|
||||||
|
.leftJoin(T_SALESPROFILE).on(T_SALESPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP))
|
||||||
|
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_SALESPROFILE.FK_PROFILE))
|
||||||
|
.where(T_PROFILE.USERNAME.eq(username))
|
||||||
|
.and(T_PERSON.PK.eq(id));
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
Record r = sql.fetchOne();
|
||||||
|
if (r == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
String forename = r.get(T_PERSON.FORENAME);
|
||||||
|
String surname = r.get(T_PERSON.SURNAME);
|
||||||
|
EnumCamprole role = r.get(T_PERSON.CAMPROLE);
|
||||||
|
EnumSex sex = r.get(T_PERSON.SEX);
|
||||||
|
String campName = r.get(V_CAMP.NAME);
|
||||||
|
Double campYear = r.get(V_CAMP.YEAR);
|
||||||
|
BookerBean bean = new BookerBean();
|
||||||
|
bean.setPk(r.get(T_PERSON.PK));
|
||||||
|
bean.setName(String.format("%s %s", forename, surname));
|
||||||
|
bean.setRole(EnumCamprole.student.equals(role) ? "Teilnehmer" : "Mitarbeiter");
|
||||||
|
bean.setSex(EnumSex.female.equals(sex) ? "weiblich" : "männlich");
|
||||||
|
bean.setBookingDate(r.get(T_PERSON.CREATED));
|
||||||
|
bean.setAccept(r.get(T_PERSON.ACCEPT));
|
||||||
|
bean.setPaid(r.get(T_PERSON.PAID));
|
||||||
|
bean.setCamp(String.format("%s %4.0f", campName, campYear));
|
||||||
|
bean.setPrice(r.get(V_CAMP.PRICE));
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add payment for user referenced by pk
|
||||||
|
*
|
||||||
|
* @param pk the ID of the user
|
||||||
|
* @param payment the payment (additional)
|
||||||
|
* @return the number of affected database rows, should be 1
|
||||||
|
*/
|
||||||
|
public Integer addPayment(Integer pk, Double payment) {
|
||||||
|
BigDecimal oldValue = jooq.select(T_PERSON.PAID).from(T_PERSON).where(T_PERSON.PK.eq(pk)).fetchOne().get(T_PERSON.PAID);
|
||||||
|
BigDecimal value = oldValue == null ? BigDecimal.valueOf(payment) : oldValue.add(BigDecimal.valueOf(payment));
|
||||||
|
UpdateConditionStep<TPersonRecord> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.update(T_PERSON)
|
||||||
|
.set(T_PERSON.PAID, value)
|
||||||
|
.where(T_PERSON.PK.eq(pk));
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
return sql.execute();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.bookings.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.bookings.IBookingsService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class BookingsService implements IBookingsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BookingsGateway bookingsGateway;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BookerBean> getBookers(String username) {
|
||||||
|
return bookingsGateway.getBookings(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BookerBean getBooker(Integer id, String username) {
|
||||||
|
return bookingsGateway.getBooking(id, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer addPayment(Integer id, Double payment) {
|
||||||
|
return bookingsGateway.addPayment(id, payment);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.business;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author henkej
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class BusinessController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBusinessService indexService;
|
||||||
|
|
||||||
|
@GetMapping("/business")
|
||||||
|
public String getIndex(Model model) {
|
||||||
|
String username = indexService.getCurrentUser(request);
|
||||||
|
model.addAttribute("currentUser", username);
|
||||||
|
model.addAttribute("campBudgets", indexService.getCampBudgets(username));
|
||||||
|
return "business/business";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.business;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.business.impl.CampBudgetBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IBusinessService {
|
||||||
|
/**
|
||||||
|
* get the user of this session
|
||||||
|
*
|
||||||
|
* @param request the request
|
||||||
|
* @return the username of the current user
|
||||||
|
*/
|
||||||
|
public String getCurrentUser(HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a list of all camp budgets of all years
|
||||||
|
*
|
||||||
|
* @param username the name of the current user in this session
|
||||||
|
* @return the list; an empty one at least
|
||||||
|
*/
|
||||||
|
public List<CampBudgetBean> getCampBudgets(String username);
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.business.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BusinessBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final Integer fkPerson;
|
||||||
|
private final String forename;
|
||||||
|
private final String surname;
|
||||||
|
private final String campName;
|
||||||
|
private final String campPrice;
|
||||||
|
private final LocalDateTime campArrive;
|
||||||
|
private final String locationName;
|
||||||
|
private BigDecimal paid;
|
||||||
|
private boolean changed;
|
||||||
|
|
||||||
|
public BusinessBean(Integer fkPerson, String forename, String surname, String campName, String campPrice,
|
||||||
|
LocalDateTime campArrive, String locationName, BigDecimal paid) {
|
||||||
|
super();
|
||||||
|
this.fkPerson = fkPerson;
|
||||||
|
this.forename = forename;
|
||||||
|
this.surname = surname;
|
||||||
|
this.campName = campName;
|
||||||
|
this.campPrice = campPrice;
|
||||||
|
this.campArrive = campArrive;
|
||||||
|
this.locationName = locationName;
|
||||||
|
this.paid = paid;
|
||||||
|
this.changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the paid
|
||||||
|
*/
|
||||||
|
public BigDecimal getPaid() {
|
||||||
|
return paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paid the paid to set
|
||||||
|
*/
|
||||||
|
public void setPaid(BigDecimal paid) {
|
||||||
|
this.paid = paid;
|
||||||
|
this.changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fkPerson
|
||||||
|
*/
|
||||||
|
public Integer getFkPerson() {
|
||||||
|
return fkPerson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the forename
|
||||||
|
*/
|
||||||
|
public String getForename() {
|
||||||
|
return forename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the surname
|
||||||
|
*/
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campName
|
||||||
|
*/
|
||||||
|
public String getCampName() {
|
||||||
|
return campName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campPrice
|
||||||
|
*/
|
||||||
|
public String getCampPrice() {
|
||||||
|
return campPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campArrive
|
||||||
|
*/
|
||||||
|
public LocalDateTime getCampArrive() {
|
||||||
|
return campArrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the locationName
|
||||||
|
*/
|
||||||
|
public String getLocationName() {
|
||||||
|
return locationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChanged() {
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.business.impl;
|
||||||
|
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP;
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.T_LOCATION;
|
||||||
|
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_SALESPROFILE;
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP_BUDGET;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.Record4;
|
||||||
|
import org.jooq.Record8;
|
||||||
|
import org.jooq.SelectConditionStep;
|
||||||
|
import org.jooq.SelectSeekStep1;
|
||||||
|
import org.jooq.UpdateConditionStep;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@Transactional(transactionManager = "transactionManager")
|
||||||
|
public class BusinessGateway {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(BusinessGateway.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext jooq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a list of all camp budgets of all years
|
||||||
|
*
|
||||||
|
* @param username the name of the user for privilege checks
|
||||||
|
*
|
||||||
|
* @return the list of all camp budgets
|
||||||
|
*/
|
||||||
|
public List<CampBudgetBean> getCampBudgets(String username) {
|
||||||
|
SelectSeekStep1<Record4<BigDecimal, String, Double, Integer>, LocalDateTime> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.select(V_CAMP_BUDGET.BUDGET,
|
||||||
|
V_CAMP_BUDGET.CAMP_NAME,
|
||||||
|
V_CAMP_BUDGET.YEAR,
|
||||||
|
V_CAMP_BUDGET.FK_CAMP)
|
||||||
|
.from(V_CAMP_BUDGET)
|
||||||
|
.leftJoin(T_CAMP).on(T_CAMP.PK.eq(V_CAMP_BUDGET.FK_CAMP))
|
||||||
|
.leftJoin(T_SALESPROFILE).on(T_SALESPROFILE.FK_CAMP.eq(V_CAMP_BUDGET.FK_CAMP))
|
||||||
|
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_SALESPROFILE.FK_PROFILE))
|
||||||
|
.where(T_PROFILE.USERNAME.eq(username))
|
||||||
|
.orderBy(T_CAMP.ARRIVE);
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
List<CampBudgetBean> list = new ArrayList<>();
|
||||||
|
for (Record4<BigDecimal, String, Double, Integer> r : sql.fetch()) {
|
||||||
|
BigDecimal b = r.get(V_CAMP_BUDGET.BUDGET);
|
||||||
|
String n = r.get(V_CAMP_BUDGET.CAMP_NAME);
|
||||||
|
Double y = r.get(V_CAMP_BUDGET.YEAR);
|
||||||
|
Integer c = r.get(V_CAMP_BUDGET.FK_CAMP);
|
||||||
|
list.add(new CampBudgetBean().withBudget(b).withCampName(n).withCampYear(y).withCampId(c));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all registrations for the search mask
|
||||||
|
*
|
||||||
|
* @param username the name of the user for privilege checks
|
||||||
|
*
|
||||||
|
* @return a list of business beans; an empty one at least
|
||||||
|
*/
|
||||||
|
public List<BusinessBean> getAllRegistrations(String username) {
|
||||||
|
SelectConditionStep<Record8<Integer, String, String, String, String, LocalDateTime, String, BigDecimal>> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.select(T_PERSON.PK,
|
||||||
|
T_PERSON.FORENAME,
|
||||||
|
T_PERSON.SURNAME,
|
||||||
|
T_CAMP.NAME,
|
||||||
|
T_CAMP.PRICE,
|
||||||
|
T_CAMP.ARRIVE,
|
||||||
|
T_LOCATION.NAME,
|
||||||
|
T_PERSON.PAID)
|
||||||
|
.from(T_PERSON)
|
||||||
|
.leftJoin(T_CAMP).on(T_CAMP.PK.eq(T_PERSON.FK_CAMP))
|
||||||
|
.leftJoin(T_LOCATION).on(T_LOCATION.PK.eq(T_CAMP.FK_LOCATION))
|
||||||
|
.leftJoin(T_SALESPROFILE).on(T_SALESPROFILE.FK_CAMP.eq(T_CAMP.PK))
|
||||||
|
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_SALESPROFILE.FK_PROFILE))
|
||||||
|
.where(T_PROFILE.USERNAME.eq(username));
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
List<BusinessBean> list = new ArrayList<>();
|
||||||
|
for (Record8<Integer, String, String, String, String, LocalDateTime, String, BigDecimal> r : sql.fetch()) {
|
||||||
|
Integer fkPerson = r.get(T_PERSON.PK);
|
||||||
|
String forename = r.get(T_PERSON.FORENAME);
|
||||||
|
String surname = r.get(T_PERSON.SURNAME);
|
||||||
|
String campName = r.get(T_CAMP.NAME);
|
||||||
|
String campPrice = r.get(T_CAMP.PRICE);
|
||||||
|
LocalDateTime campArrive = r.get(T_CAMP.ARRIVE);
|
||||||
|
String locationName = r.get(T_CAMP.NAME);
|
||||||
|
BigDecimal paid = r.get(T_PERSON.PAID);
|
||||||
|
list.add(new BusinessBean(fkPerson, forename, surname, campName, campPrice, campArrive, locationName, paid));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update the database by changed records in the list
|
||||||
|
*
|
||||||
|
* @param list the list of beans
|
||||||
|
* @return the number of affected database rows
|
||||||
|
*/
|
||||||
|
public int updatePaid(List<BusinessBean> list) {
|
||||||
|
Integer count = 0;
|
||||||
|
for (BusinessBean bean : list) {
|
||||||
|
if (bean.isChanged()) {
|
||||||
|
UpdateConditionStep<TPersonRecord> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.update(T_PERSON)
|
||||||
|
.set(T_PERSON.PAID, bean.getPaid())
|
||||||
|
.where(T_PERSON.PK.eq(bean.getFkPerson()));
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
count += sql.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.business.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.jooq.exception.DataAccessException;
|
||||||
|
import org.keycloak.KeycloakSecurityContext;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.business.IBusinessService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class BusinessService implements IBusinessService {
|
||||||
|
@Autowired
|
||||||
|
private BusinessGateway gateway;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCurrentUser(HttpServletRequest request) {
|
||||||
|
KeycloakSecurityContext ksc = (KeycloakSecurityContext) request
|
||||||
|
.getAttribute(KeycloakSecurityContext.class.getName());
|
||||||
|
if (ksc == null) {
|
||||||
|
throw new DataAccessException("no keycloak user in session");
|
||||||
|
}
|
||||||
|
return ksc.getIdToken().getPreferredUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CampBudgetBean> getCampBudgets(String username) {
|
||||||
|
return gateway.getCampBudgets(username);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.business.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CampBudgetBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private BigDecimal budget;
|
||||||
|
private String campName;
|
||||||
|
private Double campYear;
|
||||||
|
private Integer campId;
|
||||||
|
|
||||||
|
public CampBudgetBean withCampId(Integer campId) {
|
||||||
|
setCampId(campId);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CampBudgetBean withCampName(String campName) {
|
||||||
|
setCampName(campName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CampBudgetBean withCampYear(Double campYear) {
|
||||||
|
setCampYear(campYear);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CampBudgetBean withBudget(BigDecimal budget) {
|
||||||
|
setBudget(budget);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the budget
|
||||||
|
*/
|
||||||
|
public BigDecimal getBudget() {
|
||||||
|
return budget;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param budget the budget to set
|
||||||
|
*/
|
||||||
|
public void setBudget(BigDecimal budget) {
|
||||||
|
this.budget = budget;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campName
|
||||||
|
*/
|
||||||
|
public String getCampName() {
|
||||||
|
return campName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param campName the campName to set
|
||||||
|
*/
|
||||||
|
public void setCampName(String campName) {
|
||||||
|
this.campName = campName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campYear
|
||||||
|
*/
|
||||||
|
public Double getCampYear() {
|
||||||
|
return campYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param campYear the campYear to set
|
||||||
|
*/
|
||||||
|
public void setCampYear(Double campYear) {
|
||||||
|
this.campYear = campYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCampId() {
|
||||||
|
return campId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCampId(Integer campId) {
|
||||||
|
this.campId = campId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp;
|
||||||
|
|
||||||
|
import javax.annotation.security.RolesAllowed;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
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.business.business.IBusinessService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class CampController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBusinessService indexService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ICampService campService;
|
||||||
|
|
||||||
|
@GetMapping("/business/camp/{id}")
|
||||||
|
@RolesAllowed({"business"})
|
||||||
|
public String getCamp(Model model, @PathVariable Integer id) {
|
||||||
|
String username = indexService.getCurrentUser(request);
|
||||||
|
model.addAttribute("currentUser", username);
|
||||||
|
model.addAttribute("campId", id);
|
||||||
|
model.addAttribute("camp", campService.getCamp(id, username));
|
||||||
|
model.addAttribute("booking", campService.getBookings(id, username));
|
||||||
|
model.addAttribute("bookers", campService.getBookers(id, username));
|
||||||
|
return "business/camp";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.camp.impl.BookingBean;
|
||||||
|
import de.jottyfan.camporganizer.module.business.camp.impl.CampBean;
|
||||||
|
import de.jottyfan.camporganizer.module.business.camp.impl.PersonBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ICampService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the camp bean of id
|
||||||
|
*
|
||||||
|
* @param id the id of the camp
|
||||||
|
* @param username the name of the user in this session
|
||||||
|
* @return the camp bean if found; null otherwise
|
||||||
|
*/
|
||||||
|
public CampBean getCamp(Integer id, String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the booking information for camp with id
|
||||||
|
*
|
||||||
|
* @param id the id of the camp
|
||||||
|
* @param username the name of the user in this session
|
||||||
|
* @return a booking bean
|
||||||
|
*/
|
||||||
|
public BookingBean getBookings(Integer id, String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the bookers information for camp with id
|
||||||
|
*
|
||||||
|
* @param id the id of the camp
|
||||||
|
* @param username the name of the user in this session
|
||||||
|
* @return the list of bookers; an empty one at least
|
||||||
|
*/
|
||||||
|
public List<PersonBean> getBookers(Integer id, String username);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,108 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BookerBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer pk;
|
||||||
|
private String name;
|
||||||
|
private EnumCamprole campRole;
|
||||||
|
private EnumSex sex;
|
||||||
|
private LocalDateTime bookingDate;
|
||||||
|
private BigDecimal paid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pk
|
||||||
|
*/
|
||||||
|
public Integer getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pk the pk to set
|
||||||
|
*/
|
||||||
|
public void setPk(Integer pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campRole
|
||||||
|
*/
|
||||||
|
public EnumCamprole getCampRole() {
|
||||||
|
return campRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param campRole the campRole to set
|
||||||
|
*/
|
||||||
|
public void setCampRole(EnumCamprole campRole) {
|
||||||
|
this.campRole = campRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sex
|
||||||
|
*/
|
||||||
|
public EnumSex getSex() {
|
||||||
|
return sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sex the sex to set
|
||||||
|
*/
|
||||||
|
public void setSex(EnumSex sex) {
|
||||||
|
this.sex = sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the bookingDate
|
||||||
|
*/
|
||||||
|
public LocalDateTime getBookingDate() {
|
||||||
|
return bookingDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bookingDate the bookingDate to set
|
||||||
|
*/
|
||||||
|
public void setBookingDate(LocalDateTime bookingDate) {
|
||||||
|
this.bookingDate = bookingDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the paid
|
||||||
|
*/
|
||||||
|
public BigDecimal getPaid() {
|
||||||
|
return paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paid the paid to set
|
||||||
|
*/
|
||||||
|
public void setPaid(BigDecimal paid) {
|
||||||
|
this.paid = paid;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BookingBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer approved;
|
||||||
|
private Integer rejected;
|
||||||
|
private Integer open;
|
||||||
|
private BigDecimal paid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the approved
|
||||||
|
*/
|
||||||
|
public Integer getApproved() {
|
||||||
|
return approved;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param approved the approved to set
|
||||||
|
*/
|
||||||
|
public void setApproved(Integer approved) {
|
||||||
|
this.approved = approved;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the rejected
|
||||||
|
*/
|
||||||
|
public Integer getRejected() {
|
||||||
|
return rejected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param rejected the rejected to set
|
||||||
|
*/
|
||||||
|
public void setRejected(Integer rejected) {
|
||||||
|
this.rejected = rejected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the open
|
||||||
|
*/
|
||||||
|
public Integer getOpen() {
|
||||||
|
return open;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param open the open to set
|
||||||
|
*/
|
||||||
|
public void setOpen(Integer open) {
|
||||||
|
this.open = open;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the paid
|
||||||
|
*/
|
||||||
|
public BigDecimal getPaid() {
|
||||||
|
return paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paid the paid to set
|
||||||
|
*/
|
||||||
|
public void setPaid(BigDecimal paid) {
|
||||||
|
this.paid = paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.privileges.impl.ProfileBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CampBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 2L;
|
||||||
|
|
||||||
|
private Integer pk;
|
||||||
|
private String name;
|
||||||
|
private Double year;
|
||||||
|
private LocalDateTime arrive;
|
||||||
|
private LocalDateTime depart;
|
||||||
|
private String locationName;
|
||||||
|
private String price;
|
||||||
|
private List<ProfileBean> profiles;
|
||||||
|
|
||||||
|
public CampBean() {
|
||||||
|
profiles = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the year
|
||||||
|
*/
|
||||||
|
public Double getYear() {
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param year the year to set
|
||||||
|
*/
|
||||||
|
public void setYear(Double year) {
|
||||||
|
this.year = year;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the arrive
|
||||||
|
*/
|
||||||
|
public LocalDateTime getArrive() {
|
||||||
|
return arrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param arrive the arrive to set
|
||||||
|
*/
|
||||||
|
public void setArrive(LocalDateTime arrive) {
|
||||||
|
this.arrive = arrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the depart
|
||||||
|
*/
|
||||||
|
public LocalDateTime getDepart() {
|
||||||
|
return depart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param depart the depart to set
|
||||||
|
*/
|
||||||
|
public void setDepart(LocalDateTime depart) {
|
||||||
|
this.depart = depart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the locationName
|
||||||
|
*/
|
||||||
|
public String getLocationName() {
|
||||||
|
return locationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param locationName the locationName to set
|
||||||
|
*/
|
||||||
|
public void setLocationName(String locationName) {
|
||||||
|
this.locationName = locationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the price
|
||||||
|
*/
|
||||||
|
public String getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param price the price to set
|
||||||
|
*/
|
||||||
|
public void setPrice(String price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the profiles
|
||||||
|
*/
|
||||||
|
public List<ProfileBean> getProfiles() {
|
||||||
|
return profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPk(Integer pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp.impl;
|
||||||
|
|
||||||
|
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_SALESPROFILE;
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.Record;
|
||||||
|
import org.jooq.Record6;
|
||||||
|
import org.jooq.Record8;
|
||||||
|
import org.jooq.SelectConditionStep;
|
||||||
|
import org.jooq.SelectSeekStep4;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@Transactional(transactionManager = "transactionManager")
|
||||||
|
public class CampGateway {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(CampGateway.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext jooq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the camp referenced by pk
|
||||||
|
*
|
||||||
|
* @param pk the ID of the camp
|
||||||
|
* @param username the name of the current user in this session
|
||||||
|
*
|
||||||
|
* @return the camp if found or null
|
||||||
|
*/
|
||||||
|
public CampBean getCamp(Integer pk, String username) {
|
||||||
|
SelectConditionStep<Record6<String, Double, LocalDateTime, LocalDateTime, String, String>> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.select(V_CAMP.NAME, V_CAMP.YEAR, V_CAMP.ARRIVE, V_CAMP.DEPART, V_CAMP.LOCATION_NAME, V_CAMP.PRICE)
|
||||||
|
.from(V_CAMP)
|
||||||
|
.leftJoin(T_SALESPROFILE).on(T_SALESPROFILE.FK_CAMP.eq(V_CAMP.PK))
|
||||||
|
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_SALESPROFILE.FK_PROFILE))
|
||||||
|
.where(V_CAMP.PK.eq(pk))
|
||||||
|
.and(T_PROFILE.USERNAME.eq(username));
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
CampBean bean = new CampBean();
|
||||||
|
for (Record6<String, Double, LocalDateTime, LocalDateTime, String, String> r : sql.fetch()) {
|
||||||
|
bean.setName(r.get(V_CAMP.NAME));
|
||||||
|
bean.setYear(r.get(V_CAMP.YEAR));
|
||||||
|
bean.setArrive(r.get(V_CAMP.ARRIVE));
|
||||||
|
bean.setDepart(r.get(V_CAMP.DEPART));
|
||||||
|
bean.setLocationName(r.get(V_CAMP.LOCATION_NAME));
|
||||||
|
bean.setPrice(r.get(V_CAMP.PRICE));
|
||||||
|
}
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a list of all registered persons that have booked the camp
|
||||||
|
*
|
||||||
|
* @param pk the ID of the camp
|
||||||
|
* @param username the name of the current user in this session
|
||||||
|
*
|
||||||
|
* @return a list of bookings; an empty one at least
|
||||||
|
*/
|
||||||
|
public List<PersonBean> getBookings(Integer pk, String username) {
|
||||||
|
SelectSeekStep4<Record8<Integer, Boolean, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>, EnumCamprole, EnumSex, String, String> sql = jooq
|
||||||
|
// @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)
|
||||||
|
.from(T_PERSON)
|
||||||
|
.leftJoin(T_SALESPROFILE).on(T_SALESPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP))
|
||||||
|
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_SALESPROFILE.FK_PROFILE))
|
||||||
|
.where(T_PERSON.FK_CAMP.eq(pk))
|
||||||
|
.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());
|
||||||
|
List<PersonBean> list = new ArrayList<>();
|
||||||
|
for (Record r : sql.fetch()) {
|
||||||
|
String forename = r.get(T_PERSON.FORENAME);
|
||||||
|
String surname = r.get(T_PERSON.SURNAME);
|
||||||
|
EnumCamprole role = r.get(T_PERSON.CAMPROLE);
|
||||||
|
EnumSex sex = r.get(T_PERSON.SEX);
|
||||||
|
PersonBean bean = new PersonBean();
|
||||||
|
bean.setPk(r.get(T_PERSON.PK));
|
||||||
|
bean.setName(String.format("%s %s", forename, surname));
|
||||||
|
bean.setRole(EnumCamprole.student.equals(role) ? "Teilnehmer" : "Mitarbeiter");
|
||||||
|
bean.setSex(EnumSex.female.equals(sex) ? "weiblich" : "männlich");
|
||||||
|
bean.setBookingDate(r.get(T_PERSON.CREATED));
|
||||||
|
bean.setAccept(r.get(T_PERSON.ACCEPT));
|
||||||
|
bean.setPaid(r.get(T_PERSON.PAID));
|
||||||
|
list.add(bean);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp.impl;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.camp.ICampService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CampService implements ICampService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CampGateway campGateway;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CampBean getCamp(Integer id, String username) {
|
||||||
|
return campGateway.getCamp(id, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BookingBean getBookings(Integer id, String username) {
|
||||||
|
Integer approved = 0;
|
||||||
|
Integer open = 0;
|
||||||
|
Integer rejected = 0;
|
||||||
|
BigDecimal paid = new BigDecimal(0);
|
||||||
|
for (PersonBean p : campGateway.getBookings(id, username)) {
|
||||||
|
Boolean acceptence = p.getAccept();
|
||||||
|
if (acceptence == null) {
|
||||||
|
open += 1;
|
||||||
|
} else if (acceptence) {
|
||||||
|
approved +=1;
|
||||||
|
} else {
|
||||||
|
rejected +=1;
|
||||||
|
}
|
||||||
|
paid = paid.add(p.getPaid() == null ? new BigDecimal(0) : p.getPaid());
|
||||||
|
}
|
||||||
|
BookingBean bean = new BookingBean();
|
||||||
|
bean.setApproved(approved);
|
||||||
|
bean.setOpen(open);
|
||||||
|
bean.setRejected(rejected);
|
||||||
|
bean.setPaid(paid);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PersonBean> getBookers(Integer id, String username) {
|
||||||
|
return campGateway.getBookings(id, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.camp.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PersonBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 2L;
|
||||||
|
|
||||||
|
private Integer pk;
|
||||||
|
private String name;
|
||||||
|
private String role;
|
||||||
|
private String sex;
|
||||||
|
private Boolean accept;
|
||||||
|
private LocalDateTime bookingDate;
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public BigDecimal getPaid() {
|
||||||
|
return paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param paid the paid to set
|
||||||
|
*/
|
||||||
|
public void setPaid(BigDecimal paid) {
|
||||||
|
this.paid = paid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pk
|
||||||
|
*/
|
||||||
|
public Integer getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pk the pk to set
|
||||||
|
*/
|
||||||
|
public void setPk(Integer pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(String role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSex() {
|
||||||
|
return sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSex(String sex) {
|
||||||
|
this.sex = sex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getBookingDate() {
|
||||||
|
return bookingDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBookingDate(LocalDateTime bookingDate) {
|
||||||
|
this.bookingDate = bookingDate;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.privileges;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.camp.impl.CampBean;
|
||||||
|
import de.jottyfan.camporganizer.module.business.privileges.impl.PrivilegesBean;
|
||||||
|
import de.jottyfan.camporganizer.module.business.privileges.impl.ProfileBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IPrivilegesService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all current privileges for the sales
|
||||||
|
*
|
||||||
|
* @return the privileges for sales
|
||||||
|
*/
|
||||||
|
public Map<Integer, CampBean> getPrivileges();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all profiles
|
||||||
|
*
|
||||||
|
* @return the profiles
|
||||||
|
*/
|
||||||
|
public List<ProfileBean> getProfiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a privilege
|
||||||
|
*
|
||||||
|
* @param bean the bean
|
||||||
|
*/
|
||||||
|
public void add(PrivilegesBean bean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a privilege
|
||||||
|
*
|
||||||
|
* @param bean the bean
|
||||||
|
* @param currentUser the current user in this sessionö
|
||||||
|
*/
|
||||||
|
public void remove(PrivilegesBean bean, String currentUser);
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.privileges;
|
||||||
|
|
||||||
|
import javax.annotation.security.RolesAllowed;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.websocket.server.PathParam;
|
||||||
|
|
||||||
|
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.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.business.IBusinessService;
|
||||||
|
import de.jottyfan.camporganizer.module.business.privileges.impl.PrivilegesBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author henkej
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class PrivilegesController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPrivilegesService privilegesService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBusinessService indexService;
|
||||||
|
|
||||||
|
@GetMapping("/business/privileges")
|
||||||
|
@RolesAllowed({ "admin" })
|
||||||
|
public String getIndex(Model model) {
|
||||||
|
String username = indexService.getCurrentUser(request);
|
||||||
|
model.addAttribute("currentUser", username);
|
||||||
|
model.addAttribute("privileges", privilegesService.getPrivileges());
|
||||||
|
model.addAttribute("profiles", privilegesService.getProfiles());
|
||||||
|
model.addAttribute("bean", new PrivilegesBean());
|
||||||
|
return "business/privileges";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/business/privileges/add")
|
||||||
|
@RolesAllowed({ "admin" })
|
||||||
|
public String getAdd(@ModelAttribute PrivilegesBean bean, Model model) {
|
||||||
|
privilegesService.add(bean);
|
||||||
|
return getIndex(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/business/privileges/delete")
|
||||||
|
@RolesAllowed({ "admin" })
|
||||||
|
public String getDelete(@PathParam(value = "fkCamp") Integer fkCamp,
|
||||||
|
@PathParam(value = "fkProfile") Integer fkProfile, Model model) {
|
||||||
|
PrivilegesBean bean = new PrivilegesBean();
|
||||||
|
bean.setFkCamp(fkCamp);
|
||||||
|
bean.setFkProfile(fkProfile);
|
||||||
|
privilegesService.remove(bean, indexService.getCurrentUser(request));
|
||||||
|
return getIndex(model);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,134 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.privileges.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PrivilegesBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String forename;
|
||||||
|
private String surname;
|
||||||
|
private String username;
|
||||||
|
private LocalDateTime duedate;
|
||||||
|
private Integer fkProfile;
|
||||||
|
private Integer fkCamp;
|
||||||
|
private String campName;
|
||||||
|
private Double campYear;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the forename
|
||||||
|
*/
|
||||||
|
public String getForename() {
|
||||||
|
return forename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param forename the forename to set
|
||||||
|
*/
|
||||||
|
public void setForename(String forename) {
|
||||||
|
this.forename = forename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the surname
|
||||||
|
*/
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param surname the surname to set
|
||||||
|
*/
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fkProfile
|
||||||
|
*/
|
||||||
|
public Integer getFkProfile() {
|
||||||
|
return fkProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fkProfile the fkProfile to set
|
||||||
|
*/
|
||||||
|
public void setFkProfile(Integer fkProfile) {
|
||||||
|
this.fkProfile = fkProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fkCamp
|
||||||
|
*/
|
||||||
|
public Integer getFkCamp() {
|
||||||
|
return fkCamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fkCamp the fkCamp to set
|
||||||
|
*/
|
||||||
|
public void setFkCamp(Integer fkCamp) {
|
||||||
|
this.fkCamp = fkCamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campName
|
||||||
|
*/
|
||||||
|
public String getCampName() {
|
||||||
|
return campName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param campName the campName to set
|
||||||
|
*/
|
||||||
|
public void setCampName(String campName) {
|
||||||
|
this.campName = campName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the campYear
|
||||||
|
*/
|
||||||
|
public Double getCampYear() {
|
||||||
|
return campYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param campYear the campYear to set
|
||||||
|
*/
|
||||||
|
public void setCampYear(Double campYear) {
|
||||||
|
this.campYear = campYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the username
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username the username to set
|
||||||
|
*/
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duedate
|
||||||
|
*/
|
||||||
|
public LocalDateTime getDuedate() {
|
||||||
|
return duedate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param duedate the duedate to set
|
||||||
|
*/
|
||||||
|
public void setDuedate(LocalDateTime duedate) {
|
||||||
|
this.duedate = duedate;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.privileges.impl;
|
||||||
|
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE;
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.T_SALESPROFILE;
|
||||||
|
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.DeleteConditionStep;
|
||||||
|
import org.jooq.InsertReturningStep;
|
||||||
|
import org.jooq.Record5;
|
||||||
|
import org.jooq.Record8;
|
||||||
|
import org.jooq.SelectSeekStep3;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.db.jooq.tables.records.TSalesprofileRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@Transactional(transactionManager = "transactionManager")
|
||||||
|
public class PrivilegesGateway {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(PrivilegesGateway.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext jooq;
|
||||||
|
|
||||||
|
public List<PrivilegesBean> getPrivileges() {
|
||||||
|
SelectSeekStep3<Record8<String, String, LocalDateTime, String, Integer, Integer, String, Double>, LocalDateTime, String, String> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.select(T_PROFILE.FORENAME, T_PROFILE.SURNAME, T_PROFILE.DUEDATE, T_PROFILE.USERNAME, T_PROFILE.PK, V_CAMP.PK, V_CAMP.NAME, V_CAMP.YEAR)
|
||||||
|
.from(V_CAMP)
|
||||||
|
.leftJoin(T_SALESPROFILE).on(T_SALESPROFILE.FK_CAMP.eq(V_CAMP.PK))
|
||||||
|
.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_SALESPROFILE.FK_PROFILE))
|
||||||
|
.orderBy(V_CAMP.ARRIVE, T_PROFILE.SURNAME, T_PROFILE.FORENAME);
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
List<PrivilegesBean> list = new ArrayList<>();
|
||||||
|
for (Record8<String, String, LocalDateTime, String, Integer, Integer, String, Double> r : sql.fetch()) {
|
||||||
|
PrivilegesBean bean = new PrivilegesBean();
|
||||||
|
bean.setCampName(r.get(V_CAMP.NAME));
|
||||||
|
bean.setCampYear(r.get(V_CAMP.YEAR));
|
||||||
|
bean.setFkCamp(r.get(V_CAMP.PK));
|
||||||
|
bean.setFkProfile(r.get(T_PROFILE.PK));
|
||||||
|
bean.setForename(r.get(T_PROFILE.FORENAME));
|
||||||
|
bean.setSurname(r.get(T_PROFILE.SURNAME));
|
||||||
|
bean.setUsername(r.get(T_PROFILE.USERNAME));
|
||||||
|
bean.setDuedate(r.get(T_PROFILE.DUEDATE));
|
||||||
|
list.add(bean);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProfileBean> getProfiles() {
|
||||||
|
SelectSeekStep3<Record5<Integer, String, String, LocalDateTime, String>, String, String, LocalDateTime> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.select(T_PROFILE.PK, T_PROFILE.FORENAME, T_PROFILE.SURNAME, T_PROFILE.DUEDATE, T_PROFILE.USERNAME)
|
||||||
|
.from(T_PROFILE)
|
||||||
|
.orderBy(T_PROFILE.SURNAME, T_PROFILE.FORENAME, T_PROFILE.DUEDATE);
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
List<ProfileBean> list = new ArrayList<>();
|
||||||
|
for (Record5<Integer, String, String, LocalDateTime, String> r : sql.fetch()) {
|
||||||
|
ProfileBean bean = new ProfileBean();
|
||||||
|
bean.setPk(r.get(T_PROFILE.PK));
|
||||||
|
bean.setForename(r.get(T_PROFILE.FORENAME));
|
||||||
|
bean.setSurname(r.get(T_PROFILE.SURNAME));
|
||||||
|
bean.setUsername(r.get(T_PROFILE.USERNAME));
|
||||||
|
bean.setDuedate(r.get(T_PROFILE.DUEDATE));
|
||||||
|
list.add(bean);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer add(PrivilegesBean bean) {
|
||||||
|
InsertReturningStep<TSalesprofileRecord> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.insertInto(T_SALESPROFILE, T_SALESPROFILE.FK_CAMP, T_SALESPROFILE.FK_PROFILE)
|
||||||
|
.values(bean.getFkCamp(), bean.getFkProfile())
|
||||||
|
.onConflict(T_SALESPROFILE.FK_CAMP, T_SALESPROFILE.FK_PROFILE)
|
||||||
|
.doNothing();
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
return sql.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer remove(PrivilegesBean bean, String currentUser) {
|
||||||
|
DeleteConditionStep<TSalesprofileRecord> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.deleteFrom(T_SALESPROFILE)
|
||||||
|
.where(T_SALESPROFILE.FK_CAMP.eq(bean.getFkCamp()))
|
||||||
|
.and(T_SALESPROFILE.FK_PROFILE.eq(bean.getFkProfile()))
|
||||||
|
.and(T_SALESPROFILE.FK_PROFILE.notIn(jooq
|
||||||
|
.select(T_PROFILE.PK)
|
||||||
|
.from(T_PROFILE)
|
||||||
|
.where(T_PROFILE.USERNAME.eq(currentUser))));
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.debug(sql.toString());
|
||||||
|
return sql.execute();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.privileges.impl;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import de.jottyfan.camporganizer.module.business.camp.impl.CampBean;
|
||||||
|
import de.jottyfan.camporganizer.module.business.privileges.IPrivilegesService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PrivilegesService implements IPrivilegesService {
|
||||||
|
@Autowired
|
||||||
|
private PrivilegesGateway gateway;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Integer, CampBean> getPrivileges() {
|
||||||
|
List<PrivilegesBean> list = gateway.getPrivileges();
|
||||||
|
Map<Integer, CampBean> camps = new HashMap<>();
|
||||||
|
for (PrivilegesBean bean : list) {
|
||||||
|
CampBean campBean = camps.get(bean.getFkCamp());
|
||||||
|
if (campBean == null) {
|
||||||
|
campBean = new CampBean();
|
||||||
|
camps.put(bean.getFkCamp(), campBean);
|
||||||
|
}
|
||||||
|
campBean.setPk(bean.getFkCamp());
|
||||||
|
campBean.setName(bean.getCampName());
|
||||||
|
campBean.setYear(bean.getCampYear());
|
||||||
|
ProfileBean profileBean = new ProfileBean();
|
||||||
|
profileBean.setPk(bean.getFkProfile());
|
||||||
|
profileBean.setForename(bean.getForename());
|
||||||
|
profileBean.setSurname(bean.getSurname());
|
||||||
|
profileBean.setUsername(bean.getUsername());
|
||||||
|
profileBean.setDuedate(bean.getDuedate());
|
||||||
|
campBean.getProfiles().add(profileBean);
|
||||||
|
}
|
||||||
|
return camps;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ProfileBean> getProfiles() {
|
||||||
|
return gateway.getProfiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(PrivilegesBean bean) {
|
||||||
|
gateway.add(bean);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(PrivilegesBean bean, String currentUser) {
|
||||||
|
gateway.remove(bean, currentUser);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
package de.jottyfan.camporganizer.module.business.privileges.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProfileBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer pk;
|
||||||
|
private String forename;
|
||||||
|
private String surname;
|
||||||
|
private String username;
|
||||||
|
private LocalDateTime duedate;
|
||||||
|
|
||||||
|
public String dropdown() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append(forename).append(" ");
|
||||||
|
buf.append(surname).append(" (");
|
||||||
|
buf.append(username).append(", ");
|
||||||
|
buf.append(duedate == null ? "" : duedate.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")));
|
||||||
|
buf.append(")");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append("{pk=").append(pk);
|
||||||
|
buf.append(", forename=").append(forename);
|
||||||
|
buf.append(", surname=").append(surname);
|
||||||
|
buf.append(", username=").append(username);
|
||||||
|
buf.append(", duedate=").append(duedate);
|
||||||
|
buf.append("}");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pk
|
||||||
|
*/
|
||||||
|
public Integer getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pk the pk to set
|
||||||
|
*/
|
||||||
|
public void setPk(Integer pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the forename
|
||||||
|
*/
|
||||||
|
public String getForename() {
|
||||||
|
return forename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param forename the forename to set
|
||||||
|
*/
|
||||||
|
public void setForename(String forename) {
|
||||||
|
this.forename = forename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the surname
|
||||||
|
*/
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param surname the surname to set
|
||||||
|
*/
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the username
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username the username to set
|
||||||
|
*/
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duedate
|
||||||
|
*/
|
||||||
|
public LocalDateTime getDuedate() {
|
||||||
|
return duedate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param duedate the duedate to set
|
||||||
|
*/
|
||||||
|
public void setDuedate(LocalDateTime duedate) {
|
||||||
|
this.duedate = duedate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,6 @@ package de.jottyfan.camporganizer.module.common;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.jooq.exception.DataAccessException;
|
|
||||||
import org.keycloak.KeycloakSecurityContext;
|
import org.keycloak.KeycloakSecurityContext;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
@ -27,6 +26,7 @@ public abstract class CommonController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* setup the session for the template
|
* setup the session for the template
|
||||||
|
*
|
||||||
* @param model the model
|
* @param model the model
|
||||||
* @param request the request
|
* @param request the request
|
||||||
*/
|
*/
|
||||||
@ -34,4 +34,14 @@ public abstract class CommonController {
|
|||||||
String username = getCurrentUser(request);
|
String username = getCurrentUser(request);
|
||||||
model.addAttribute("currentUser", username);
|
model.addAttribute("currentUser", username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true if the user has a valid keycloak session token
|
||||||
|
*
|
||||||
|
* @param request the request
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
public boolean isLoggedIn(HttpServletRequest request) {
|
||||||
|
return getCurrentUser(request) != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,19 +29,19 @@ public class IndexController extends CommonController {
|
|||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
super.setupSession(model, request);
|
super.setupSession(model, request);
|
||||||
model.addAttribute("camps", service.getAllCamps());
|
model.addAttribute("camps", service.getAllCamps());
|
||||||
return "/index";
|
return super.isLoggedIn(request) ? dashboard(model) : "/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/user")
|
@GetMapping("/dashboard")
|
||||||
public String user(Model model) {
|
public String dashboard(Model model) {
|
||||||
super.setupSession(model, request);
|
super.setupSession(model, request);
|
||||||
model.addAttribute("camps", service.getAllCamps());
|
return "/dashboard";
|
||||||
return "/user/index";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/logout")
|
@GetMapping("/logout")
|
||||||
public String getLogout(HttpServletRequest request) throws ServletException {
|
public String getLogout(HttpServletRequest request) throws ServletException {
|
||||||
request.logout();
|
request.logout();
|
||||||
|
LOGGER.debug("logout");
|
||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,8 @@ package de.jottyfan.camporganizer.module.common;
|
|||||||
|
|
||||||
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
|
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ body {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
color: silver;
|
color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-icon-silent:hover {
|
.btn-icon-silent:hover {
|
||||||
|
77
src/main/resources/templates/business/booker.html
Normal file
77
src/main/resources/templates/business/booker.html
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:replace="~{template :: layout(~{::title}, ~{::libs}, ~{::header}, ~{::content})}" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer Business</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<libs> </libs>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<a th:href="@{/}" class="btn btn-secondary btn-icon-silent" title="zur Hauptseite"><i class="fas fa-home"></i></a>
|
||||||
|
<a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent" title="zur Finanzübersicht"><i class="far fa-money-bill-alt"></i></a>
|
||||||
|
<a th:href="@{/business/bookings}" class="btn btn-secondary btn-icon-silent" title="Buchungsübersicht" sec:authorize="hasRole('business_booking')"><i class="fas fa-users"></i></a>
|
||||||
|
<a th:href="@{'/business/bookings/' + ${booker.pk}}" class="btn btn-secondary btn-icon-silent" title="aktualisieren"><i class="fas fa-sync"></i></a>
|
||||||
|
</header>
|
||||||
|
<content>
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="container" style="max-width: 100%">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card" style="width: 480px" sec:authorize="hasRole('business_booking')">
|
||||||
|
<div class="card-header">Angemeldete Person</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<td th:text="${booker.name}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Geschlecht</th>
|
||||||
|
<td th:text="${booker.sex}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Freizeit</th>
|
||||||
|
<td th:text="${booker.camp}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Rolle</th>
|
||||||
|
<td th:text="${booker.role}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Angemeldet</th>
|
||||||
|
<td th:text="${#temporals.format(booker.bookingDate, 'dd.MM.yyyy')}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Bestätigt</th>
|
||||||
|
<td th:text="${booker.accept == null ? '' : (booker.accept ? 'Ja' : 'abgelehnt')}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Preis</th>
|
||||||
|
<td th:text="${booker.price}" />
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Kontostand</th>
|
||||||
|
<td><span th:text="${#strings.replace(#numbers.formatCurrency(booker.paid), '¤', '€')}" th:if="${booker.paid != null}"></span>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="card" style="width: 480px" sec:authorize="hasRole('business_booking')">
|
||||||
|
<div class="card-header">Einzahlung</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form action="#" th:action="@{'/business/bookings/payment/' + ${booker.pk}}" th:object="${addBean}" method="post">
|
||||||
|
<input type="number" step="0.01" th:field="*{payment}"> <input type="submit" style="padding: 4px" value="einzahlen">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</content>
|
||||||
|
</body>
|
||||||
|
</html>
|
58
src/main/resources/templates/business/bookings.html
Normal file
58
src/main/resources/templates/business/bookings.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:replace="~{template :: layout(~{::title}, ~{::libs}, ~{::header}, ~{::content})}" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer Business</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<libs> </libs>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<a th:href="@{/}" class="btn btn-secondary btn-icon-silent" title="zur Hauptseite"><i class="fas fa-home"></i></a>
|
||||||
|
<a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent" title="zur Finanzübersicht"><i class="far fa-money-bill-alt"></i></a>
|
||||||
|
<a th:href="@{/business/bookings}" class="btn btn-secondary btn-icon-silent" title="aktualisieren"><i class="fas fa-sync"></i></a>
|
||||||
|
</header>
|
||||||
|
<content>
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="card" sec:authorize="hasRole('business_booking')">
|
||||||
|
<div class="card-header">Angemeldete Personen</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table id="bookers" class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Geschlecht</th>
|
||||||
|
<th>Freizeit</th>
|
||||||
|
<th>Rolle</th>
|
||||||
|
<th>Kontostand</th>
|
||||||
|
<th>Angemeldet</th>
|
||||||
|
<th>Bestätigt</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<th:block th:each="b : ${bookers}">
|
||||||
|
<tr>
|
||||||
|
<td th:text="${b.name}"></td>
|
||||||
|
<td th:text="${b.sex}"></td>
|
||||||
|
<td th:text="${b.camp}"></td>
|
||||||
|
<td th:text="${b.role}"></td>
|
||||||
|
<td><span th:text="${#strings.replace(#numbers.formatCurrency(b.paid), '¤', '€')}"></span> <a class="btn btn-icon-silent" th:href="@{/business/bookings/{id}(id=${b.pk})}"
|
||||||
|
title="bearbeiten"><i class="fas fa-edit"></i></a></td>
|
||||||
|
<td th:text="${#temporals.format(b.bookingDate, 'dd.MM.yyyy')}"></td>
|
||||||
|
<td th:text="${b.accept == null ? '' : (b.accept ? 'Ja' : 'abgelehnt')}"></td>
|
||||||
|
</tr>
|
||||||
|
</th:block>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#bookers").DataTable({
|
||||||
|
language : locale_de
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</content>
|
||||||
|
</body>
|
||||||
|
</html>
|
43
src/main/resources/templates/business/business.html
Normal file
43
src/main/resources/templates/business/business.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:replace="~{template :: layout(~{::title}, ~{::libs}, ~{::header}, ~{::content})}" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer Business</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<libs></libs>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<a th:href="@{/}" class="btn btn-secondary btn-icon-silent" title="zur Hauptseite"><i class="fas fa-home"></i></a>
|
||||||
|
<a th:href="@{/business}" class="btn btn-secondary btn-icon-silent" title="aktualisieren"><i class="fas fa-sync"></i></a>
|
||||||
|
<a th:href="@{/business/bookings}" class="btn btn-secondary btn-icon-silent" title="zur Buchungsübersicht" sec:authorize="hasRole('business_booking')"><i class="fas fa-users"></i></a>
|
||||||
|
<a th:href="@{/business/privileges}" class="btn btn-secondary btn-icon-silent" title="Nutzerverwaltung" sec:authorize="hasRole('admin')"><i class="fas fa-user-lock"></i></a>
|
||||||
|
</header>
|
||||||
|
<content>
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="card" style="width: 500px">
|
||||||
|
<div class="card-header">Finanzübersicht über alle Freizeiten</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Jahr</th>
|
||||||
|
<th scope="col">Freizeit</th>
|
||||||
|
<th scope="col">Kontostand</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<th:block th:each="b : ${campBudgets}" sec:authorize="hasRole('business')">
|
||||||
|
<tr>
|
||||||
|
<td th:text="${#numbers.formatDecimal(b.campYear, 1, 0)}"></td>
|
||||||
|
<td><a th:href="@{/business/camp/{id}(id=${b.campId})}" th:text="${b.campName}" class="tablelink" title="Freizeitübersicht laden"></a></td>
|
||||||
|
<td th:text="${#strings.replace(#numbers.formatCurrency(b.budget), '¤', '€')}"></td>
|
||||||
|
</tr>
|
||||||
|
</th:block>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</content>
|
||||||
|
</body>
|
||||||
|
</html>
|
105
src/main/resources/templates/business/camp.html
Normal file
105
src/main/resources/templates/business/camp.html
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:replace="~{template :: layout(~{::title}, ~{::libs}, ~{::header}, ~{::content})}" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer Business</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<libs> </libs>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<a th:href="@{/}" class="btn btn-secondary btn-icon-silent" title="zur Hauptseite"><i class="fas fa-home"></i></a>
|
||||||
|
<a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent" title="zur Finanzübersicht"><i class="far fa-money-bill-alt"></i></a>
|
||||||
|
<a th:href="@{/business/camp/{id}(id=${campId})}" class="btn btn-secondary btn-icon-silent" title="aktualisieren"><i class="fas fa-sync"></i></a>
|
||||||
|
</header>
|
||||||
|
<content>
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="container" style="max-width: 100%">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="card" style="width: 480px" th:if="${camp != null}">
|
||||||
|
<div class="card-header">
|
||||||
|
<span th:text="${camp.name}"></span> von <span th:text="${#numbers.formatInteger(camp.year, 0)}"></span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Freizeitname</td>
|
||||||
|
<th th:text="${camp.name}"></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Zeit</td>
|
||||||
|
<th><span th:text="${#temporals.format(camp.arrive, 'dd.MM.')}"></span> - <span th:text="${#temporals.format(camp.depart, 'dd.MM.yyyy')}"></span></th>
|
||||||
|
<tr>
|
||||||
|
<td>Ort</td>
|
||||||
|
<th th:text="${camp.locationName}"></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Preis</td>
|
||||||
|
<th><pre th:utext="${camp.price}"></pre></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>bestätigt</td>
|
||||||
|
<th th:text="${booking.approved}"></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>abgelehnt</td>
|
||||||
|
<th th:text="${booking.rejected}"></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>offen</td>
|
||||||
|
<th th:text="${booking.open}"></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Beiträge</td>
|
||||||
|
<th th:text="${#strings.replace(#numbers.formatCurrency(booking.paid), '¤', '€')}"></th>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col" sec:authorize="hasRole('business_booking')">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Angemeldete Personen</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table id="bookers" class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Geschlecht</th>
|
||||||
|
<th>Rolle</th>
|
||||||
|
<th>Kontostand</th>
|
||||||
|
<th>Angemeldet</th>
|
||||||
|
<th>Bestätigt</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<th:block th:each="b : ${bookers}">
|
||||||
|
<tr>
|
||||||
|
<td th:text="${b.name}"></td>
|
||||||
|
<td th:text="${b.sex}"></td>
|
||||||
|
<td th:text="${b.role}"></td>
|
||||||
|
<td th:text="${#strings.replace(#numbers.formatCurrency(b.paid), '¤', '€')}"></td>
|
||||||
|
<td th:text="${#temporals.format(b.bookingDate, 'dd.MM.yyyy')}"></td>
|
||||||
|
<td th:text="${b.accept == null ? '' : (b.accept ? 'Ja' : 'abgelehnt')}"></td>
|
||||||
|
</tr>
|
||||||
|
</th:block>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#bookers").DataTable({
|
||||||
|
language: locale_de
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger" role="alert" th:if="${camp == null}">Es wurde keine Freizeit gefunden, die über diese ID angesprochen werden kann.</div>
|
||||||
|
</div>
|
||||||
|
</content>
|
||||||
|
</body>
|
||||||
|
</html>
|
80
src/main/resources/templates/business/privileges.html
Normal file
80
src/main/resources/templates/business/privileges.html
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:replace="~{template :: layout(~{::title}, ~{::libs}, ~{::header}, ~{::content})}" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer Business</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<libs>
|
||||||
|
</libs>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<a th:href="@{/}" class="btn btn-secondary btn-icon-silent" title="zur Hauptseite"><i class="fas fa-home"></i></a>
|
||||||
|
<a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent" title="zur Finanzübersicht"><i class="far fa-money-bill-alt"></i></a>
|
||||||
|
<a th:href="@{/business/privileges}" class="btn btn-secondary btn-icon-silent" title="aktualisieren"><i class="fas fa-sync"></i></a>
|
||||||
|
</header>
|
||||||
|
<content>
|
||||||
|
<div class="mainpage">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Nutzerverwaltung für die Abrechnung von Freizeiten</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table id="privs">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Freizeit</th>
|
||||||
|
<th scope="col">Abrechnung darf bearbeiten</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<th:block th:each="e : ${privileges.entrySet()}" sec:authorize="hasRole('admin')">
|
||||||
|
<tr>
|
||||||
|
<td><span th:text="${e.value.name}"></span> <span th:text="${#numbers.formatDecimal(e.value.year, 1, 0)}"></span></td>
|
||||||
|
<td><th:block th:each="p : ${e.value.profiles}">
|
||||||
|
<div class="dropdown" style="display: inline" th:if="${p.pk != null}">
|
||||||
|
<button class="btn dropdown-toggle" style="border: 1px solid silver" type="button" th:id="'btn_' + ${e.key} + '_' + ${p.pk}" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
<span th:text="${p.forename} + ' ' + ${p.surname}"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" style="background-image: linear-gradient(to bottom right, #defac0, #9ef542) !important;" th:aria-labelledby="'btn_' + ${e.key} + '_' + ${p.pk}">
|
||||||
|
<li><div style="padding: 8px">
|
||||||
|
Login: <span th:text="${p.username}"></span>
|
||||||
|
</div></li>
|
||||||
|
<li><div style="padding: 8px">
|
||||||
|
Ablaufdatum: <span th:text="${#temporals.format(p.duedate, 'dd.MM.yyyy')}"></span>
|
||||||
|
</div></li>
|
||||||
|
<li><hr class="dropdown-divider" th:if="${p.username != currentUser}"></li>
|
||||||
|
<li><a class="dropdown-item" th:if="${p.username != currentUser}" th:href="@{/business/privileges/delete?fkCamp={c}&fkProfile={r}(c=${e.key},r=${p.pk})}">Recht entziehen</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</th:block></td>
|
||||||
|
<td>
|
||||||
|
<form action="#" th:action="@{/business/privileges/add?fkCamp={cid}(cid=${e.key})}" th:object="${bean}" method="post">
|
||||||
|
<span class="btn-group"> <select th:id="${e.value.pk}" class="form-control select2-single" th:field="*{fkProfile}">
|
||||||
|
<option value="">Auswählen</option>
|
||||||
|
<th:block th:each="u : ${profiles}">
|
||||||
|
<option th:if="${u != null}" th:value="${u.pk}" th:text="${u.dropdown()}" />
|
||||||
|
</th:block>
|
||||||
|
</select> <input type="submit" style="padding: 4px" value="Recht erteilen">
|
||||||
|
</span>
|
||||||
|
<script>
|
||||||
|
var id = "[[${e.value.pk}]]";
|
||||||
|
$("#" + id).select2();
|
||||||
|
</script>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</th:block>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#privs").DataTable({
|
||||||
|
language: locale_de
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</content>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
src/main/resources/templates/dashboard.html
Normal file
19
src/main/resources/templates/dashboard.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html th:replace="~{template :: layout(~{::title}, ~{::libs}, ~{::header}, ~{::content})}" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
<head>
|
||||||
|
<title>Camp Organizer 2</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<libs></libs>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<a th:href="@{/}" class="btn btn-secondary btn-icon-silent" title="aktualisieren"><i class="fas fa-sync"></i></a>
|
||||||
|
<a th:href="@{/business}" class="btn btn-secondary btn-icon-silent" title="Abrechnungen"><i class="far fa-money-bill-alt"></i></a>
|
||||||
|
<span>Das Buchungsportal dess Onkel Werner Freizeiten e.V.</span>
|
||||||
|
</header>
|
||||||
|
<content>
|
||||||
|
<div class="mainpage">
|
||||||
|
</div>
|
||||||
|
</content>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -23,7 +23,7 @@
|
|||||||
<b th:inline="text">[[${currentUser}]]</b> aus Version <span th:text="${@manifestBean.getVersion()}"></span> <a th:href="@{/logout}">ausloggen</a>
|
<b th:inline="text">[[${currentUser}]]</b> aus Version <span th:text="${@manifestBean.getVersion()}"></span> <a th:href="@{/logout}">ausloggen</a>
|
||||||
</span>
|
</span>
|
||||||
<span th:if="${#strings.isEmpty(currentUser)}">
|
<span th:if="${#strings.isEmpty(currentUser)}">
|
||||||
<a th:href="@{/user}">einloggen</a>
|
<a th:href="@{/dashboard}">einloggen</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span th:replace="${header}">Layout header</span>
|
<span th:replace="${header}">Layout header</span>
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html th:replace="~{template :: layout(~{::title}, ~{::libs}, ~{::header}, ~{::content})}" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
|
||||||
<head>
|
|
||||||
<title>Camp Organizer 2</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<libs></libs>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<a th:href="@{/}" class="btn btn-secondary btn-icon-silent" title="aktualisieren"><i class="fas fa-sync"></i></a>
|
|
||||||
<span>Das Buchungsportal dess Onkel Werner Freizeiten e.V.</span>
|
|
||||||
</header>
|
|
||||||
<content>
|
|
||||||
<div class="mainpage">
|
|
||||||
<script type="text/javascript">
|
|
||||||
var mytoggle = new MyToggle();
|
|
||||||
</script>
|
|
||||||
<h1>Unsere Freizeiten</h1>
|
|
||||||
<div class="card bottomdist16" th:each="c : ${camps}">
|
|
||||||
<div class="card-header mytoggle_btn" th:onclick="mytoggle.toggle('campdiv_[[${c.pk}]]')">
|
|
||||||
<span th:text="${c.name}"></span> <span th:text="${#numbers.formatInteger(c.year, 0)}" th:if="${c.year != null}"></span>
|
|
||||||
</div>
|
|
||||||
<div th:id="'campdiv_' + ${c.pk}" class="card-body mytoggle_collapsed">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">Ort</div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<a th:href="${c.url}" th:text="${c.locationName}" target="_blank"></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">Jungen und Mädchen</div>
|
|
||||||
<div class="col-sm-9" th:text="${c.minAge} + ' - ' + ${c.maxAge}"></div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">Zeit</div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<span th:text="${#temporals.format(c.arrive, 'dd.MM.')} + ' - ' + ${#temporals.format(c.depart, 'dd.MM.yyyy')}" th:if="${c.arrive != null && c.depart != null}"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">Preis</div>
|
|
||||||
<div class="col-sm-9" th:text="${c.price}"></div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">Ferien</div>
|
|
||||||
<div class="col-sm-9" th:text="${c.countries}"></div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3"></div>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<button class="btn btn-primary">jetzt anmelden</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</content>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
x
Reference in New Issue
Block a user