Commit 1926238c authored by Florent Chehab's avatar Florent Chehab
Browse files

Tweaks and new modules for userData

parent 34b53036
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
!include AbstractModules.pu !include AbstractModules.pu
!include Core.pu !include Core.pu
!include CountryModules.pu
!include CityModules.pu !include CityModules.pu
!include UniversityModules.pu !include UniversityModules.pu
!include CountryModules.pu
!include CampusAndModules.pu !include CampusAndModules.pu
!include UserFunctions.pu !include UserFunctions.pu
......
...@@ -21,17 +21,17 @@ package Campus { ...@@ -21,17 +21,17 @@ package Campus {
class CultureAndStudentLife class CultureAndStudentLife
class Accomodation class Accomodation
class Transport class Transport
class OtherStuff class CampusOtherStuff
CultureAndStudentLife -up-|> BasicModuleCopyCampusExtra CultureAndStudentLife -up-|> BasicModuleCopyCampusExtra
Accomodation -up-|> BasicModuleCopyCampusExtra Accomodation -up-|> BasicModuleCopyCampusExtra
Transport -up-|> BasicModuleCopyCampusExtra Transport -up-|> BasicModuleCopyCampusExtra
OtherStuff -up-|> BasicModuleCopyCampusExtra CampusOtherStuff -up-|> BasicModuleCopyCampusExtra
CultureAndStudentLife "1" -down[bold,#green]- "1" Campus CultureAndStudentLife "1" -down[bold,#green]- "1" Campus
Accomodation "1" -down[bold,#green]- "1" Campus Accomodation "1" -down[bold,#green]- "1" Campus
Transport "1" -down[bold,#green]- "1" Campus Transport "1" -down[bold,#green]- "1" Campus
OtherStuff "1" -down[bold,#green]- "1" Campus CampusOtherStuff "1" -down[bold,#green]- "1" Campus
} }
Campus "1..n" -- "1" University Campus "1..n" -- "1" University
......
...@@ -25,9 +25,11 @@ package CountryModule{ ...@@ -25,9 +25,11 @@ package CountryModule{
CountryTransport -up-|> BasicModuleCopyCountry CountryTransport -up-|> BasicModuleCopyCountry
CountryTourism -up-|> BasicModuleCopyCountry CountryTourism -up-|> BasicModuleCopyCountry
CountryPhoto -up-|> PhotoCopyCountry CountryPhoto -left-|> PhotoCopyCountry
CountryPhoto "*" -right- "1" CountryVirtualCopy
ScholarshipCountry -up-|> ScholarShipCopyCountry ScholarshipCountry -right-|> ScholarShipCopyCountry
ScholarshipCountry "*" -left- "*" CountryVirtualCopy
class CountryVirtualCopy as "Country" < copy for\n cleaner UML> #lightgrey class CountryVirtualCopy as "Country" < copy for\n cleaner UML> #lightgrey
...@@ -39,9 +41,7 @@ package CountryModule{ ...@@ -39,9 +41,7 @@ package CountryModule{
CountryOtherStuff "1" -down[bold,#green]- "1" CountryVirtualCopy CountryOtherStuff "1" -down[bold,#green]- "1" CountryVirtualCopy
CountryTransport "1" -down[bold,#green]- "1" CountryVirtualCopy CountryTransport "1" -down[bold,#green]- "1" CountryVirtualCopy
CountryTourism "1" -down[bold,#green]- "1" CountryVirtualCopy CountryTourism "1" -down[bold,#green]- "1" CountryVirtualCopy
CountryPhoto "1" -down[bold,#green]- "1" CountryVirtualCopy
ScholarshipCountry "*" -down- "*" CountryVirtualCopy
} }
CountryVirtualCopy -down[bold,#green]- Country CountryVirtualCopy -down[bold,#green]- Country
......
...@@ -13,7 +13,7 @@ package UniversityModule{ ...@@ -13,7 +13,7 @@ package UniversityModule{
class UniversityPhoto class UniversityPhoto
class Courses class Courses
class SpecialOffer class SpecialOffer
class OtherStuff class UniversityOtherStuff
class Insurances class Insurances
class SemestersDates{ class SemestersDates{
...@@ -31,7 +31,7 @@ package UniversityModule{ ...@@ -31,7 +31,7 @@ package UniversityModule{
CultureUniversity -up-|> BasicModuleCopyUniversity CultureUniversity -up-|> BasicModuleCopyUniversity
Courses -up-|> BasicModuleCopyUniversity Courses -up-|> BasicModuleCopyUniversity
SpecialOffer -up-|> BasicModuleCopyUniversity SpecialOffer -up-|> BasicModuleCopyUniversity
OtherStuff -up-|> BasicModuleCopyUniversity UniversityOtherStuff -up-|> BasicModuleCopyUniversity
Insurances -up-|> BasicModuleCopyUniversity Insurances -up-|> BasicModuleCopyUniversity
SemestersDates -up-|> BasicModuleCopyUniversity SemestersDates -up-|> BasicModuleCopyUniversity
UniversityInfo -up-|> BasicModuleCopyUniversity UniversityInfo -up-|> BasicModuleCopyUniversity
...@@ -46,7 +46,7 @@ package UniversityModule{ ...@@ -46,7 +46,7 @@ package UniversityModule{
CultureUniversity "1" -down[bold,#green]- "1" UniversityVirtualCopy CultureUniversity "1" -down[bold,#green]- "1" UniversityVirtualCopy
UniversityPhoto "*" -right- "1" UniversityVirtualCopy UniversityPhoto "*" -right- "1" UniversityVirtualCopy
Courses "1" -down[bold,#green]- "1" UniversityVirtualCopy Courses "1" -down[bold,#green]- "1" UniversityVirtualCopy
OtherStuff "1" -down[bold,#green]- "1" UniversityVirtualCopy UniversityOtherStuff "1" -down[bold,#green]- "1" UniversityVirtualCopy
Insurances "1" -down[bold,#green]- "1" UniversityVirtualCopy Insurances "1" -down[bold,#green]- "1" UniversityVirtualCopy
SpecialOffer "1" -down[bold,#green]- "1" UniversityVirtualCopy SpecialOffer "1" -down[bold,#green]- "1" UniversityVirtualCopy
UniversityInfo "1" -down[bold,#green]- "1" UniversityVirtualCopy UniversityInfo "1" -down[bold,#green]- "1" UniversityVirtualCopy
......
...@@ -30,16 +30,34 @@ package UserFunctionalities #lightblue{ ...@@ -30,16 +30,34 @@ package UserFunctionalities #lightblue{
end note end note
class PreviousDeparture{ class PreviousDeparture{
+ is_anonymous : bool
+ courses : JSON
+ Utc_departure_id : int
}
class PreviousDepartureFeedback{
+ adequation_comment : MD + adequation_comment : MD
+ integration_comment : MD + integration_comment : MD
+ adequation_grade : integer + adequation_grade : integer
+ adequation_grade : integer + adequation_grade : integer
+ courses_and_courses_feedback : JSON
} }
PreviousDeparture "1" -right- "1" PreviousDepartureFeedback
PreviousDeparture "*" -left- "1" UserCopy1 PreviousDeparture "*" -left- "1" UserCopy1
PreviousDeparture "*" -up- "1" SpecialtyCopy1 PreviousDeparture "*" -up- "1" SpecialtyCopy1
PreviousDeparture "*" -up- "1" UniversityCopy1 PreviousDeparture "*" -up- "1" UniversityCopy1
PreviousDeparture "*" -up- "1..n" SemesterCopy1 PreviousDeparture "*" -up- "1..n" SemesterCopy1
class UserData{
+ contact_info : JSON
+ contact_info_is_public : bool
+ config : JSON
+ other_data : JSON
}
UserData "1"-up-"1" UserCopy1
} }
@enduml @enduml
\ No newline at end of file
...@@ -44,6 +44,8 @@ from rex.models.otherCore import Specialty ...@@ -44,6 +44,8 @@ from rex.models.otherCore import Specialty
from rex.models.user import Recommendation from rex.models.user import Recommendation
from rex.models.user import RecommendationList from rex.models.user import RecommendationList
from rex.models.user import PreviousDeparture from rex.models.user import PreviousDeparture
from rex.models.user import PreviousDepartureFeedback
from rex.models.user import UserData
CLASSIC_MODELS = [ CLASSIC_MODELS = [
Country, Country,
...@@ -56,6 +58,8 @@ CLASSIC_MODELS = [ ...@@ -56,6 +58,8 @@ CLASSIC_MODELS = [
Recommendation, Recommendation,
RecommendationList, RecommendationList,
PreviousDeparture, PreviousDeparture,
PreviousDepartureFeedback,
UserData
] ]
VERSIONNED_MODELS = [ VERSIONNED_MODELS = [
......
# Generated by Django 2.0.3 on 2018-08-21 19:04
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('rex', '0027_auto_20180821_1748'),
]
operations = [
migrations.CreateModel(
name='PreviousDepartureFeedback',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('adequation_comment', models.TextField()),
('integration_comment', models.TextField()),
('adequation_grate', models.PositiveIntegerField(validators=[django.core.validators.MaxValueValidator(20)])),
('integration_grade', models.PositiveIntegerField(validators=[django.core.validators.MaxValueValidator(20)])),
],
options={
'abstract': False,
},
),
migrations.RemoveField(
model_name='previousdeparture',
name='adequation_comment',
),
migrations.RemoveField(
model_name='previousdeparture',
name='adequation_grate',
),
migrations.RemoveField(
model_name='previousdeparture',
name='integration_comment',
),
migrations.RemoveField(
model_name='previousdeparture',
name='integration_grade',
),
migrations.AddField(
model_name='offer',
name='nb_seats_offered_double_degree',
field=models.PositiveIntegerField(null=True),
),
migrations.AddField(
model_name='offer',
name='nb_seats_offered_exchange',
field=models.PositiveIntegerField(null=True),
),
migrations.AddField(
model_name='previousdeparture',
name='Utc_departure_id',
field=models.IntegerField(default=1),
preserve_default=False,
),
migrations.AddField(
model_name='previousdeparture',
name='courses',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='previousdeparture',
name='is_anonymous',
field=models.BooleanField(default=True),
preserve_default=False,
),
migrations.AlterField(
model_name='offer',
name='nb_seats_offered',
field=models.PositiveIntegerField(),
),
migrations.AlterField(
model_name='previousdeparture',
name='user',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='previousdeparturefeedback',
name='departure',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='rex.PreviousDeparture'),
),
migrations.AddField(
model_name='previousdeparturefeedback',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]
# Generated by Django 2.0.3 on 2018-08-21 19:10
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('rex', '0028_auto_20180821_2104'),
]
operations = [
migrations.AddField(
model_name='previousdeparturefeedback',
name='courses_and_courses_feedback',
field=django.contrib.postgres.fields.jsonb.JSONField(null=True),
),
migrations.AlterField(
model_name='previousdeparture',
name='courses',
field=django.contrib.postgres.fields.jsonb.JSONField(null=True),
),
]
# Generated by Django 2.0.3 on 2018-08-21 19:38
from django.conf import settings
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
import rex.models.tools.usefullLinksField
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('rex', '0029_auto_20180821_2110'),
]
operations = [
migrations.CreateModel(
name='UserData',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_anonymous', models.BooleanField(default=True)),
('is_public', models.BooleanField(default=False)),
('contact_info', rex.models.tools.usefullLinksField.UsefullLinksField(default=[], null=True, validators=[rex.models.tools.usefullLinksField.validate_usefull_links])),
('contact_info_is_public', models.BooleanField(default=False)),
('config', django.contrib.postgres.fields.jsonb.JSONField(default={}, null=True)),
('other_data', django.contrib.postgres.fields.jsonb.JSONField(default={}, null=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='previousdeparturefeedback',
name='is_anonymous',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='previousdeparturefeedback',
name='is_public',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='recommendation',
name='is_anonymous',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='recommendation',
name='is_public',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='recommendationlist',
name='is_anonymous',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='recommendationlist',
name='is_public',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='countryphoto',
name='country',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='country_photos', to='rex.Country'),
),
migrations.AlterField(
model_name='universityphoto',
name='university',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='university_photos', to='rex.University'),
),
]
...@@ -7,7 +7,7 @@ from rest_framework import viewsets, permissions ...@@ -7,7 +7,7 @@ from rest_framework import viewsets, permissions
class CountryPhoto(Photo): class CountryPhoto(Photo):
country = models.OneToOneField( country = models.ForeignKey(
Country, Country,
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name='country_photos') related_name='country_photos')
......
...@@ -7,7 +7,12 @@ from rex.models.otherCore import Semester, Specialty ...@@ -7,7 +7,12 @@ from rex.models.otherCore import Semester, Specialty
class Offer(models.Model): class Offer(models.Model):
semester = models.ForeignKey(Semester, on_delete=models.PROTECT) semester = models.ForeignKey(Semester, on_delete=models.PROTECT)
university = models.ForeignKey(University, on_delete=models.PROTECT) university = models.ForeignKey(University, on_delete=models.PROTECT)
nb_seats_offered = models.IntegerField()
nb_seats_offered = models.PositiveIntegerField()
# null => exchange not possible
nb_seats_offered_exchange = models.PositiveIntegerField(null=True)
nb_seats_offered_double_degree = models.PositiveIntegerField(null=True)
specialty = models.ManyToManyField( specialty = models.ManyToManyField(
Specialty, related_name="has_seats_at_univ") Specialty, related_name="has_seats_at_univ")
......
...@@ -7,7 +7,7 @@ from rest_framework import viewsets, permissions ...@@ -7,7 +7,7 @@ from rest_framework import viewsets, permissions
class UniversityPhoto(Photo): class UniversityPhoto(Photo):
university = models.OneToOneField( university = models.ForeignKey(
University, University,
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name='university_photos') related_name='university_photos')
......
from .userRestrictedModule import UserRestrictedModule, UserRestrictedModuleSerializer # noqa: F401 from .userRestrictedModule import UserRestrictedModule, UserRestrictedModuleSerializer # noqa: F401
from .previousDeparture import PreviousDeparture, PreviousDepartureViewSet # noqa: F401 from .previousDeparture import PreviousDeparture, PreviousDepartureViewSet # noqa: F401
from .previousDepartureFeedback import PreviousDepartureFeedback, PreviousDepartureFeedbackViewSet # noqa: F401
from .recommendationList import RecommendationList, RecommendationListSerializer, RecommendationListViewSet # noqa: F401 from .recommendationList import RecommendationList, RecommendationListSerializer, RecommendationListViewSet # noqa: F401
from .recommendation import Recommendation, RecommendationSerializer, RecommendationViewSet # noqa: F401 from .recommendation import Recommendation, RecommendationSerializer, RecommendationViewSet # noqa: F401
from .userData import UserData, UserDataViewSet # noqa: F401
from django.db import models from django.db import models
from rest_framework import viewsets, permissions from rest_framework import viewsets, permissions, serializers
from django.core.validators import MaxValueValidator
from rex.models.otherCore.specialty import Specialty from rex.models.otherCore.specialty import Specialty
from rex.models.otherCore.semester import Semester from rex.models.otherCore.semester import Semester
from rex.models.university import University from rex.models.university import University
from django.contrib.auth.models import User
from django.contrib.postgres.fields import JSONField
from rex.models.user import UserRestrictedModule, UserRestrictedModuleSerializer
class PreviousDeparture(models.Model):
class PreviousDeparture(UserRestrictedModule): # This model should be filled with data from the ENT
semester = models.ForeignKey(Semester, on_delete=models.PROTECT) semester = models.ForeignKey(Semester, on_delete=models.PROTECT)
university = models.ForeignKey(University, on_delete=models.PROTECT) university = models.ForeignKey(University, on_delete=models.PROTECT)
specialty = models.ForeignKey(Specialty, on_delete=models.PROTECT) specialty = models.ForeignKey(Specialty, on_delete=models.PROTECT)
# TODO check where we store specialty or at least check that it is coherent with user user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
# Usefull to relink a departure with a user
Utc_departure_id = models.IntegerField()
adequation_comment = models.TextField() is_anonymous = models.BooleanField()
integration_comment = models.TextField() courses = JSONField(null=True) # Store data from ENT
adequation_grate = models.PositiveIntegerField( # TODO ask the DSI to return an anonymous ID with data so
validators=[MaxValueValidator(20)]) # when someone delete the link and relink we can rematch the data
integration_grade = models.PositiveIntegerField(
validators=[MaxValueValidator(20)])
class PreviousDepartureSerializer(UserRestrictedModuleSerializer): class PreviousDepartureSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = PreviousDeparture model = PreviousDeparture
...@@ -31,6 +31,7 @@ class PreviousDepartureSerializer(UserRestrictedModuleSerializer): ...@@ -31,6 +31,7 @@ class PreviousDepartureSerializer(UserRestrictedModuleSerializer):
class PreviousDepartureViewSet(viewsets.ModelViewSet): class PreviousDepartureViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.DjangoModelPermissions,) permission_classes = (permissions.IsAdminUser,)
queryset = PreviousDeparture.objects.all() # pylint: disable=E1101 queryset = PreviousDeparture.objects.all() # pylint: disable=E1101
serializer_class = PreviousDepartureSerializer serializer_class = PreviousDepartureSerializer
# todo if is_anonymous set user to null
from django.db import models
from rest_framework import viewsets, permissions
from django.core.validators import MaxValueValidator
from rex.models.user import UserRestrictedModule, UserRestrictedModuleSerializer
from rex.models.user import PreviousDeparture
from django.contrib.postgres.fields import JSONField
class PreviousDepartureFeedback(UserRestrictedModule):
departure = models.OneToOneField(
PreviousDeparture, on_delete=models.CASCADE)
courses_and_courses_feedback = JSONField(null=True)
adequation_comment = models.TextField()
integration_comment = models.TextField()
adequation_grate = models.PositiveIntegerField(
validators=[MaxValueValidator(20)])
integration_grade = models.PositiveIntegerField(
validators=[MaxValueValidator(20)])
# TODO check on save that courses are coherent with Previous Departure
class PreviousDepartureFeedbackSerializer(UserRestrictedModuleSerializer):
class Meta:
model = PreviousDepartureFeedback
fields = '__all__'
class PreviousDepartureFeedbackViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.DjangoModelPermissions,)
queryset = PreviousDepartureFeedback.objects.all() # pylint: disable=E1101
serializer_class = PreviousDepartureFeedbackSerializer
from django.db import models
from rest_framework import viewsets, permissions
from rex.models.tools import UsefullLinksField
from django.contrib.postgres.fields import JSONField
from rex.models.user import UserRestrictedModule, UserRestrictedModuleSerializer
class UserData(UserRestrictedModule):
contact_info = UsefullLinksField(null=True)
contact_info_is_public = models.BooleanField(default=False)
config = JSONField(null=True, default={})
other_data = JSONField(null=True, default={})
class UserDataSerializer(UserRestrictedModuleSerializer):
class Meta:
model = UserData
fields = '__all__'
class UserDataViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAdminUser,) # TODO change
queryset = UserData.objects.all() # pylint: disable=E1101
serializer_class = UserDataSerializer
# TODO change to require a login not display all
...@@ -7,6 +7,12 @@ class UserRestrictedModule(models.Model): ...@@ -7,6 +7,12 @@ class UserRestrictedModule(models.Model):
# RGPD made easy with CASCADE # RGPD made easy with CASCADE
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
# User is anonymised
is_anonymous = models.BooleanField(default=True)
# To be seen by others than the user, is public needs to be set to True
is_public = models.BooleanField(default=False)