diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 13f6eb93..45398007 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 d8020d23..5be37b13 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 7787f23e..80579ed4 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 ac45bc43..a7ff35b4 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 2e7f59fd..8d79560a 100644 --- a/osinaweb/osinacore/admin.py +++ b/osinaweb/osinacore/admin.py @@ -35,4 +35,5 @@ admin.site.register(Tag) admin.site.register(Point) admin.site.register(DailyReport) admin.site.register(BusinessType) +admin.site.register(PointActivity) diff --git a/osinaweb/osinacore/migrations/0054_remove_point_date_completed_and_more.py b/osinaweb/osinacore/migrations/0054_remove_point_date_completed_and_more.py new file mode 100644 index 00000000..45911d01 --- /dev/null +++ b/osinaweb/osinacore/migrations/0054_remove_point_date_completed_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.5 on 2024-01-31 13:37 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0053_pointactivity'), + ] + + operations = [ + migrations.RemoveField( + model_name='point', + name='date_completed', + ), + migrations.RemoveField( + model_name='point', + name='date_workingon', + ), + migrations.RemoveField( + model_name='point', + name='time_completed', + ), + migrations.RemoveField( + model_name='point', + name='time_workingon', + ), + ] diff --git a/osinaweb/osinacore/migrations/0055_alter_point_status.py b/osinaweb/osinacore/migrations/0055_alter_point_status.py new file mode 100644 index 00000000..a1e584d2 --- /dev/null +++ b/osinaweb/osinacore/migrations/0055_alter_point_status.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-01-31 13:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0054_remove_point_date_completed_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='point', + name='status', + field=models.CharField(choices=[('Not Completed', 'Not Completed'), ('Working On', 'Working On'), ('Paused', 'Paused'), ('Completed', 'Completed')], max_length=200, null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0056_alter_pointactivity_end_time.py b/osinaweb/osinacore/migrations/0056_alter_pointactivity_end_time.py new file mode 100644 index 00000000..25e17f9b --- /dev/null +++ b/osinaweb/osinacore/migrations/0056_alter_pointactivity_end_time.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-01-31 14:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0055_alter_point_status'), + ] + + operations = [ + migrations.AlterField( + model_name='pointactivity', + name='end_time', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0057_point_total_time_hours_point_total_time_minutes_and_more.py b/osinaweb/osinacore/migrations/0057_point_total_time_hours_point_total_time_minutes_and_more.py new file mode 100644 index 00000000..ea3b8274 --- /dev/null +++ b/osinaweb/osinacore/migrations/0057_point_total_time_hours_point_total_time_minutes_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.5 on 2024-01-31 14:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0056_alter_pointactivity_end_time'), + ] + + operations = [ + migrations.AddField( + model_name='point', + name='total_time_hours', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='point', + name='total_time_minutes', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='point', + name='total_time_seconds', + field=models.IntegerField(default=0), + ), + ] diff --git a/osinaweb/osinacore/migrations/0058_remove_point_total_time_hours_and_more.py b/osinaweb/osinacore/migrations/0058_remove_point_total_time_hours_and_more.py new file mode 100644 index 00000000..54416993 --- /dev/null +++ b/osinaweb/osinacore/migrations/0058_remove_point_total_time_hours_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.5 on 2024-01-31 14:47 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0057_point_total_time_hours_point_total_time_minutes_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='point', + name='total_time_hours', + ), + migrations.RemoveField( + model_name='point', + name='total_time_minutes', + ), + migrations.RemoveField( + model_name='point', + name='total_time_seconds', + ), + ] diff --git a/osinaweb/osinacore/migrations/__pycache__/0054_remove_point_date_completed_and_more.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0054_remove_point_date_completed_and_more.cpython-310.pyc new file mode 100644 index 00000000..193c493d Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0054_remove_point_date_completed_and_more.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0055_alter_point_status.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0055_alter_point_status.cpython-310.pyc new file mode 100644 index 00000000..b9bfc1d6 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0055_alter_point_status.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0056_alter_pointactivity_end_time.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0056_alter_pointactivity_end_time.cpython-310.pyc new file mode 100644 index 00000000..22d2d1b4 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0056_alter_pointactivity_end_time.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0057_point_total_time_hours_point_total_time_minutes_and_more.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0057_point_total_time_hours_point_total_time_minutes_and_more.cpython-310.pyc new file mode 100644 index 00000000..85d595f2 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0057_point_total_time_hours_point_total_time_minutes_and_more.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0058_remove_point_total_time_hours_and_more.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0058_remove_point_total_time_hours_and_more.cpython-310.pyc new file mode 100644 index 00000000..f8cdafdc Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0058_remove_point_total_time_hours_and_more.cpython-310.pyc differ diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index 9072d3f5..709d149b 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -4,6 +4,8 @@ from colorfield.fields import ColorField from datetime import datetime from django.db.models import Max from django.utils import timezone +from django.db.models import Sum +from datetime import timedelta # Create your models here. @@ -249,20 +251,43 @@ class Point(models.Model): STATUS_CHOICES = ( ('Not Completed', 'Not Completed'), ('Working On', 'Working On'), + ('Paused', 'Paused'), ('Completed', 'Completed') ) status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True) task = models.ForeignKey(Task, on_delete=models.CASCADE, null=True) - date_workingon = models.CharField(max_length=200, null=True, blank=True) - date_completed = models.CharField(max_length=200, null=True, blank=True) - time_workingon = models.CharField(max_length=200, null=True, blank=True) - time_completed = models.CharField(max_length=200, null=True, blank=True) + def total_time(self): + # Calculate the total time for ongoing activities + ongoing_total_time_timedelta = timedelta() + ongoing_activities = self.pointactivity_set.filter(end_time__isnull=True) + + for activity in ongoing_activities: + start_time_aware = activity.start_time + current_time_aware = timezone.now() + ongoing_total_time_timedelta += current_time_aware - start_time_aware + + # Calculate the total time for completed activities + completed_total_time_timedelta = self.pointactivity_set.filter(end_time__isnull=False).aggregate(total_time=Sum(models.F('end_time') - models.F('start_time')))['total_time'] + + # Add the total times together + total_time_timedelta = ongoing_total_time_timedelta + (completed_total_time_timedelta or timedelta()) + + # Convert total seconds to timedelta + total_time_timedelta = timedelta(seconds=total_time_timedelta.total_seconds()) + + # Extract hours, minutes, and seconds from timedelta + hours, remainder = divmod(total_time_timedelta.seconds, 3600) + minutes, seconds = divmod(remainder, 60) + + # Return the total time as a tuple (hours, minutes, seconds) + return hours, minutes, seconds + class PointActivity(models.Model): point = models.ForeignKey(Point, on_delete=models.CASCADE, null=True) start_time = models.DateTimeField() - end_time = models.DateTimeField() + end_time = models.DateTimeField(null=True, blank=True) diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index a90f1c84..92bbc5cf 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -1192,100 +1192,6 @@ def save_point(request): -@login_required -def mark_point_working_on(request, point_id, task_id): - task = get_object_or_404(Task, id=task_id) - point = get_object_or_404(Point, id=point_id) - point.status = 'Working On' - current_datetime = datetime.now() - point.date_workingon = current_datetime.date() - point.time_workingon = current_datetime.strftime("%I:%M %p") - - point.save() - - # Create a new Status object - status_text = f'Working On: {point.text}' - status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) - status.save() - - - - task_id_str = task.task_id - - showpoints_url = reverse('showpoints', args=[task_id_str]) - return HttpResponseRedirect(showpoints_url) - - -@login_required -def mark_point_working_on_task_page(request, point_id, task_id): - task = get_object_or_404(Task, id=task_id) - point = get_object_or_404(Point, id=point_id) - point.status = 'Working On' - current_datetime = datetime.now() - point.date_workingon = current_datetime.date() - point.time_workingon = current_datetime.strftime("%I:%M %p") - - point.save() - - # Create a new Status object - status_text = f'Working On: {point.text}' - status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) - status.save() - - return redirect('detailed-task', task_id=task.task_id) - - -@login_required -def mark_point_completed(request, point_id, task_id): - task = get_object_or_404(Task, id=task_id) - point = get_object_or_404(Point, id=point_id) - point.status = 'Completed' - current_datetime = datetime.now() - point.date_workingon = current_datetime.date() - point.time_workingon = current_datetime.strftime("%I:%M %p") - - point.save() - - # Create a new Status object - status_text = f'{point.text} - Completed' - status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) - status.save() - - - - task_id_str = task.task_id - - showpoints_url = reverse('showpoints', args=[task_id_str]) - return HttpResponseRedirect(showpoints_url) - - - -@login_required -def mark_point_completed_task_page(request, point_id, task_id): - task = get_object_or_404(Task, id=task_id) - point = get_object_or_404(Point, id=point_id) - point.status = 'Completed' - current_datetime = datetime.now() - point.date_workingon = current_datetime.date() - point.time_workingon = current_datetime.strftime("%I:%M %p") - - point.save() - - # Create a new Status object - status_text = f'{point.text} - Completed' - status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) - status.save() - - - - task_id_str = task.task_id - - return redirect('detailed-task', task_id=task.task_id) - - - - - @login_required def save_dailyreport(request): if request.method == 'POST': @@ -1858,4 +1764,161 @@ def delete_task_modal(request, task_id): context = { 'task': task, } - return render(request, "delete_modals/delete-task-modal.html", context) \ No newline at end of file + return render(request, "delete_modals/delete-task-modal.html", context) + + + + + + + + +#Mark points + +@login_required +def mark_point_working_on(request, point_id, task_id): + task = get_object_or_404(Task, id=task_id) + point = get_object_or_404(Point, id=point_id) + point.status = 'Working On' + current_datetime = datetime.now() + + point.save() + + activity = PointActivity( + point = point, + start_time = datetime.now(), + ) + activity.save() + + if PointActivity.objects.filter(point=point).count() == 1: + status_text = f'Started Working On: {point.text}' + status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) + status.save() + else: + status_text = f'Resumed Working On: {point.text}' + status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) + status.save() + + + + task_id_str = task.task_id + + showpoints_url = reverse('showpoints', args=[task_id_str]) + return HttpResponseRedirect(showpoints_url) + + + +@login_required +def mark_point_working_on_task_page(request, point_id, task_id): + task = get_object_or_404(Task, id=task_id) + point = get_object_or_404(Point, id=point_id) + point.status = 'Working On' + current_datetime = datetime.now() + + point.save() + + activity = PointActivity( + point = point, + start_time = datetime.now(), + ) + activity.save() + + if PointActivity.objects.filter(point=point).count() == 1: + status_text = f'Started Working On: {point.text}' + status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) + status.save() + else: + status_text = f'Resumed Working On: {point.text}' + status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) + status.save() + + + return redirect('detailed-task', task_id=task.task_id) + + + + + +@login_required +def mark_point_paused(request, point_id, task_id): + task = get_object_or_404(Task, id=task_id) + point = get_object_or_404(Point, id=point_id) + point.status = 'Paused' + current_datetime = datetime.now() + + + point.save() + + last_activity = PointActivity.objects.filter(point=point).last() + last_activity.end_time = datetime.now() + last_activity.save() + + + status_text = f'{point.text} - Paused' + status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) + status.save() + + + + task_id_str = task.task_id + + showpoints_url = reverse('showpoints', args=[task_id_str]) + return HttpResponseRedirect(showpoints_url) + + + + + +@login_required +def mark_point_completed(request, point_id, task_id): + task = get_object_or_404(Task, id=task_id) + point = get_object_or_404(Point, id=point_id) + point.status = 'Completed' + current_datetime = datetime.now() + + + point.save() + + last_activity = PointActivity.objects.filter(point=point).last() + last_activity.end_time = datetime.now() + last_activity.save() + + + status_text = f'{point.text} - Completed' + status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) + status.save() + + + + task_id_str = task.task_id + + showpoints_url = reverse('showpoints', args=[task_id_str]) + return HttpResponseRedirect(showpoints_url) + + + +@login_required +def mark_point_completed_task_page(request, point_id, task_id): + task = get_object_or_404(Task, id=task_id) + point = get_object_or_404(Point, id=point_id) + point.status = 'Completed' + current_datetime = datetime.now() + + + point.save() + + + last_activity = PointActivity.objects.filter(point=point).last() + last_activity.end_time = datetime.now() + last_activity.save() + + + status_text = f'{point.text} - Completed' + status = Status(text=status_text, date=current_datetime.date(), time=current_datetime.strftime("%I:%M %p"), staff=request.user.staffprofile) + status.save() + + + + task_id_str = task.task_id + + return redirect('detailed-task', task_id=task.task_id) \ No newline at end of file diff --git a/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/urls.cpython-310.pyc index b66428c2..88df1181 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 294ca4b6..27e096b5 100644 --- a/osinaweb/osinaweb/urls.py +++ b/osinaweb/osinaweb/urls.py @@ -140,6 +140,7 @@ urlpatterns = [ path('mark_point_working_on_task_page///', views.mark_point_working_on_task_page, name='mark_point_working_on_task_page'), path('mark_point_completed///', views.mark_point_completed, name='mark_point_completed'), path('mark_point_completed_task_page///', views.mark_point_completed_task_page, name='mark_point_completed_task_page'), + path('mark_point_paused///', views.mark_point_paused, name='mark_point_paused'), diff --git a/osinaweb/templates/popup_modals/showpoints-modal.html b/osinaweb/templates/popup_modals/showpoints-modal.html index 19474eb4..363dc66e 100644 --- a/osinaweb/templates/popup_modals/showpoints-modal.html +++ b/osinaweb/templates/popup_modals/showpoints-modal.html @@ -21,53 +21,46 @@
{% for point in points %} - {% if point.status == 'Not Completed' %}
+ {% if point.status == 'Completed' %} +

{{point.text}}

+ {% else %}

{{point.text}}

+ {% endif %}
-
- - + {% endif %} + + {% if point.status == 'Working On' and not point.status == 'Completed' %} + - + {% endif %} + - - + + {% endif %}
{% csrf_token %} @@ -80,57 +73,34 @@
-

Total Time: 0min

-
-
- - {% endif %} - - {% if point.status == 'Completed' %} -
-
-

{{point.text}}

-
-
- -
-
- {% endif %} - - - {% if point.status == 'Working On' %} -
-
-

{{point.text}}

-
-
- - - {% csrf_token %} - - -
- {% csrf_token %} - -
+

Total Time: + + {% if point.total_time.0 > 0 %} + {{ point.total_time.0 }}hr + {% if point.total_time.1 > 0 %} + , + {% endif %} + {% endif %} + + {% if point.total_time.1 > 0 %} + {{ point.total_time.1 }}min + {% if point.total_time.2 > 0 %} + , + {%endif%} + {% endif %} + + {% if point.total_time.2 > 0 %} + {{ point.total_time.2 }}sec + {% endif %} + +

-
- {% endif %} {% endfor %}
- \ No newline at end of file