Compare commits
2 Commits
fca5af2c9a
...
fcfc8ad1e0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcfc8ad1e0 | ||
|
|
d54f2ae2e6 |
5
frontend/src/app.d.ts
vendored
5
frontend/src/app.d.ts
vendored
@@ -30,7 +30,7 @@ interface BankAccount {
|
|||||||
mandate_reference: string | "";
|
mandate_reference: string | "";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DriversLicence {
|
interface Licence {
|
||||||
id: number | -1;
|
id: number | -1;
|
||||||
status: number | -1;
|
status: number | -1;
|
||||||
licence_number: string | "";
|
licence_number: string | "";
|
||||||
@@ -63,7 +63,7 @@ interface User {
|
|||||||
payment_status: number | -1;
|
payment_status: number | -1;
|
||||||
membership: Membership;
|
membership: Membership;
|
||||||
bank_account: BankAccount;
|
bank_account: BankAccount;
|
||||||
drivers_licence: DriversLicence;
|
licence: Licence;
|
||||||
notes: string | "";
|
notes: string | "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +72,7 @@ declare global {
|
|||||||
// interface Error {}
|
// interface Error {}
|
||||||
interface Locals {
|
interface Locals {
|
||||||
user: User;
|
user: User;
|
||||||
|
users: User[];
|
||||||
subscriptions: Subscription[];
|
subscriptions: Subscription[];
|
||||||
licence_categories: LicenceCategory[];
|
licence_categories: LicenceCategory[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export async function handle({ event, resolve }) {
|
|||||||
event.cookies.delete("jwt", { path: "/" });
|
event.cookies.delete("jwt", { path: "/" });
|
||||||
return await resolve(event);
|
return await resolve(event);
|
||||||
}
|
}
|
||||||
// find the user based on the jwt
|
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
@@ -62,13 +61,13 @@ export async function handle({ event, resolve }) {
|
|||||||
event.locals.user.membership.end_date.split("T")[0];
|
event.locals.user.membership.end_date.split("T")[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event.locals.user.drivers_licence?.issued_date) {
|
if (event.locals.user.licence?.issued_date) {
|
||||||
event.locals.user.drivers_licence.issued_date =
|
event.locals.user.licence.issued_date =
|
||||||
event.locals.user.drivers_licence.issued_date.split("T")[0];
|
event.locals.user.licence.issued_date.split("T")[0];
|
||||||
}
|
}
|
||||||
if (event.locals.user.drivers_licence?.expiration_date) {
|
if (event.locals.user.licence?.expiration_date) {
|
||||||
event.locals.user.drivers_licence.expiration_date =
|
event.locals.user.licence.expiration_date =
|
||||||
event.locals.user.drivers_licence.expiration_date.split("T")[0];
|
event.locals.user.licence.expiration_date.split("T")[0];
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
event.locals.user.bank_account &&
|
event.locals.user.bank_account &&
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
case "licence_number":
|
case "licence_number":
|
||||||
return typeof value === "string" && value.length == 11
|
return typeof value === "string" && value.length == 11
|
||||||
? null
|
? null
|
||||||
: $t("validation.drivers_licence");
|
: $t("validation.licence");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return typeof value === "string" && !value.trim() && required
|
return typeof value === "string" && !value.trim() && required
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import InputField from "$lib/components/InputField.svelte";
|
import InputField from "$lib/components/InputField.svelte";
|
||||||
import SmallLoader from "$lib/components/SmallLoader.svelte";
|
import SmallLoader from "$lib/components/SmallLoader.svelte";
|
||||||
import { onMount } from "svelte";
|
|
||||||
import { applyAction, enhance } from "$app/forms";
|
import { applyAction, enhance } from "$app/forms";
|
||||||
import { page } from "$app/stores";
|
|
||||||
import { receive, send } from "$lib/utils/helpers";
|
import { receive, send } from "$lib/utils/helpers";
|
||||||
import { t } from "svelte-i18n";
|
import { t } from "svelte-i18n";
|
||||||
import { fly } from "svelte/transition";
|
|
||||||
|
|
||||||
/** @type {import('../../routes/auth/about/[id]/$types').ActionData} */
|
/** @type {import('../../routes/auth/about/[id]/$types').ActionData} */
|
||||||
export let form;
|
export let form;
|
||||||
@@ -88,10 +85,6 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
console.dir(user);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the active tab
|
* Sets the active tab
|
||||||
* @param {string} tab - The tab to set as active
|
* @param {string} tab - The tab to set as active
|
||||||
@@ -277,14 +270,14 @@
|
|||||||
name="licence_status"
|
name="licence_status"
|
||||||
type="select"
|
type="select"
|
||||||
label={$t("status")}
|
label={$t("status")}
|
||||||
bind:value={user.drivers_licence.status}
|
bind:value={user.licence.status}
|
||||||
options={licenceStatusOptions}
|
options={licenceStatusOptions}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<InputField
|
||||||
name="licence_number"
|
name="licence_number"
|
||||||
type="text"
|
type="text"
|
||||||
label={$t("licence_number")}
|
label={$t("licence_number")}
|
||||||
bind:value={user.drivers_licence.licence_number}
|
bind:value={user.licence.licence_number}
|
||||||
placeholder={$t("placeholder.licence_number")}
|
placeholder={$t("placeholder.licence_number")}
|
||||||
toUpperCase={true}
|
toUpperCase={true}
|
||||||
/>
|
/>
|
||||||
@@ -292,20 +285,20 @@
|
|||||||
name="issued_date"
|
name="issued_date"
|
||||||
type="date"
|
type="date"
|
||||||
label={$t("issued_date")}
|
label={$t("issued_date")}
|
||||||
bind:value={user.drivers_licence.issued_date}
|
bind:value={user.licence.issued_date}
|
||||||
placeholder={$t("placeholder.issued_date")}
|
placeholder={$t("placeholder.issued_date")}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<InputField
|
||||||
name="expiration_date"
|
name="expiration_date"
|
||||||
type="date"
|
type="date"
|
||||||
label={$t("expiration_date")}
|
label={$t("expiration_date")}
|
||||||
bind:value={user.drivers_licence.expiration_date}
|
bind:value={user.licence.expiration_date}
|
||||||
placeholder={$t("placeholder.expiration_date")}
|
placeholder={$t("placeholder.expiration_date")}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<InputField
|
||||||
name="country"
|
name="country"
|
||||||
label={$t("country")}
|
label={$t("country")}
|
||||||
bind:value={user.drivers_licence.country}
|
bind:value={user.licence.country}
|
||||||
placeholder={$t("placeholder.issuing_country")}
|
placeholder={$t("placeholder.issuing_country")}
|
||||||
/>
|
/>
|
||||||
<div class="licence-categories">
|
<div class="licence-categories">
|
||||||
@@ -323,8 +316,8 @@
|
|||||||
name="licence_categories[]"
|
name="licence_categories[]"
|
||||||
value={JSON.stringify(category)}
|
value={JSON.stringify(category)}
|
||||||
label={category.category}
|
label={category.category}
|
||||||
checked={user.drivers_licence.licence_categories != null &&
|
checked={user.licence.licence_categories != null &&
|
||||||
user.drivers_licence.licence_categories.some(
|
user.licence.licence_categories.some(
|
||||||
(cat) => cat.category === category.category
|
(cat) => cat.category === category.category
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export default {
|
|||||||
iban: "Ungültige IBAN",
|
iban: "Ungültige IBAN",
|
||||||
date: "Bitte geben Sie ein Datum ein",
|
date: "Bitte geben Sie ein Datum ein",
|
||||||
email: "Ungültige Emailadresse",
|
email: "Ungültige Emailadresse",
|
||||||
drivers_licence: "Nummer zu kurz(11 Zeichen)",
|
licence: "Nummer zu kurz(11 Zeichen)",
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
error: {
|
error: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/** @type {import('./$types').LayoutLoad} */
|
/** @type {import('./$types').LayoutLoad} */
|
||||||
export async function load({ fetch, url, data }) {
|
export async function load({ fetch, url, data }) {
|
||||||
const { user, subscriptions, licence_categories } = data;
|
const { user } = data;
|
||||||
return { fetch, url: url.pathname, user, subscriptions, licence_categories };
|
return { fetch, url: url.pathname, user };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,5 @@
|
|||||||
export async function load({ locals }) {
|
export async function load({ locals }) {
|
||||||
return {
|
return {
|
||||||
user: locals.user,
|
user: locals.user,
|
||||||
subscriptions: locals.subscriptions,
|
|
||||||
licence_categories: locals.licence_categories,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
5
frontend/src/routes/auth/about/[id]/+layout.js
Normal file
5
frontend/src/routes/auth/about/[id]/+layout.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/** @type {import('./$types').LayoutLoad} */
|
||||||
|
export async function load({ fetch, url, data }) {
|
||||||
|
const { user, subscriptions, licence_categories } = data;
|
||||||
|
return { fetch, url: url.pathname, user, subscriptions, licence_categories };
|
||||||
|
}
|
||||||
66
frontend/src/routes/auth/about/[id]/+layout.server.js
Normal file
66
frontend/src/routes/auth/about/[id]/+layout.server.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { BASE_API_URI } from "$lib/utils/constants";
|
||||||
|
|
||||||
|
/** @type {import('./$types').LayoutServerLoad} */
|
||||||
|
export async function load({ cookies, fetch, locals }) {
|
||||||
|
const jwt = cookies.get("jwt");
|
||||||
|
try {
|
||||||
|
// Fetch user data, subscriptions, and licence categories in parallel
|
||||||
|
const [subscriptionsResponse, licenceCategoriesResponse] =
|
||||||
|
await Promise.all([
|
||||||
|
fetch(`${BASE_API_URI}/backend/membership/subscriptions`, {
|
||||||
|
credentials: "include",
|
||||||
|
headers: { Cookie: `jwt=${jwt}` },
|
||||||
|
}),
|
||||||
|
fetch(`${BASE_API_URI}/backend/licence/categories`, {
|
||||||
|
credentials: "include",
|
||||||
|
headers: { Cookie: `jwt=${jwt}` },
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Check if any of the responses are not ok
|
||||||
|
if (!subscriptionsResponse.ok || !licenceCategoriesResponse.ok) {
|
||||||
|
cookies.delete("jwt", { path: "/" });
|
||||||
|
throw new Error("One or more API requests failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the JSON responses
|
||||||
|
const [subscriptionsData, licence_categoriesData] = await Promise.all([
|
||||||
|
subscriptionsResponse.json(),
|
||||||
|
licenceCategoriesResponse.json(),
|
||||||
|
]);
|
||||||
|
// Check if the server sent a new token
|
||||||
|
const newToken =
|
||||||
|
subscriptionsResponse.headers.get("Set-Cookie") == null
|
||||||
|
? licenceCategoriesResponse.headers.get("Set-Cookie")
|
||||||
|
: subscriptionsResponse.headers.get("Set-Cookie");
|
||||||
|
|
||||||
|
if (newToken) {
|
||||||
|
const match = newToken.match(/jwt=([^;]+)/);
|
||||||
|
if (match) {
|
||||||
|
cookies.set("jwt", match[1], {
|
||||||
|
path: "/",
|
||||||
|
httpOnly: true,
|
||||||
|
secure: process.env.NODE_ENV === "production", // Secure in production
|
||||||
|
sameSite: "lax",
|
||||||
|
maxAge: 5 * 24 * 60 * 60, // 5 days in seconds
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.dir(subscriptionsData);
|
||||||
|
console.dir(licence_categoriesData);
|
||||||
|
return {
|
||||||
|
user: locals.user,
|
||||||
|
subscriptions: subscriptionsData.subscriptions,
|
||||||
|
licence_categories: licence_categoriesData.licence_categories,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching data:", error);
|
||||||
|
// In case of any error, clear the JWT cookie
|
||||||
|
cookies.delete("jwt", { path: "/" });
|
||||||
|
return {
|
||||||
|
user: locals.user,
|
||||||
|
subscriptions: null,
|
||||||
|
licence_categories: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,7 +72,7 @@ export const actions = {
|
|||||||
bic: String(formData.get("bic")),
|
bic: String(formData.get("bic")),
|
||||||
mandate_reference: String(formData.get("mandate_reference")),
|
mandate_reference: String(formData.get("mandate_reference")),
|
||||||
},
|
},
|
||||||
drivers_licence: {
|
licence: {
|
||||||
id: Number(formData.get("drivers_licence_id")),
|
id: Number(formData.get("drivers_licence_id")),
|
||||||
status: Number(formData.get("licence_status")),
|
status: Number(formData.get("licence_status")),
|
||||||
licence_number: String(formData.get("licence_number")),
|
licence_number: String(formData.get("licence_number")),
|
||||||
@@ -128,13 +128,13 @@ export const actions = {
|
|||||||
locals.user.bank_account.mandate_date_signed =
|
locals.user.bank_account.mandate_date_signed =
|
||||||
locals.user.bank_account.mandate_date_signed.split("T")[0];
|
locals.user.bank_account.mandate_date_signed.split("T")[0];
|
||||||
}
|
}
|
||||||
if (locals.user.drivers_licence?.issued_date) {
|
if (locals.user.licence?.issued_date) {
|
||||||
locals.user.drivers_licence.issued_date =
|
locals.user.licence.issued_date =
|
||||||
locals.user.drivers_licence.issued_date.split("T")[0];
|
locals.user.licence.issued_date.split("T")[0];
|
||||||
}
|
}
|
||||||
if (locals.user.drivers_licence?.expiration_date) {
|
if (locals.user.licence?.expiration_date) {
|
||||||
locals.user.drivers_licence.expiration_date =
|
locals.user.licence.expiration_date =
|
||||||
locals.user.drivers_licence.expiration_date.split("T")[0];
|
locals.user.licence.expiration_date.split("T")[0];
|
||||||
}
|
}
|
||||||
throw redirect(303, `/auth/about/${response.id}`);
|
throw redirect(303, `/auth/about/${response.id}`);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,14 +12,7 @@
|
|||||||
/** @type {import('./$types').ActionData} */
|
/** @type {import('./$types').ActionData} */
|
||||||
export let form;
|
export let form;
|
||||||
|
|
||||||
/** @type {App.Locals['subscriptions']}*/
|
$: ({ user, subscriptions, licence_categories } = $page.data);
|
||||||
$: subscriptions = $page.data.subscriptions;
|
|
||||||
|
|
||||||
/** @type {App.Locals['user']}*/
|
|
||||||
$: user = $page.data.user;
|
|
||||||
|
|
||||||
/** @type {App.Locals['licence_categories']} */
|
|
||||||
$: licence_categories = $page.data.licence_categories;
|
|
||||||
|
|
||||||
let showModal = false;
|
let showModal = false;
|
||||||
|
|
||||||
@@ -110,89 +103,6 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.category-break {
|
|
||||||
grid-column: 1 / -1;
|
|
||||||
height: 1px;
|
|
||||||
background-color: #ccc;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-left: 20%;
|
|
||||||
width: 60%;
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.licence-categories {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
gap: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-item {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-label-container {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
width: 4em;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-description {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 15px;
|
|
||||||
color: #9b9b9b;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.checkbox-grid {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
gap: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.checkbox-item {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-description {
|
|
||||||
margin-left: 24px;
|
|
||||||
margin-top: 5px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.subscription-info {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 1rem;
|
|
||||||
margin-top: 1rem;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subscription-column {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subscription-column p {
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subscription-column strong {
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 100px;
|
|
||||||
}
|
|
||||||
.tab-content {
|
|
||||||
padding: 1rem;
|
|
||||||
border-radius: 0 0 3px 3px;
|
|
||||||
}
|
|
||||||
.hero-container .hero-subtitle:not(:last-of-type) {
|
.hero-container .hero-subtitle:not(:last-of-type) {
|
||||||
margin: 0 0 0 0;
|
margin: 0 0 0 0;
|
||||||
}
|
}
|
||||||
@@ -247,25 +157,4 @@
|
|||||||
.value {
|
.value {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
margin-top: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-container button {
|
|
||||||
flex: 1 1 0;
|
|
||||||
min-width: 120px;
|
|
||||||
max-width: calc(50%-5px);
|
|
||||||
}
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.button-container button {
|
|
||||||
flex-basis: 100%;
|
|
||||||
max-width: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -99,13 +99,13 @@ func TestSuite(t *testing.T) {
|
|||||||
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
|
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
|
||||||
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
||||||
|
|
||||||
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
||||||
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
||||||
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
|
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
|
||||||
|
|
||||||
driversLicenceService := &services.DriversLicenceService{Repo: licenceRepo}
|
licenceService := &services.LicenceService{Repo: licenceRepo}
|
||||||
|
|
||||||
Uc = &UserController{Service: userService, DriversLicenceService: driversLicenceService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
Uc = &UserController{Service: userService, LicenceService: licenceService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
||||||
Mc = &MembershipController{Service: *membershipService}
|
Mc = &MembershipController{Service: *membershipService}
|
||||||
Cc = &ContactController{EmailService: emailService}
|
Cc = &ContactController{EmailService: emailService}
|
||||||
|
|
||||||
@@ -147,23 +147,23 @@ func TestSuite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initLicenceCategories() error {
|
func initLicenceCategories() error {
|
||||||
categories := []models.LicenceCategory{
|
categories := []models.Category{
|
||||||
{Category: "AM"},
|
{Name: "AM"},
|
||||||
{Category: "A1"},
|
{Name: "A1"},
|
||||||
{Category: "A2"},
|
{Name: "A2"},
|
||||||
{Category: "A"},
|
{Name: "A"},
|
||||||
{Category: "B"},
|
{Name: "B"},
|
||||||
{Category: "C1"},
|
{Name: "C1"},
|
||||||
{Category: "C"},
|
{Name: "C"},
|
||||||
{Category: "D1"},
|
{Name: "D1"},
|
||||||
{Category: "D"},
|
{Name: "D"},
|
||||||
{Category: "BE"},
|
{Name: "BE"},
|
||||||
{Category: "C1E"},
|
{Name: "C1E"},
|
||||||
{Category: "CE"},
|
{Name: "CE"},
|
||||||
{Category: "D1E"},
|
{Name: "D1E"},
|
||||||
{Category: "DE"},
|
{Name: "DE"},
|
||||||
{Category: "T"},
|
{Name: "T"},
|
||||||
{Category: "L"},
|
{Name: "L"},
|
||||||
}
|
}
|
||||||
for _, category := range categories {
|
for _, category := range categories {
|
||||||
result := database.DB.Create(&category)
|
result := database.DB.Create(&category)
|
||||||
@@ -258,7 +258,7 @@ func getBaseUser() models.User {
|
|||||||
Phone: "01738484993",
|
Phone: "01738484993",
|
||||||
BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"},
|
BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"},
|
||||||
Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}},
|
Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}},
|
||||||
DriversLicence: models.DriversLicence{},
|
Licence: models.Licence{},
|
||||||
ProfilePicture: "",
|
ProfilePicture: "",
|
||||||
Password: "password123",
|
Password: "password123",
|
||||||
Company: "",
|
Company: "",
|
||||||
|
|||||||
31
internal/controllers/licenceController.go
Normal file
31
internal/controllers/licenceController.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"GoMembership/internal/services"
|
||||||
|
"GoMembership/pkg/logger"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LicenceController struct {
|
||||||
|
Service services.LicenceService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *LicenceController) GetAllCategories(c *gin.Context) {
|
||||||
|
|
||||||
|
categories, err := lc.Service.GetAllCategories()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error.Printf("Error retrieving licence categories: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
|
||||||
|
"field": "general",
|
||||||
|
"key": "validation.internal_server_error",
|
||||||
|
}}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.Error.Printf("categories: %v", categories)
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"licence_categories": categories,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -46,3 +46,19 @@ func (mc *MembershipController) RegisterSubscription(c *gin.Context) {
|
|||||||
"id": id,
|
"id": id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mc *MembershipController) GetSubscriptions(c *gin.Context) {
|
||||||
|
subscriptions, err := mc.Service.GetSubscriptions(nil)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error.Printf("Error retrieving subscriptions: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
|
||||||
|
"field": "general",
|
||||||
|
"key": "validation.internal_server_error",
|
||||||
|
}}})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"subscriptions": subscriptions,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ type UserController struct {
|
|||||||
ConsentService services.ConsentServiceInterface
|
ConsentService services.ConsentServiceInterface
|
||||||
BankAccountService services.BankAccountServiceInterface
|
BankAccountService services.BankAccountServiceInterface
|
||||||
MembershipService services.MembershipServiceInterface
|
MembershipService services.MembershipServiceInterface
|
||||||
DriversLicenceService services.DriversLicenceInterface
|
LicenceService services.LicenceInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegistrationData struct {
|
type RegistrationData struct {
|
||||||
@@ -172,28 +172,8 @@ func (uc *UserController) CurrentUserHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptions, err := uc.MembershipService.GetSubscriptions(nil)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error.Printf("Error retrieving subscriptions: %v", err)
|
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
|
|
||||||
"field": "general",
|
|
||||||
"key": "validation.internal_server_error",
|
|
||||||
}}})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
licenceCategories, err := uc.DriversLicenceService.GetAllCategories()
|
|
||||||
if err != nil {
|
|
||||||
logger.Error.Printf("Error retrieving licence categories: %v", err)
|
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
|
|
||||||
"field": "general",
|
|
||||||
"key": "validation.internal_server_error",
|
|
||||||
}}})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"user": user.Safe(),
|
"user": user.Safe(),
|
||||||
"subscriptions": subscriptions,
|
|
||||||
"licence_categories": licenceCategories,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func testUserController(t *testing.T) {
|
|||||||
|
|
||||||
loginEmail, loginCookie := testLoginHandler(t)
|
loginEmail, loginCookie := testLoginHandler(t)
|
||||||
logoutCookie := testCurrentUserHandler(t, loginEmail, loginCookie)
|
logoutCookie := testCurrentUserHandler(t, loginEmail, loginCookie)
|
||||||
testUpdateUser(t, loginEmail, loginCookie)
|
testUpdateUser(t, loginCookie)
|
||||||
testLogoutHandler(t, logoutCookie)
|
testLogoutHandler(t, logoutCookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@ func validateUser(assert bool, wantDBData map[string]interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||||
|
|
||||||
invalidCookie := http.Cookie{
|
invalidCookie := http.Cookie{
|
||||||
Name: "jwt",
|
Name: "jwt",
|
||||||
@@ -480,7 +480,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Change LicenceNumber",
|
name: "Change Number",
|
||||||
setupCookie: func(req *http.Request) {
|
setupCookie: func(req *http.Request) {
|
||||||
req.AddCookie(&loginCookie)
|
req.AddCookie(&loginCookie)
|
||||||
},
|
},
|
||||||
@@ -489,7 +489,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
u.FirstName = "John Updated"
|
u.FirstName = "John Updated"
|
||||||
u.LastName = "Doe Updated"
|
u.LastName = "Doe Updated"
|
||||||
u.Phone = "01738484994"
|
u.Phone = "01738484994"
|
||||||
u.DriversLicence.LicenceNumber = "B072RRE2I50"
|
u.Licence.Number = "B072RRE2I50"
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusAccepted,
|
expectedStatus: http.StatusAccepted,
|
||||||
},
|
},
|
||||||
@@ -503,11 +503,11 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
u.FirstName = "John Updated"
|
u.FirstName = "John Updated"
|
||||||
u.LastName = "Doe Updated"
|
u.LastName = "Doe Updated"
|
||||||
u.Phone = "01738484994"
|
u.Phone = "01738484994"
|
||||||
u.DriversLicence.LicenceNumber = "B072RRE2I50"
|
u.Licence.Number = "B072RRE2I50"
|
||||||
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
||||||
category, err := licenceRepo.FindCategoryByName("B")
|
category, err := licenceRepo.FindCategoryByName("B")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category}
|
u.Licence.Categories = []models.Category{category}
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusAccepted,
|
expectedStatus: http.StatusAccepted,
|
||||||
},
|
},
|
||||||
@@ -521,12 +521,12 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
u.FirstName = "John Updated"
|
u.FirstName = "John Updated"
|
||||||
u.LastName = "Doe Updated"
|
u.LastName = "Doe Updated"
|
||||||
u.Phone = "01738484994"
|
u.Phone = "01738484994"
|
||||||
u.DriversLicence.LicenceNumber = "B072RRE2I50"
|
u.Licence.Number = "B072RRE2I50"
|
||||||
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
||||||
category, err := licenceRepo.FindCategoryByName("A")
|
category, err := licenceRepo.FindCategoryByName("A")
|
||||||
category2, err := licenceRepo.FindCategoryByName("BE")
|
category2, err := licenceRepo.FindCategoryByName("BE")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category, category2}
|
u.Licence.Categories = []models.Category{category, category2}
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusAccepted,
|
expectedStatus: http.StatusAccepted,
|
||||||
},
|
},
|
||||||
@@ -540,11 +540,11 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
u.FirstName = "John Updated"
|
u.FirstName = "John Updated"
|
||||||
u.LastName = "Doe Updated"
|
u.LastName = "Doe Updated"
|
||||||
u.Phone = "01738484994"
|
u.Phone = "01738484994"
|
||||||
u.DriversLicence.LicenceNumber = "B072RRE2I50"
|
u.Licence.Number = "B072RRE2I50"
|
||||||
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
||||||
category, err := licenceRepo.FindCategoryByName("A")
|
category, err := licenceRepo.FindCategoryByName("A")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category}
|
u.Licence.Categories = []models.Category{category}
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusAccepted,
|
expectedStatus: http.StatusAccepted,
|
||||||
},
|
},
|
||||||
@@ -558,8 +558,8 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
u.FirstName = "John Updated"
|
u.FirstName = "John Updated"
|
||||||
u.LastName = "Doe Updated"
|
u.LastName = "Doe Updated"
|
||||||
u.Phone = "01738484994"
|
u.Phone = "01738484994"
|
||||||
u.DriversLicence.LicenceNumber = "B072RRE2I50"
|
u.Licence.Number = "B072RRE2I50"
|
||||||
u.DriversLicence.LicenceCategories = []models.LicenceCategory{}
|
u.Licence.Categories = []models.Category{}
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusAccepted,
|
expectedStatus: http.StatusAccepted,
|
||||||
},
|
},
|
||||||
@@ -573,7 +573,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
u.ID = 1
|
u.ID = 1
|
||||||
u.LastName = "Doe Updated"
|
u.LastName = "Doe Updated"
|
||||||
u.Phone = "01738484994"
|
u.Phone = "01738484994"
|
||||||
u.DriversLicence.LicenceNumber = "B072RRE2I50"
|
u.Licence.Number = "B072RRE2I50"
|
||||||
u.FirstName = "John Missing ID"
|
u.FirstName = "John Missing ID"
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusForbidden,
|
expectedStatus: http.StatusForbidden,
|
||||||
@@ -590,7 +590,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
u.Password = ""
|
u.Password = ""
|
||||||
u.LastName = "Doe Updated"
|
u.LastName = "Doe Updated"
|
||||||
u.Phone = "01738484994"
|
u.Phone = "01738484994"
|
||||||
u.DriversLicence.LicenceNumber = "B072RRE2I50"
|
u.Licence.Number = "B072RRE2I50"
|
||||||
u.Password = "NewPassword"
|
u.Password = "NewPassword"
|
||||||
},
|
},
|
||||||
expectedStatus: http.StatusAccepted,
|
expectedStatus: http.StatusAccepted,
|
||||||
@@ -713,23 +713,23 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
|
|||||||
assert.Equal(t, updatedUser.Membership.SubscriptionModelID, updatedUserFromDB.Membership.SubscriptionModelID, "Membership.SubscriptionModelID mismatch")
|
assert.Equal(t, updatedUser.Membership.SubscriptionModelID, updatedUserFromDB.Membership.SubscriptionModelID, "Membership.SubscriptionModelID mismatch")
|
||||||
assert.Equal(t, updatedUser.Membership.ParentMembershipID, updatedUserFromDB.Membership.ParentMembershipID, "Membership.ParentMembershipID mismatch")
|
assert.Equal(t, updatedUser.Membership.ParentMembershipID, updatedUserFromDB.Membership.ParentMembershipID, "Membership.ParentMembershipID mismatch")
|
||||||
|
|
||||||
if updatedUser.DriversLicence.Status == 0 {
|
if updatedUser.Licence.Status == 0 {
|
||||||
updatedUser.DriversLicence.Status = constants.UnverifiedStatus
|
updatedUser.Licence.Status = constants.UnverifiedStatus
|
||||||
}
|
}
|
||||||
assert.Equal(t, updatedUser.DriversLicence.Status, updatedUserFromDB.DriversLicence.Status, "DriversLicence.Status mismatch")
|
assert.Equal(t, updatedUser.Licence.Status, updatedUserFromDB.Licence.Status, "Licence.Status mismatch")
|
||||||
assert.Equal(t, updatedUser.DriversLicence.LicenceNumber, updatedUserFromDB.DriversLicence.LicenceNumber, "DriversLicence.LicenceNumber mismatch")
|
assert.Equal(t, updatedUser.Licence.Number, updatedUserFromDB.Licence.Number, "Licence.Number mismatch")
|
||||||
assert.Equal(t, updatedUser.DriversLicence.IssuedDate, updatedUserFromDB.DriversLicence.IssuedDate, "DriversLicence.IssuedDate mismatch")
|
assert.Equal(t, updatedUser.Licence.IssuedDate, updatedUserFromDB.Licence.IssuedDate, "Licence.IssuedDate mismatch")
|
||||||
assert.Equal(t, updatedUser.DriversLicence.ExpirationDate, updatedUserFromDB.DriversLicence.ExpirationDate, "DriversLicence.ExpirationDate mismatch")
|
assert.Equal(t, updatedUser.Licence.ExpirationDate, updatedUserFromDB.Licence.ExpirationDate, "Licence.ExpirationDate mismatch")
|
||||||
assert.Equal(t, updatedUser.DriversLicence.IssuingCountry, updatedUserFromDB.DriversLicence.IssuingCountry, "DriversLicence.IssuingCountry mismatch")
|
assert.Equal(t, updatedUser.Licence.IssuingCountry, updatedUserFromDB.Licence.IssuingCountry, "Licence.IssuingCountry mismatch")
|
||||||
|
|
||||||
// For slices or more complex nested structures, you might want to use deep equality checks
|
// For slices or more complex nested structures, you might want to use deep equality checks
|
||||||
assert.ElementsMatch(t, updatedUser.Consents, updatedUserFromDB.Consents, "Consents mismatch")
|
assert.ElementsMatch(t, updatedUser.Consents, updatedUserFromDB.Consents, "Consents mismatch")
|
||||||
if len(updatedUser.DriversLicence.LicenceCategories) > 0 {
|
if len(updatedUser.Licence.Categories) > 0 {
|
||||||
for i := range updatedUser.DriversLicence.LicenceCategories {
|
for i := range updatedUser.Licence.Categories {
|
||||||
assert.Equal(t, updatedUser.DriversLicence.LicenceCategories[i].Category, updatedUserFromDB.DriversLicence.LicenceCategories[i].Category, "LicenceCategory Category mismatch at index %d", i)
|
assert.Equal(t, updatedUser.Licence.Categories[i].Name, updatedUserFromDB.Licence.Categories[i].Name, "Category Category mismatch at index %d", i)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert.Emptyf(t, updatedUserFromDB.DriversLicence.LicenceCategories, "Categories aren't empty when they should")
|
assert.Emptyf(t, updatedUserFromDB.Licence.Categories, "Categories aren't empty when they should")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1094,18 +1094,18 @@ func getTestUsers() []RegisterUserTest {
|
|||||||
Assert: false,
|
Assert: false,
|
||||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||||
user.Email = "john.wronglicence.doe@example.com"
|
user.Email = "john.wronglicence.doe@example.com"
|
||||||
user.DriversLicence.LicenceNumber = "AAAA12345AA"
|
user.Licence.Number = "AAAA12345AA"
|
||||||
return user
|
return user
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Correct DriversLicence number, should pass",
|
Name: "Correct Licence number, should pass",
|
||||||
WantResponse: http.StatusCreated,
|
WantResponse: http.StatusCreated,
|
||||||
WantDBData: map[string]interface{}{"email": "john.correctLicenceNumber@example.com"},
|
WantDBData: map[string]interface{}{"email": "john.correctLicenceNumber@example.com"},
|
||||||
Assert: true,
|
Assert: true,
|
||||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||||
user.Email = "john.correctLicenceNumber@example.com"
|
user.Email = "john.correctLicenceNumber@example.com"
|
||||||
user.DriversLicence.LicenceNumber = "B072RRE2I55"
|
user.Licence.Number = "B072RRE2I55"
|
||||||
return user
|
return user
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ func Open(dbPath string, adminMail string) error {
|
|||||||
&models.Membership{},
|
&models.Membership{},
|
||||||
&models.Consent{},
|
&models.Consent{},
|
||||||
&models.Verification{},
|
&models.Verification{},
|
||||||
&models.DriversLicence{},
|
&models.Licence{},
|
||||||
&models.LicenceCategory{},
|
&models.Category{},
|
||||||
&models.BankAccount{}); err != nil {
|
&models.BankAccount{}); err != nil {
|
||||||
logger.Error.Fatalf("Couldn't create database: %v", err)
|
logger.Error.Fatalf("Couldn't create database: %v", err)
|
||||||
return err
|
return err
|
||||||
@@ -82,24 +82,24 @@ func createSubscriptionModels() []models.SubscriptionModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLicenceCategories() []models.LicenceCategory {
|
func createLicenceCategories() []models.Category {
|
||||||
return []models.LicenceCategory{
|
return []models.Category{
|
||||||
{Category: "AM"},
|
{Name: "AM"},
|
||||||
{Category: "A1"},
|
{Name: "A1"},
|
||||||
{Category: "A2"},
|
{Name: "A2"},
|
||||||
{Category: "A"},
|
{Name: "A"},
|
||||||
{Category: "B"},
|
{Name: "B"},
|
||||||
{Category: "C1"},
|
{Name: "C1"},
|
||||||
{Category: "C"},
|
{Name: "C"},
|
||||||
{Category: "D1"},
|
{Name: "D1"},
|
||||||
{Category: "D"},
|
{Name: "D"},
|
||||||
{Category: "BE"},
|
{Name: "BE"},
|
||||||
{Category: "C1E"},
|
{Name: "C1E"},
|
||||||
{Category: "CE"},
|
{Name: "CE"},
|
||||||
{Category: "D1E"},
|
{Name: "D1E"},
|
||||||
{Category: "DE"},
|
{Name: "DE"},
|
||||||
{Category: "T"},
|
{Name: "T"},
|
||||||
{Category: "L"},
|
{Name: "L"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ func createAdmin(userMail string, subscriptionModelID uint) (*models.User, error
|
|||||||
SubscriptionModelID: subscriptionModelID,
|
SubscriptionModelID: subscriptionModelID,
|
||||||
},
|
},
|
||||||
BankAccount: models.BankAccount{},
|
BankAccount: models.BankAccount{},
|
||||||
DriversLicence: models.DriversLicence{
|
Licence: models.Licence{
|
||||||
Status: constants.UnverifiedStatus,
|
Status: constants.UnverifiedStatus,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DriversLicence struct {
|
type Licence struct {
|
||||||
ID uint `json:"id" gorm:"primaryKey"`
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
Status int8 `json:"status" binding:"omitempty,number"`
|
Status int8 `json:"status" binding:"omitempty,number"`
|
||||||
LicenceNumber string `json:"number" binding:"omitempty,euDriversLicence,safe_content"`
|
Number string `json:"number" binding:"omitempty,euDriversLicence,safe_content"`
|
||||||
IssuedDate time.Time `json:"issued_date" binding:"omitempty,lte"`
|
IssuedDate time.Time `json:"issued_date" binding:"omitempty,lte"`
|
||||||
ExpirationDate time.Time `json:"expiration_date" binding:"omitempty,gt"`
|
ExpirationDate time.Time `json:"expiration_date" binding:"omitempty,gt"`
|
||||||
IssuingCountry string `json:"country" binding:"safe_content"`
|
IssuingCountry string `json:"country" binding:"safe_content"`
|
||||||
LicenceCategories []LicenceCategory `json:"licence_categories" gorm:"many2many:licence_2_categories"`
|
Categories []Category `json:"licence_categories" gorm:"many2many:licence_2_categories"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LicenceCategory struct {
|
type Category struct {
|
||||||
ID uint `json:"id" gorm:"primaryKey"`
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
Category string `json:"category" binding:"safe_content"`
|
Name string `json:"category" binding:"safe_content"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ type User struct {
|
|||||||
VerificationID uint
|
VerificationID uint
|
||||||
Membership Membership `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"membership"`
|
Membership Membership `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"membership"`
|
||||||
MembershipID uint
|
MembershipID uint
|
||||||
DriversLicence DriversLicence `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"drivers_licence"`
|
Licence Licence `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"licence"`
|
||||||
DriversLicenceID uint
|
LicenceID uint
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
PaymentStatus int8 `json:"payment_status"`
|
PaymentStatus int8 `json:"payment_status"`
|
||||||
Status int8 `json:"status"`
|
Status int8 `json:"status"`
|
||||||
@@ -99,14 +99,14 @@ func (u *User) Safe() map[string]interface{} {
|
|||||||
"bic": u.BankAccount.BIC,
|
"bic": u.BankAccount.BIC,
|
||||||
"mandate_reference": u.BankAccount.MandateReference,
|
"mandate_reference": u.BankAccount.MandateReference,
|
||||||
},
|
},
|
||||||
"drivers_licence": map[string]interface{}{
|
"licence": map[string]interface{}{
|
||||||
"id": u.DriversLicence.ID,
|
"id": u.Licence.ID,
|
||||||
"licence_number": u.DriversLicence.LicenceNumber,
|
"number": u.Licence.Number,
|
||||||
"status": u.DriversLicence.Status,
|
"status": u.Licence.Status,
|
||||||
"issued_date": u.DriversLicence.IssuedDate,
|
"issued_date": u.Licence.IssuedDate,
|
||||||
"expiration_date": u.DriversLicence.ExpirationDate,
|
"expiration_date": u.Licence.ExpirationDate,
|
||||||
"country": u.DriversLicence.IssuingCountry,
|
"country": u.Licence.IssuingCountry,
|
||||||
"licence_categories": u.DriversLicence.LicenceCategories,
|
"licence_categories": u.Licence.Categories,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
package repositories
|
|
||||||
|
|
||||||
import (
|
|
||||||
"GoMembership/internal/database"
|
|
||||||
"GoMembership/internal/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DriversLicenceInterface interface {
|
|
||||||
FindCategoryByName(categoryName string) (models.LicenceCategory, error)
|
|
||||||
FindCategoriesByIDs(ids []uint) ([]models.LicenceCategory, error)
|
|
||||||
GetAllCategories() ([]models.LicenceCategory, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DriversLicenceRepository struct{}
|
|
||||||
|
|
||||||
func (r *DriversLicenceRepository) GetAllCategories() ([]models.LicenceCategory, error) {
|
|
||||||
var categories []models.LicenceCategory
|
|
||||||
err := database.DB.Find(&categories).Error
|
|
||||||
return categories, err
|
|
||||||
}
|
|
||||||
func (r *DriversLicenceRepository) FindCategoriesByIDs(ids []uint) ([]models.LicenceCategory, error) {
|
|
||||||
var categories []models.LicenceCategory
|
|
||||||
err := database.DB.Where("id IN ?", ids).Find(&categories).Error
|
|
||||||
return categories, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *DriversLicenceRepository) FindCategoryByName(categoryName string) (models.LicenceCategory, error) {
|
|
||||||
var category models.LicenceCategory
|
|
||||||
err := database.DB.Where("category = ?", categoryName).First(&category).Error
|
|
||||||
return category, err
|
|
||||||
}
|
|
||||||
31
internal/repositories/licence_repository.go
Normal file
31
internal/repositories/licence_repository.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"GoMembership/internal/database"
|
||||||
|
"GoMembership/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LicenceInterface interface {
|
||||||
|
FindCategoryByName(categoryName string) (models.Category, error)
|
||||||
|
FindCategoriesByIDs(ids []uint) ([]models.Category, error)
|
||||||
|
GetAllCategories() ([]models.Category, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type LicenceRepository struct{}
|
||||||
|
|
||||||
|
func (r *LicenceRepository) GetAllCategories() ([]models.Category, error) {
|
||||||
|
var categories []models.Category
|
||||||
|
err := database.DB.Find(&categories).Error
|
||||||
|
return categories, err
|
||||||
|
}
|
||||||
|
func (r *LicenceRepository) FindCategoriesByIDs(ids []uint) ([]models.Category, error) {
|
||||||
|
var categories []models.Category
|
||||||
|
err := database.DB.Where("id IN ?", ids).Find(&categories).Error
|
||||||
|
return categories, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *LicenceRepository) FindCategoryByName(categoryName string) (models.Category, error) {
|
||||||
|
var category models.Category
|
||||||
|
err := database.DB.Where("category = ?", categoryName).First(&category).Error
|
||||||
|
return category, err
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
|
|||||||
err := database.DB.Transaction(func(tx *gorm.DB) error {
|
err := database.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
// Check if the user exists in the database
|
// Check if the user exists in the database
|
||||||
var existingUser models.User
|
var existingUser models.User
|
||||||
if err := tx.Preload("DriversLicence.LicenceCategories").
|
if err := tx.Preload("Licence.Categories").
|
||||||
Preload("Membership").
|
Preload("Membership").
|
||||||
First(&existingUser, user.ID).Error; err != nil {
|
First(&existingUser, user.ID).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -57,9 +57,9 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle the update of the LicenceCategories explicitly
|
// Handle the update of the LicenceCategories explicitly
|
||||||
if user.DriversLicence.ID != 0 {
|
if user.Licence.ID != 0 {
|
||||||
// Replace the LicenceCategories with the new list
|
// Replace the Categories with the new list
|
||||||
if err := tx.Model(&existingUser.DriversLicence).Association("LicenceCategories").Replace(user.DriversLicence.LicenceCategories); err != nil {
|
if err := tx.Model(&existingUser.Licence).Association("Categories").Replace(user.Licence.Categories); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,9 +71,9 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the DriversLicence fields if provided
|
// Update the Licence fields if provided
|
||||||
if user.DriversLicence.ID != 0 {
|
if user.Licence.ID != 0 {
|
||||||
if err := tx.Model(&existingUser.DriversLicence).Updates(user.DriversLicence).Error; err != nil {
|
if err := tx.Model(&existingUser.Licence).Updates(user.Licence).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var updatedUser models.User
|
var updatedUser models.User
|
||||||
if err := database.DB.Preload("DriversLicence.LicenceCategories").
|
if err := database.DB.Preload("Licence.Categories").
|
||||||
Preload("Membership").
|
Preload("Membership").
|
||||||
First(&updatedUser, user.ID).Error; err != nil {
|
First(&updatedUser, user.ID).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -99,7 +99,7 @@ func (ur *UserRepository) GetUsers(where map[string]interface{}) (*[]models.User
|
|||||||
result := database.DB.
|
result := database.DB.
|
||||||
Preload(clause.Associations).
|
Preload(clause.Associations).
|
||||||
Preload("Membership.SubscriptionModel").
|
Preload("Membership.SubscriptionModel").
|
||||||
Preload("DriversLicence.LicenceCategories").
|
Preload("Licence.Categories").
|
||||||
Where(where).Find(&users)
|
Where(where).Find(&users)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
if result.Error == gorm.ErrRecordNotFound {
|
if result.Error == gorm.ErrRecordNotFound {
|
||||||
@@ -115,7 +115,7 @@ func GetUserByID(userID *uint) (*models.User, error) {
|
|||||||
result := database.DB.
|
result := database.DB.
|
||||||
Preload(clause.Associations).
|
Preload(clause.Associations).
|
||||||
Preload("Membership.SubscriptionModel").
|
Preload("Membership.SubscriptionModel").
|
||||||
Preload("DriversLicence.LicenceCategories").
|
Preload("Licence.Categories").
|
||||||
First(&user, userID)
|
First(&user, userID)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
if result.Error == gorm.ErrRecordNotFound {
|
if result.Error == gorm.ErrRecordNotFound {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterRoutes(router *gin.Engine, userController *controllers.UserController, membershipcontroller *controllers.MembershipController, contactController *controllers.ContactController) {
|
func RegisterRoutes(router *gin.Engine, userController *controllers.UserController, membershipcontroller *controllers.MembershipController, contactController *controllers.ContactController, licenceController *controllers.LicenceController) {
|
||||||
router.GET("/users/verify", userController.VerifyMailHandler)
|
router.GET("/users/verify", userController.VerifyMailHandler)
|
||||||
router.POST("/users/register", userController.RegisterUser)
|
router.POST("/users/register", userController.RegisterUser)
|
||||||
router.POST("/users/contact", contactController.RelayContactRequest)
|
router.POST("/users/contact", contactController.RelayContactRequest)
|
||||||
@@ -21,12 +21,23 @@ func RegisterRoutes(router *gin.Engine, userController *controllers.UserControll
|
|||||||
router.POST("/v1/subscription", membershipcontroller.RegisterSubscription)
|
router.POST("/v1/subscription", membershipcontroller.RegisterSubscription)
|
||||||
}
|
}
|
||||||
|
|
||||||
authRouter := router.Group("/backend/users")
|
userRouter := router.Group("/backend/users")
|
||||||
authRouter.Use(middlewares.AuthMiddleware())
|
userRouter.Use(middlewares.AuthMiddleware())
|
||||||
{
|
{
|
||||||
authRouter.GET("/current", userController.CurrentUserHandler)
|
userRouter.GET("/current", userController.CurrentUserHandler)
|
||||||
authRouter.POST("/logout", userController.LogoutHandler)
|
userRouter.POST("/logout", userController.LogoutHandler)
|
||||||
authRouter.PATCH("/update", userController.UpdateHandler)
|
userRouter.PATCH("/update", userController.UpdateHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
membershipRouter := router.Group("/backend/membership")
|
||||||
|
membershipRouter.Use(middlewares.AuthMiddleware())
|
||||||
|
{
|
||||||
|
membershipRouter.GET("/subscriptions", membershipcontroller.GetSubscriptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
licenceRouter := router.Group("/backend/licence")
|
||||||
|
licenceRouter.Use(middlewares.AuthMiddleware())
|
||||||
|
{
|
||||||
|
licenceRouter.GET("/categories", licenceController.GetAllCategories)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,14 +39,15 @@ func Run() {
|
|||||||
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
|
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
|
||||||
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
|
||||||
|
|
||||||
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
||||||
|
licenceService := &services.LicenceService{Repo: licenceRepo}
|
||||||
|
|
||||||
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
|
||||||
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
|
|
||||||
driversLicenceService := &services.DriversLicenceService{Repo: licenceRepo}
|
|
||||||
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
|
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
|
||||||
|
|
||||||
userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, DriversLicenceService: driversLicenceService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, LicenceService: licenceService, BankAccountService: bankAccountService, MembershipService: membershipService}
|
||||||
membershipController := &controllers.MembershipController{Service: *membershipService}
|
membershipController := &controllers.MembershipController{Service: *membershipService}
|
||||||
|
licenceController := &controllers.LicenceController{Service: *licenceService}
|
||||||
contactController := &controllers.ContactController{EmailService: emailService}
|
contactController := &controllers.ContactController{EmailService: emailService}
|
||||||
|
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
@@ -63,7 +64,7 @@ func Run() {
|
|||||||
limiter := middlewares.NewIPRateLimiter(config.Security.Ratelimits.Limit, config.Security.Ratelimits.Burst)
|
limiter := middlewares.NewIPRateLimiter(config.Security.Ratelimits.Limit, config.Security.Ratelimits.Burst)
|
||||||
router.Use(middlewares.RateLimitMiddleware(limiter))
|
router.Use(middlewares.RateLimitMiddleware(limiter))
|
||||||
|
|
||||||
routes.RegisterRoutes(router, userController, membershipController, contactController)
|
routes.RegisterRoutes(router, userController, membershipController, contactController, licenceController)
|
||||||
validation.SetupValidators()
|
validation.SetupValidators()
|
||||||
|
|
||||||
logger.Info.Println("Starting server on :8080")
|
logger.Info.Println("Starting server on :8080")
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"GoMembership/internal/models"
|
|
||||||
"GoMembership/internal/repositories"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DriversLicenceInterface interface {
|
|
||||||
GetAllCategories() ([]models.LicenceCategory, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DriversLicenceService struct {
|
|
||||||
Repo repositories.DriversLicenceInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DriversLicenceService) GetAllCategories() ([]models.LicenceCategory, error) {
|
|
||||||
return s.Repo.GetAllCategories()
|
|
||||||
}
|
|
||||||
18
internal/services/licence_service.go
Normal file
18
internal/services/licence_service.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"GoMembership/internal/models"
|
||||||
|
"GoMembership/internal/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LicenceInterface interface {
|
||||||
|
GetAllCategories() ([]models.Category, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type LicenceService struct {
|
||||||
|
Repo repositories.LicenceInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LicenceService) GetAllCategories() ([]models.Category, error) {
|
||||||
|
return s.Repo.GetAllCategories()
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ type UserServiceInterface interface {
|
|||||||
|
|
||||||
type UserService struct {
|
type UserService struct {
|
||||||
Repo repositories.UserRepositoryInterface
|
Repo repositories.UserRepositoryInterface
|
||||||
Licences repositories.DriversLicenceInterface
|
Licences repositories.LicenceInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *UserService) UpdateUser(user *models.User, userRole int8) (*models.User, error) {
|
func (service *UserService) UpdateUser(user *models.User, userRole int8) (*models.User, error) {
|
||||||
@@ -38,9 +38,9 @@ func (service *UserService) UpdateUser(user *models.User, userRole int8) (*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.UpdatedAt = time.Now()
|
user.UpdatedAt = time.Now()
|
||||||
if user.DriversLicence.Status == 0 {
|
if user.Licence.Status == 0 {
|
||||||
// This is a new drivers licence
|
// This is a new drivers licence
|
||||||
user.DriversLicence.Status = constants.UnverifiedStatus
|
user.Licence.Status = constants.UnverifiedStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedUser, err := service.Repo.UpdateUser(user)
|
updatedUser, err := service.Repo.UpdateUser(user)
|
||||||
@@ -66,7 +66,7 @@ func (service *UserService) RegisterUser(user *models.User) (uint, string, error
|
|||||||
user.CreatedAt = time.Now()
|
user.CreatedAt = time.Now()
|
||||||
user.UpdatedAt = time.Now()
|
user.UpdatedAt = time.Now()
|
||||||
user.PaymentStatus = constants.AwaitingPaymentStatus
|
user.PaymentStatus = constants.AwaitingPaymentStatus
|
||||||
user.DriversLicence.Status = constants.UnverifiedStatus
|
user.Licence.Status = constants.UnverifiedStatus
|
||||||
user.BankAccount.MandateDateSigned = time.Now()
|
user.BankAccount.MandateDateSigned = time.Now()
|
||||||
id, err := service.Repo.CreateUser(user)
|
id, err := service.Repo.CreateUser(user)
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ValidateDriversLicence(fl validator.FieldLevel) bool {
|
func ValidateLicence(fl validator.FieldLevel) bool {
|
||||||
fieldValue := fl.Field().String()
|
fieldValue := fl.Field().String()
|
||||||
if len(fieldValue) != 11 {
|
if len(fieldValue) != 11 {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func SetupValidators() {
|
|||||||
v.RegisterValidation("safe_content", ValidateSafeContent)
|
v.RegisterValidation("safe_content", ValidateSafeContent)
|
||||||
v.RegisterValidation("iban", IBANValidator)
|
v.RegisterValidation("iban", IBANValidator)
|
||||||
v.RegisterValidation("bic", BICValidator)
|
v.RegisterValidation("bic", BICValidator)
|
||||||
v.RegisterValidation("euDriversLicence", ValidateDriversLicence)
|
v.RegisterValidation("euDriversLicence", ValidateLicence)
|
||||||
|
|
||||||
// Register struct-level validations
|
// Register struct-level validations
|
||||||
v.RegisterStructValidation(validateUser, models.User{})
|
v.RegisterStructValidation(validateUser, models.User{})
|
||||||
|
|||||||
Reference in New Issue
Block a user