diff --git a/.DS_Store b/.DS_Store index 72284900..684dd60e 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index ff81c433..27294133 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc b/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc index 0be67e87..168b2481 100644 Binary files a/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/admin.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc index dafa1b1a..6ee63c3d 100644 Binary files a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc index 24f8e941..767e375a 100644 Binary files a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/osinacore/admin.py b/osinaweb/osinacore/admin.py index 9f1a1161..491a4ec2 100644 --- a/osinaweb/osinacore/admin.py +++ b/osinaweb/osinacore/admin.py @@ -30,4 +30,6 @@ admin.site.register(Milestone) admin.site.register(Epic) admin.site.register(Note) admin.site.register(Task) +admin.site.register(Status) + diff --git a/osinaweb/osinacore/migrations/0024_task_task_id.py b/osinaweb/osinacore/migrations/0024_task_task_id.py new file mode 100644 index 00000000..ddca6f47 --- /dev/null +++ b/osinaweb/osinacore/migrations/0024_task_task_id.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2023-09-18 18:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0023_task_assigned_to'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='task_id', + field=models.CharField(blank=True, max_length=20, null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0025_status.py b/osinaweb/osinacore/migrations/0025_status.py new file mode 100644 index 00000000..d713c769 --- /dev/null +++ b/osinaweb/osinacore/migrations/0025_status.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.5 on 2023-09-18 19:42 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('osinacore', '0024_task_task_id'), + ] + + operations = [ + migrations.CreateModel( + name='Status', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField(blank=True)), + ('date', models.CharField(max_length=40)), + ('time', models.CharField(max_length=40)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/osinaweb/osinacore/migrations/0026_remove_status_user_status_staff.py b/osinaweb/osinacore/migrations/0026_remove_status_user_status_staff.py new file mode 100644 index 00000000..bb8bc393 --- /dev/null +++ b/osinaweb/osinacore/migrations/0026_remove_status_user_status_staff.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.5 on 2023-09-18 20:11 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0025_status'), + ] + + operations = [ + migrations.RemoveField( + model_name='status', + name='user', + ), + migrations.AddField( + model_name='status', + name='staff', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='osinacore.customerprofile'), + ), + ] diff --git a/osinaweb/osinacore/migrations/0027_alter_status_staff.py b/osinaweb/osinacore/migrations/0027_alter_status_staff.py new file mode 100644 index 00000000..d196b1dd --- /dev/null +++ b/osinaweb/osinacore/migrations/0027_alter_status_staff.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.5 on 2023-09-18 20:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0026_remove_status_user_status_staff'), + ] + + operations = [ + migrations.AlterField( + model_name='status', + name='staff', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='osinacore.staffprofile'), + ), + ] diff --git a/osinaweb/osinacore/migrations/__pycache__/0024_task_task_id.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0024_task_task_id.cpython-310.pyc new file mode 100644 index 00000000..d785efcc Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0024_task_task_id.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0025_status.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0025_status.cpython-310.pyc new file mode 100644 index 00000000..a4d16c85 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0025_status.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0026_remove_status_user_status_staff.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0026_remove_status_user_status_staff.cpython-310.pyc new file mode 100644 index 00000000..a32ec842 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0026_remove_status_user_status_staff.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0027_alter_status_staff.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0027_alter_status_staff.cpython-310.pyc new file mode 100644 index 00000000..74b97d90 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0027_alter_status_staff.cpython-310.pyc differ diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index f1cf7b41..3239a06c 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -2,6 +2,8 @@ from django.db import models from django.contrib.auth.models import User from colorfield.fields import ColorField from datetime import datetime +from django.db.models import Max + # Create your models here. @@ -191,4 +193,31 @@ class Task(models.Model): description = models.TextField() start_date = models.CharField(max_length=200) end_date = models.CharField(max_length=200) - assigned_to = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True) \ No newline at end of file + assigned_to = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True) + task_id = models.CharField(max_length=20, null=True, blank=True) + def save(self, *args, **kwargs): + if not self.task_id: + # Get the last two digits of the current year + current_year = str(datetime.now().year)[-2:] + # Find the maximum project ID in the database and increment it + max_id = Task.objects.aggregate(models.Max('task_id'))['task_id__max'] + new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001' + self.task_id = 'T' + current_year + new_id # Add 'p' prefix + super(Task, self).save(*args, **kwargs) + + def formatted_start_date(self): + # Assuming start_date is stored as "day-month-year" + parts = self.start_date.split('-') + return f"{parts[2]}-{parts[1]}-{parts[0]}" + + def formatted_end_date(self): + # Assuming end_date is stored as "day-month-year" + parts = self.end_date.split('-') + return f"{parts[2]}-{parts[1]}-{parts[0]}" + + +class Status(models.Model): + text = models.TextField(blank=True) + date = models.CharField(max_length=40) + time = models.CharField(max_length=40) + staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True,blank=True, related_name='staff') diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index 67dc5fa7..fb5ff0c2 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -7,6 +7,7 @@ from .forms import * from django.utils import timezone from django.urls import reverse from django.http import HttpResponse +from django.db.models import Q # Pages views @@ -42,18 +43,34 @@ def signout(request): @login_required def home(request, *args, **kwargs): - notes = Note.objects.filter(user=request.user).order_by('-date')[:6] - - context = { + recent_note = Note.objects.last() + + if request.user.is_superuser: + # Superadmin can see the last 8 tasks for all users + tasks = Task.objects.filter(Q(status='Open') | Q(status='Working On')).order_by('-id')[:8] + open_task_count = Task.objects.filter(status='Open').count() + working_on_task_count = Task.objects.filter(status='Working On').count() + total_tasks = open_task_count + working_on_task_count + else: + # Non-superadmin user can only see their assigned tasks + tasks = Task.objects.filter(Q(assigned_to=request.user.staffprofile) & (Q(status='Open') | Q(status='Working On'))) + open_task_count = Task.objects.filter(assigned_to=request.user.staffprofile,status='Open').count() + working_on_task_count = Task.objects.filter(assigned_to=request.user.staffprofile, status='Working On').count() + total_tasks = open_task_count + working_on_task_count - 'notes' : notes, - + + context = { + 'notes': notes, + 'recent_note': recent_note, + 'tasks': tasks, + 'total_tasks' :total_tasks, } return render(request, 'index.html', context) + @login_required def my_projects(request, *args, **kwargs): user = request.user @@ -98,14 +115,23 @@ def customers(request, *args, **kwargs): def detailed_project(request, project_id): project = get_object_or_404(Project, project_id=project_id) epics = Epic.objects.filter(project=project) - - context = { - 'project' : project, - 'epics' : epics - + selected_epic_id = request.GET.get('epic_id') # Get the selected epic_id from the query parameters + if selected_epic_id: + selected_epic = get_object_or_404(Epic, id=selected_epic_id) + related_tasks = Task.objects.filter(epic=selected_epic) + else: + selected_epic = None + related_tasks = [] + + context = { + 'project': project, + 'epics': epics, + 'selected_epic': selected_epic, # Pass the selected epic to the template + 'related_tasks': related_tasks, # Pass the related tasks to the template } + return render(request, 'project-details.html', context) @@ -113,10 +139,12 @@ def detailed_project(request, project_id): def createtask_project(request, project_id): project = get_object_or_404(Project, project_id=project_id) epics_of_my_project = Epic.objects.filter(project=project) + staffs = StaffProfile.objects.all().order_by('-id') context = { 'project' : project, 'epics_of_my_project' : epics_of_my_project, + 'staffs' : staffs, } return render(request, 'createtask-project.html', context) @@ -234,6 +262,29 @@ def users(request): +@login_required +def detailed_task(request, task_id): + task = get_object_or_404(Task, task_id=task_id) + + context = { + 'task': task, + + } + + return render(request, 'task-details.html', context) + + + + + + + + + + + + + @@ -330,7 +381,6 @@ def save_note(request): return render(request, 'addnote-modal.html') - @login_required @@ -424,6 +474,7 @@ def save_task(request): status = request.POST.get('status') project_id = request.POST.get('project') epic_id = request.POST.get('epic') + assigned_to_id = request.POST.get('assigned_to') extra = request.POST.get('extra') description = request.POST.get('description') start_date = request.POST.get('start_date') @@ -443,6 +494,15 @@ def save_task(request): # You might want to display an error message or redirect to an appropriate page. pass + try: + + assigned_to = StaffProfile.objects.get(id=assigned_to_id) + except StaffProfile.DoesNotExist: + # Handle the case where the StaffProfile with the provided ID doesn't exist + # You might want to display an error message or redirect to an appropriate page. + pass + + # Create the Task object with the Project and Epic instances task = Task( name=name, @@ -452,7 +512,9 @@ def save_task(request): extra=extra, description=description, start_date=start_date, - end_date=end_date + end_date=end_date, + assigned_to = assigned_to + ) # Save the Task object to the database @@ -527,3 +589,30 @@ def save_customer(request): return redirect('customers') + +@login_required +def save_status(request): + if request.method == 'POST': + text = request.POST.get('text') + current_datetime = timezone.now() + date = current_datetime.date() + time = current_datetime.hour + + try: + staff_profile = StaffProfile.objects.get(user=request.user) + except StaffProfile.DoesNotExist: + # Handle the case where a StaffProfile does not exist for the user + staff_profile = None + + status = Status( + text=text, + staff=staff_profile, + date=date, + time = time, + ) + status.save() + + # Reload the parent page + return HttpResponse('') + + return render(request, 'addstatus-modal.html') diff --git a/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc index c61ce4f3..5d8843b5 100644 Binary files a/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc and b/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/osinaweb/urls.py b/osinaweb/osinaweb/urls.py index 905ba1b0..f3e07a14 100644 --- a/osinaweb/osinaweb/urls.py +++ b/osinaweb/osinaweb/urls.py @@ -41,6 +41,7 @@ urlpatterns = [ path('createtask/', views.create_task, name='createtask'), path('createtask//', views.createtask_project, name='createtaskproject'), path('createtaskepic/', views.createtask_epic, name='createtaskepic'), + path('taskdetails//', views.detailed_task, name='detailed-task'), # Modals urls @@ -62,4 +63,5 @@ urlpatterns = [ path('save_task/', views.save_task, name='save_task'), path('save_business/', views.save_business, name='save_business'), path('save_customer/', views.save_customer, name='save_customer'), + path('save_status/', views.save_status, name='save_status'), ] diff --git a/osinaweb/templates/addpoint-modal.html b/osinaweb/templates/addpoint-modal.html index e02c11f8..39dc3795 100644 --- a/osinaweb/templates/addpoint-modal.html +++ b/osinaweb/templates/addpoint-modal.html @@ -36,7 +36,7 @@ Save - Notes + Point(s) diff --git a/osinaweb/templates/addstatus-modal.html b/osinaweb/templates/addstatus-modal.html index 93eaf429..dd3f3776 100644 --- a/osinaweb/templates/addstatus-modal.html +++ b/osinaweb/templates/addstatus-modal.html @@ -14,11 +14,12 @@ - + + {% csrf_token %} Add Status - @@ -29,7 +30,7 @@ - Choose Task Task 1 @@ -55,10 +56,10 @@ - Add - +