[FIX] PROJECT: Fixed missing login_required and errors while passing get request with with invalid ids

This commit is contained in:
Horilla
2025-12-05 19:24:27 +05:30
parent 6058d25cd6
commit e18cb640cf
7 changed files with 249 additions and 254 deletions

View File

@@ -79,11 +79,11 @@ class ProjectDetailView(HorillaDetailedView):
"description": 12, "description": 12,
} }
def __init__(self, **kwargs: Any) -> None: def get_context_data(self, **kwargs):
super().__init__(**kwargs) context = super().get_context_data(**kwargs)
instnce_id = resolve(self.request.path_info).kwargs.get("pk") instance_id = resolve(self.request.path_info).kwargs.get("pk")
employee = self.request.user.employee_get employee = self.request.user.employee_get
project = Project.objects.get(id=instnce_id) project = Project.objects.get(id=instance_id)
if ( if (
employee in project.managers.all() employee in project.managers.all()
or employee in project.members.all() or employee in project.members.all()
@@ -99,6 +99,8 @@ class ProjectDetailView(HorillaDetailedView):
""", """,
} }
] ]
context["actions"] = self.actions
return context
def get_queryset(self) -> QuerySet[Any]: def get_queryset(self) -> QuerySet[Any]:
queryset = super().get_queryset() queryset = super().get_queryset()

View File

@@ -346,9 +346,12 @@ class ProjectCardView(HorillaCardView):
queryset = task_filter | project_filter queryset = task_filter | project_filter
return queryset.distinct() return queryset.distinct()
def __init__(self, **kwargs: Any) -> None: def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.search_url = reverse("project-card-view") self.search_url = reverse("project-card-view")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if ( if (
self.request.user.has_perm("project.change_project") self.request.user.has_perm("project.change_project")
or self.request.user.has_perm("project.delete_project") or self.request.user.has_perm("project.delete_project")
@@ -388,6 +391,8 @@ class ProjectCardView(HorillaCardView):
""", """,
}, },
] ]
context["actions"] = self.actions
return context
details = { details = {
"image_src": "get_avatar", "image_src": "get_avatar",

View File

@@ -186,21 +186,7 @@ class TasksNavBar(HorillaNavView):
def __init__(self, **kwargs: Any) -> None: def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs) super().__init__(**kwargs)
employee = self.request.user.employee_get
projects = Project.objects.all()
managers = [
manager for project in projects for manager in project.managers.all()
]
self.search_url = reverse("tasks-list-view") self.search_url = reverse("tasks-list-view")
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"
data-target="#genericModal"
hx-target="#genericModalBody"
hx-get="{reverse('create-task-all')}"
"""
self.view_types = [ self.view_types = [
{ {
"type": "list", "type": "list",
@@ -220,6 +206,22 @@ class TasksNavBar(HorillaNavView):
}, },
] ]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
employee = self.request.user.employee_get
projects = Project.objects.all()
managers = [
manager for project in projects for manager in project.managers.all()
]
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"
data-target="#genericModal"
hx-target="#genericModalBody"
hx-get="{reverse('create-task-all')}"
"""
if self.request.user.has_perm("project.view_task"): if self.request.user.has_perm("project.view_task"):
self.actions = [ self.actions = [
{ {
@@ -246,6 +248,9 @@ class TasksNavBar(HorillaNavView):
""", """,
}, },
] ]
context["actions"] = self.actions
context["create_attrs"] = self.create_attrs
return context
@method_decorator(login_required, name="dispatch") @method_decorator(login_required, name="dispatch")

View File

@@ -73,7 +73,6 @@ class TimeSheetNavView(HorillaNavView):
def __init__(self, **kwargs: Any) -> None: def __init__(self, **kwargs: Any) -> None:
super().__init__(**kwargs) super().__init__(**kwargs)
self.search_url = reverse("time-sheet-list") self.search_url = reverse("time-sheet-list")
url = f"{reverse('personal-time-sheet-view',kwargs={'emp_id': self.request.user.employee_get.id})}"
self.actions = [ self.actions = [
{ {
"action": _("Delete"), "action": _("Delete"),
@@ -85,6 +84,17 @@ class TimeSheetNavView(HorillaNavView):
""", """,
}, },
] ]
self.create_attrs = f"""
onclick = "event.stopPropagation();"
data-toggle="oh-modal-toggle"
data-target="#genericModal"
hx-target="#genericModalBody"
hx-get="{reverse('create-time-sheet')}"
"""
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
url = f"{reverse('personal-time-sheet-view',kwargs={'emp_id': self.request.user.employee_get.id})}"
self.view_types = [ self.view_types = [
{ {
"type": "list", "type": "list",
@@ -105,21 +115,14 @@ class TimeSheetNavView(HorillaNavView):
{ {
"type": "graph", "type": "graph",
"icon": "bar-chart", "icon": "bar-chart",
"url": url,
"attrs": f""" "attrs": f"""
onclick="event.stopPropagation();
window.location.href='{url}'"
title ='Graph' title ='Graph'
""", """,
}, },
] ]
context["view_types"] = self.view_types
self.create_attrs = f""" return context
onclick = "event.stopPropagation();"
data-toggle="oh-modal-toggle"
data-target="#genericModal"
hx-target="#genericModalBody"
hx-get="{reverse('create-time-sheet')}"
"""
@method_decorator(login_required, name="dispatch") @method_decorator(login_required, name="dispatch")

View File

@@ -1,4 +1,4 @@
{% extends 'index.html' %}{% block content %}{% load static %} {% load i18n %} {% load static %} {% load i18n %}
{% load basefilters %} {% if request.user.employee_get.id == emp_id or perms.project.view_timesheet or request.user|is_reportingmanager %} {% load basefilters %} {% if request.user.employee_get.id == emp_id or perms.project.view_timesheet or request.user|is_reportingmanager %}
<div <div
class="oh-card-dashboard oh-card-dashboard--no-scale oh-card-dashboard--transparent" class="oh-card-dashboard oh-card-dashboard--no-scale oh-card-dashboard--transparent"
@@ -15,7 +15,9 @@
<span class="oh-card-dashboard__title me-5" <span class="oh-card-dashboard__title me-5"
><a id="previous">Previous</a></span ><a id="previous">Previous</a></span
> >
<span class="oh-card-dashboard__title me-5"><a id="next">Next</a></span> <span class="oh-card-dashboard__title me-5"
><a id="next">Next</a></span
>
<select <select
class="oh-select oh-select--sm me-5" class="oh-select oh-select--sm me-5"
name="" name=""
@@ -35,218 +37,201 @@
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
Date.prototype.getWeek = function () {
return $.datepicker.iso8601Week(this);
};
Date.prototype.getWeek = function () { return $.datepicker.iso8601Week(this); } var myDate = new Date();
var myWeek = myDate.getWeek();
var year = myDate.getFullYear();
var month = myDate.getMonth();
var myDate = new Date(); function personalChart(dataSet, labels) {
var myWeek=myDate.getWeek(); const data = {
var year = myDate. getFullYear() labels: labels,
var month = myDate.getMonth() datasets: dataSet,
};
// Create chart using the Chart.js library
window["personalChart"] = {};
const ctx = document
.getElementById("personalChart")
.getContext("2d");
personalChart = new Chart(ctx, {
type: "bar",
data: data,
options: {
animation: {
duration: 1000, // Duration of the animation in milliseconds
easing: "easeInOutQuart", // Easing function for the animation
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
},
},
},
});
}
function personalChart_one(dataSet, labels) {
personalChart.destroy();
const data = {
labels: labels,
datasets: dataSet,
};
// Create chart using the Chart.js library
window["personalChart"] = {};
const ctx = document
.getElementById("personalChart")
.getContext("2d");
personalChart = new Chart(ctx, {
type: "bar",
data: data,
options: {
animation: {
duration: 1000, // Duration of the animation in milliseconds
easing: "easeInOutQuart", // Easing function for the animation
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true,
},
},
},
});
}
$.ajax({
type: "GET",
url: "/project/personal-time-sheet/",
data: {
emp_id: {{emp_id}},
year: year,
week: myWeek,
month: month,
selected: $("#personalTimesheetSelect").val(),
},
success: function (response) {
// Code to handle the response
dataSet = response.dataSet;
labels = response.labels;
function personalChart(dataSet, labels) { personalChart(dataSet, labels);
const data = { },
labels: labels, error: function (response) {
datasets: dataSet, console.log("error");
},
});
}; $("#previous").click(function () {
// Create chart using the Chart.js library if ($("#personalTimesheetSelect").val() == "week") {
window["personalChart"] = {}; myWeek -= 1;
const ctx = document.getElementById("personalChart").getContext("2d"); if (myWeek < 1) {
personalChart = new Chart(ctx, { year = year - 1;
type: "bar", myWeek = 52 + myWeek;
data: data, }
options: { } else if ($("#personalTimesheetSelect").val() == "month") {
animation: { month -= 1;
duration: 1000, // Duration of the animation in milliseconds if (month < 0) {
easing: 'easeInOutQuart', // Easing function for the animation year = year - 1;
}, month = 12 + month;
scales: { }
x: { }
stacked: true, $.ajax({
}, type: "GET",
y: { url: "/project/personal-time-sheet/",
stacked: true, data: {
} emp_id: {{emp_id}},
} year: year,
}, week: myWeek,
}); month: month,
} selected: $("#personalTimesheetSelect").val(),
},
success: function (response) {
// Code to handle the response
dataSet = response.dataSet;
labels = response.labels;
function personalChart_one(dataSet, labels) { personalChart_one(dataSet, labels);
personalChart.destroy() },
const data = { error: function (response) {
labels: labels, console.log("error");
datasets: dataSet, },
});
});
}; $("#next").click(function () {
// Create chart using the Chart.js library this_week = myDate.getWeek();
window["personalChart"] = {}; this_month = myDate.getMonth();
const ctx = document.getElementById("personalChart").getContext("2d");
personalChart = new Chart(ctx, {
type: "bar",
data: data,
options: {
animation: {
duration: 1000, // Duration of the animation in milliseconds
easing: 'easeInOutQuart', // Easing function for the animation
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
},
});
}
if ($("#personalTimesheetSelect").val() == "week") {
if (myWeek < this_week) {
myWeek += 1;
} else {
myWeek = this_week;
}
} else if ($("#personalTimesheetSelect").val() == "month") {
if (month < this_month) {
month += 1;
} else {
month = this_month;
}
}
$.ajax({ year = myDate.getFullYear();
type: "GET", $.ajax({
url: "/project/personal-time-sheet/" , type: "GET",
data :{ url: "/project/personal-time-sheet/",
emp_id : {{emp_id}}, data: {
year : year, emp_id: {{emp_id}},
week:myWeek, year: year,
month:month, week: myWeek,
selected : $("#personalTimesheetSelect").val(), month: month,
}, selected: $("#personalTimesheetSelect").val(),
success: function (response) { },
// Code to handle the response success: function (response) {
dataSet = response.dataSet; // Code to handle the response
labels = response.labels; dataSet = response.dataSet;
labels = response.labels;
personalChart(dataSet, labels); personalChart_one(dataSet, labels);
}, },
error: function(response){ error: function (response) {
console.log("error") console.log("error");
}, },
}); });
});
$("#previous").click(function(){ $("#personalTimesheetSelect").change(function () {
if ($("#personalTimesheetSelect").val() == "week"){ $.ajax({
myWeek-=1 type: "GET",
if (myWeek<1){ url: "/project/personal-time-sheet/",
year = year - 1; data: {
myWeek = 52+myWeek; emp_id: {{emp_id}},
} year: year,
} week: myWeek,
else if ($("#personalTimesheetSelect").val() == "month"){ week: myWeek,
month-=1 month: month,
if (month<0){ selected: $("#personalTimesheetSelect").val(),
year=year-1; },
month = 12+month success: function (response) {
} // Code to handle the response.labels
} dataSet = response.dataSet;
$.ajax({ labels = response.labels;
type: "GET",
url: "/project/personal-time-sheet/",
data :{
emp_id : {{emp_id}},
year : year,
week:myWeek,
month:month,
selected : $("#personalTimesheetSelect").val()
},
success: function (response) {
// Code to handle the response
dataSet = response.dataSet;
labels = response.labels;
personalChart_one(dataSet, labels);
},
error: function(response){
console.log("error")
},
});
})
$("#next").click(function(){
this_week = myDate.getWeek()
this_month = myDate.getMonth()
if ($("#personalTimesheetSelect").val() == "week"){
if (myWeek < this_week){
myWeek+=1
} else {
myWeek = this_week
}
}
else if ($("#personalTimesheetSelect").val() == "month"){
if (month < this_month){
month+=1
} else {
month = this_month
}
}
year = myDate. getFullYear()
$.ajax({
type: "GET",
url: "/project/personal-time-sheet/",
data :{
emp_id : {{emp_id}},
year:year,
week:myWeek,
month:month,
selected : $("#personalTimesheetSelect").val()
},
success: function (response) {
// Code to handle the response
dataSet = response.dataSet;
labels = response.labels;
personalChart_one(dataSet, labels);
},
error: function(response){
console.log("error")
},
});
})
$("#personalTimesheetSelect").change(function(){
$.ajax({
type: "GET",
url: "/project/personal-time-sheet/",
data :{
emp_id : {{emp_id}},
year:year,
week:myWeek,
week:myWeek,
month:month,
selected:$("#personalTimesheetSelect").val(),
},
success: function (response) {
// Code to handle the response.labels
dataSet = response.dataSet;
labels = response.labels;
personalChart_one(dataSet, labels);
},
error: function(response){
console.log("error")
},
});
})
personalChart_one(dataSet, labels);
},
error: function (response) {
console.log("error");
},
});
});
}); });
</script> </script>
{% endblock %}

View File

@@ -11,7 +11,7 @@ urlpatterns = [
"project-dashboard-view/", views.dashboard_view, name="project-dashboard-view" "project-dashboard-view/", views.dashboard_view, name="project-dashboard-view"
), ),
path( path(
"projects-due-in-this-month", "projects-due-in-this-month/",
dashboard.ProjectsDueInMonth.as_view(), dashboard.ProjectsDueInMonth.as_view(),
name="projects-due-in-this-month", name="projects-due-in-this-month",
), ),
@@ -43,7 +43,7 @@ urlpatterns = [
name="project-card-view", name="project-card-view",
), ),
path("project-view/", projects.ProjectsView.as_view(), name="project-view"), path("project-view/", projects.ProjectsView.as_view(), name="project-view"),
# path("create-project/", views.create_project, name="create-project"), # path("create-project", views.create_project, name="create-project"),
path("create-project/", projects.ProjectFormView.as_view(), name="create-project"), path("create-project/", projects.ProjectFormView.as_view(), name="create-project"),
# path( # path(
# "update-project/<int:project_id>/", # "update-project/<int:project_id>/",
@@ -227,7 +227,7 @@ urlpatterns = [
), ),
# path("create-time-sheet", views.time_sheet_creation, name="create-time-sheet"), # path("create-time-sheet", views.time_sheet_creation, name="create-time-sheet"),
path( path(
"create-time-sheet", "create-time-sheet/",
timesheet.TimeSheetFormView.as_view(), timesheet.TimeSheetFormView.as_view(),
name="create-time-sheet", name="create-time-sheet",
), ),
@@ -248,7 +248,7 @@ urlpatterns = [
# ), # ),
path("filter-time-sheet/", views.time_sheet_filter, name="filter-time-sheet"), path("filter-time-sheet/", views.time_sheet_filter, name="filter-time-sheet"),
path("time-sheet-initial/", views.time_sheet_initial, name="time-sheet-initial"), path("time-sheet-initial/", views.time_sheet_initial, name="time-sheet-initial"),
# path("get-project/", views.get_project, name="get-project"), # path("get-project", views.get_project, name="get-project"),
path("create-time-sheet/", views.time_sheet_creation, name="create-time-sheet"), path("create-time-sheet/", views.time_sheet_creation, name="create-time-sheet"),
path( path(
"create-project-time-sheet/", "create-project-time-sheet/",
@@ -265,8 +265,8 @@ urlpatterns = [
views.time_sheet_delete, views.time_sheet_delete,
name="delete-time-sheet", name="delete-time-sheet",
), ),
path("filter-time-sheet", views.time_sheet_filter, name="filter-time-sheet"), path("filter-time-sheet/", views.time_sheet_filter, name="filter-time-sheet"),
path("time-sheet-initial", views.time_sheet_initial, name="time-sheet-initial"), path("time-sheet-initial/", views.time_sheet_initial, name="time-sheet-initial"),
path( path(
"personal-time-sheet-view/<int:emp_id>/", "personal-time-sheet-view/<int:emp_id>/",
views.personal_time_sheet_view, views.personal_time_sheet_view,

View File

@@ -1487,16 +1487,6 @@ def time_sheet_view(request):
) )
def time_sheet_initial(request):
"""
This is an ajax method to return json response to take only tasks related
to the project in the timesheet form fields
"""
project_id = request.GET["project_id"]
tasks = Task.objects.filter(project=project_id).values("title", "id")
return JsonResponse({"data": list(tasks)})
# def get_members(request): # def get_members(request):
# project_id = request.GET.get("project_id") # project_id = request.GET.get("project_id")
# project = Project.objects.get(id=project_id) # project = Project.objects.get(id=project_id)
@@ -1511,6 +1501,7 @@ def time_sheet_initial(request):
# return JsonResponse({'data': list(members)}) # return JsonResponse({'data': list(members)})
@login_required
def get_members(request): def get_members(request):
project_id = request.GET.get("project_id") project_id = request.GET.get("project_id")
task_id = request.GET.get("task_id") task_id = request.GET.get("task_id")
@@ -1548,6 +1539,7 @@ def get_members(request):
return HttpResponse(employee_field_html) return HttpResponse(employee_field_html)
@login_required
def get_tasks_in_timesheet(request): def get_tasks_in_timesheet(request):
project_id = request.GET.get("project_id") project_id = request.GET.get("project_id")
form = TimeSheetForm() form = TimeSheetForm()
@@ -1721,7 +1713,7 @@ def time_sheet_update(request, time_sheet_id):
messages.success(request, _("Time sheet updated")) messages.success(request, _("Time sheet updated"))
form = TimeSheetForm() form = TimeSheetForm()
response = render( response = render(
request, "./time_sheet/form-create.html", context={"form": form} request, "time_sheet/form-create.html", context={"form": form}
) )
return HttpResponse( return HttpResponse(
response.content.decode("utf-8") response.content.decode("utf-8")
@@ -1729,13 +1721,14 @@ def time_sheet_update(request, time_sheet_id):
) )
return render( return render(
request, request,
"./time_sheet/form-update.html", "time_sheet/form-update.html",
{ {
"form": update_form, "form": update_form,
}, },
) )
else: else:
return render(request, "error.html") messages.error(request, "You dont have permission.")
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
@login_required @login_required
@@ -1764,6 +1757,7 @@ def time_sheet_delete(request, time_sheet_id):
return you_dont_have_permission(request) return you_dont_have_permission(request)
@login_required
def time_sheet_filter(request): def time_sheet_filter(request):
""" """
Filter Time sheet based on the provided query parameters. Filter Time sheet based on the provided query parameters.
@@ -1817,6 +1811,7 @@ def time_sheet_initial(request):
return JsonResponse({"data": list(tasks)}) return JsonResponse({"data": list(tasks)})
@login_required
def personal_time_sheet(request): def personal_time_sheet(request):
""" """
This is an ajax method to return json response for generating bar charts to employees. This is an ajax method to return json response for generating bar charts to employees.
@@ -1891,6 +1886,7 @@ def personal_time_sheet(request):
return JsonResponse(response) return JsonResponse(response)
@login_required
def personal_time_sheet_view(request, emp_id): def personal_time_sheet_view(request, emp_id):
""" """
Function for viewing the barcharts for timesheet of a specific employee. Function for viewing the barcharts for timesheet of a specific employee.
@@ -1902,10 +1898,7 @@ def personal_time_sheet_view(request, emp_id):
Renders the chart.html template containing barchat of the specific employee. Renders the chart.html template containing barchat of the specific employee.
""" """
try: Employee.objects.get(id=emp_id)
Employee.objects.get(id=emp_id)
except:
return render(request, "error.html")
emp_last_name = ( emp_last_name = (
Employee.objects.get(id=emp_id).employee_last_name Employee.objects.get(id=emp_id).employee_last_name
if Employee.objects.get(id=emp_id).employee_last_name != None if Employee.objects.get(id=emp_id).employee_last_name != None
@@ -1922,6 +1915,7 @@ def personal_time_sheet_view(request, emp_id):
return render(request, "time_sheet/chart.html", context=context) return render(request, "time_sheet/chart.html", context=context)
@login_required
def time_sheet_single_view(request, time_sheet_id): def time_sheet_single_view(request, time_sheet_id):
""" """
Renders a single timesheet view page. Renders a single timesheet view page.
@@ -1939,6 +1933,7 @@ def time_sheet_single_view(request, time_sheet_id):
return render(request, "time_sheet/time_sheet_single_view.html", context) return render(request, "time_sheet/time_sheet_single_view.html", context)
@login_required
def time_sheet_bulk_delete(request): def time_sheet_bulk_delete(request):
""" """
This method is used to delete set of Task instances This method is used to delete set of Task instances