from django.shortcuts import render, redirect, get_object_or_404 from .models import * from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from .forms import * from django.utils import timezone from django.http import HttpResponse from django.db.models import Q from django.http import JsonResponse from .models import Task, Epic from django.template.loader import render_to_string from .custom_context import calculate_time_ago # Pages views def signin(request): if request.user.is_authenticated: return redirect('home') if request.method == 'POST': form = CustomLoginForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) Connection.objects.create(status='Online', date=datetime.now(), user=user) return redirect('home') else: form.add_error(None, 'Invalid email or password. Please try again.') else: form = CustomLoginForm() return render(request, 'login.html', {'form': form}) def go_online(request): user = request.user Connection.objects.create(status='Online', date=datetime.now(), user=user) return HttpResponse('') def signout(request): if request.user.is_authenticated: logout(request) return redirect('signin') @login_required def home(request, *args, **kwargs): notes = Note.objects.filter(user=request.user).order_by('-date')[:6] recent_note = Note.objects.filter(user=request.user).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('-status_date', '-id')[:8] 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'))).order_by('-status_date', '-id') context = { 'notes': notes, 'recent_note': recent_note, 'tasks': tasks, } return render(request, 'index.html', context) def status_mobile_modal (request, *args, **kwargs): context = { } return render(request, 'details_templates/status-on-mobile-modal.html', context) def user_recent_activities_modal(request, user_id): current_time = timezone.now() # Calculate the datetime of 24 hours ago twenty_four_hours_ago = current_time - timezone.timedelta(hours=24) if user_id: specific_user = get_object_or_404(User, id=user_id) # Fetch the specific user's statuses from the last 24 hours user_statuses = Status.objects.filter(staff__user=specific_user, date__gte=twenty_four_hours_ago).order_by('-id') # Calculate time ago for each user status and store it in a dictionary user_statuses_time_ago = [{'status': status, 'time_ago': calculate_time_ago(status)} for status in user_statuses] else: # No specific user ID provided, fetch statuses for all users in the last 24 hours all_user_statuses = Status.objects.filter(date__gte=twenty_four_hours_ago).order_by('-id') # Calculate time ago for each user status and store it in a dictionary user_statuses_time_ago = [{'status': status, 'time_ago': calculate_time_ago(status)} for status in all_user_statuses] context = { 'user_statuses_time_ago': user_statuses_time_ago, } return render(request, 'user-recent-activities.html', context) @login_required def customers(request, *args, **kwargs): customers = CustomerProfile.objects.all().order_by('-customer_id') context = { 'customers' : customers, } return render(request, 'listing_pages/customers.html', context) @login_required def businesses(request): businesses = Business.objects.all().order_by('-business_id') context = { 'businesses' : businesses, } return render(request, 'listing_pages/businesses.html', context) @login_required def staffs(request): staffs = StaffProfile.objects.all().order_by('-staff_id') context = { 'staffs' : staffs, } return render(request, 'listing_pages/staffs.html', context) @login_required def my_projects(request, *args, **kwargs): user = request.user if user.is_superuser: # Superadmin can see all projects with total time worked on each project projects = Project.objects.all().order_by('-project_id') else: # Non-superuser, filter projects where the user is either the manager or a member projects = Project.objects.filter( Q(manager=user.staffprofile) | Q(members=user.staffprofile) ).distinct().order_by('-project_id') for project in projects: total_time_seconds = 0 # Modify task queryset based on user role if user.is_superuser: tasks = project.task_set.all() else: tasks = project.task_set.filter(assigned_to=user.staffprofile) for task in tasks: total_time_hours, total_time_minutes, total_time_seconds_task = task.total_task_time() total_time_seconds += (total_time_hours * 3600) + (total_time_minutes * 60) + total_time_seconds_task total_time_hours = total_time_seconds // 3600 total_time_minutes = (total_time_seconds % 3600) // 60 total_time_seconds = total_time_seconds % 60 project.total_time_worked_hours = total_time_hours project.total_time_worked_minutes = total_time_minutes project.total_time_worked_seconds = total_time_seconds context = { 'projects': projects, } return render(request, 'listing_pages/projects.html', context) @login_required def my_tasks(request, *args, **kwargs): if request.user.is_superuser: # Superadmin can see all projects my_tasks = Task.objects.all().order_by('-status_date', '-id') else: # Non-superuser, filter projects where the user is either the manager or a member my_tasks = Task.objects.all().filter(Q(assigned_to=request.user.staffprofile)).order_by('-status_date', '-id') context = { 'my_tasks' : my_tasks } return render(request, 'listing_pages/tasks.html', context) @login_required def my_notes(request): my_notes = Note.objects.filter(user=request.user).order_by('-id') context = { 'my_notes': my_notes, } return render(request, 'listing_pages/notes.html', context) def daily_reports(request): user = request.user if user.is_superuser: dailyreports = DailyReport.objects.all().order_by('-id') else: dailyreports = DailyReport.objects.filter(staff=request.user.staffprofile).order_by('-id') context = { 'dailyreports': dailyreports, } return render(request, 'listing_pages/daily-reports.html', context) @login_required def project_types(request): projecttypes = ProjectType.objects.all().order_by('-id') context = { 'projecttypes' : projecttypes, } return render(request, 'listing_pages/project-types.html', context) @login_required def staff_positions(request): staffpositions = StaffPosition.objects.all().order_by('-id') context = { 'staffpositions' : staffpositions, } return render(request, 'listing_pages/staff-positions.html', context) @login_required def business_types(request): businesstypes = BusinessType.objects.all().order_by('-id') context = { 'businesstypes' : businesstypes, } return render(request, 'listing_pages/business-types.html', context) @login_required def references(request): references = Reference.objects.all().order_by('-id') context = { 'references' : references, } return render(request, 'listing_pages/references.html', context) @login_required def tags(request): tags = Tag.objects.all().order_by('-id') context = { 'tags' : tags, } return render(request, 'listing_pages/tags.html', context) #Details @login_required def customerdetails(request, customer_id): customer = get_object_or_404(CustomerProfile, customer_id=customer_id) context = { 'customer' : customer, } return render(request, 'details_templates/customer-details.html', context) @login_required def businessdetails(request, business_id): business = get_object_or_404(Business, business_id=business_id) context = { 'business' : business, } return render(request, 'details_templates/business-details.html', context) @login_required def staffdetails( request, staff_id): staff = get_object_or_404(StaffProfile, staff_id=staff_id) context = { 'staff' : staff, } return render(request, 'details_templates/staff-details.html', context) @login_required def taskdetails(request, task_id): task = get_object_or_404(Task, task_id=task_id) points = Point.objects.filter(task=task).order_by('-id') context = { 'task': task, 'points' : points, } return render(request, 'details_templates/task-details.html', context) def show_points_modal(request, task_id): task = get_object_or_404(Task, task_id=task_id) points = Point.objects.filter(task=task).order_by('-id') context = { 'task' : task, 'points' : points, } return render(request, 'details_templates/showpoints-modal.html', context) def timeline_modal(request, *args, **kwargs): context = { } return render(request, 'details_templates/timeline-modal.html', context) @login_required def projectdetails(request, project_id): project = get_object_or_404(Project, project_id=project_id) epics = Epic.objects.filter(project=project).order_by('-id') project_notes = Note.objects.filter(project=project).order_by('-id') context = { 'project': project, 'epics': epics, 'project_notes' : project_notes, } return render(request, 'details_templates/project-details.html', context) #FETCH EPIC RELATED TASKS def get_tasks(request, epic_id): epic = get_object_or_404(Epic, id=epic_id) related_tasks = Task.objects.filter(epic=epic).order_by('-id') context = { 'epic': epic, 'related_tasks': related_tasks, } return render(request, 'epic-fetched-tasks.html', context) # TO DISPALY ALL THE OPEN TASKS OF THIS PROJECT def open_tasks_for_project(request, project_id): project = Project.objects.get(pk=project_id) open_tasks = Task.objects.filter(project=project, status='Open').order_by('-id') context = { 'project': project, 'open_tasks': open_tasks, } return render(request, 'project-open-tasks.html', context) # TO FETCH THE EPICS OF THE SELECTED PROJECT WHEN EDITING A TASK def fetch_epics(request): project_id = request.GET.get('project_id') epics = Epic.objects.filter(project_id=project_id).values('id', 'title') return JsonResponse({'epics': list(epics)}) # TO UPDATE THE STATUS CONTAINER def get_updated_last_status(request): if request.user.is_authenticated: last_status = Status.objects.filter(staff=request.user.staffprofile).last() if last_status: status_time = datetime.strptime(last_status.time, '%I:%M %p') current_time = datetime.now().time() time_difference = abs(datetime.combine(datetime.today(), current_time) - datetime.combine(datetime.today(), status_time.time())) minutes_ago = int(time_difference.total_seconds() / 60) else: minutes_ago = 0 else: last_status = None minutes_ago = 0 if minutes_ago > 60: hours_ago = minutes_ago // 60 remaining_minutes = minutes_ago % 60 hours_minutes_ago = f"{hours_ago}hr {remaining_minutes}min ago" else: hours_minutes_ago = f"{minutes_ago}min ago" response_data = { 'last_status': last_status, 'minutes_ago': minutes_ago, 'hours_minutes_ago': hours_minutes_ago, } recent_status = render_to_string('recent-status.html', response_data) return HttpResponse(recent_status) # TO GET USER ACTIVITIES def get_latest_activities(request): latest_connections = Connection.objects.filter( user__staffprofile__isnull=False ).values('user').annotate( latest_connection=Max('date') ) online_staff_profiles = [] for connection in latest_connections: user_id = connection['user'] latest_connection = connection['latest_connection'] last_connection = Connection.objects.filter(user_id=user_id, date=latest_connection).first() if last_connection.status == 'Online': online_staff_profiles.append(last_connection.user.staffprofile) if request.user.is_authenticated and request.user.is_superuser: open_task_count = Task.objects.filter(status='Open').count() working_on_task_count = Task.objects.filter(status='Working On').count() elif request.user.is_authenticated: 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() else: open_task_count = 0 working_on_task_count = 0 total_tasks = open_task_count + working_on_task_count # Get the current time current_time = timezone.now() # Calculate the datetime of 24 hours ago twenty_four_hours_ago = current_time - timezone.timedelta(hours=24) # Fetch the latest statuses from the last 24 hours latest_statuses = Status.objects.filter(date__gte=twenty_four_hours_ago).order_by('-id') # Calculate time ago for each status and store it in a dictionary latest_statuses_time_ago = [{'status': status, 'time_ago': calculate_time_ago(status)} for status in latest_statuses] response_data = { 'total_tasks': total_tasks, 'latest_statuses_time_ago': latest_statuses_time_ago, 'online_staff_profiles' : online_staff_profiles, } recent_activities = render_to_string('recent-activities.html', response_data) return HttpResponse(recent_activities) def recent_activities_page(request): context = { } return render(request, 'recent-activities-page.html', context) # CUSTOMER DASHBOARD @login_required def customer_index(request, *args, **kwargs): context = { } return render(request, 'customer_dashboard/customer_index.html', context) @login_required def customer_invoices(request, *args, **kwargs): context = { } return render(request, 'customer_dashboard/listing_pages/customer-invoices.html', context) def add_reaction(request, status_id, emoji): status = get_object_or_404(Status, pk=status_id) user = request.user existing_reaction = Reaction.objects.filter(status=status, user=user).first() if existing_reaction: # If the user has already reacted, update the reaction existing_reaction.emoji = emoji existing_reaction.save() return JsonResponse({'message': 'Reaction updated successfully.'}) else: # If the user hasn't reacted yet, create a new reaction new_reaction = Reaction.objects.create(status=status, emoji=emoji, user=user) return JsonResponse({'message': 'Reaction added successfully.'})