[UPDT] OFFBOARDING: Notification and message while adding employee and changing status and stage
This commit is contained in:
@@ -165,7 +165,8 @@ class TaskForm(ModelForm):
|
||||
|
||||
verbose_name = "Offboarding Task"
|
||||
tasks_to = forms.ModelMultipleChoiceField(
|
||||
queryset=OffboardingEmployee.objects.all()
|
||||
queryset=OffboardingEmployee.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -179,6 +180,8 @@ class TaskForm(ModelForm):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["stage_id"].empty_label = "All Stages in Offboarding"
|
||||
self.fields["managers"].empty_label = None
|
||||
queryset = OffboardingEmployee.objects.filter(stage_id__offboarding_id=OffboardingStage.objects.filter(id=self.initial.get("stage_id")).first().offboarding_id)
|
||||
self.fields["tasks_to"].queryset = queryset
|
||||
|
||||
def as_p(self):
|
||||
"""
|
||||
@@ -192,7 +195,6 @@ class TaskForm(ModelForm):
|
||||
super().save(commit)
|
||||
if commit:
|
||||
employees = self.cleaned_data["tasks_to"]
|
||||
print(employees)
|
||||
for employee in employees:
|
||||
assinged_task = EmployeeTask.objects.get_or_create(
|
||||
employee_id=employee,
|
||||
|
||||
@@ -6,6 +6,9 @@ from django.dispatch import receiver
|
||||
from base import thread_local_middleware
|
||||
from employee.models import Employee
|
||||
from horilla_audit.models import HorillaAuditInfo, HorillaAuditLog
|
||||
from notifications.signals import notify
|
||||
from django.contrib.auth.models import User
|
||||
from base.thread_local_middleware import _thread_locals
|
||||
|
||||
# Create your models here.
|
||||
|
||||
@@ -22,6 +25,9 @@ class Offboarding(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
status = models.CharField(max_length=10, default="ongoing", choices=statuses)
|
||||
is_active = models.BooleanField(default=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class OffboardingStage(models.Model):
|
||||
@@ -150,6 +156,21 @@ class EmployeeTask(models.Model):
|
||||
|
||||
class Meta:
|
||||
unique_together = ["employee_id", "task_id"]
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
request = getattr(_thread_locals, "request", None)
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=self.employee_id.employee_id.employee_user_id,
|
||||
verb=f'Offboarding task "{self.task_id.title}" has been assiged',
|
||||
verb_ar=f"",
|
||||
verb_de=f"",
|
||||
verb_es=f"",
|
||||
verb_fr=f"",
|
||||
redirect="offboarding/offboarding-pipeline",
|
||||
icon="information",
|
||||
)
|
||||
|
||||
|
||||
class ExitReason(models.Model):
|
||||
|
||||
@@ -1,82 +1,92 @@
|
||||
{% load i18n offboarding_filter %}
|
||||
{% for employee in stage.offboardingemployee_set.all %}
|
||||
<div class="oh-sticky-table__tr oh-multiple-table-sort__movable" data-employee="{{employee.employee_id.get_full_name}}" data-employee-id="{{ employee.id }}">
|
||||
<div class="oh-sticky-table__sd">
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img src="{{ employee.employee_id.get_avatar }}" class="oh-profile__image" />
|
||||
</div>
|
||||
<span class="oh-profile__name oh-text--dark">{{ employee.employee_id.get_full_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
{% trans 'In' %} {{ employee.notice_period }}
|
||||
{{ employee.get_unit_display }}
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">{{ employee.notice_period_starts }}</div>
|
||||
<div class="oh-sticky-table__td">{{ employee.notice_period_ends }}</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
<form hx-get="{% url "offboarding-change-stage" %}?employee_ids={{employee.id}}"
|
||||
hx-target="#offboardingBody{{offboarding.id}}">
|
||||
{{ stage_forms|stages:stage }}
|
||||
<input type="submit" hidden>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
<div class="oh-btn-group">
|
||||
<button type="button" hx-get="{% url 'send-mail-employee' employee.employee_id.id %}"
|
||||
title="{% trans 'Send Mail' %}" hx-target="#offboardingModalBody" class="oh-btn oh-btn--light"
|
||||
data-toggle="oh-modal-toggle" data-target="#offboardingModal"
|
||||
style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon
|
||||
name="mail-open-outline"></ion-icon></button>
|
||||
<button type="button" title="{% trans 'Notes' %}" class="oh-btn oh-btn--light oh-activity-sidebar__open"
|
||||
data-target="#activitySidebar" hx-get="{% url 'view-offboarding-note' %}?employee_id={{ employee.id }}"
|
||||
hx-target="#noteContainer" style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon
|
||||
name="newspaper-outline"></ion-icon>
|
||||
</button>
|
||||
{% if not employee.employee_id.is_active %}
|
||||
<a type="button" href="{% url 'employee-archive' employee.employee_id.id %}" title="{% trans 'Un Archive' %}"
|
||||
class="oh-btn oh-btn--light tex-primary"
|
||||
style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon name="archive"></ion-icon></a>
|
||||
{% else %}
|
||||
<a type="button" hx-target="#offboardingModalBody" data-toggle="oh-modal-toggle" data-target="#offboardingModal" hx-get="{% url "add-employee" %}?instance_id={{employee.id}}&stage_id={{stage.id}}" title="{% trans 'Edit' %}"
|
||||
class="oh-btn oh-btn--light tex-primary"
|
||||
style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon name="create-outline"></ion-icon></a>
|
||||
{% endif %}
|
||||
{% if perms.offboarding.delete_offboardingemployee %}
|
||||
<a type="button" style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;" title="{% trans 'Delete' %}" onclick="return confirm('Do you want to delete this offboarding user?')" class="oh-btn oh-btn--light" href="{% url "delete-offboarding-employee" %}"><ion-icon
|
||||
name="trash-outline"></ion-icon>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% for task in stage.offboardingtask_set.all %}
|
||||
<div class="oh-sticky-table__td">
|
||||
{% if task|have_task:employee %}
|
||||
{% for assinged_tasks in employee|get_assigned_task:task %}
|
||||
<select hx-get="{% url "update-task-status" %}?stage_id={{stage.id}}&employee_ids={{employee.id}}&task_id={{assinged_tasks.task_id.id}}"
|
||||
hx-target="#offboardingBody{{offboarding.id}}" name="task_status" id="task_status{{assinged_tasks.id}}"
|
||||
class="oh-select-custom w-100">
|
||||
{% for assinged_task in assinged_tasks.statuses %}
|
||||
{% if assinged_tasks.status == assinged_task.0 %}
|
||||
<option value="{{ assinged_task.0 }}" selected>{{ assinged_task.1 }}</option>
|
||||
{% else %}
|
||||
<option value="{{ assinged_task.0 }}">{{ assinged_task.1 }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<button hx-get="{% url "offboarding-assign-task" %}?employee_ids={{employee.id}}&task_id={{task.id}}"
|
||||
hx-target="#offboardingBody{{offboarding.id}}" class="oh-checkpoint-badge text-info"
|
||||
data-toggle="oh-modal-toggle">{% trans 'Assign' %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="oh-sticky-table__td"></div>
|
||||
{% if response_message %}
|
||||
<div class="oh-alert-container">
|
||||
<div class="oh-alert oh-alert--animated oh-alert--success">
|
||||
{{response_message}}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for employee in stage.offboardingemployee_set.all %}
|
||||
{% if perms.offboarding.view_offboarding or request.user.employee_get|is_in_managers:offboarding or request.user.employee_get|is_in_managers:stage or request.user.employee_get|is_in_managers:employee %}
|
||||
<div class="oh-sticky-table__tr oh-multiple-table-sort__movable" data-employee="{{employee.employee_id.get_full_name}}" data-employee-id="{{ employee.id }}">
|
||||
<div class="oh-sticky-table__sd">
|
||||
<div class="oh-profile oh-profile--md">
|
||||
<div class="oh-profile__avatar mr-1">
|
||||
<img src="{{ employee.employee_id.get_avatar }}" class="oh-profile__image" />
|
||||
</div>
|
||||
<span class="oh-profile__name oh-text--dark">{{ employee.employee_id.get_full_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">
|
||||
{% trans 'In' %} {{ employee.notice_period }}
|
||||
{{ employee.get_unit_display }}
|
||||
</div>
|
||||
<div class="oh-sticky-table__td">{{ employee.notice_period_starts }}</div>
|
||||
<div class="oh-sticky-table__td">{{ employee.notice_period_ends }}</div>
|
||||
{% if request.user.employee_get|is_any_stage_manager or perms.offboarding.change_offboarding or perms.offboarding.change_offboardingemployee %}
|
||||
<div class="oh-sticky-table__td">
|
||||
<form hx-get="{% url "offboarding-change-stage" %}?employee_ids={{employee.id}}"
|
||||
hx-target="#offboardingBody{{offboarding.id}}">
|
||||
{{ stage_forms|stages:stage }}
|
||||
<input type="submit" hidden>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="oh-sticky-table__td">
|
||||
<div class="oh-btn-group">
|
||||
<button type="button" hx-get="{% url 'send-mail-employee' employee.employee_id.id %}"
|
||||
title="{% trans 'Send Mail' %}" hx-target="#offboardingModalBody" class="oh-btn oh-btn--light"
|
||||
data-toggle="oh-modal-toggle" data-target="#offboardingModal"
|
||||
style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon
|
||||
name="mail-open-outline"></ion-icon></button>
|
||||
<button type="button" title="{% trans 'Notes' %}" class="oh-btn oh-btn--light oh-activity-sidebar__open"
|
||||
data-target="#activitySidebar" hx-get="{% url 'view-offboarding-note' %}?employee_id={{ employee.id }}"
|
||||
hx-target="#noteContainer" style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon
|
||||
name="newspaper-outline"></ion-icon>
|
||||
</button>
|
||||
{% if not employee.employee_id.is_active %}
|
||||
<a type="button" href="{% url 'employee-archive' employee.employee_id.id %}" title="{% trans 'Un Archive' %}"
|
||||
class="oh-btn oh-btn--light tex-primary"
|
||||
style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon name="archive"></ion-icon></a>
|
||||
{% else %}
|
||||
<a type="button" hx-target="#offboardingModalBody" data-toggle="oh-modal-toggle" data-target="#offboardingModal" hx-get="{% url "add-employee" %}?instance_id={{employee.id}}&stage_id={{stage.id}}" title="{% trans 'Edit' %}"
|
||||
class="oh-btn oh-btn--light tex-primary"
|
||||
style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"><ion-icon name="create-outline"></ion-icon></a>
|
||||
{% endif %}
|
||||
{% if perms.offboarding.delete_offboardingemployee %}
|
||||
<a type="button" style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;" title="{% trans 'Delete' %}" onclick="return confirm('Do you want to delete this offboarding user?')" class="oh-btn oh-btn--light" href="{% url "delete-offboarding-employee" %}?employee_ids={{employee.id}}"><ion-icon
|
||||
name="trash-outline"></ion-icon>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% for task in stage.offboardingtask_set.all %}
|
||||
<div class="oh-sticky-table__td">
|
||||
{% if task|have_task:employee %}
|
||||
{% for assinged_tasks in employee|get_assigned_task:task %}
|
||||
<select hx-get="{% url "update-task-status" %}?stage_id={{stage.id}}&employee_ids={{employee.id}}&task_id={{assinged_tasks.task_id.id}}"
|
||||
hx-target="#offboardingBody{{offboarding.id}}" name="task_status" id="task_status{{assinged_tasks.id}}"
|
||||
class="oh-select-custom w-100">
|
||||
{% for assinged_task in assinged_tasks.statuses %}
|
||||
{% if assinged_tasks.status == assinged_task.0 %}
|
||||
<option value="{{ assinged_task.0 }}" selected>{{ assinged_task.1 }}</option>
|
||||
{% else %}
|
||||
<option value="{{ assinged_task.0 }}">{{ assinged_task.1 }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<button hx-get="{% url "offboarding-assign-task" %}?employee_ids={{employee.id}}&task_id={{task.id}}"
|
||||
hx-target="#offboardingBody{{offboarding.id}}" class="oh-checkpoint-badge text-info"
|
||||
data-toggle="oh-modal-toggle">{% trans 'Assign' %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="oh-sticky-table__td"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<script>
|
||||
$("[data-archive-stage=true]").find(".oh-sticky-table__tr[data-employee-id]").hide();
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.shortcuts import redirect, render
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.models import User
|
||||
from employee.models import Employee
|
||||
from horilla.decorators import login_required, permission_required
|
||||
from offboarding.decorators import any_manager_can_enter, offboarding_manager_can_enter, offboarding_or_stage_manager_can_enter
|
||||
from offboarding.decorators import (
|
||||
any_manager_can_enter,
|
||||
offboarding_manager_can_enter,
|
||||
offboarding_or_stage_manager_can_enter,
|
||||
)
|
||||
from offboarding.forms import (
|
||||
NoteForm,
|
||||
OffboardingEmployeeForm,
|
||||
@@ -21,13 +26,17 @@ from offboarding.models import (
|
||||
OffboardingStageMultipleFile,
|
||||
OffboardingTask,
|
||||
)
|
||||
from notifications.signals import notify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
@login_required
|
||||
@any_manager_can_enter("offboarding.view_offboarding")
|
||||
@any_manager_can_enter(
|
||||
"offboarding.view_offboarding", offboarding_employee_can_enter=True
|
||||
)
|
||||
def pipeline(request):
|
||||
"""
|
||||
Offboarding pipleine view
|
||||
@@ -58,7 +67,7 @@ def create_offboarding(request):
|
||||
form = OffboardingForm(request.POST, instance=instance)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, "Offboarding saved")
|
||||
messages.success(request, _("Offboarding saved"))
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
|
||||
return render(
|
||||
@@ -78,7 +87,7 @@ def delete_offboarding(request):
|
||||
"""
|
||||
ids = request.GET.getlits("id")
|
||||
Offboarding.objects.filter(id__in=ids).delete()
|
||||
messages.success(request, "Offboarding deleted")
|
||||
messages.success(request, _("Offboarding deleted"))
|
||||
return redirect(pipeline)
|
||||
|
||||
|
||||
@@ -103,7 +112,7 @@ def create_stage(request):
|
||||
instance.offboarding_id = offboarding
|
||||
instance.save()
|
||||
instance.managers.set(form.data.getlist("managers"))
|
||||
messages.success(request, "Stage saved")
|
||||
messages.success(request, _("Stage saved"))
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
return render(request, "offboarding/stage/form.html", {"form": form})
|
||||
|
||||
@@ -123,15 +132,24 @@ def add_employee(request):
|
||||
form = OffboardingEmployeeForm(initial={"stage_id": stage}, instance=instance)
|
||||
form.instance.stage_id = stage
|
||||
if request.method == "POST":
|
||||
form = OffboardingEmployeeForm(
|
||||
request.POST,
|
||||
instance=instance
|
||||
)
|
||||
form = OffboardingEmployeeForm(request.POST, instance=instance)
|
||||
if form.is_valid():
|
||||
instance = form.save(commit=False)
|
||||
instance.stage_id = stage
|
||||
instance.save()
|
||||
messages.success(request, "Employee added to the stage")
|
||||
messages.success(request, _("Employee added to the stage"))
|
||||
if not instance_id:
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=instance.employee_id.employee_user_id,
|
||||
verb=f"You have been added to the {stage} of {stage.offboarding_id}",
|
||||
verb_ar=f"",
|
||||
verb_de=f"",
|
||||
verb_es=f"",
|
||||
verb_fr=f"",
|
||||
redirect="offboarding/offboarding-pipeline",
|
||||
icon="information",
|
||||
)
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
return render(request, "offboarding/employee/form.html", {"form": form})
|
||||
|
||||
@@ -143,8 +161,20 @@ def delete_employee(request):
|
||||
This method is used to delete the offboarding employee
|
||||
"""
|
||||
employee_ids = request.GET.getlist("employee_ids")
|
||||
instances = OffboardingEmployee.objects.filter(id__in=employee_ids)
|
||||
OffboardingEmployee.objects.filter(id__in=employee_ids).delete()
|
||||
messages.success(request, "Offboarding employee deleted")
|
||||
messages.success(request, _("Offboarding employee deleted"))
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=User.objects.filter(id__in=instances.values_list("employee_id__employee_user_id",flat=True)),
|
||||
verb=f"You have been removed from the offboarding",
|
||||
verb_ar=f"",
|
||||
verb_de=f"",
|
||||
verb_es=f"",
|
||||
verb_fr=f"",
|
||||
redirect="offboarding/offboarding-pipeline",
|
||||
icon="information",
|
||||
)
|
||||
return redirect(pipeline)
|
||||
|
||||
|
||||
@@ -156,7 +186,7 @@ def delete_stage(request):
|
||||
"""
|
||||
ids = request.GET.getlist("ids")
|
||||
OffboardingStage.objects.filter(id__in=ids).delete()
|
||||
messages.success(request, "Stage deleted")
|
||||
messages.success(request, _("Stage deleted"))
|
||||
return redirect(pipeline)
|
||||
|
||||
|
||||
@@ -183,15 +213,26 @@ def change_stage(request):
|
||||
stage_forms[str(stage.offboarding_id.id)] = StageSelectForm(
|
||||
offboarding=stage.offboarding_id
|
||||
)
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=User.objects.filter(id__in=employees.values_list("employee_id__employee_user_id",flat=True)),
|
||||
verb=f"Offboarding stage has been changed",
|
||||
verb_ar=f"",
|
||||
verb_de=f"",
|
||||
verb_es=f"",
|
||||
verb_fr=f"",
|
||||
redirect="offboarding/offboarding-pipeline",
|
||||
icon="information",
|
||||
)
|
||||
return render(
|
||||
request,
|
||||
"offboarding/stage/offboarding_body.html",
|
||||
{"offboarding": stage.offboarding_id, "stage_forms": stage_forms},
|
||||
{"offboarding": stage.offboarding_id, "stage_forms": stage_forms,"response_message":_("stage changed successfully.")},
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@any_manager_can_enter("offboarding.view_offboardingnote")
|
||||
@any_manager_can_enter("offboarding.view_offboardingnote",offboarding_employee_can_enter=True)
|
||||
def view_notes(request):
|
||||
"""
|
||||
This method is used to render all the notes of the employee
|
||||
@@ -288,17 +329,21 @@ def add_task(request):
|
||||
instance=instance,
|
||||
)
|
||||
if request.method == "POST":
|
||||
form = TaskForm(request.POST, instance=instance)
|
||||
form = TaskForm(request.POST, instance=instance,initial={
|
||||
"stage_id": stage_id,
|
||||
})
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, "Task Added")
|
||||
return HttpResponse("<script>window.location.reload()</script>")
|
||||
return render(request, "offboarding/task/form.html", {"form": form})
|
||||
return render(request, "offboarding/task/form.html", {"form": form,})
|
||||
|
||||
|
||||
@login_required
|
||||
@any_manager_can_enter("offboarding.change_employeetask")
|
||||
def update_task_status(request):
|
||||
@any_manager_can_enter(
|
||||
"offboarding.change_employeetask", offboarding_employee_can_enter=True
|
||||
)
|
||||
def update_task_status(request,*args, **kwargs):
|
||||
"""
|
||||
This method is used to update the assigned tasks status
|
||||
"""
|
||||
@@ -306,10 +351,21 @@ def update_task_status(request):
|
||||
employee_ids = request.GET.getlist("employee_ids")
|
||||
task_id = request.GET["task_id"]
|
||||
status = request.GET["task_status"]
|
||||
EmployeeTask.objects.filter(
|
||||
employee_task = EmployeeTask.objects.filter(
|
||||
employee_id__id__in=employee_ids, task_id__id=task_id
|
||||
).update(status=status)
|
||||
|
||||
)
|
||||
employee_task.update(status=status)
|
||||
notify.send(
|
||||
request.user.employee_get,
|
||||
recipient=User.objects.filter(id__in=employee_task.values_list("task_id__managers__employee_user_id",flat=True)),
|
||||
verb=f"Offboarding Task status has been updated",
|
||||
verb_ar=f"",
|
||||
verb_de=f"",
|
||||
verb_es=f"",
|
||||
verb_fr=f"",
|
||||
redirect="offboarding/offboarding-pipeline",
|
||||
icon="information",
|
||||
)
|
||||
stage = OffboardingStage.objects.get(id=stage_id)
|
||||
stage_forms = {}
|
||||
stage_forms[str(stage.offboarding_id.id)] = StageSelectForm(
|
||||
@@ -318,7 +374,7 @@ def update_task_status(request):
|
||||
return render(
|
||||
request,
|
||||
"offboarding/stage/offboarding_body.html",
|
||||
{"offboarding": stage.offboarding_id, "stage_forms": stage_forms},
|
||||
{"offboarding": stage.offboarding_id, "stage_forms": stage_forms,"response_message": _("Task status changed successfully.")},
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user