Skip to content

Commit

Permalink
[UPDT] PROJECT: Missing files updated
Browse files Browse the repository at this point in the history
  • Loading branch information
horilla-opensource committed Feb 14, 2025
1 parent 07e9c23 commit d453c1d
Show file tree
Hide file tree
Showing 95 changed files with 12,119 additions and 7,536 deletions.
16 changes: 9 additions & 7 deletions project/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from django.contrib import admin
from .models import *
# Register your models here.
admin.site.register(Project)
admin.site.register(ProjectStage)
admin.site.register(Task)
admin.site.register(TimeSheet)
from django.contrib import admin

from .models import *

# Register your models here.
admin.site.register(Project)
admin.site.register(ProjectStage)
admin.site.register(Task)
admin.site.register(TimeSheet)
40 changes: 28 additions & 12 deletions project/apps.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
from django.apps import AppConfig


class ProjectConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "project"

def ready(self):
from horilla.horilla_settings import APPS

APPS.append("project")
super().ready()
from django.apps import AppConfig


class ProjectConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "project"

def ready(self):
from django.urls import include, path

from horilla.urls import urlpatterns

urlpatterns.append(
path("project/", include("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
"""
Empty file added project/cbv/__init__.py
Empty file.
31 changes: 31 additions & 0 deletions project/cbv/accessibility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Accessibility
"""


from django.contrib.auth.context_processors import PermWrapper

from employee.models import Employee
from project.models import Project, Task


def task_crud_accessibility(request, instance: object = None, user_perms: PermWrapper = [], *args, **kwargs
) -> bool:
"""
to access crud operations
"""
employee = request.user.employee_get
is_task_manager = employee in instance.task_managers.all()
is_project_manager = employee in instance.project.managers.all()
if (request.user.has_perm("project.view_task") or is_project_manager or is_task_manager):
return True
else:
return False

def project_manager_accessibility(request, instance: object = None, user_perms: PermWrapper = [], *args, **kwargs
) -> bool:
"""
to access edit Project
"""
return (request.user.employee_get in instance.managers.all() or
request.user.is_superuser)
33 changes: 33 additions & 0 deletions project/cbv/cbv_decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@


from project.methods import any_project_manager, any_project_member, any_task_manager, any_task_member, has_subordinates
from django.contrib import messages
from django.http import HttpResponseRedirect
from horilla.horilla_middlewares import _thread_locals
# from project.sidebar import has_subordinates


decorator_with_arguments = lambda decorator: lambda *args, **kwargs: lambda func: decorator(func, *args, **kwargs)


@decorator_with_arguments
def is_projectmanager_or_member_or_perms(function,perm):
def _function(self, *args, **kwargs):
"""
This method is used to check the employee is project manager or not
"""
request = getattr(_thread_locals,"request")
if not getattr(self,"request",None):
self.request = request
user = request.user
if (
user.has_perm(perm) or
any_project_manager(user) or
any_project_member(user) or
any_task_manager(user) or
any_task_member(user)
):
return function(self, *args, **kwargs)
messages.info(request, "You don't have permission.")
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
return _function
107 changes: 107 additions & 0 deletions project/cbv/dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""
Dashbord of project
"""

import calendar
import datetime
from typing import Any
from django.db.models import Count
from django.db.models.query import QuerySet
from django.urls import resolve, reverse
from django.utils.translation import gettext_lazy as _
from django.utils.decorators import method_decorator
from django.db.models import Q
from base.methods import get_subordinates
from horilla_views.generic.cbv.views import HorillaListView, HorillaDetailedView
from horilla_views.cbv_methods import login_required
from project.filters import ProjectFilter
from project.models import Project
from project.cbv.cbv_decorators import is_projectmanager_or_member_or_perms


@method_decorator(login_required, name="dispatch")
@method_decorator(
is_projectmanager_or_member_or_perms("project.view_project"), name="dispatch"
)
class ProjectsDueInMonth(HorillaListView):

model = Project
filter_class = ProjectFilter
bulk_select_option = False
columns = [(_("Project"), "title", "get_avatar")]
show_filter_tags = False

def get_queryset(self):
queryset = super().get_queryset()
if not self.request.user.has_perm("project.view_project"):
employee = self.request.user.employee_get
task_filter = queryset.filter(
Q(task__task_members=employee) | Q(task__task_manager=employee)
)
project_filter = queryset.filter(Q(manager=employee) | Q(members=employee))
queryset = task_filter | project_filter
today = datetime.date.today()
first_day = today.replace(day=1)
last_day = calendar.monthrange(today.year, today.month)[1]
last_day_of_month = today.replace(day=last_day)
queryset = queryset.filter(
Q(end_date__gte=first_day) & Q(end_date__lte=last_day_of_month)
).exclude(status="expired")
return queryset

def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
self.search_url = reverse("projects-due-in-this-month")

row_attrs = """
hx-get='{get_detail_url}?instance_ids={ordered_ids}'
hx-target="#genericModalBody"
data-target="#genericModal"
data-toggle="oh-modal-toggle"
"""


class ProjectDetailView(HorillaDetailedView):
"""
detail view of the projects
"""

model = Project
title = _("Details")
header = {"title": "title", "subtitle": "", "avatar": "get_avatar"}
body = [
(_("Manager"), "manager"),
(_("Members"), "get_members"),
(_("Status"), "status_column"),
(_("No of Tasks"), "task_count"),
(_("Start date"), "start_date"),
(_("End date"), "end_date"),
(_("Document"), "get_document_html"),
(_("Description"), "description"),
]

def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs)
instnce_id = resolve(self.request.path_info).kwargs.get("pk")
employee = self.request.user.employee_get
project = Project.objects.get(id=instnce_id)
if (
employee in project.managers.all()
or employee in project.members.all()
or self.request.user.has_perm("project.view_project")
):
self.actions = [
{
"action": _("View Project"),
"icon": "create-outline",
"attrs": """
class = "oh-btn oh-btn--info w-100"
{redirect}
""",
}
]

def get_queryset(self) -> QuerySet[Any]:
queryset = super().get_queryset()
queryset = queryset.annotate(task_count=Count("task"))
return queryset
135 changes: 135 additions & 0 deletions project/cbv/project_stage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
"""
This page handles the cbv methods for project stages
"""

import logging
from typing import Any
from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _
from django.utils.decorators import method_decorator
from django.contrib import messages
from horilla_views.cbv_methods import login_required
from horilla_views.generic.cbv.views import HorillaFormView

# from project.decorator import project_delete_permission
from project.forms import ProjectStageForm
from project.methods import you_dont_have_permission
from project.models import Project, ProjectStage

logger = logging.getLogger(__name__)


@method_decorator(login_required, name="dispatch")
# @method_decorator(project_delete_permission, name="dispatch")
class ProjectStageCreateForm(HorillaFormView):
"""
form view fro create and edit stages
"""

form_class = ProjectStageForm
model = ProjectStage
new_display_title = _("Create Project Stage")

def get(self, request, *args, pk=None, **kwargs):
if request.GET.get("project_id"):
project_id = request.GET.get("project_id")
else:
project_id = self.kwargs.get("project_id")
stage_id = self.kwargs.get("pk")
if project_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
if (
request.user.employee_get in project.managers.all()
or request.user.is_superuser
):
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 super().get(request, *args, pk=pk, **kwargs)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
project_id = self.kwargs.get("project_id")
if project_id:
project = Project.objects.get(id=project_id)
self.form.fields["project"].initial = project
if self.form.instance.pk:
self.form_class.verbose_name = _("Update Project Stage")
return context

def form_valid(self, form: ProjectStageForm) -> HttpResponse:
if form.is_valid():
if form.instance.pk:
project_id = self.form.cleaned_data["project"].id
message = _(f"{self.form.instance} Updated")
else:
project_id = self.kwargs.get("project_id")
message = _("New project stage created")
form.save()
messages.success(self.request, message)
return self.HttpResponse(
f"<span hx-get='/project/task-filter/{project_id}' hx-trigger='load' hx-target='#viewContainer'></span>"
)
return super().form_valid(form)


from django import forms


class StageDynamicCreateForm(ProjectStageCreateForm):
"""
dynamic create form for stage
"""

is_dynamic_create_view = True
template_name = HorillaFormView.template_name

def get_initial(self):
initial = super().get_initial()
project = self.request.GET.get("project")
initial["project"] = project
return initial

def init_form(self, *args, data, files, instance=None, **kwargs):
initial = self.get_initial()
form = super().init_form(
*args, data=data, files=files, instance=instance, initial=initial, **kwargs
)
if not initial.get("project"):
form.fields["project"].widget = forms.Select(
attrs={"class": "oh-select oh-select-2 w-100 oh-select2"}
)
form.fields["project"].queryset = Project.objects.all()

return form

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
project_id = self.request.GET.get("project_id")
if not project_id:
project_id = self.request.GET.get("project")
if project_id:
project = Project.objects.get(id=project_id)
self.form.fields["project"].initial = project
self.form.fields["project"].choices = [(project.id, project.title)]
return context

def form_valid(self, form: ProjectStageForm) -> HttpResponse:
if form.is_valid():
if form.instance.pk:
message = _(f"{self.form.instance} Updated")
else:
message = _("New project stage created")
form.save()
messages.success(self.request, _(message))
return self.HttpResponse()
return super().form_valid(form)
Loading

0 comments on commit d453c1d

Please sign in to comment.