initial commit

This commit is contained in:
2025-03-04 21:21:35 +01:00
commit 882bc0f26b
34 changed files with 2442 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
package nl.veenm.paypoint.service;
import io.quarkus.scheduler.Scheduled;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import nl.veenm.paypoint.domain.Appointment;
import nl.veenm.paypoint.repository.AppointmentRepository;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@ApplicationScoped
public class AppointmentService {
@Inject
AppointmentRepository appointmentRepository;
@Inject
EmailService emailService;
private List<Appointment> appointments;
public AppointmentService() {
LocalDateTime now = LocalDateTime.now();
appointments = new ArrayList<>();
appointments.add(new Appointment(1L, "Knippen Mel", "", now, 12, 0, 13, 0, 60));
appointments.add(new Appointment(2L, "Knippen Mel", "", now, 14, 0, 15, 0, 60));
}
@Transactional
public List<Appointment> getAllAppointments() {
return appointmentRepository.listAll();
}
@Transactional
public void add(Appointment appointment) {
// appointment.setStartDate(appointment.getStartDate().plusDays(1));
appointmentRepository.persist(appointment);
emailService.stuurBevestiging(appointment);
}
@Transactional
public List<Appointment> getAppointmentsByDate(String start) {
LocalDate date = LocalDate.parse(start);
LocalDateTime startOfDay = date.atStartOfDay(); // 00:00:00
LocalDateTime endOfDay = date.atTime(23, 59, 59); // 23:59:59
return appointmentRepository.find("startDate BETWEEN ?1 AND ?2", startOfDay, endOfDay).list();
}
@Transactional
public void delete(Long id) {
emailService.stuurVerwijdering(appointmentRepository.findById(id));
appointmentRepository.deleteById(id);
}
@Transactional
public void update(Appointment appointment) {
Appointment appointmentToUpdate = appointmentRepository.findById(appointment.getId());
appointmentToUpdate.setTitle(appointment.getTitle());
appointmentToUpdate.setStartDate(appointment.getStartDate());
appointmentToUpdate.setDescription(appointment.getDescription());
appointmentToUpdate.setStartHour(appointment.getStartHour());
appointmentToUpdate.setStartMinute(appointment.getStartMinute());
appointmentToUpdate.setEndHour(appointment.getEndHour());
appointmentToUpdate.setEndMinute(appointment.getEndMinute());
appointmentToUpdate.setCustomer(appointment.getCustomer());
appointmentToUpdate.setDurationInMinutes(appointment.getDurationInMinutes());
appointmentRepository.persist(appointmentToUpdate);
emailService.stuurBewerking(appointmentToUpdate);
}
@Transactional
public Appointment getAppointment(Long id) {
return appointmentRepository.findById(id);
}
@Transactional
@Scheduled(cron = "0 0 0 * * ?")
public void sendReminder() {
LocalDate date = LocalDate.now();
date = date.plusDays(1);
LocalDateTime startOfDay = date.atStartOfDay(); // 00:00:00
LocalDateTime endOfDay = date.atTime(23, 59, 59); // 23:59:59
List<Appointment> allAppointments = appointmentRepository.find("date BETWEEN ?1 AND ?2", startOfDay, endOfDay).list();
allAppointments.forEach(appointment -> {
emailService.stuurHerinnering(appointment);
});
}
public Appointment getMostRecentByUserId(Long userId) {
return appointmentRepository.findMostRecentByUserId(userId).orElse(null);
}
}

View File

@@ -0,0 +1,34 @@
package nl.veenm.paypoint.service;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import nl.veenm.paypoint.domain.Customer;
import nl.veenm.paypoint.repository.CustomerRepository;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@ApplicationScoped
public class CustomerService {
@Inject
CustomerRepository customerRepository;
public CustomerService() {
}
@Transactional
public List<Customer> getCustomers() {
List<Customer> customers = customerRepository.listAll();
return customers.stream()
.sorted(Comparator.comparing(Customer::getFirstName))
.collect(Collectors.toList());
}
@Transactional
public void addCustomer(Customer customer) {
customerRepository.persist(customer);
}
}

View File

@@ -0,0 +1,381 @@
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.Appointment;
import nl.veenm.paypoint.helper.EmailHelper;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
@ApplicationScoped
public class EmailService {
private final Mailer mailer;
public EmailService(Mailer mailer) {
this.mailer = mailer;
}
public void stuurBevestiging(Appointment appointment) {
String location = "<br>Groenestraat 29<br>6681DW Bemmel";
String imageUrl = "https://hairstylingbydaan.nl/assets/img/Logo.png";
String formattedDate = appointment.getStartDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.forLanguageTag("nl")));
String formattedHour = String.valueOf(appointment.getStartHour()).length() == 1 ? "0" + appointment.getStartHour() : String.valueOf(appointment.getStartHour());
String formattedMinute = String.valueOf(appointment.getStartMinute()).length() == 1 ? "0" + appointment.getStartMinute() : String.valueOf(appointment.getStartMinute());
String formattedTime = formattedHour + ":" + formattedMinute;
String formattedEndHour = String.valueOf(appointment.getEndHour()).length() == 1 ? "0" + appointment.getEndHour() : String.valueOf(appointment.getEndHour());
String formattedEndMinute = String.valueOf(appointment.getEndMinute()).length() == 1 ? "0" + appointment.getEndMinute() : String.valueOf(appointment.getEndMinute());
String formattedEndTime = formattedEndHour + ":" + formattedEndMinute;
// Bouw de HTML-inhoud van de e-mail
String emailBody = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Afspraakbevestiging</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 80%%;
max-width: 600px;
background-color: #ffffff;
margin: 20px auto;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
.header {
background-color: #3c3c3c;
color: white;
text-align: center;
padding: 15px;
font-size: 20px;
font-weight: bold;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.content {
padding: 20px;
text-align: center;
font-size: 16px;
color: #333;
}
.footer {
text-align: center;
font-size: 12px;
color: #666;
margin-top: 20px;
}
.image {
height: 128px;
width: auto;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">Bevestiging van uw afspraak</div>
<div class="content">
<h4>Beste %s,</h4>
<h4>Uw afspraak is succesvol ingepland!</h4>
<h4><strong>Datum:</strong> %s<br>
<strong>Tijd:</strong> %s<br><br>
<strong>Locatie:</strong> %s</h4>
</div>
<div class="footer">
<img src="%s" alt="Afspraak bevestiging" class="image">
<h4>Met vriendelijke groet,<br>Danielle<br>Hairstyling By Daan</h4>
<p>&copy; 2025 PayPoint. Alle rechten voorbehouden.</p>
</div>
</div>
</body>
</html>
""".formatted(appointment.getCustomer().getFirstName(), formattedDate, formattedTime,
location, imageUrl);
String subject = String.format(" Afspraak bevestigd: %s", formattedDate);
String recipient = appointment.getCustomer().getEmail();
LocalDateTime date = appointment.getStartDate();
date = date.withHour(appointment.getStartHour()).withMinute(appointment.getStartMinute());
String dtStamp = date.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"));
mailer.send(Mail.withHtml(recipient, subject, emailBody)
.setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>")
.addAttachment("afspraak.ics", EmailHelper.getIcs(dtStamp, date.toLocalDate(), formattedTime, formattedEndTime, location).getBytes(), "text/calendar"));
}
public void stuurVerwijdering(Appointment appointment) {
String imageUrl = "https://hairstylingbydaan.nl/assets/img/Logo.png";
String formattedDate = appointment.getStartDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.forLanguageTag("nl")));
// Bouw de HTML-inhoud van de e-mail
String emailBody = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Afspraakbevestiging</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 80%%;
max-width: 600px;
background-color: #ffffff;
margin: 20px auto;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
.header {
background-color: #3c3c3c;
color: white;
text-align: center;
padding: 15px;
font-size: 20px;
font-weight: bold;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.content {
padding: 20px;
text-align: center;
font-size: 16px;
color: #333;
}
.footer {
text-align: center;
font-size: 12px;
color: #666;
margin-top: 20px;
}
.image {
height: 128px;
width: auto;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">Annulering van uw afspraak</div>
<div class="content">
<h4>Beste %s,</h4>
<h4>Uw afspraak op %s is geannuleerd.</h4>
</div>
<div class="footer">
<img src="%s" alt="Afspraak bevestiging" class="image">
<h4>Met vriendelijke groet,<br>Danielle<br>Hairstyling By Daan</h4>
<p>&copy; 2025 PayPoint. Alle rechten voorbehouden.</p>
</div>
</div>
</body>
</html>
""".formatted(appointment.getCustomer().getFirstName(), formattedDate, imageUrl);
String subject = String.format(" Afspraak geannuleerd: %s", formattedDate);
String recipient = appointment.getCustomer().getEmail();
mailer.send(Mail.withHtml(recipient, subject, emailBody).setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>"));
}
public void stuurBewerking(Appointment appointment) {
String location = "<br>Groenestraat 29<br>6681DW Bemmel";
String imageUrl = "https://hairstylingbydaan.nl/assets/img/Logo.png";
String formattedDate = appointment.getStartDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.forLanguageTag("nl")));
String formattedTime = String.format("%s:%s", appointment.getStartHour(), String.valueOf(appointment.getStartMinute()).length() == 1 ? "0" + appointment.getStartMinute() : appointment.getStartMinute());
// Bouw de HTML-inhoud van de e-mail
String emailBody = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Afspraakbevestiging</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 80%%;
max-width: 600px;
background-color: #ffffff;
margin: 20px auto;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
.header {
background-color: #3c3c3c;
color: white;
text-align: center;
padding: 15px;
font-size: 20px;
font-weight: bold;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.content {
padding: 20px;
text-align: center;
font-size: 16px;
color: #333;
}
.footer {
text-align: center;
font-size: 12px;
color: #666;
margin-top: 20px;
}
.image {
height: 128px;
width: auto;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">Wijziging van uw afspraak</div>
<div class="content">
<h4>Beste %s,</h4>
<h4>Uw afspraak op %s is gewijzigd.</h4>
<h4><strong>Datum:</strong> %s<br>
<strong>Tijd:</strong> %s<br><br>
<strong>Locatie:</strong> %s</h4>
</div>
<div class="footer">
<img src="%s" alt="Afspraak bevestiging" class="image">
<h4>Met vriendelijke groet,<br>Danielle<br>Hairstyling By Daan</h4>
<p>&copy; 2025 PayPoint. Alle rechten voorbehouden.</p>
</div>
</div>
</body>
</html>
""".formatted(appointment.getCustomer().getFirstName(), formattedDate, formattedDate, formattedTime,
location, imageUrl);
String subject = String.format(" Afspraak gewijzigd: %s", formattedDate);
String recipient = appointment.getCustomer().getEmail();
mailer.send(Mail.withHtml(recipient, subject, emailBody).setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>"));
}
public void stuurHerinnering(Appointment appointment) {
String location = "<br>Groenestraat 29<br>6681DW Bemmel";
String imageUrl = "https://hairstylingbydaan.nl/assets/img/Logo.png";
String formattedDate = appointment.getStartDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.forLanguageTag("nl")));
String formattedTime = String.format("%s:%s", appointment.getStartHour(), String.valueOf(appointment.getStartMinute()).length() == 1 ? "0" + appointment.getStartMinute() : appointment.getStartMinute());
// Bouw de HTML-inhoud van de e-mail
String emailBody = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Afspraakbevestiging</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
.container {
width: 80%%;
max-width: 600px;
background-color: #ffffff;
margin: 20px auto;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
.header {
background-color: #3c3c3c;
color: white;
text-align: center;
padding: 15px;
font-size: 20px;
font-weight: bold;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.content {
padding: 20px;
text-align: center;
font-size: 16px;
color: #333;
}
.footer {
text-align: center;
font-size: 12px;
color: #666;
margin-top: 20px;
}
.image {
height: 128px;
width: auto;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">Herinnering van uw afspraak</div>
<div class="content">
<h4>Beste %s,</h4>
<h4>U heeft morgen een afspraak.</h4>
<h4><strong>Datum:</strong> %s<br>
<strong>Tijd:</strong> %s<br><br>
<strong>Locatie:</strong> %s</h4>
</div>
<div class="footer">
<img src="%s" alt="Afspraak bevestiging" class="image">
<h4>Met vriendelijke groet,<br>Danielle<br>Hairstyling By Daan</h4>
<p>&copy; 2025 PayPoint. Alle rechten voorbehouden.</p>
</div>
</div>
</body>
</html>
""".formatted(appointment.getCustomer().getFirstName(), formattedDate, formattedTime,
location, imageUrl);
String subject = String.format("Herinnering afspraak: %s", formattedDate);
String recipient = appointment.getCustomer().getEmail();
mailer.send(Mail.withHtml(recipient, subject, emailBody).setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>"));
}
}

View File

@@ -0,0 +1,11 @@
package nl.veenm.paypoint.service;
import at.favre.lib.crypto.bcrypt.BCrypt;
public class PasswordService {
public static String hashPassword(String plainPassword) {
return BCrypt.withDefaults().hashToString(12, plainPassword.toCharArray());
}
}

View File

@@ -0,0 +1,24 @@
package nl.veenm.paypoint.service;
import io.smallrye.jwt.build.Jwt;
import jakarta.enterprise.context.ApplicationScoped;
import nl.veenm.paypoint.domain.AppUser;
import java.time.Duration;
@ApplicationScoped
public class TokenService {
public String generateToken(AppUser appUser) {
return Jwt.issuer("PayPoint")
.subject(appUser.getUsername())
.expiresIn(Duration.ofHours(1))
.claim("username", appUser.getUsername())
.claim("firstName", appUser.getFirstName())
.claim("lastName", appUser.getLastName())
.claim("email", appUser.getEmail())
.claim("groups", appUser.getRole())
.sign();
}
}

View File

@@ -0,0 +1,33 @@
package nl.veenm.paypoint.service;
import at.favre.lib.crypto.bcrypt.BCrypt;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import nl.veenm.paypoint.domain.AppUser;
import nl.veenm.paypoint.repository.UserRepository;
@ApplicationScoped
public class UserService {
@Inject
UserRepository userRepository;
@Transactional
public void registerUser(AppUser appUser) {
appUser.setPassword(PasswordService.hashPassword(appUser.getPassword()));
userRepository.persist(appUser);
}
public AppUser authenticate(String username, String password) {
AppUser user = userRepository.findByUsername(username);
if (user == null) {
return null;
}
if (BCrypt.verifyer().verify(password.toCharArray(), user.getPassword()).verified) {
return user;
}
return null;
}
}