Verschillende functionaliteit:
-een gebruiker kan meerdere bedrijven hebben -manier van afspraken maken veranderd in de backend ivm meerdere bedrijven gebruiker -bedrijven van een gebruiker zijn op te roepen -gebruikers zijn aan een bestaand bedrijf te koppelen via een REST call -email is aangepast op bedrijf en gebruiker
This commit is contained in:
@@ -2,6 +2,9 @@ package nl.veenm.paypoint.domain;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
public class AppUser {
|
||||
@Id
|
||||
@@ -14,8 +17,13 @@ public class AppUser {
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
@ManyToOne(cascade = CascadeType.ALL)
|
||||
private Company company;
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = "user_company",
|
||||
joinColumns = @JoinColumn(name = "user_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "company_id")
|
||||
)
|
||||
private Set<Company> companies = new HashSet<>();
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
@@ -73,12 +81,12 @@ public class AppUser {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Company getCompany() {
|
||||
return company;
|
||||
public Set<Company> getCompanies() {
|
||||
return companies;
|
||||
}
|
||||
|
||||
public void setCompany(Company company) {
|
||||
this.company = company;
|
||||
public void setCompanies(Set<Company> companies) {
|
||||
this.companies = companies;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package nl.veenm.paypoint.domain;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
public class Company {
|
||||
@@ -17,6 +18,10 @@ public class Company {
|
||||
private String postal_code;
|
||||
private String city;
|
||||
|
||||
@ManyToMany(mappedBy = "companies")
|
||||
@JsonIgnore
|
||||
private Set<AppUser> users = new HashSet<>();
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
@@ -72,4 +77,12 @@ public class Company {
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public Set<AppUser> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(Set<AppUser> users) {
|
||||
this.users = users;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,14 @@ public class Customer {
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String email;
|
||||
private String phone;
|
||||
|
||||
public Customer(Long id, String firstName, String lastName, String email) {
|
||||
public Customer(Long id, String firstName, String lastName, String email, String phone) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public Customer() {
|
||||
@@ -55,4 +57,12 @@ public class Customer {
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,36 @@
|
||||
package nl.veenm.paypoint.helper;
|
||||
|
||||
import nl.veenm.paypoint.domain.Appointment;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class EmailHelper {
|
||||
public static String getIcs(String dtStamp, LocalDate date, String formattedTime, String formattedEndTime, String location) {
|
||||
public static String getIcs(String dtStamp, LocalDate date, String formattedTime, String formattedEndTime, String location, Appointment appointment) {
|
||||
String organizer = appointment.getCompany().getName() + ":" + appointment.getCompany().getEmail();
|
||||
String formatted = """
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//PayPoint//Afspraak//NL
|
||||
BEGIN:VEVENT
|
||||
ORGANIZER;CN=Hairstyling By Daan:mailto:danielle@hairstylingbydaan.nl
|
||||
ORGANIZER;CN=%s
|
||||
UID:12345
|
||||
DTSTAMP:%s
|
||||
DTSTART:%sT%s00
|
||||
DTEND:%sT%s00
|
||||
SUMMARY:Afspraak bij Hairstyling By Daan
|
||||
SUMMARY:Afspraak bij %s
|
||||
LOCATION:%s
|
||||
DESCRIPTION:Bevestiging van uw afspraak bij Hairstyling By Daan
|
||||
DESCRIPTION:Bevestiging van uw afspraak bij %s
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
""".formatted(dtStamp, date.toString().replace("-", ""), formattedTime.replace(":", ""), date.toString().replace("-", ""), formattedEndTime.replace(":", ""), location.replace("<br>", " "));
|
||||
""".formatted(organizer,
|
||||
dtStamp,
|
||||
date.toString().replace("-", ""),
|
||||
formattedTime.replace(":", ""),
|
||||
date.toString().replace("-", ""),
|
||||
formattedEndTime.replace(":", ""),
|
||||
appointment.getCompany().getName(),
|
||||
location.replace("<br>", " "),
|
||||
appointment.getCompany().getName());
|
||||
System.out.println(formatted);
|
||||
return formatted;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package nl.veenm.paypoint.repository;
|
||||
|
||||
import io.quarkus.hibernate.orm.panache.PanacheRepository;
|
||||
import io.quarkus.panache.common.Parameters;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import nl.veenm.paypoint.domain.Appointment;
|
||||
import nl.veenm.paypoint.domain.Company;
|
||||
@@ -8,6 +9,7 @@ import nl.veenm.paypoint.domain.Company;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@ApplicationScoped
|
||||
public class AppointmentRepository implements PanacheRepository<Appointment> {
|
||||
@@ -23,4 +25,11 @@ public class AppointmentRepository implements PanacheRepository<Appointment> {
|
||||
public List<Appointment> findMostRecentByCompanyId(Company company) {
|
||||
return find("company = ?1", company).list();
|
||||
}
|
||||
|
||||
public List<Appointment> findAppointmentsForCompanies(Set<Company> companies, LocalDateTime startDate, LocalDateTime endDate) {
|
||||
return find("SELECT a FROM Appointment a WHERE a.company IN :companies AND a.startDate BETWEEN :start AND :end",
|
||||
Parameters.with("companies", companies).and("start", startDate).and("end", endDate))
|
||||
.list();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package nl.veenm.paypoint.resource;
|
||||
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.json.JsonNumber;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
@@ -32,12 +31,10 @@ public class AppointmentResource {
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/date")
|
||||
public List<Appointment> getAppointmentsByDate(@QueryParam("start") String start) {
|
||||
JsonNumber companyIdJson = jwt.getClaim("company_id");
|
||||
Long companyId = companyIdJson.longValue();
|
||||
return appointmentService.getAppointmentsByDate(start, companyId);
|
||||
String user = jwt.getClaim("username");
|
||||
return appointmentService.getAppointmentsByDate(start, user);
|
||||
}
|
||||
|
||||
|
||||
//TODO: Deze werkend maken
|
||||
|
||||
// @GET
|
||||
@@ -55,11 +52,11 @@ public class AppointmentResource {
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{companyId}")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response addAppointment(Appointment appointment) {
|
||||
JsonNumber companyIdJson = jwt.getClaim("company_id");
|
||||
Long companyId = companyIdJson.longValue();
|
||||
return Response.ok(appointmentService.add(appointment, companyId)).build();
|
||||
public Response addAppointment(@PathParam("companyId") Long companyId, Appointment appointment) {
|
||||
String user = jwt.getClaim("username");
|
||||
return Response.ok(appointmentService.add(appointment, companyId, user)).build();
|
||||
}
|
||||
|
||||
@DELETE
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package nl.veenm.paypoint.resource;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import nl.veenm.paypoint.domain.Company;
|
||||
import nl.veenm.paypoint.service.CompanyService;
|
||||
import org.eclipse.microprofile.jwt.JsonWebToken;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Path("/company")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class CompanyResource {
|
||||
|
||||
@Inject
|
||||
CompanyService companyService;
|
||||
|
||||
@Inject
|
||||
JsonWebToken jwt;
|
||||
|
||||
@GET
|
||||
public Set<Company> getCompanies() {
|
||||
return this.companyService.getCompanies(this.jwt.getClaim("username"));
|
||||
}
|
||||
|
||||
@POST
|
||||
public void linkCompany(@QueryParam("user") Long userId, @QueryParam("company") Long companyId) {
|
||||
System.out.println(userId);
|
||||
System.out.println(companyId);
|
||||
this.companyService.linkCompany(userId, companyId);
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import io.quarkus.scheduler.Scheduled;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import nl.veenm.paypoint.domain.AppUser;
|
||||
import nl.veenm.paypoint.domain.Appointment;
|
||||
import nl.veenm.paypoint.domain.Company;
|
||||
import nl.veenm.paypoint.repository.AppointmentRepository;
|
||||
import nl.veenm.paypoint.repository.CompanyRepository;
|
||||
import nl.veenm.paypoint.repository.UserRepository;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -18,6 +20,9 @@ public class AppointmentService {
|
||||
@Inject
|
||||
AppointmentRepository appointmentRepository;
|
||||
|
||||
@Inject
|
||||
UserRepository userRepository;
|
||||
|
||||
@Inject
|
||||
CompanyRepository companyRepository;
|
||||
|
||||
@@ -34,23 +39,25 @@ public class AppointmentService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Appointment add(Appointment appointment, Long companyId) {
|
||||
public Appointment add(Appointment appointment, Long companyId, String username) {
|
||||
Company company = companyRepository.findById(companyId);
|
||||
AppUser user = userRepository.findByUsername(username);
|
||||
appointment.setCompany(company);
|
||||
appointmentRepository.persist(appointment);
|
||||
emailService.stuurBevestiging(appointment);
|
||||
emailService.stuurBevestiging(appointment, user);
|
||||
return appointment;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<Appointment> getAppointmentsByDate(String start, Long companyId) {
|
||||
public List<Appointment> getAppointmentsByDate(String start, String username) {
|
||||
LocalDate date = LocalDate.parse(start);
|
||||
Company company = companyRepository.findById(companyId);
|
||||
AppUser user = userRepository.findByUsername(username);
|
||||
|
||||
|
||||
LocalDateTime startOfDay = date.atStartOfDay();
|
||||
LocalDateTime endOfDay = date.atTime(23, 59, 59);
|
||||
|
||||
return appointmentRepository.find("startDate BETWEEN ?1 AND ?2 AND company = ?3", startOfDay, endOfDay, company).list();
|
||||
return appointmentRepository.findAppointmentsForCompanies(user.getCompanies(), startOfDay, endOfDay);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -93,9 +100,7 @@ public class AppointmentService {
|
||||
|
||||
List<Appointment> allAppointments = appointmentRepository.find("date BETWEEN ?1 AND ?2", startOfDay, endOfDay).list();
|
||||
|
||||
allAppointments.forEach(appointment -> {
|
||||
emailService.stuurHerinnering(appointment);
|
||||
});
|
||||
allAppointments.forEach(emailService::stuurHerinnering);
|
||||
}
|
||||
|
||||
public Appointment getMostRecentByUserId(Long userId) {
|
||||
|
||||
40
src/main/java/nl/veenm/paypoint/service/CompanyService.java
Normal file
40
src/main/java/nl/veenm/paypoint/service/CompanyService.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package nl.veenm.paypoint.service;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import nl.veenm.paypoint.domain.AppUser;
|
||||
import nl.veenm.paypoint.domain.Company;
|
||||
import nl.veenm.paypoint.repository.CompanyRepository;
|
||||
import nl.veenm.paypoint.repository.UserRepository;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ApplicationScoped
|
||||
public class CompanyService {
|
||||
@Inject
|
||||
CompanyRepository companyRepository;
|
||||
|
||||
@Inject
|
||||
UserRepository userRepository;
|
||||
|
||||
public Set<Company> getCompanies(String username) {
|
||||
AppUser user = this.userRepository.findByUsername(username);
|
||||
return user.getCompanies();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void linkCompany(Long userId, Long companyId) {
|
||||
AppUser user = this.userRepository.findById(userId);
|
||||
Company company = this.companyRepository.findById(companyId);
|
||||
|
||||
System.out.println(user.getCompanies());
|
||||
user.getCompanies().add(company);
|
||||
company.getUsers().add(user);
|
||||
|
||||
System.out.println(user.getCompanies());
|
||||
|
||||
userRepository.persist(user);
|
||||
companyRepository.persist(company);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package nl.veenm.paypoint.service;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import nl.veenm.paypoint.domain.Company;
|
||||
import nl.veenm.paypoint.domain.Customer;
|
||||
import nl.veenm.paypoint.repository.CustomerRepository;
|
||||
|
||||
@@ -32,4 +33,8 @@ public class CustomerService {
|
||||
customerRepository.persist(customer);
|
||||
return customer;
|
||||
}
|
||||
|
||||
public List<Company> getCompanies() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package nl.veenm.paypoint.service;
|
||||
import io.quarkus.mailer.Mail;
|
||||
import io.quarkus.mailer.Mailer;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import nl.veenm.paypoint.domain.AppUser;
|
||||
import nl.veenm.paypoint.domain.Appointment;
|
||||
import nl.veenm.paypoint.domain.Company;
|
||||
import nl.veenm.paypoint.helper.EmailHelper;
|
||||
@@ -20,7 +21,7 @@ public class EmailService {
|
||||
this.mailer = mailer;
|
||||
}
|
||||
|
||||
public void stuurBevestiging(Appointment appointment) {
|
||||
public void stuurBevestiging(Appointment appointment, AppUser user) {
|
||||
Company company = appointment.getCompany();
|
||||
String location = String.format("<br>%s<br>%s %s", company.getAddress(), company.getPostal_code(), company.getCity());
|
||||
String imageUrl = appointment.getCompany().getImg_href();
|
||||
@@ -98,14 +99,14 @@ public class EmailService {
|
||||
</div>
|
||||
<div class="footer">
|
||||
<img src="%s" alt="Afspraak bevestiging" class="image">
|
||||
<h4>Met vriendelijke groet,<br>Danielle<br>Hairstyling By Daan</h4>
|
||||
<h4>Met vriendelijke groet,<br>%s<br>%s</h4>
|
||||
<p>© 2025 PayPoint. Alle rechten voorbehouden.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
""".formatted(appointment.getCustomer().getFirstName(), formattedDate, formattedTime,
|
||||
location, imageUrl);
|
||||
location, imageUrl, user.getFirstName(), appointment.getCompany().getName());
|
||||
|
||||
String subject = String.format(" Afspraak bevestigd: %s", formattedDate);
|
||||
String recipient = appointment.getCustomer().getEmail();
|
||||
@@ -113,11 +114,12 @@ public class EmailService {
|
||||
date = date.withHour(appointment.getStartHour()).withMinute(appointment.getStartMinute());
|
||||
|
||||
String dtStamp = date.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"));
|
||||
String sender = appointment.getCompany().getName() + " <paypoint@melvanveen.nl>";
|
||||
|
||||
mailer.send(Mail.withHtml(recipient, subject, emailBody)
|
||||
.setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>")
|
||||
.setFrom(sender)
|
||||
.setReplyTo(company.getEmail())
|
||||
.addAttachment("afspraak.ics", EmailHelper.getIcs(dtStamp, date.toLocalDate(), formattedTime, formattedEndTime, location).getBytes(), "text/calendar"));
|
||||
.addAttachment("afspraak.ics", EmailHelper.getIcs(dtStamp, date.toLocalDate(), formattedTime, formattedEndTime, location, appointment).getBytes(), "text/calendar"));
|
||||
}
|
||||
|
||||
public void stuurVerwijdering(Appointment appointment) {
|
||||
|
||||
@@ -18,7 +18,6 @@ public class TokenService {
|
||||
.claim("lastName", appUser.getLastName())
|
||||
.claim("email", appUser.getEmail())
|
||||
.claim("groups", appUser.getRole())
|
||||
.claim("company_id", appUser.getCompany().getId())
|
||||
.sign();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user