Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions back/admin/people/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@
MultiSelectField,
UploadField,
)
from misc.mixins import FilterDepartmentsFieldByUserMixin
from organization.models import Organization
from users.models import User
from users.models import DepartmentRole, User
from users.selectors import get_available_roles_for_user


class RoleModelMultipleChoiceField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
return obj.department.name + " // " + obj.name


class NewHireAddForm(forms.ModelForm):
Expand All @@ -25,7 +30,13 @@ class NewHireAddForm(forms.ModelForm):
to_field_name="id",
initial=Sequence.onboarding.filter(auto_add=True),
required=False,
label=_("Sequences"),
label=_("Additional sequences"),
)
roles = RoleModelMultipleChoiceField(
queryset=DepartmentRole.objects.none(),
to_field_name="id",
required=False,
label=_("Roles"),
)
buddy = forms.ModelChoiceField(
queryset=get_user_model().managers_and_admins_or_slack_users.all(),
Expand All @@ -41,14 +52,18 @@ class NewHireAddForm(forms.ModelForm):
widget=forms.DateInput(attrs={"type": "date"}, format=("%Y-%m-%d")),
)

def __init__(self, *args, **kwargs):
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["buddy"].required = False
self.fields["manager"].required = False
self.fields["profile_image"].required = False
self.fields["language"].initial = Organization.object.get().language
self.fields["timezone"].initial = Organization.object.get().timezone
self.fields["start_day"].initial = timezone.now().date()
self.fields["roles"].queryset = get_available_roles_for_user(
user=user
).order_by("department")
print(self.fields["roles"].queryset)
self.helper = FormHelper()
layout = Layout(
Div(
Expand Down Expand Up @@ -93,7 +108,7 @@ def __init__(self, *args, **kwargs):
css_class="row",
),
Div(
Div(Field("departments"), css_class="col-6"),
Div(Field("roles"), css_class="col-6"),
Div(
UploadField(
"profile_image",
Expand Down Expand Up @@ -140,7 +155,7 @@ class Meta:
"language",
"buddy",
"manager",
"departments",
"roles",
"profile_image",
)

Expand Down Expand Up @@ -189,6 +204,10 @@ def __init__(self, *args, **kwargs):
Div(
Field("last_name"),
Field("phone"),
UploadField(
"profile_image",
extra_context={"file": self.instance.profile_image},
),
Field("start_day"),
css_class="col-6",
),
Expand All @@ -198,17 +217,6 @@ def __init__(self, *args, **kwargs):
Div(Field("message"), css_class="col-12"),
css_class="row",
),
Div(
Div(Field("departments"), css_class="col-6"),
Div(
UploadField(
"profile_image",
extra_context={"file": self.instance.profile_image},
),
css_class="col-6",
),
css_class="row",
),
Div(
Div(
Field("timezone"),
Expand All @@ -228,19 +236,17 @@ class Meta:
"last_name",
"position",
"email",
"phone",
"start_day",
"message",
"timezone",
"language",
"buddy",
"manager",
"departments",
"profile_image",
)


class ColleagueUpdateForm(FilterDepartmentsFieldByUserMixin, forms.ModelForm):
class ColleagueUpdateForm(forms.ModelForm):
birthday = forms.DateField(
widget=forms.DateInput(attrs={"type": "date"}, format=("%Y-%m-%d")),
required=False,
Expand All @@ -259,7 +265,6 @@ def __init__(self, *args, **kwargs):
Div(
Div(Field("email"), css_class="col-12"),
Div(Field("position"), css_class="col-12"),
Div(Field("departments"), css_class="col-12"),
Div(Field("phone"), css_class="col-12"),
Div(Field("birthday"), css_class="col-12"),
Div(Field("message"), css_class="col-12"),
Expand All @@ -281,7 +286,6 @@ class Meta:
"first_name",
"last_name",
"position",
"departments",
"birthday",
"email",
"phone",
Expand All @@ -295,7 +299,7 @@ class Meta:
)


class ColleagueCreateForm(FilterDepartmentsFieldByUserMixin, forms.ModelForm):
class ColleagueCreateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
Expand All @@ -311,7 +315,6 @@ def __init__(self, *args, **kwargs):
Div(
Div(Field("email"), css_class="col-12"),
Div(Field("position"), css_class="col-12"),
Div(Field("departments"), css_class="col-12"),
Div(Field("phone"), css_class="col-12"),
Div(Field("message"), css_class="col-12"),
Div(Field("facebook"), css_class="col-12"),
Expand All @@ -332,7 +335,6 @@ class Meta:
"first_name",
"last_name",
"position",
"departments",
"email",
"phone",
"message",
Expand Down
1 change: 1 addition & 0 deletions back/admin/people/templates/colleague_update.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{% load crispy_forms_tags %}

{% block actions %}
<a href="{% url 'people:new_hire' object.id %}" class="btn">{% translate "Progress" %}</a>
{% if object.termination_date is None %}
<a href="{% url 'people:terminate' object.id %}" class="btn">{% translate "Terminate" %}</a>
{% else %}
Expand Down
18 changes: 12 additions & 6 deletions back/admin/people/templates/colleagues.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<tr>
<th>{% translate "Name" %}</th>
<th>{% translate "Position" %}</th>
<th>{% translate "Departments" %}</th>
<th>{% translate "Has access to departments" %}</th>
<th></th>
</tr>
</thead>
Expand All @@ -47,11 +47,17 @@
{{ colleague.position }}
</td>
<td>
{% for department in colleague.departments.all %}
<span class="badge bg-blue-lt text-blue-lt-fg">{{ department }}</span>
{% empty %}
{% trans "Not in a department" %}
{% endfor %}
{% if colleague.is_admin %}
<span class="badge bg-lime-lt text-lime-lt-fg">{% trans "All" %}</span>
{% elif colleague.is_manager %}
{% for department in colleague.departments.all %}
<span class="badge bg-blue-lt text-blue-lt-fg">{{ department }}</span>
{% empty %}
<span class="badge bg-lime-lt text-lime-lt-fg">{% trans "All" %}</span>
{% endfor %}
{% else %}
User has no admin/manager access
{% endif %}
</td>
<td class="text-end">
{% if slack_active %}
Expand Down
10 changes: 6 additions & 4 deletions back/admin/people/templates/new_hire_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
</div>
</div>
{% endif %}
{% include "_new_hire_menu.html" %}
{% if object.is_new_hire %}
{% include "_new_hire_menu.html" %}
{% endif %}
<div class="row mt-3">
<div class="col-8">
<div class="card">
Expand All @@ -29,7 +31,7 @@ <h3 class="card-title">{% translate "What's up next..." %}</h3>
<div class="card-body">
<ul class="timeline">
{# only show preboarding if before first day #}
{% if object.workday == 0 and object.preboarding.all|length %}
{% if object.workday == 0 and object.preboarding.all|length and object.is_new_hire %}
<li class="timeline-event">
<div class="timeline-event-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-stack-front"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 4l-8 4l8 4l8 -4l-8 -4" fill="currentColor" /><path d="M8 14l-4 2l8 4l8 -4l-4 -2" /><path d="M8 10l-4 2l8 4l8 -4l-4 -2" /></svg>
Expand Down Expand Up @@ -61,7 +63,7 @@ <h4 class="card-title">{% translate "Before first day" %}</h4>
{% endif %}
{% for condition in conditions %}
{% show_highlighted_date_card conditions forloop.counter0 object.start_day as show_start %}
{% if show_start %}
{% if show_start and object.is_new_hire %}
<li class="timeline-event">
<div class="timeline-event-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-player-play"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 4v16l13 -8z" /></svg>
Expand All @@ -83,7 +85,7 @@ <h4 class="card-title">{% blocktranslate with start_day=object.start_day %}{{ st
<div class="card">
<div class="card-header">
{% if condition.condition_type == ConditionType.AFTER or condition.condition_type == ConditionType.BEFORE %}
<h4 class="card-title">{{ condition|new_hire_trigger_date:object }} {% trans "at" %} {{ condition.time }}</h4>
<h4 class="card-title">{{ condition|new_hire_trigger_date:condition_start_date_map }} {% trans "at" %} {{ condition.time }}</h4>
{% elif condition.condition_type == ConditionType.ADMIN_TASK %}
<h4 class="card-title">
{% trans "When these admin tasks are completed:" %}
Expand Down
9 changes: 2 additions & 7 deletions back/admin/people/views/colleagues.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
from admin.resources.selectors import get_resource_templates_for_user
from admin.sequences.models import Condition, Sequence
from api.permissions import AdminPermission
from misc.mixins import FormWithUserContextMixin
from organization.models import Organization, WelcomeMessage
from slack_bot.utils import Slack, actions, button, paragraph
from users.emails import email_new_admin_cred
Expand Down Expand Up @@ -89,9 +88,7 @@ def get_context_data(self, **kwargs):
return context


class ColleagueCreateView(
AdminOrManagerPermMixin, FormWithUserContextMixin, SuccessMessageMixin, CreateView
):
class ColleagueCreateView(AdminOrManagerPermMixin, SuccessMessageMixin, CreateView):
template_name = "colleague_create.html"
model = get_user_model()
form_class = ColleagueCreateForm
Expand All @@ -109,9 +106,7 @@ def get_context_data(self, **kwargs):
return context


class ColleagueUpdateView(
AdminOrManagerPermMixin, FormWithUserContextMixin, SuccessMessageMixin, UpdateView
):
class ColleagueUpdateView(AdminOrManagerPermMixin, SuccessMessageMixin, UpdateView):
template_name = "colleague_update.html"
model = get_user_model()
form_class = ColleagueUpdateForm
Expand Down
41 changes: 34 additions & 7 deletions back/admin/people/views/new_hires.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@
send_reminder_email,
)
from users.mixins import AdminOrManagerPermMixin
from users.models import NewHireWelcomeMessage, PreboardingUser, ResourceUser, ToDoUser
from users.models import (
NewHireWelcomeMessage,
PreboardingUser,
ResourceUser,
ToDoUser,
UserCondition,
)


class NewHireListView(AdminOrManagerPermMixin, ListView):
Expand All @@ -68,6 +74,11 @@ class NewHireAddView(AdminOrManagerPermMixin, SuccessMessageMixin, CreateView):
success_message = _("New hire has been created")
success_url = reverse_lazy("people:new_hires")

def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["user"] = self.request.user
return kwargs

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = _("Add new hire")
Expand All @@ -82,8 +93,17 @@ def form_valid(self, form):

new_hire = form.save()

# Add sequences to new hire
new_hire.add_sequences(sequences)
# additional sequences, then add the ones from the roles
sequence_pks = list(sequences.values_list("pk", flat=True))

for role in form.cleaned_data["roles"]:
role.users.add(new_hire)
sequence_pks += list(
role.sequences.all().values_list("pk", flat=True)
) + list(role.department.sequences.all().values_list("pk", flat=True))

sequences = Sequence.objects.filter(id__in=sequence_pks)
new_hire.add_sequences(Sequence.objects.filter(id__in=sequence_pks))

# Send credentials email if the user was created after their start day
org = Organization.object.get()
Expand Down Expand Up @@ -313,24 +333,31 @@ class NewHireSequenceView(AdminOrManagerPermMixin, DetailView):
template_name = "new_hire_detail.html"

def get_queryset(self):
return get_new_hires_for_user(user=self.request.user)
return get_colleagues_for_user(user=self.request.user)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
new_hire = context["object"]
context["title"] = new_hire.full_name
context["subtitle"] = _("new hire")
context["subtitle"] = _("new hire") if new_hire.is_new_hire else _("employee")

conditions = new_hire.conditions.prefetched()
user_conditions = UserCondition.objects.filter(
condition__in=conditions
).values_list("condition", "role_start_date")
u_con = {}
for u, start_date in user_conditions:
u_con[u] = start_date
context["condition_start_date_map"] = u_con

# condition items
context["conditions"] = (
(
conditions.filter(
condition_type=2, days__lte=new_hire.days_before_starting()
condition_type=2 # , days__lte=new_hire.days_before_starting()
)
| conditions.filter(
condition_type=Condition.Type.AFTER, days__gte=new_hire.workday()
condition_type=Condition.Type.AFTER # , days__gte=new_hire.workday()
)
| conditions.filter(condition_type=Condition.Type.TODO)
| conditions.filter(condition_type=Condition.Type.ADMIN_TASK)
Expand Down
4 changes: 1 addition & 3 deletions back/admin/settings/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,7 @@ def __init__(self, *args, **kwargs):

class Meta:
model = get_user_model()
fields = [
"role",
]
fields = ["role", "departments"]


class WelcomeMessagesUpdateForm(forms.ModelForm):
Expand Down
1 change: 1 addition & 0 deletions back/admin/settings/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def form_valid(self, form):
# Change user if user already exists
user = user.first()
user.role = form.cleaned_data["role"]
user.departments = form.cleaned_data["departments"]
user.save()
else:
user = form.save()
Expand Down
9 changes: 6 additions & 3 deletions back/back/templatetags/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from admin.sequences.models import Condition
from organization.models import File
from users.utils import workday_to_datetime

register = template.Library()

Expand Down Expand Up @@ -56,15 +57,17 @@ def personalize(text, user):


@register.filter(name="new_hire_trigger_date")
def new_hire_trigger_date(condition, new_hire):
def new_hire_trigger_date(condition, condition_start_date_map):
"""
Shows the actual date that the condition will trigger
"""

if condition.condition_type == Condition.Type.BEFORE:
return new_hire.start_day - timedelta(days=condition.days)
return condition_start_date_map[condition.id] - timedelta(days=condition.days)
else:
return new_hire.workday_to_datetime(condition.days)
return workday_to_datetime(
condition.days, condition_start_date_map[condition.id]
)


@register.filter(name="offboarding_trigger_date")
Expand Down
Loading