[FIX] PROJECT: #810

This commit is contained in:
Horilla
2025-07-09 14:10:43 +05:30
parent 5223c63eff
commit ea372bab16
10 changed files with 68 additions and 61 deletions

View File

@@ -8,21 +8,12 @@ class ProjectConfig(AppConfig):
def ready(self):
from django.urls import include, path
from horilla.horilla_settings import APP_URLS, APPS
from horilla.urls import urlpatterns
APPS.append("project")
urlpatterns.append(
path("project/", include("project.urls")),
)
APP_URLS.append("project.urls")
super().ready()
try:
from django.urls import include, path
from horilla.urls import urlpatterns
urlpatterns.append(
path("project/", include("project.urls")),
)
except:
"""
Models not ready yet
"""

View File

@@ -187,11 +187,8 @@ class TasksNavBar(HorillaNavView):
managers = [
manager for project in projects for manager in project.managers.all()
]
members = [member for project in projects for member in project.members.all()]
self.search_url = reverse("tasks-list-view")
if employee in managers + members or self.request.user.has_perm(
"project.add_task"
):
if employee in managers or self.request.user.has_perm("project.add_task"):
self.create_attrs = f"""
onclick = "event.stopPropagation();"
data-toggle="oh-modal-toggle"
@@ -271,35 +268,36 @@ class TaskCreateForm(HorillaFormView):
project_id = self.kwargs.get("project_id")
stage_id = self.kwargs.get("stage_id")
task_id = self.kwargs.get("pk")
try:
if project_id:
project = Project.objects.filter(id=project_id).first()
elif stage_id:
project = ProjectStage.objects.filter(id=stage_id).first().project
elif task_id:
task = Task.objects.filter(id=task_id).first()
project = task.project
elif not task_id:
# try:
if project_id:
project = Project.objects.filter(id=project_id).first()
elif stage_id:
project = ProjectStage.objects.filter(id=stage_id).first().project
elif task_id:
task = Task.objects.filter(id=task_id).first()
project = task.project
elif not task_id:
return super().get(request, *args, pk=pk, **kwargs)
if (
request.user.employee_get in project.managers.all()
or request.user.is_superuser
or request.user.has_perm("project.add_task")
):
self.dynamic_create_fields = [
("project", DynamicProjectCreationFormView),
("stage", StageDynamicCreateForm),
]
return super().get(request, *args, pk=pk, **kwargs)
elif task_id:
if request.user.employee_get in task.task_managers.all():
return super().get(request, *args, pk=pk, **kwargs)
if (
request.user.employee_get in project.managers.all()
or request.user.is_superuser
):
self.dynamic_create_fields = [
("project", DynamicProjectCreationFormView),
("stage", StageDynamicCreateForm),
]
return super().get(request, *args, pk=pk, **kwargs)
elif task_id:
if request.user.employee_get in task.task_managers.all():
return super().get(request, *args, pk=pk, **kwargs)
else:
return you_dont_have_permission(request)
except Exception as e:
logger.error(e)
messages.error(request, _("Something went wrong!"))
return HttpResponse("<script>window.location.reload()</script>")
else:
return you_dont_have_permission(request)
# except Exception as e:
# logger.error(e)
# messages.error(request, _("Something went wrong!"))
# return HttpResponse("<script>window.location.reload()</script>")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

View File

@@ -258,7 +258,8 @@ class TaskTimeSheet(TimeSheetList):
if employee_id:
employee = Employee.objects.filter(id=employee_id).first()
if (
not employee in task.task_managers.all()
employee
and not employee in task.task_managers.all()
and not employee in task.project.managers.all()
and not employee.employee_user_id.is_superuser
):

View File

@@ -187,10 +187,12 @@ class TaskAllForm(ModelForm):
request = getattr(_thread_locals, "request", None)
employee = request.user.employee_get
if not self.instance.pk:
if request.user.is_superuser:
if request.user.is_superuser or request.user.has_perm("project.add_task"):
projects = Project.objects.all()
elif Project.objects.filter(managers=employee).exists():
projects = Project.objects.filter(managers=employee)
else:
projects = Project.objects.none()
self.fields["project"].queryset = projects
else:

View File

@@ -17,7 +17,10 @@ from django.utils import timezone
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from base.horilla_company_manager import HorillaCompanyManager
from base.models import Company
from employee.models import Employee
from horilla import horilla_middlewares
from horilla.horilla_middlewares import _thread_locals
from horilla.models import HorillaModel
from horilla_views.cbv_methods import render_template
@@ -75,6 +78,10 @@ class Project(HorillaModel):
upload_to="project/files", blank=True, null=True, verbose_name=_("Project File")
)
description = models.TextField(verbose_name=_("Description"))
company_id = models.ForeignKey(
Company, null=True, editable=False, on_delete=models.PROTECT
)
objects = HorillaCompanyManager("company_id")
def get_description(self, length=50):
"""
@@ -222,15 +229,15 @@ class Project(HorillaModel):
self.status = "expired"
def save(self, *args, **kwargs):
is_new = self.pk is None
is_new, request = self.pk is None, getattr(
horilla_middlewares._thread_locals, "request", None
)
if is_new and (cid := request.session.get("selected_company")) and cid != "all":
self.company_id = Company.find(cid)
super().save(*args, **kwargs)
if is_new:
ProjectStage.objects.create(
title="Todo",
project=self,
sequence=1,
is_end_stage=False,
title="Todo", project=self, sequence=1, is_end_stage=False
)
def __str__(self):
@@ -261,6 +268,7 @@ class ProjectStage(HorillaModel):
)
sequence = models.IntegerField(null=True, blank=True, editable=False)
is_end_stage = models.BooleanField(default=False, verbose_name=_("Is end stage"))
objects = HorillaCompanyManager("project__company_id")
def __str__(self) -> str:
return f"{self.title}"
@@ -351,6 +359,7 @@ class Task(HorillaModel):
)
description = models.TextField(verbose_name=_("Description"))
sequence = models.IntegerField(default=0)
objects = HorillaCompanyManager("project__company_id")
def clean(self) -> None:
if self.end_date is not None and self.project.end_date is not None:
@@ -552,6 +561,7 @@ class TimeSheet(HorillaModel):
verbose_name=_("Status"),
)
description = models.TextField(blank=True, null=True, verbose_name=_("Description"))
objects = HorillaCompanyManager("project_id__company_id")
class Meta:
ordering = ("-id",)

View File

@@ -28,7 +28,7 @@
</span>
</div>
</span>
{% if request.user|is_project_manager:stage.project or request.user.is_superuser %}
{% if request.user|is_project_manager:stage.project %}
<div class="oh-kanban__head-actions oh-kanban__dropdown" onclick="event.stopPropagation();">
<button class="oh-btn oh-btn--small oh-btn--transparent oh-kanban__btn oh-kanban__dropdown-toggle">
<ion-icon name="ellipsis-vertical-sharp" role="img" class="md hydrated"
@@ -78,7 +78,7 @@
<span class="oh-profile__name oh-text--dark" data-type="label"
style="font-weight:bold">{{task}}</span>
</div>
{% if request.user|is_project_manager:stage.project or request.user.is_superuser or request.user|is_task_manager:task %}
{% if request.user|is_project_manager:stage.project or request.user|is_task_manager:task %}
<div class="oh-kanban__card-actions oh-kanban__dropdown" onclick="event.stopPropagation();">
<button
class="oh-btn oh-btn--small oh-btn--transparent oh-kanban__btn oh-kanban__dropdown-toggle">
@@ -144,7 +144,7 @@
</div>
</div>
{% endfor %}
{% if request.user|is_project_manager:stages.first.project or request.user.is_superuser %}
{% if request.user|is_project_manager:stages.first.project %}
<div class="oh-kanban__add-container">
<button class="oh-btn oh-btn--x-small oh-kanban__add-section mr-2" data-toggle="oh-modal-toggle"
data-target="#objectCreateModal" hx-get="{% url 'create-project-stage' project_id %}"

View File

@@ -13,7 +13,7 @@
{% endif %}
{% include "filter_tags.html" %}
<div id="projectStages" class="oh-card" style="margin-top: 5px">
{% if request.user|is_project_manager:stages.first.project or request.user.is_superuser %}
{% if request.user|is_project_manager:stages.first.project %}
<div class="oh-kanban__add-container mb-2">
<button class="oh-btn oh-btn--x-small oh-kanban__add-section mr-2" data-toggle="oh-modal-toggle"
data-target="#objectCreateModal" hx-get="{% url 'create-project-stage' project_id %}"
@@ -43,7 +43,7 @@
</div>
<div class="oh-btn-group ml-3">
{% if request.user|is_project_manager:stage.project or request.user.is_superuser %}
{% if request.user|is_project_manager:stage.project %}
<div class="mr-2" onclick="event.stopPropagation();">
<a class="oh-btn oh-btn--secondary oh-btn--shadow"
data-toggle = "oh-modal-toggle" data-target="#genericModal"
@@ -110,7 +110,7 @@
<div class="oh-sticky-table__th">{% trans "Stage" %}</div>
<div class="oh-sticky-table__th">{% trans "Document" %}</div>
<div class="oh-sticky-table__th">{% trans "Description" %}</div>
{% if request.user|is_project_manager:stage.project or request.user.is_superuser %}
{% if request.user|is_project_manager:stage.project %}
<div class="oh-sticky-table__th">{% trans "Actions" %}</div>
{% endif %}
</div>
@@ -160,7 +160,7 @@
{% endif %}
</div>
<div class="oh-sticky-table__td">{{task.description}}</div>
{% if request.user|is_project_manager:stage.project or request.user.is_superuser %}
{% if request.user|is_project_manager:stage.project %}
<div class="oh-sticky-table__td">
<div class="oh-btn-group"
onclick="event.preventDefault();event.stopPropagation()"

View File

@@ -54,7 +54,7 @@
{% include 'task/new/filter_task.html' %}
</div>
</div>
{% if request.user|is_project_manager:project or request.user.is_superuser %}
{% if perms.project.add_task or request.user|is_project_manager:project %}
<div class="oh-main__titlebar-button-container">
<div class="oh-btn-group ml-2">
<div>

View File

@@ -57,6 +57,8 @@ def is_project_manager(user, project):
"""
This method will return true, if the user is manager of the project
"""
if user.is_superuser:
return True
employee = user.employee_get
return Project.objects.filter(id=project.id, managers=employee).exists()

View File

@@ -1141,11 +1141,14 @@ def task_all_create(request):
@login_required
def update_project_task_status(request, task_id):
status = request.GET.get("status")
task = get_object_or_404(Task, id=task_id)
if task.end_date and task.end_date < date.today():
messages.warning(request, _("Cannot update status. Task has already expired."))
return HttpResponse("<script>$('#reloadMessagesButton').click();</script>")
task.status = status
task.save()
messages.success(request, _("Task status has been updated successfully"))
return HttpResponse("<script>$('#reloadMessagesButton').click();</script>")