feat: add organisations as model

This commit is contained in:
Reto Aebersold 2023-11-14 17:13:27 +01:00 committed by Christian Cueni
parent 0f6232e6f4
commit 437ffde8b1
15 changed files with 245 additions and 138 deletions

View File

@ -14,18 +14,30 @@ import { profileNextRoute } from "@/services/onboarding";
const { t } = useTranslation();
type Organisation = {
id: string;
name: string;
organisation_id: number;
name_de: string;
name_fr: string;
name_it: string;
};
const user = useUserStore();
const route = useRoute();
const fetchResult = useFetch("/api/core/organisations/");
const organisations: Ref<Organisation[] | null> = fetchResult.data;
const organisationData: Ref<Organisation[] | null> = fetchResult.data;
const organisations = computed(() => {
if (organisationData.value) {
return organisationData.value.map((c) => ({
id: c.organisation_id,
name: c[`name_${user.language}`],
}));
}
return [];
});
const selectedOrganisation = ref({
id: "0",
id: 0,
name: t("a.Auswählen"),
});
@ -58,7 +70,6 @@ watch(avatarFileInfo, (info) => {
});
watch(selectedOrganisation, (organisation) => {
console.log("organisation changed", organisation);
itPut("/api/core/me/", {
organisation: organisation.id,
});
@ -82,7 +93,7 @@ const nextRoute = computed(() => {
</p>
<ItDropdownSelect
v-if="organisations"
v-if="organisationData"
v-model="selectedOrganisation"
:items="organisations"
/>

View File

@ -25,7 +25,7 @@ export type UserState = {
email: string;
username: string;
avatar_url: string;
organisation: string;
organisation: number;
is_superuser: boolean;
course_session_experts: string[];
loggedIn: boolean;
@ -58,7 +58,7 @@ const initialUserState: UserState = {
username: "",
avatar_url: "",
is_superuser: false,
organisation: "",
organisation: 0,
course_session_experts: [],
loggedIn: false,
language: defaultLanguage,

View File

@ -13,6 +13,7 @@ from graphene_django.views import GraphQLView
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from vbv_lernwelt.api.user import list_organisations, me_user_view
from vbv_lernwelt.assignment.views import request_assignment_completion_status
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
from vbv_lernwelt.core.schema import schema
@ -20,8 +21,6 @@ from vbv_lernwelt.core.views import (
check_rate_limit,
cypress_reset_view,
generate_web_component_icons,
list_organisations,
me_user_view,
permission_denied_view,
rate_limit_exceeded_view,
vue_home,

View File

View File

@ -30,10 +30,10 @@ class MeUserViewTest(APITestCase):
url = reverse("me_user_view") # replace with your actual URL name
# WHEN
response = self.client.put(url, {"organisation": "6"})
response = self.client.put(url, {"organisation": 6})
# THEN
self.assertEqual(response.status_code, status.HTTP_200_OK)
updated_user = User.objects.get(username="testuser")
self.assertEquals(updated_user.organisation, "6")
self.assertEquals(updated_user.organisation.organisation_id, 6)

View File

@ -3,7 +3,6 @@ from rest_framework import status
from rest_framework.test import APITestCase
from vbv_lernwelt.core.models import User
from vbv_lernwelt.core.organisations import ORGANISATIONS
class OrganisationViewTest(APITestCase):
@ -23,5 +22,12 @@ class OrganisationViewTest(APITestCase):
# THEN
self.assertEqual(response.status_code, status.HTTP_200_OK)
_id, name = ORGANISATIONS[0]
self.assertEqual(response.data[0], {"id": _id, "name": name})
self.assertEqual(
response.data[0],
{
"organisation_id": 1,
"name_de": "andere Broker",
"name_fr": "autres Broker",
"name_it": "altre Broker",
},
)

View File

@ -0,0 +1,35 @@
from rest_framework.decorators import api_view
from rest_framework.response import Response
from vbv_lernwelt.core.models import Organisation
from vbv_lernwelt.core.serializers import OrganisationSerializer, UserSerializer
@api_view(["GET"])
def list_organisations(request):
if not request.user.is_authenticated:
return Response(status=403)
serializer = OrganisationSerializer(Organisation.objects.all(), many=True)
return Response(serializer.data)
@api_view(["GET", "PUT"])
def me_user_view(request):
if not request.user.is_authenticated:
return Response(status=403)
if request.method == "GET":
return Response(UserSerializer(request.user).data)
if request.method == "PUT":
serializer = UserSerializer(
request.user,
data=request.data,
partial=True,
)
if serializer.is_valid():
serializer.save()
return Response(UserSerializer(request.user).data)
return Response(status=400)

View File

@ -2,7 +2,7 @@ from django.contrib import admin
from django.contrib.auth import admin as auth_admin, get_user_model
from django.utils.translation import gettext_lazy as _
from vbv_lernwelt.core.models import JobLog
from vbv_lernwelt.core.models import JobLog, Organisation
from vbv_lernwelt.core.utils import pretty_print_json
User = get_user_model()
@ -78,3 +78,13 @@ class JobLogAdmin(LogAdmin):
if obj.ended:
return (obj.ended - obj.started).seconds // 60
return None
@admin.register(Organisation)
class OrganisationAdmin(admin.ModelAdmin):
list_display = (
"organisation_id",
"name_de",
"name_fr",
"name_it",
)

View File

@ -0,0 +1,145 @@
import django.db.models.deletion
from django.db import migrations, models
orgs = {
1: {"de": "andere Broker", "fr": "autres Broker", "it": "altre Broker"},
2: {
"de": "andere Krankenversicherer",
"fr": "autres assureurs santé",
"it": "altre assicurazioni sanitarie",
},
3: {
"de": "andere Privatversicherer",
"fr": "autres Assurance privée",
"it": "altre Assicurazione privato",
},
4: {"de": "Allianz Suisse", "fr": "Allianz Suisse", "it": "Allianz Suisse"},
5: {"de": "AON", "fr": "AON", "it": "AON"},
6: {
"de": "AXA Winterthur",
"fr": "AXA Assurances SA",
"it": "AXA Assicurazioni SA",
},
7: {"de": "Baloise", "fr": "Baloise", "it": "Baloise"},
8: {
"de": "CAP Rechtsschutz",
"fr": "CAP Protection juridique",
"it": "CAP Protezione giuridica",
},
9: {
"de": "Coop Rechtsschutz",
"fr": "Coop Protection juridique",
"it": "Coop Protezione giuridica",
},
10: {"de": "CSS", "fr": "CSS", "it": "CSS"},
11: {"de": "Die Mobiliar", "fr": "La Mobilière", "it": "La Mobiliare"},
12: {
"de": "Emmental Versicherung",
"fr": "Emmental Assurance",
"it": "Emmental Assicurazione",
},
13: {
"de": "GENERALI Versicherungen",
"fr": "Generali Assurances",
"it": "Generali Assicurazioni",
},
14: {"de": "Groupe Mutuel", "fr": "GROUPE MUTUEL", "it": "GROUPE MUTUEL"},
15: {"de": "Helsana", "fr": "Helsana", "it": "Helsana"},
16: {"de": "Helvetia", "fr": "Helvetia", "it": "Helvetia"},
17: {"de": "Kessler & Co AG", "fr": "Kessler & Co AG", "it": "Kessler & Co AG"},
18: {
"de": "Orion Rechtsschutz Versicherung",
"fr": "Orion Protection juridique",
"it": "Orion Protezione giuridica",
},
19: {"de": "PAX", "fr": "PAX", "it": "PAX"},
20: {"de": "Sanitas", "fr": "Sanitas", "it": "Sanitas"},
21: {"de": "SUVA", "fr": "SUVA", "it": "SUVA"},
22: {"de": "Swica", "fr": "Swica", "it": "Swica"},
23: {"de": "Swiss Life", "fr": "Swiss Life", "it": "Swiss Life"},
24: {"de": "Swiss Re", "fr": "Swiss Re", "it": "Swiss Re"},
25: {
"de": "Visana Services AG",
"fr": "Visana Services SA",
"it": "Visana Services SA",
},
26: {
"de": "VZ VermögensZentrum AG",
"fr": "VZ VermögensZentrum AG",
"it": "VZ VermögensZentrum AG",
},
27: {
"de": "Würth Financial Services AG",
"fr": "Würth Financial Services SA",
"it": "Würth Financial Services SA",
},
28: {"de": "Zürich", "fr": "Zurich", "it": "Zurigo"},
29: {"de": "VBV", "fr": "AFA", "it": "AFA"},
30: {"de": "Vaudoise", "fr": "Vaudoise", "it": "Vaudoise"},
31: {
"de": "Keine Firmenzugehörigkeit",
"fr": "Pas d'appartenance à une entreprise",
"it": "Nessuna affiliazione aziendale",
},
}
def add_organisations(apps, schema_editor):
Organisation = apps.get_model("core", "Organisation")
for org_id, org_data in orgs.items():
Organisation.objects.create(
organisation_id=org_id,
name_de=org_data["de"],
name_fr=org_data["fr"],
name_it=org_data["it"],
)
def remove_organisations(apps, schema_editor):
Organisation = apps.get_model("core", "Organisation")
for org_id, org_data in orgs.items():
Organisation.objects.filter(
organisation_id=org_id,
name_de=org_data["de"],
name_fr=org_data["fr"],
name_it=org_data["it"],
).delete()
class Migration(migrations.Migration):
dependencies = [
("core", "0002_joblog"),
]
operations = [
migrations.CreateModel(
name="Organisation",
fields=[
(
"organisation_id",
models.IntegerField(primary_key=True, serialize=False),
),
("name_de", models.CharField(max_length=255)),
("name_fr", models.CharField(max_length=255)),
("name_it", models.CharField(max_length=255)),
],
options={
"verbose_name": "Organisation",
"verbose_name_plural": "Organisations",
"ordering": ["organisation_id"],
},
),
migrations.AddField(
model_name="user",
name="organisation",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="core.organisation",
),
),
migrations.RunPython(add_organisations, remove_organisations),
]

View File

@ -1,53 +0,0 @@
# Generated by Django 3.2.20 on 2023-11-13 13:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("core", "0002_joblog"),
]
operations = [
migrations.AddField(
model_name="user",
name="organisation",
field=models.CharField(
blank=True,
choices=[
("1", "Andere Broker"),
("2", "Andere Krankenversicherer"),
("3", "Andere Privatversicherer"),
("4", "Allianz Suisse"),
("5", "AON"),
("6", "AXA Winterthur"),
("7", "Baloise"),
("8", "CAP Rechtsschutz"),
("9", "Coop Rechtsschutz"),
("10", "CSS"),
("11", "Die Mobiliar"),
("12", "Emmental Versicherung"),
("13", "GENERALI Versicherungen"),
("14", "Groupe Mutuel"),
("15", "Helsana"),
("16", "Helvetia"),
("17", "Kessler & Co AG"),
("18", "Orion Rechtsschutz Versicherung"),
("19", "PAX"),
("20", "Sanitas"),
("21", "SUVA"),
("22", "Swica"),
("23", "Swiss Life"),
("24", "Swiss Re"),
("25", "Visana Services AG"),
("26", "VZ VermögensZentrum AG"),
("27", "Würth Financial Services AG"),
("28", "Zürich"),
("29", "VBV"),
("30", "Vaudoise"),
("31", "Keine Firmenzugehörigkeit"),
],
max_length=255,
),
),
]

View File

@ -4,7 +4,20 @@ from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models import JSONField
from vbv_lernwelt.core.organisations import ORGANISATIONS
class Organisation(models.Model):
organisation_id = models.IntegerField(primary_key=True)
name_de = models.CharField(max_length=255)
name_fr = models.CharField(max_length=255)
name_it = models.CharField(max_length=255)
def __str__(self):
return f"{self.name_de} ({self.organisation_id})"
class Meta:
verbose_name = "Organisation"
verbose_name_plural = "Organisations"
ordering = ["organisation_id"]
class User(AbstractUser):
@ -31,10 +44,8 @@ class User(AbstractUser):
additional_json_data = JSONField(default=dict, blank=True)
language = models.CharField(max_length=2, choices=LANGUAGE_CHOICES, default="de")
organisation = models.CharField(
max_length=255,
choices=ORGANISATIONS,
blank=True,
organisation = models.ForeignKey(
Organisation, on_delete=models.SET_NULL, null=True, blank=True
)

View File

@ -1,33 +0,0 @@
ORGANISATIONS = [
("1", "Andere Broker"),
("2", "Andere Krankenversicherer"),
("3", "Andere Privatversicherer"),
("4", "Allianz Suisse"),
("5", "AON"),
("6", "AXA Winterthur"),
("7", "Baloise"),
("8", "CAP Rechtsschutz"),
("9", "Coop Rechtsschutz"),
("10", "CSS"),
("11", "Die Mobiliar"),
("12", "Emmental Versicherung"),
("13", "GENERALI Versicherungen"),
("14", "Groupe Mutuel"),
("15", "Helsana"),
("16", "Helvetia"),
("17", "Kessler & Co AG"),
("18", "Orion Rechtsschutz Versicherung"),
("19", "PAX"),
("20", "Sanitas"),
("21", "SUVA"),
("22", "Swica"),
("23", "Swiss Life"),
("24", "Swiss Re"),
("25", "Visana Services AG"),
("26", "VZ VermögensZentrum AG"),
("27", "Würth Financial Services AG"),
("28", "Zürich"),
("29", "VBV"),
("30", "Vaudoise"),
("31", "Keine Firmenzugehörigkeit"),
]

View File

@ -3,7 +3,7 @@ from typing import List
from rest_framework import serializers
from rest_framework.renderers import JSONRenderer
from vbv_lernwelt.core.models import User
from vbv_lernwelt.core.models import Organisation, User
from vbv_lernwelt.course.models import CourseSessionUser
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
@ -53,3 +53,9 @@ class UserSerializer(serializers.ModelSerializer):
)
return [str(_id) for _id in (supervisor_in_session_ids | expert_in_session_ids)]
class OrganisationSerializer(serializers.ModelSerializer):
class Meta:
model = Organisation
fields = "__all__"

View File

@ -27,7 +27,6 @@ from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
from vbv_lernwelt.core.organisations import ORGANISATIONS
from vbv_lernwelt.core.serializers import UserSerializer
logger = structlog.get_logger(__name__)
@ -91,35 +90,6 @@ def vue_login(request):
)
@api_view(["GET"])
def list_organisations(request):
if not request.user.is_authenticated:
return Response(status=403)
return Response([{"id": _id, "name": name} for _id, name in ORGANISATIONS])
@api_view(["GET", "PUT"])
def me_user_view(request):
if not request.user.is_authenticated:
return Response(status=403)
if request.method == "GET":
return Response(UserSerializer(request.user).data)
if request.method == "PUT":
serializer = UserSerializer(
request.user,
data=request.data,
partial=True,
)
if serializer.is_valid():
serializer.save()
return Response(UserSerializer(request.user).data)
return Response(status=400)
@api_view(["POST"])
def vue_logout(request):
logout(request)