Skip to content

Commit

Permalink
Merge pull request #318 from maykinmedia/develop
Browse files Browse the repository at this point in the history
[WIP] Release v1.0.4
  • Loading branch information
alextreme authored Oct 20, 2022
2 parents 2816a3f + fb8c3b8 commit dd30803
Show file tree
Hide file tree
Showing 42 changed files with 343 additions and 94 deletions.
6 changes: 0 additions & 6 deletions docs/install/dev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ Quick start
Next steps
----------

Optionally, you can load demo data and extract demo media files::

$ python src/manage.py loaddata demo
$ cd media
$ tar -xzf demo.tgz

You can now run your installation and point your browser to the address given
by this command::

Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions requirements/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ django-rich
django-csp
django-csp-reports
mozilla-django-oidc-db
django-open-forms-client

# API libraries
djangorestframework
Expand Down
5 changes: 5 additions & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ django==3.2.15
# django-hijack
# django-import-export
# django-localflavor
# django-open-forms-client
# django-otp
# django-phonenumber-field
# django-polymorphic
Expand Down Expand Up @@ -141,6 +142,8 @@ django-localflavor==3.1
# via -r requirements/base.in
django-mptt==0.13.4
# via django-filer
django-open-forms-client==0.2.2
# via -r requirements/base.in
django-ordered-model==3.4.3
# via
# -r requirements/base.in
Expand Down Expand Up @@ -176,6 +179,7 @@ django-sniplates==0.7.0
django-solo==1.2.0
# via
# -r requirements/base.in
# django-open-forms-client
# mozilla-django-oidc-db
# zgw-consumers
django-timeline-logger==2.0.0
Expand Down Expand Up @@ -323,6 +327,7 @@ redis==3.5.3
# via django-redis
requests==2.26.0
# via
# django-open-forms-client
# django-rosetta
# gemma-zds-client
# mozilla-django-oidc
Expand Down
7 changes: 7 additions & 0 deletions requirements/ci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ django==3.2.15
# django-hijack
# django-import-export
# django-localflavor
# django-open-forms-client
# django-otp
# django-phonenumber-field
# django-polymorphic
Expand Down Expand Up @@ -233,6 +234,10 @@ django-mptt==0.13.4
# -c requirements/base.txt
# -r requirements/base.txt
# django-filer
django-open-forms-client==0.2.2
# via
# -c requirements/base.txt
# -r requirements/base.txt
django-ordered-model==3.4.3
# via
# -c requirements/base.txt
Expand Down Expand Up @@ -297,6 +302,7 @@ django-solo==1.2.0
# via
# -c requirements/base.txt
# -r requirements/base.txt
# django-open-forms-client
# mozilla-django-oidc-db
# zgw-consumers
django-timeline-logger==2.0.0
Expand Down Expand Up @@ -614,6 +620,7 @@ requests==2.26.0
# via
# -c requirements/base.txt
# -r requirements/base.txt
# django-open-forms-client
# django-rosetta
# gemma-zds-client
# mozilla-django-oidc
Expand Down
7 changes: 7 additions & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ django==3.2.15
# django-hijack
# django-import-export
# django-localflavor
# django-open-forms-client
# django-otp
# django-phonenumber-field
# django-polymorphic
Expand Down Expand Up @@ -264,6 +265,10 @@ django-mptt==0.13.4
# -c requirements/ci.txt
# -r requirements/ci.txt
# django-filer
django-open-forms-client==0.2.2
# via
# -c requirements/ci.txt
# -r requirements/ci.txt
django-ordered-model==3.4.3
# via
# -c requirements/ci.txt
Expand Down Expand Up @@ -328,6 +333,7 @@ django-solo==1.2.0
# via
# -c requirements/ci.txt
# -r requirements/ci.txt
# django-open-forms-client
# mozilla-django-oidc-db
# zgw-consumers
django-timeline-logger==2.0.0
Expand Down Expand Up @@ -712,6 +718,7 @@ requests==2.26.0
# -c requirements/ci.txt
# -r requirements/ci.txt
# ddt-api-calls
# django-open-forms-client
# django-rosetta
# gemma-zds-client
# mozilla-django-oidc
Expand Down
7 changes: 7 additions & 0 deletions src/open_inwoner/accounts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ class ActionAdmin(UUIDAdminFirstInOrder, PrivateMediaMixin, admin.ModelAdmin):
@admin.register(Contact)
class ContactAdmin(UUIDAdminFirstInOrder, admin.ModelAdmin):
readonly_fields = ("uuid",)
search_fields = (
"first_name",
"last_name",
"email",
"contact_user__email",
"created_by__email",
)
list_display = (
"first_name",
"last_name",
Expand Down
14 changes: 9 additions & 5 deletions src/open_inwoner/accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,16 @@ def clean(self):
cleaned_data = super().clean()
email = cleaned_data.get("email")

if self.create and email and self.user.contacts.filter(email=email).exists():
raise ValidationError(
_(
"Het ingevoerde e-mailadres komt al voor in uw contactpersonen. Pas de gegevens aan en probeer het opnieuw."
if self.create and email:
if (
self.user.contacts.filter(email=email).exists()
or self.user.assigned_contacts.filter(created_by__email=email).exists()
):
raise ValidationError(
_(
"Het ingevoerde e-mailadres komt al voor in uw contactpersonen. Pas de gegevens aan en probeer het opnieuw."
)
)
)

def save(self, commit=True):
if not self.instance.pk:
Expand Down
14 changes: 9 additions & 5 deletions src/open_inwoner/accounts/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,15 @@ def get_extended_contacts_for_user(self, me):
- other_user_email
- other_user_phonenumber (Null in case of reversed contacts)
If the user and other user have contacts with each other only mine contact is shown
If the user and other user have contacts with each other return both contacts
"""

my_contacts_users = self.filter(created_by=me).values_list(
"contact_user", flat=True
)
return (
self.filter(
Q(created_by=me)
| Q(~Q(created_by__in=my_contacts_users), contact_user=me)
)
self.filter(Q(created_by=me) | Q(contact_user=me))
.distinct()
.annotate(reverse=Case(When(created_by=me, then=False), default=True))
.annotate(
other_user_id=Case(
Expand All @@ -135,6 +133,12 @@ def get_extended_contacts_for_user(self, me):
default=F("created_by__last_name"),
)
)
.annotate(
other_user_type=Case(
When(created_by=me, then=F("contact_user__contact_type")),
default=F("created_by__contact_type"),
)
)
.annotate(
other_user_email=Case(
When(created_by=me, then=F("contact_user__email")),
Expand Down
2 changes: 1 addition & 1 deletion src/open_inwoner/accounts/templates/accounts/inbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h1 class="h1">{% trans 'Mijn berichten' %}</h1>
<div class="sticky">
{% render_list %}
{% for conversation in conversations.page_obj %}
{% querystring conversation.other_user_email conversations.page_obj.number query='with={}&page={}' as href %}
{% querystring conversation.other_user_email|urlencode conversations.page_obj.number query='with={}&page={}' as href %}
{% firstof '?'|add:href as href %}
{% firstof conversation.other_user_first_name|add:' '|add:conversation.other_user_last_name as other_user_fullname %}

Expand Down
5 changes: 3 additions & 2 deletions src/open_inwoner/accounts/templates/registration/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
<h1 class="h1">{% trans 'Welkom' %}</h1>
{% if login_text %}<p class="p">{{ login_text }}</p>{% endif %}
<br>

{% if settings.DIGID_ENABLED %}
{% render_card direction='horizontal' tinted=True %}
<a href="{% url 'digid:login' %}" class="link digid-logo" aria-describedby="Digid logo" title="Digid logo">
<img class="digid-logo__image" src="{% static 'accounts/digid_logo.svg' %}" alt="Digid logo">
</a>
{% link href='digid:login' text=_('Inloggen met DigiD') secondary=True icon='arrow_forward' extra_classes="link--digid" %}
{% endrender_card %}

{% endif %}

{% get_solo 'mozilla_django_oidc_db.OpenIDConnectConfig' as oidc_config %}
{% get_solo 'configurations.SiteConfiguration' as site_config %}
{% if oidc_config.enabled %}
Expand Down
14 changes: 2 additions & 12 deletions src/open_inwoner/accounts/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,7 @@ def test_registration_with_invite(self):
self.assertEqual(invite.invitee, user)

# reverse contact checks
self.assertEqual(user.contacts.count(), 1)
reverse_contact = user.contacts.get()
self.assertEqual(reverse_contact.contact_user, contact.created_by)
self.assertEqual(reverse_contact.email, contact.created_by.email)
self.assertEqual(reverse_contact.first_name, contact.created_by.first_name)
self.assertEqual(reverse_contact.last_name, contact.created_by.last_name)
self.assertEqual(user.contacts.count(), 0)

def test_registration_active_user(self):
"""the user should be redirected to the registration complete page"""
Expand Down Expand Up @@ -276,12 +271,7 @@ def test_submit_with_invite(self):
self.assertEqual(invite.invitee, user)

# reverse contact checks
self.assertEqual(user.contacts.count(), 1)
reverse_contact = user.contacts.get()
self.assertEqual(reverse_contact.contact_user, contact.created_by)
self.assertEqual(reverse_contact.email, contact.created_by.email)
self.assertEqual(reverse_contact.first_name, contact.created_by.first_name)
self.assertEqual(reverse_contact.last_name, contact.created_by.last_name)
self.assertEqual(user.contacts.count(), 0)

def test_submit_not_unique_email(self):
UserFactory.create(email="[email protected]")
Expand Down
4 changes: 2 additions & 2 deletions src/open_inwoner/accounts/tests/test_contact_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def test_mine_and_reverse_contact(self):

contacts = Contact.objects.get_extended_contacts_for_user(self.me)

self.assertEqual(contacts.count(), 1)
self.assertEqual(contacts.count(), 2)

extended_contact = contacts.get()
extended_contact = contacts.filter(created_by=self.me)[0]
self.assertEqual(extended_contact.id, direct_contact.id)
self.assertEqual(extended_contact.other_user_id, other_user.id)
self.assertFalse(extended_contact.reverse)
Expand Down
5 changes: 4 additions & 1 deletion src/open_inwoner/accounts/views/contacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ def get_queryset(self):
| Q(contact_user__isnull=True)
)
else:
base_qs = base_qs.filter(contact_user__contact_type=type_filter)
base_qs = base_qs.filter(
Q(contact_user__contact_type=type_filter)
| Q(created_by__contact_type=type_filter)
)
return base_qs

def get_context_data(self, **kwargs):
Expand Down
3 changes: 3 additions & 0 deletions src/open_inwoner/accounts/views/invite.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def form_valid(self, form):
def get_object(self, queryset=None):
invite = super().get_object(queryset)

if self.request.user.is_authenticated:
raise Http404(_("U bent al ingelogd."))

if invite.expired():
self.log_system_action(_("invitation expired"), invite)
raise Http404(_("The invitation was expired"))
Expand Down
41 changes: 30 additions & 11 deletions src/open_inwoner/accounts/views/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from open_inwoner.utils.views import LogMixin

from ..forms import ThemesForm, UserForm
from ..models import Action, User
from ..models import Action, Contact, User


class MyProfileView(LogMixin, LoginRequiredMixin, BaseBreadcrumbMixin, FormView):
Expand All @@ -34,21 +34,28 @@ def crumbs(self):
return [(_("Mijn profiel"), reverse("accounts:my_profile"))]

def get_context_data(self, **kwargs):
contact_names = [
f"{contact.first_name} ({contact.get_type_display()})"
for contact in self.request.user.contacts.all()[:3]
]

context = super().get_context_data(**kwargs)
today = date.today()
context["anchors"] = [
("#title", _("Persoonlijke gegevens")),
("#overview", _("Persoonlijk overzicht")),
("#files", _("Bestanden")),
]
context["mentor_contacts"] = self.request.user.contacts.filter(
contact_user__contact_type=ContactTypeChoices.begeleider
)
# List of names of 'mentor' users that are a contact of me
mentor_contacts = [
str(c.contact_user.get_full_name())
for c in self.request.user.contacts.filter(
contact_user__contact_type=ContactTypeChoices.begeleider
)
] + [
str(c.created_by.get_full_name())
for c in Contact.objects.filter(
created_by__contact_type=ContactTypeChoices.begeleider,
contact_user=self.request.user,
)
]

context["mentor_contacts"] = mentor_contacts
context["next_action"] = (
Action.objects.connected(self.request.user)
.filter(end_date__gte=today, status=StatusChoices.open)
Expand All @@ -60,10 +67,22 @@ def get_context_data(self, **kwargs):
context["action_text"] = _(
f"{Action.objects.connected(self.request.user).filter(status=StatusChoices.open).count()} acties staan open."
)
if self.request.user.contacts.count() > 0:
contacts = Contact.objects.get_extended_contacts_for_user(self.request.user)
# Invited contacts
contact_names = [
f"{contact.first_name} ({contact.get_type_display()})"
for contact in self.request.user.contacts.all()[:3]
]
# Reverse contacts
contact_names += [
f"{contact.created_by.first_name} ({contact.created_by.get_contact_type_display()})"
for contact in self.request.user.assigned_contacts.all()[:3]
]

if contacts.count() > 0:
context[
"contact_text"
] = f"{', '.join(contact_names)}{'...' if self.request.user.contacts.count() > 3 else ''}"
] = f"{', '.join(contact_names)}{'...' if contacts.count() > 3 else ''}"
else:
context["contact_text"] = _("U heeft nog geen contacten.")
context["questionnaire_exists"] = QuestionnaireStep.objects.exists()
Expand Down
14 changes: 0 additions & 14 deletions src/open_inwoner/accounts/views/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,6 @@ def add_invitee(self, invite, user):
contact.contact_user = user
contact.save()

# create reverse contact
reverse_contact, created = Contact.objects.get_or_create(
contact_user=invite.inviter,
created_by=user,
defaults={
"first_name": invite.inviter.first_name,
"last_name": invite.inviter.last_name,
"email": invite.inviter.email,
},
)
if created:
self.request.user = user
self.log_user_action(reverse_contact, _("contact was created"))


class CustomRegistrationView(LogMixin, InviteMixin, RegistrationView):
form_class = CustomRegistrationForm
Expand Down
Loading

0 comments on commit dd30803

Please sign in to comment.