Compare commits
18 Commits
adfe4dcbc2
...
feature/we
| Author | SHA1 | Date | |
|---|---|---|---|
| dc9d5ff8eb | |||
| ebce9820d2 | |||
| bb9b5a93f9 | |||
| 1089b0d74c | |||
| 608785088c | |||
| df85f7da5c | |||
| fa3067892b | |||
| 274737b4d7 | |||
| 7688a60f5a | |||
| 51e4d55e37 | |||
| 5d1b52b444 | |||
| 6571c9d62f | |||
| 479d845b29 | |||
| fae54422e3 | |||
| a1d7bc0f19 | |||
| 40f983980d | |||
| 2a50edc41d | |||
| 70f6b0c7b2 |
186
.github/workflows/deploy-docker-to-ont.yml
vendored
Normal file
186
.github/workflows/deploy-docker-to-ont.yml
vendored
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
name: Docker Image CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- feature/**
|
||||||
|
tags:
|
||||||
|
- "docker-build-*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Stap 1: Code ophalen
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Stap 2: Versienummer ophalen uit pom.xml en opslaan als artifact
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'temurin'
|
||||||
|
|
||||||
|
- name: Setup Maven + Java
|
||||||
|
uses: s4u/setup-maven-action@v1.6.0
|
||||||
|
with:
|
||||||
|
java-version: '21'
|
||||||
|
maven-version: '3.9.5'
|
||||||
|
|
||||||
|
- name: Extract Quarkus version from pom.xml
|
||||||
|
run: |
|
||||||
|
VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
|
||||||
|
echo $VERSION > version.txt
|
||||||
|
|
||||||
|
- name: Inject private key into resources
|
||||||
|
run: |
|
||||||
|
mkdir -p src/main/resources
|
||||||
|
echo "${{ secrets.PRIVATE_KEY }}" > src/main/resources/privateKey.pem
|
||||||
|
chmod 600 src/main/resources/privateKey.pem
|
||||||
|
|
||||||
|
- name: Decode keystore
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > src/main/resources/keystore.jks
|
||||||
|
chmod 600 src/main/resources/keystore.jks
|
||||||
|
|
||||||
|
- name: Inject public key into resources
|
||||||
|
run: |
|
||||||
|
mkdir -p src/main/resources
|
||||||
|
echo "${{ secrets.PUBLIC_KEY }}" > src/main/resources/publicKey.pem
|
||||||
|
chmod 600 src/main/resources/publicKey.pem
|
||||||
|
|
||||||
|
- name: Save version as artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: version
|
||||||
|
path: version.txt
|
||||||
|
|
||||||
|
# Stap 3: Notify Mattermost via Bot (Build gestart)
|
||||||
|
- name: Notify Mattermost via Bot
|
||||||
|
env:
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
BRANCH: ${{ gitea.ref }}
|
||||||
|
MATTERMOST_BOT_TOKEN: ${{ secrets.MATTERMOST_BOT_TOKEN }}
|
||||||
|
run: |
|
||||||
|
curl --fail -X POST -H "Authorization: Bearer $MATTERMOST_BOT_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"channel_id": "wgcfotx7x3bipcwchzn45tuxxr",
|
||||||
|
"message": "🚀 *Build gestart!* Een nieuwe build is begonnen voor de repository *'"$REPO"'* op branch *'"$BRANCH"'*."
|
||||||
|
}' \
|
||||||
|
https://mattermost.melvanveen.nl/api/v4/posts
|
||||||
|
|
||||||
|
# Stap 4: Inloggen bij Docker Hub
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
# Stap 5: Quarkus JAR bouwen (via Maven) en Docker-image bouwen
|
||||||
|
- name: Build the Quarkus JAR and Docker image
|
||||||
|
run: |
|
||||||
|
VERSION=$(cat version.txt)
|
||||||
|
mvn clean package -DskipTests -Dquarkus.profile=test
|
||||||
|
docker buildx build . --file Dockerfile-tst --tag veenm/paypoint-backend-jvm:$VERSION --platform linux/amd64
|
||||||
|
|
||||||
|
# Stap 6: Docker-image pushen naar Docker Hub (huidige versie tag)
|
||||||
|
- name: Push the Docker image (version)
|
||||||
|
run: |
|
||||||
|
VERSION=$(cat version.txt)
|
||||||
|
docker push veenm/paypoint-backend-jvm:$VERSION
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build-and-push
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Stap 1: Artifact ophalen
|
||||||
|
- name: Download version artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: version
|
||||||
|
|
||||||
|
# Stap 2: Lees versie uit het artifact
|
||||||
|
- name: Read version
|
||||||
|
id: read_version
|
||||||
|
run: echo "VERSION=$(cat version.txt)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: SSH into Alpine and update Docker container
|
||||||
|
uses: appleboy/ssh-action@v0.1.10
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.ALPINE_HOST_ONT }}
|
||||||
|
username: root
|
||||||
|
key: ${{ secrets.ALPINE_SSH_KEY }}
|
||||||
|
envs: VERSION,DB_HOST,DB_PORT,DB_USERNAME,DB_PASSWORD,CORS_ORIGINS,MAILER_FROM,MAILER_HOST,MAILER_PORT,MAILER_USERNAME,MAILER_PASSWORD
|
||||||
|
script: |
|
||||||
|
echo "Gekozen versie: $VERSION"
|
||||||
|
|
||||||
|
docker stop paypoint-backend || true
|
||||||
|
docker rm paypoint-backend || true
|
||||||
|
|
||||||
|
docker pull veenm/paypoint-backend-jvm:$VERSION
|
||||||
|
|
||||||
|
docker run -d --name paypoint-backend --restart unless-stopped -p 15001:8080 \
|
||||||
|
-e DB_HOST="$DB_HOST" \
|
||||||
|
-e DB_PORT="$DB_PORT" \
|
||||||
|
-e DB_USERNAME="$DB_USERNAME" \
|
||||||
|
-e DB_PASSWORD="$DB_PASSWORD" \
|
||||||
|
-e CORS_ORIGINS="$CORS_ORIGINS" \
|
||||||
|
-e MAILER_FROM="$MAILER_FROM" \
|
||||||
|
-e MAILER_HOST="$MAILER_HOST" \
|
||||||
|
-e MAILER_PORT="$MAILER_PORT" \
|
||||||
|
-e MAILER_USERNAME="$MAILER_USERNAME" \
|
||||||
|
-e MAILER_PASSWORD="$MAILER_PASSWORD" \
|
||||||
|
veenm/paypoint-backend-jvm:$VERSION
|
||||||
|
|
||||||
|
docker image prune -f
|
||||||
|
env:
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
|
DB_HOST: ${{ secrets.ALPINE_HOST_ONT }}
|
||||||
|
DB_PORT: ${{ secrets.DB_PORT_TEST }}
|
||||||
|
DB_USERNAME: ${{ secrets.DB_USERNAME_TEST }}
|
||||||
|
DB_PASSWORD: ${{ secrets.DB_PASSWORD_TEST }}
|
||||||
|
CORS_ORIGINS: ${{ secrets.CORS_ORIGINS_TEST }}
|
||||||
|
MAILER_FROM: ${{ secrets.MAILER_FROM }}
|
||||||
|
MAILER_HOST: ${{ secrets.MAILER_HOST }}
|
||||||
|
MAILER_PORT: ${{ secrets.MAILER_PORT }}
|
||||||
|
MAILER_USERNAME: ${{ secrets.MAILER_USERNAME }}
|
||||||
|
MAILER_PASSWORD: ${{ secrets.MAILER_PASSWORD }}
|
||||||
|
|
||||||
|
|
||||||
|
# Stap 4: Notify Mattermost via Bot (Build is geslaagd)
|
||||||
|
- name: Notify Mattermost via Bot
|
||||||
|
env:
|
||||||
|
MATTERMOST_BOT_TOKEN: ${{ secrets.MATTERMOST_BOT_TOKEN }}
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
|
run: |
|
||||||
|
curl --fail -X POST -H "Authorization: Bearer $MATTERMOST_BOT_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"channel_id": "wgcfotx7x3bipcwchzn45tuxxr",
|
||||||
|
"message": "*Build is geslaagd!* Versie '"$VERSION"' van de backend staat klaar op ontwikkel!"
|
||||||
|
}' \
|
||||||
|
https://mattermost.melvanveen.nl/api/v4/posts
|
||||||
|
|
||||||
|
notify-failure:
|
||||||
|
needs: [ build-and-push, deploy ]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: failure()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Notify Mattermost via Bot on failure
|
||||||
|
env:
|
||||||
|
MATTERMOST_BOT_TOKEN: ${{ secrets.MATTERMOST_BOT_TOKEN }}
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
BRANCH: ${{ gitea.ref }}
|
||||||
|
run: |
|
||||||
|
curl --fail -X POST -H "Authorization: Bearer $MATTERMOST_BOT_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"channel_id": "wgcfotx7x3bipcwchzn45tuxxr",
|
||||||
|
"message": "❌ *Build gefaald!* De pipeline is stukgelopen voor *'"$REPO"'* op branch *'"$BRANCH"'*."
|
||||||
|
}' \
|
||||||
|
https://mattermost.melvanveen.nl/api/v4/posts
|
||||||
186
.github/workflows/deploy-docker-to-tst.yml
vendored
Normal file
186
.github/workflows/deploy-docker-to-tst.yml
vendored
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
name: Docker Image CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
tags:
|
||||||
|
- "docker-build-*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Stap 1: Code ophalen
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Stap 2: Versienummer ophalen uit pom.xml en opslaan als artifact
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'temurin'
|
||||||
|
|
||||||
|
- name: Setup Maven + Java
|
||||||
|
uses: s4u/setup-maven-action@v1.6.0
|
||||||
|
with:
|
||||||
|
java-version: '21'
|
||||||
|
maven-version: '3.9.5'
|
||||||
|
|
||||||
|
- name: Extract Quarkus version from pom.xml
|
||||||
|
run: |
|
||||||
|
VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
|
||||||
|
echo $VERSION > version.txt
|
||||||
|
|
||||||
|
- name: Inject private key into resources
|
||||||
|
run: |
|
||||||
|
mkdir -p src/main/resources
|
||||||
|
echo "${{ secrets.PRIVATE_KEY }}" > src/main/resources/privateKey.pem
|
||||||
|
chmod 600 src/main/resources/privateKey.pem
|
||||||
|
|
||||||
|
- name: Decode keystore
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > src/main/resources/keystore.jks
|
||||||
|
chmod 600 src/main/resources/keystore.jks
|
||||||
|
|
||||||
|
- name: Inject public key into resources
|
||||||
|
run: |
|
||||||
|
mkdir -p src/main/resources
|
||||||
|
echo "${{ secrets.PUBLIC_KEY }}" > src/main/resources/publicKey.pem
|
||||||
|
chmod 600 src/main/resources/publicKey.pem
|
||||||
|
|
||||||
|
- name: Save version as artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: version
|
||||||
|
path: version.txt
|
||||||
|
|
||||||
|
# Stap 3: Notify Mattermost via Bot (Build gestart)
|
||||||
|
- name: Notify Mattermost via Bot
|
||||||
|
env:
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
BRANCH: ${{ gitea.ref }}
|
||||||
|
MATTERMOST_BOT_TOKEN: ${{ secrets.MATTERMOST_BOT_TOKEN }}
|
||||||
|
run: |
|
||||||
|
curl --fail -X POST -H "Authorization: Bearer $MATTERMOST_BOT_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"channel_id": "9a8obynkd7rctk6qf8rfe6oppy",
|
||||||
|
"message": "@all 🚀 *Build gestart!* Een nieuwe build is begonnen voor de repository *'"$REPO"'* op branch *'"$BRANCH"'*."
|
||||||
|
}' \
|
||||||
|
https://mattermost.melvanveen.nl/api/v4/posts
|
||||||
|
|
||||||
|
# Stap 4: Inloggen bij Docker Hub
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
# Stap 5: Quarkus JAR bouwen (via Maven) en Docker-image bouwen
|
||||||
|
- name: Build the Quarkus JAR and Docker image
|
||||||
|
run: |
|
||||||
|
VERSION=$(cat version.txt)
|
||||||
|
mvn clean package -DskipTests -Dquarkus.profile=test
|
||||||
|
docker buildx build . --file Dockerfile-tst --tag veenm/paypoint-backend-jvm:$VERSION --platform linux/amd64
|
||||||
|
|
||||||
|
# Stap 6: Docker-image pushen naar Docker Hub (huidige versie tag)
|
||||||
|
- name: Push the Docker image (version)
|
||||||
|
run: |
|
||||||
|
VERSION=$(cat version.txt)
|
||||||
|
docker push veenm/paypoint-backend-jvm:$VERSION
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build-and-push
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Stap 1: Artifact ophalen
|
||||||
|
- name: Download version artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: version
|
||||||
|
|
||||||
|
# Stap 2: Lees versie uit het artifact
|
||||||
|
- name: Read version
|
||||||
|
id: read_version
|
||||||
|
run: echo "VERSION=$(cat version.txt)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: SSH into Alpine and update Docker container
|
||||||
|
uses: appleboy/ssh-action@v0.1.10
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.ALPINE_HOST }}
|
||||||
|
username: ${{ secrets.ALPINE_USER }}
|
||||||
|
password: ${{ secrets.ALPINE_PASSWORD }}
|
||||||
|
envs: VERSION,DB_HOST,DB_PORT,DB_USERNAME,DB_PASSWORD,CORS_ORIGINS,MAILER_FROM,MAILER_HOST,MAILER_PORT,MAILER_USERNAME,MAILER_PASSWORD
|
||||||
|
script: |
|
||||||
|
echo "Gekozen versie: $VERSION"
|
||||||
|
|
||||||
|
docker stop paypoint-backend || true
|
||||||
|
docker rm paypoint-backend || true
|
||||||
|
|
||||||
|
docker pull veenm/paypoint-backend-jvm:$VERSION
|
||||||
|
|
||||||
|
docker run -d --name paypoint-backend --restart unless-stopped -p 15001:8080 \
|
||||||
|
-e DB_HOST="$DB_HOST" \
|
||||||
|
-e DB_PORT="$DB_PORT" \
|
||||||
|
-e DB_USERNAME="$DB_USERNAME" \
|
||||||
|
-e DB_PASSWORD="$DB_PASSWORD" \
|
||||||
|
-e CORS_ORIGINS="$CORS_ORIGINS" \
|
||||||
|
-e MAILER_FROM="$MAILER_FROM" \
|
||||||
|
-e MAILER_HOST="$MAILER_HOST" \
|
||||||
|
-e MAILER_PORT="$MAILER_PORT" \
|
||||||
|
-e MAILER_USERNAME="$MAILER_USERNAME" \
|
||||||
|
-e MAILER_PASSWORD="$MAILER_PASSWORD" \
|
||||||
|
veenm/paypoint-backend-jvm:$VERSION
|
||||||
|
|
||||||
|
docker image prune -f
|
||||||
|
env:
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
|
DB_HOST: ${{ secrets.ALPINE_HOST }}
|
||||||
|
DB_PORT: ${{ secrets.DB_PORT_TEST }}
|
||||||
|
DB_USERNAME: ${{ secrets.DB_USERNAME_TEST }}
|
||||||
|
DB_PASSWORD: ${{ secrets.DB_PASSWORD_TEST }}
|
||||||
|
CORS_ORIGINS: ${{ secrets.CORS_ORIGINS_TEST }}
|
||||||
|
MAILER_FROM: ${{ secrets.MAILER_FROM }}
|
||||||
|
MAILER_HOST: ${{ secrets.MAILER_HOST }}
|
||||||
|
MAILER_PORT: ${{ secrets.MAILER_PORT }}
|
||||||
|
MAILER_USERNAME: ${{ secrets.MAILER_USERNAME }}
|
||||||
|
MAILER_PASSWORD: ${{ secrets.MAILER_PASSWORD }}
|
||||||
|
|
||||||
|
|
||||||
|
# Stap 4: Notify Mattermost via Bot (Build is geslaagd)
|
||||||
|
- name: Notify Mattermost via Bot
|
||||||
|
env:
|
||||||
|
MATTERMOST_BOT_TOKEN: ${{ secrets.MATTERMOST_BOT_TOKEN }}
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
|
run: |
|
||||||
|
curl --fail -X POST -H "Authorization: Bearer $MATTERMOST_BOT_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"channel_id": "9a8obynkd7rctk6qf8rfe6oppy",
|
||||||
|
"message": "@all ✅ *Build is geslaagd!* Versie '"$VERSION"' staat klaar op https://test-paypoint.melvanveen.nl"
|
||||||
|
}' \
|
||||||
|
https://mattermost.melvanveen.nl/api/v4/posts
|
||||||
|
|
||||||
|
notify-failure:
|
||||||
|
needs: [ build-and-push, deploy ]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: failure()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Notify Mattermost via Bot on failure
|
||||||
|
env:
|
||||||
|
MATTERMOST_BOT_TOKEN: ${{ secrets.MATTERMOST_BOT_TOKEN }}
|
||||||
|
REPO: ${{ gitea.repository }}
|
||||||
|
BRANCH: ${{ gitea.ref }}
|
||||||
|
run: |
|
||||||
|
curl --fail -X POST -H "Authorization: Bearer $MATTERMOST_BOT_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{
|
||||||
|
"channel_id": "9a8obynkd7rctk6qf8rfe6oppy",
|
||||||
|
"message": "@all ❌ *Build gefaald!* De pipeline is stukgelopen voor *'"$REPO"'* op branch *'"$BRANCH"'*."
|
||||||
|
}' \
|
||||||
|
https://mattermost.melvanveen.nl/api/v4/posts
|
||||||
98
Dockerfile-tst
Normal file
98
Dockerfile-tst
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
####
|
||||||
|
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||||
|
#
|
||||||
|
# Before building the container image run:
|
||||||
|
#
|
||||||
|
# ./mvnw package -Dquarkus.profile=test
|
||||||
|
#
|
||||||
|
# Then, build the image with:
|
||||||
|
#
|
||||||
|
# docker build -f src/main/docker/Dockerfile.jvm -t veenm/paypoint-backend-jvm .
|
||||||
|
#
|
||||||
|
# Then run the container using:
|
||||||
|
#
|
||||||
|
# docker run -i --rm -p 8080:8080 quarkus/paypoint-backend-jvm
|
||||||
|
#
|
||||||
|
# If you want to include the debug port into your docker image
|
||||||
|
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||||
|
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||||
|
# when running the container
|
||||||
|
#
|
||||||
|
# Then run the container using :
|
||||||
|
#
|
||||||
|
# docker run -i --rm -p 8080:8080 quarkus/paypoint-backend-jvm
|
||||||
|
#
|
||||||
|
# This image uses the `run-java.sh` script to run the application.
|
||||||
|
# This scripts computes the command line to execute your Java application, and
|
||||||
|
# includes memory/GC tuning.
|
||||||
|
# You can configure the behavior using the following environment properties:
|
||||||
|
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class")
|
||||||
|
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||||
|
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||||
|
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||||
|
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||||
|
# If used in a container without any memory constraints for the container then this
|
||||||
|
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||||
|
# of the container available memory as set here. The default is `50` which means 50%
|
||||||
|
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||||
|
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||||
|
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||||
|
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||||
|
# If used in a container without any memory constraints for the container then this
|
||||||
|
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||||
|
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||||
|
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||||
|
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||||
|
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||||
|
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||||
|
# a container without any memory constraints for the container then this option has
|
||||||
|
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||||
|
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||||
|
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||||
|
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||||
|
# when things are happening. This option, if set to true, will set
|
||||||
|
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||||
|
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||||
|
# true").
|
||||||
|
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||||
|
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||||
|
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||||
|
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||||
|
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||||
|
# (example: "20")
|
||||||
|
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||||
|
# (example: "40")
|
||||||
|
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||||
|
# (example: "4")
|
||||||
|
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||||
|
# previous GC times. (example: "90")
|
||||||
|
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||||
|
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||||
|
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||||
|
# contain the necessary JRE command-line options to specify the required GC, which
|
||||||
|
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||||
|
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||||
|
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||||
|
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||||
|
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||||
|
#
|
||||||
|
###
|
||||||
|
FROM registry.access.redhat.com/ubi8/openjdk-21:1.20
|
||||||
|
|
||||||
|
ENV LANGUAGE='en_US:en'
|
||||||
|
ENV QUARKUS_PROFILE=test
|
||||||
|
|
||||||
|
|
||||||
|
# We make four distinct layers so if there are application changes the library layers can be re-used
|
||||||
|
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
|
||||||
|
COPY --chown=185 target/quarkus-app/*.jar /deployments/
|
||||||
|
COPY --chown=185 target/quarkus-app/app/ /deployments/app/
|
||||||
|
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
USER 185
|
||||||
|
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Dquarkus.profile=test -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||||
|
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
||||||
|
|
||||||
@@ -2,6 +2,9 @@ package nl.veenm.paypoint.domain;
|
|||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class AppUser {
|
public class AppUser {
|
||||||
@Id
|
@Id
|
||||||
@@ -14,8 +17,13 @@ public class AppUser {
|
|||||||
private String firstName;
|
private String firstName;
|
||||||
private String lastName;
|
private String lastName;
|
||||||
|
|
||||||
@ManyToOne(cascade = CascadeType.ALL)
|
@ManyToMany
|
||||||
private Company company;
|
@JoinTable(
|
||||||
|
name = "user_company",
|
||||||
|
joinColumns = @JoinColumn(name = "user_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "company_id")
|
||||||
|
)
|
||||||
|
private Set<Company> companies = new HashSet<>();
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
@@ -73,12 +81,12 @@ public class AppUser {
|
|||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Company getCompany() {
|
public Set<Company> getCompanies() {
|
||||||
return company;
|
return companies;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCompany(Company company) {
|
public void setCompanies(Set<Company> companies) {
|
||||||
this.company = company;
|
this.companies = companies;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package nl.veenm.paypoint.domain;
|
package nl.veenm.paypoint.domain;
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.*;
|
||||||
import jakarta.persistence.GenerationType;
|
|
||||||
import jakarta.persistence.Id;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Company {
|
public class Company {
|
||||||
@@ -17,6 +18,10 @@ public class Company {
|
|||||||
private String postal_code;
|
private String postal_code;
|
||||||
private String city;
|
private String city;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "companies")
|
||||||
|
@JsonIgnore
|
||||||
|
private Set<AppUser> users = new HashSet<>();
|
||||||
|
|
||||||
public void setId(Long id) {
|
public void setId(Long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
@@ -72,4 +77,12 @@ public class Company {
|
|||||||
public void setCity(String city) {
|
public void setCity(String city) {
|
||||||
this.city = 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 firstName;
|
||||||
private String lastName;
|
private String lastName;
|
||||||
private String email;
|
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.id = id;
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
|
this.phone = phone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Customer() {
|
public Customer() {
|
||||||
@@ -55,4 +57,12 @@ public class Customer {
|
|||||||
public void setEmail(String email) {
|
public void setEmail(String email) {
|
||||||
this.email = 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;
|
package nl.veenm.paypoint.helper;
|
||||||
|
|
||||||
|
import nl.veenm.paypoint.domain.Appointment;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|
||||||
public class EmailHelper {
|
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 = """
|
String formatted = """
|
||||||
BEGIN:VCALENDAR
|
BEGIN:VCALENDAR
|
||||||
VERSION:2.0
|
VERSION:2.0
|
||||||
PRODID:-//PayPoint//Afspraak//NL
|
PRODID:-//PayPoint//Afspraak//NL
|
||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
ORGANIZER;CN=Hairstyling By Daan:mailto:danielle@hairstylingbydaan.nl
|
ORGANIZER;CN=%s
|
||||||
UID:12345
|
UID:12345
|
||||||
DTSTAMP:%s
|
DTSTAMP:%s
|
||||||
DTSTART:%sT%s00
|
DTSTART:%sT%s00
|
||||||
DTEND:%sT%s00
|
DTEND:%sT%s00
|
||||||
SUMMARY:Afspraak bij Hairstyling By Daan
|
SUMMARY:Afspraak bij %s
|
||||||
LOCATION:%s
|
LOCATION:%s
|
||||||
DESCRIPTION:Bevestiging van uw afspraak bij Hairstyling By Daan
|
DESCRIPTION:Bevestiging van uw afspraak bij %s
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
END:VCALENDAR
|
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);
|
System.out.println(formatted);
|
||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package nl.veenm.paypoint.repository;
|
package nl.veenm.paypoint.repository;
|
||||||
|
|
||||||
import io.quarkus.hibernate.orm.panache.PanacheRepository;
|
import io.quarkus.hibernate.orm.panache.PanacheRepository;
|
||||||
|
import io.quarkus.panache.common.Parameters;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import nl.veenm.paypoint.domain.Appointment;
|
import nl.veenm.paypoint.domain.Appointment;
|
||||||
import nl.veenm.paypoint.domain.Company;
|
import nl.veenm.paypoint.domain.Company;
|
||||||
@@ -8,6 +9,7 @@ import nl.veenm.paypoint.domain.Company;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class AppointmentRepository implements PanacheRepository<Appointment> {
|
public class AppointmentRepository implements PanacheRepository<Appointment> {
|
||||||
@@ -23,4 +25,11 @@ public class AppointmentRepository implements PanacheRepository<Appointment> {
|
|||||||
public List<Appointment> findMostRecentByCompanyId(Company company) {
|
public List<Appointment> findMostRecentByCompanyId(Company company) {
|
||||||
return find("company = ?1", company).list();
|
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.annotation.security.RolesAllowed;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.json.JsonNumber;
|
|
||||||
import jakarta.ws.rs.*;
|
import jakarta.ws.rs.*;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
@@ -32,17 +31,18 @@ public class AppointmentResource {
|
|||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("/date")
|
@Path("/date")
|
||||||
public List<Appointment> getAppointmentsByDate(@QueryParam("start") String start) {
|
public List<Appointment> getAppointmentsByDate(@QueryParam("start") String start) {
|
||||||
JsonNumber companyIdJson = jwt.getClaim("company_id");
|
String user = jwt.getClaim("username");
|
||||||
Long companyId = companyIdJson.longValue();
|
return appointmentService.getAppointmentsByDate(start, user);
|
||||||
return appointmentService.getAppointmentsByDate(start, companyId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
//TODO: Deze werkend maken
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/recent/{id}")
|
// @GET
|
||||||
public Appointment getMostRecentAppointment(@PathParam("id") Long userId) {
|
// @Produces(MediaType.APPLICATION_JSON)
|
||||||
return appointmentService.getMostRecentByUserId(userId);
|
// @Path("/recent/{id}")
|
||||||
}
|
// public Appointment getMostRecentAppointment(@PathParam("id") Long userId) {
|
||||||
|
// return appointmentService.getMostRecentByUserId(userId);
|
||||||
|
// }
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@@ -52,12 +52,11 @@ public class AppointmentResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
|
@Path("/{companyId}")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public Response addAppointment(Appointment appointment) {
|
public Response addAppointment(@PathParam("companyId") Long companyId, Appointment appointment) {
|
||||||
JsonNumber companyIdJson = jwt.getClaim("company_id");
|
String user = jwt.getClaim("username");
|
||||||
Long companyId = companyIdJson.longValue();
|
return Response.ok(appointmentService.add(appointment, companyId, user)).build();
|
||||||
appointmentService.add(appointment, companyId);
|
|
||||||
return Response.ok().build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@@ -70,7 +69,6 @@ public class AppointmentResource {
|
|||||||
@PUT
|
@PUT
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public Response updateAppointment(Appointment appointment) {
|
public Response updateAppointment(Appointment appointment) {
|
||||||
appointmentService.update(appointment);
|
return Response.ok(appointmentService.update(appointment)).build();
|
||||||
return Response.ok().build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ public class CustomerResource {
|
|||||||
@POST
|
@POST
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Response addCustomer(Customer customer) {
|
public Response addCustomer(Customer customer) {
|
||||||
customerService.addCustomer(customer);
|
return Response.ok(customerService.addCustomer(customer)).build();
|
||||||
return Response.ok().build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ import io.quarkus.scheduler.Scheduled;
|
|||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
|
import nl.veenm.paypoint.domain.AppUser;
|
||||||
import nl.veenm.paypoint.domain.Appointment;
|
import nl.veenm.paypoint.domain.Appointment;
|
||||||
import nl.veenm.paypoint.domain.Company;
|
import nl.veenm.paypoint.domain.Company;
|
||||||
import nl.veenm.paypoint.repository.AppointmentRepository;
|
import nl.veenm.paypoint.repository.AppointmentRepository;
|
||||||
import nl.veenm.paypoint.repository.CompanyRepository;
|
import nl.veenm.paypoint.repository.CompanyRepository;
|
||||||
|
import nl.veenm.paypoint.repository.UserRepository;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -18,6 +20,9 @@ public class AppointmentService {
|
|||||||
@Inject
|
@Inject
|
||||||
AppointmentRepository appointmentRepository;
|
AppointmentRepository appointmentRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
UserRepository userRepository;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CompanyRepository companyRepository;
|
CompanyRepository companyRepository;
|
||||||
|
|
||||||
@@ -34,22 +39,25 @@ public class AppointmentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void add(Appointment appointment, Long companyId) {
|
public Appointment add(Appointment appointment, Long companyId, String username) {
|
||||||
Company company = companyRepository.findById(companyId);
|
Company company = companyRepository.findById(companyId);
|
||||||
|
AppUser user = userRepository.findByUsername(username);
|
||||||
appointment.setCompany(company);
|
appointment.setCompany(company);
|
||||||
appointmentRepository.persist(appointment);
|
appointmentRepository.persist(appointment);
|
||||||
emailService.stuurBevestiging(appointment);
|
emailService.stuurBevestiging(appointment, user);
|
||||||
|
return appointment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public List<Appointment> getAppointmentsByDate(String start, Long companyId) {
|
public List<Appointment> getAppointmentsByDate(String start, String username) {
|
||||||
LocalDate date = LocalDate.parse(start);
|
LocalDate date = LocalDate.parse(start);
|
||||||
Company company = companyRepository.findById(companyId);
|
AppUser user = userRepository.findByUsername(username);
|
||||||
|
|
||||||
|
|
||||||
LocalDateTime startOfDay = date.atStartOfDay();
|
LocalDateTime startOfDay = date.atStartOfDay();
|
||||||
LocalDateTime endOfDay = date.atTime(23, 59, 59);
|
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
|
@Transactional
|
||||||
@@ -59,7 +67,7 @@ public class AppointmentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void update(Appointment appointment) {
|
public Appointment update(Appointment appointment) {
|
||||||
Appointment appointmentToUpdate = appointmentRepository.findById(appointment.getId());
|
Appointment appointmentToUpdate = appointmentRepository.findById(appointment.getId());
|
||||||
appointmentToUpdate.setTitle(appointment.getTitle());
|
appointmentToUpdate.setTitle(appointment.getTitle());
|
||||||
appointmentToUpdate.setStartDate(appointment.getStartDate());
|
appointmentToUpdate.setStartDate(appointment.getStartDate());
|
||||||
@@ -72,6 +80,7 @@ public class AppointmentService {
|
|||||||
appointmentToUpdate.setDurationInMinutes(appointment.getDurationInMinutes());
|
appointmentToUpdate.setDurationInMinutes(appointment.getDurationInMinutes());
|
||||||
appointmentRepository.persist(appointmentToUpdate);
|
appointmentRepository.persist(appointmentToUpdate);
|
||||||
emailService.stuurBewerking(appointmentToUpdate);
|
emailService.stuurBewerking(appointmentToUpdate);
|
||||||
|
return appointmentToUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -91,9 +100,7 @@ public class AppointmentService {
|
|||||||
|
|
||||||
List<Appointment> allAppointments = appointmentRepository.find("date BETWEEN ?1 AND ?2", startOfDay, endOfDay).list();
|
List<Appointment> allAppointments = appointmentRepository.find("date BETWEEN ?1 AND ?2", startOfDay, endOfDay).list();
|
||||||
|
|
||||||
allAppointments.forEach(appointment -> {
|
allAppointments.forEach(emailService::stuurHerinnering);
|
||||||
emailService.stuurHerinnering(appointment);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Appointment getMostRecentByUserId(Long userId) {
|
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.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
|
import nl.veenm.paypoint.domain.Company;
|
||||||
import nl.veenm.paypoint.domain.Customer;
|
import nl.veenm.paypoint.domain.Customer;
|
||||||
import nl.veenm.paypoint.repository.CustomerRepository;
|
import nl.veenm.paypoint.repository.CustomerRepository;
|
||||||
|
|
||||||
@@ -28,7 +29,12 @@ public class CustomerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void addCustomer(Customer customer) {
|
public Customer addCustomer(Customer customer) {
|
||||||
customerRepository.persist(customer);
|
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.Mail;
|
||||||
import io.quarkus.mailer.Mailer;
|
import io.quarkus.mailer.Mailer;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import nl.veenm.paypoint.domain.AppUser;
|
||||||
import nl.veenm.paypoint.domain.Appointment;
|
import nl.veenm.paypoint.domain.Appointment;
|
||||||
import nl.veenm.paypoint.domain.Company;
|
import nl.veenm.paypoint.domain.Company;
|
||||||
import nl.veenm.paypoint.helper.EmailHelper;
|
import nl.veenm.paypoint.helper.EmailHelper;
|
||||||
@@ -20,7 +21,7 @@ public class EmailService {
|
|||||||
this.mailer = mailer;
|
this.mailer = mailer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stuurBevestiging(Appointment appointment) {
|
public void stuurBevestiging(Appointment appointment, AppUser user) {
|
||||||
Company company = appointment.getCompany();
|
Company company = appointment.getCompany();
|
||||||
String location = String.format("<br>%s<br>%s %s", company.getAddress(), company.getPostal_code(), company.getCity());
|
String location = String.format("<br>%s<br>%s %s", company.getAddress(), company.getPostal_code(), company.getCity());
|
||||||
String imageUrl = appointment.getCompany().getImg_href();
|
String imageUrl = appointment.getCompany().getImg_href();
|
||||||
@@ -98,14 +99,14 @@ public class EmailService {
|
|||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<img src="%s" alt="Afspraak bevestiging" class="image">
|
<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>
|
<p>© 2025 PayPoint. Alle rechten voorbehouden.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
""".formatted(appointment.getCustomer().getFirstName(), formattedDate, formattedTime,
|
""".formatted(appointment.getCustomer().getFirstName(), formattedDate, formattedTime,
|
||||||
location, imageUrl);
|
location, imageUrl, user.getFirstName(), appointment.getCompany().getName());
|
||||||
|
|
||||||
String subject = String.format(" Afspraak bevestigd: %s", formattedDate);
|
String subject = String.format(" Afspraak bevestigd: %s", formattedDate);
|
||||||
String recipient = appointment.getCustomer().getEmail();
|
String recipient = appointment.getCustomer().getEmail();
|
||||||
@@ -113,11 +114,12 @@ public class EmailService {
|
|||||||
date = date.withHour(appointment.getStartHour()).withMinute(appointment.getStartMinute());
|
date = date.withHour(appointment.getStartHour()).withMinute(appointment.getStartMinute());
|
||||||
|
|
||||||
String dtStamp = date.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"));
|
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)
|
mailer.send(Mail.withHtml(recipient, subject, emailBody)
|
||||||
.setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>")
|
.setFrom(sender)
|
||||||
.setReplyTo(company.getEmail())
|
.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) {
|
public void stuurVerwijdering(Appointment appointment) {
|
||||||
@@ -197,7 +199,7 @@ public class EmailService {
|
|||||||
String subject = String.format(" Afspraak geannuleerd: %s", formattedDate);
|
String subject = String.format(" Afspraak geannuleerd: %s", formattedDate);
|
||||||
String recipient = appointment.getCustomer().getEmail();
|
String recipient = appointment.getCustomer().getEmail();
|
||||||
|
|
||||||
mailer.send(Mail.withHtml(recipient, subject, emailBody).setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>"));
|
mailer.send(Mail.withHtml(recipient, subject, emailBody).setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>").setReplyTo(company.getEmail()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stuurBewerking(Appointment appointment) {
|
public void stuurBewerking(Appointment appointment) {
|
||||||
@@ -285,7 +287,7 @@ public class EmailService {
|
|||||||
String subject = String.format(" Afspraak gewijzigd: %s", formattedDate);
|
String subject = String.format(" Afspraak gewijzigd: %s", formattedDate);
|
||||||
String recipient = appointment.getCustomer().getEmail();
|
String recipient = appointment.getCustomer().getEmail();
|
||||||
|
|
||||||
mailer.send(Mail.withHtml(recipient, subject, emailBody).setFrom(company.getEmail()));
|
mailer.send(Mail.withHtml(recipient, subject, emailBody).setFrom("Hairstyling By Daan <paypoint@melvanveen.nl>").setReplyTo(company.getEmail()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stuurHerinnering(Appointment appointment) {
|
public void stuurHerinnering(Appointment appointment) {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ public class TokenService {
|
|||||||
.claim("lastName", appUser.getLastName())
|
.claim("lastName", appUser.getLastName())
|
||||||
.claim("email", appUser.getEmail())
|
.claim("email", appUser.getEmail())
|
||||||
.claim("groups", appUser.getRole())
|
.claim("groups", appUser.getRole())
|
||||||
.claim("company_id", appUser.getCompany().getId())
|
|
||||||
.sign();
|
.sign();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ quarkus.http.cors.origins=${CORS_ORIGINS}
|
|||||||
quarkus.http.cors.methods=GET,POST,OPTIONS,DELETE,PUT
|
quarkus.http.cors.methods=GET,POST,OPTIONS,DELETE,PUT
|
||||||
quarkus.http.root-path=/api
|
quarkus.http.root-path=/api
|
||||||
|
|
||||||
quarkus.smallrye-openapi.path=/openapi
|
#quarkus.smallrye-openapi.path=/openapi
|
||||||
quarkus.swagger-ui.always-include=true
|
#quarkus.swagger-ui.always-include=true
|
||||||
|
|
||||||
# Mailer configuratie
|
# Mailer configuratie
|
||||||
quarkus.mailer.from=${MAILER_FROM}
|
quarkus.mailer.from=${MAILER_FROM}
|
||||||
@@ -40,14 +40,7 @@ smallrye.jwt.sign.key.algorithm=RS256
|
|||||||
# Token Levensduur (optioneel)
|
# Token Levensduur (optioneel)
|
||||||
smallrye.jwt.new-token.lifespan=3600
|
smallrye.jwt.new-token.lifespan=3600
|
||||||
|
|
||||||
#quarkus.log.category."io.quarkus.security".level=DEBUG
|
#Swagger UI
|
||||||
#mp.jwt.verify.claims.groups=groups
|
|
||||||
#quarkus.log.category."io.smallrye.jwt".level=DEBUG
|
|
||||||
##quarkus.log.level=DEBUG
|
|
||||||
##quarkus.log.category."io.quarkus".level=DEBUG
|
|
||||||
#quarkus.log.category."io.quarkus.rest".level=DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
%test.quarkus.smallrye-openapi.path=/openapi
|
%test.quarkus.smallrye-openapi.path=/openapi
|
||||||
%test.quarkus.swagger-ui.always-include=true
|
%test.quarkus.swagger-ui.always-include=true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user