From f97af212152cdfe70fe6df5c94f87dddc35e6a92 Mon Sep 17 00:00:00 2001 From: Abhijeet Date: Thu, 17 Oct 2024 22:33:28 +0530 Subject: [PATCH 1/2] Added endpoints in API folder in iwdModuleV2 --- .../migrations/0002_auto_20241010_1836.py | 23 + .../iwdModuleV2/api/serializers.py | 106 +-- .../applications/iwdModuleV2/api/urls.py | 19 +- .../applications/iwdModuleV2/api/views.py | 870 ++++++++++++++++-- .../migrations/0002_auto_20241010_1836.py | 40 + .../migrations/0002_auto_20241010_1836.py | 19 + 6 files changed, 906 insertions(+), 171 deletions(-) create mode 100644 FusionIIIT/applications/central_mess/migrations/0002_auto_20241010_1836.py create mode 100644 FusionIIIT/applications/online_cms/migrations/0002_auto_20241010_1836.py create mode 100644 FusionIIIT/applications/research_procedures/migrations/0002_auto_20241010_1836.py diff --git a/FusionIIIT/applications/central_mess/migrations/0002_auto_20241010_1836.py b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241010_1836.py new file mode 100644 index 000000000..45fc04fc7 --- /dev/null +++ b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241010_1836.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.5 on 2024-10-10 18:36 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('central_mess', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='payments', + name='payment_date', + field=models.DateField(default=datetime.date(2024, 10, 10)), + ), + migrations.AlterUniqueTogether( + name='payments', + unique_together=set(), + ), + ] diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index 2b6f6c37a..e96d2d4b9 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -1,190 +1,116 @@ from rest_framework import serializers +from applications.globals.models import * from applications.iwdModuleV2.models import * +from applications.ps1.models import * class PageOneDetailsSerializer(serializers.ModelSerializer): class Meta: model = PageOneDetails fields = '__all__' - class PageTwoDetailsSerializer(serializers.ModelSerializer): class Meta: model = PageTwoDetails fields = '__all__' - class PageThreeDetailsSerializer(serializers.ModelSerializer): class Meta: model = PageThreeDetails fields = '__all__' - class AESDetailsSerializer(serializers.ModelSerializer): class Meta: model = AESDetails fields = '__all__' - class CorrigendumTableSerializer(serializers.ModelSerializer): class Meta: model = CorrigendumTable fields = '__all__' - class AddendumSerializer(serializers.ModelSerializer): class Meta: model = Addendum fields = '__all__' - class PreBidDetailsSerializer(serializers.ModelSerializer): class Meta: model = PreBidDetails fields = '__all__' - class NoOfTechnicalBidTimesSerializer(serializers.ModelSerializer): class Meta: model = NoOfTechnicalBidTimes fields = '__all__' - class TechnicalBidDetailsSerializer(serializers.ModelSerializer): class Meta: model = TechnicalBidDetails fields = '__all__' - class TechnicalBidContractorDetailsSerializer(serializers.ModelSerializer): class Meta: model = TechnicalBidContractorDetails fields = '__all__' - class FinancialBidDetailsSerializer(serializers.ModelSerializer): class Meta: model = FinancialBidDetails fields = '__all__' - class FinancialContractorDetailsSerializer(serializers.ModelSerializer): class Meta: model = FinancialContractorDetails fields = '__all__' - class LetterOfIntentDetailsSerializer(serializers.ModelSerializer): class Meta: model = LetterOfIntentDetails fields = '__all__' - class WorkOrderFormSerializer(serializers.ModelSerializer): class Meta: model = WorkOrderForm fields = '__all__' - class AgreementSerializer(serializers.ModelSerializer): class Meta: model = Agreement fields = '__all__' - class MilestonesSerializer(serializers.ModelSerializer): class Meta: model = Milestones fields = '__all__' - class ExtensionOfTimeDetailsSerializer(serializers.ModelSerializer): class Meta: model = ExtensionOfTimeDetails fields = '__all__' - class ProjectsSerializer(serializers.ModelSerializer): class Meta: model = Projects fields = '__all__' - -class WorkOrderFormSerializer(serializers.ModelSerializer): - class Meta: - model = WorkOrderForm - fields = '__all__' # or list specific fields here - -class AgreementSerializer(serializers.ModelSerializer): - class Meta: - model = Agreement - fields = '__all__' # or list specific fields here - -class MilestonesSerializer(serializers.ModelSerializer): - class Meta: - model = Milestones - fields = '__all__' # or list specific fields here - -class PageThreeDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = PageThreeDetails - fields = '__all__' # or list specific fields here - -class ExtensionOfTimeDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = ExtensionOfTimeDetails - fields = '__all__' # or list specific fields here - -class AESDetailsSerializer(serializers.ModelSerializer): +class DesignationSerializer(serializers.ModelSerializer): class Meta: - model = AESDetails - fields = '__all__' # or list specific fields here + model = Designation + fields = ['id', 'name'] -class FinancialBidDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = FinancialBidDetails - fields = '__all__' # or list specific fields here +class HoldsDesignationSerializer(serializers.ModelSerializer): + designation = DesignationSerializer() -class TechnicalBidDetailsSerializer(serializers.ModelSerializer): class Meta: - model = TechnicalBidDetails - fields = '__all__' # or list specific fields here + model = HoldsDesignation + fields = ['id', 'designation', 'user'] -class FinancialContractorDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = FinancialContractorDetails - fields = '__all__' # or list specific fields here +# class RequestsSerializer(serializers.ModelSerializer): +# class Meta: +# model = Requests +# fields = ['name', 'description', 'area'] -class TechnicalBidContractorDetailsSerializer(serializers.ModelSerializer): +class RequestsSerializer(serializers.ModelSerializer): class Meta: - model = TechnicalBidContractorDetails - fields = '__all__' # or list specific fields here - -class PreBidDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = PreBidDetails - fields = '__all__' # or list specific fields here - -class CorrigendumTableSerializer(serializers.ModelSerializer): - class Meta: - model = CorrigendumTable - fields = '__all__' # or list specific fields here - -class AddendumSerializer(serializers.ModelSerializer): - class Meta: - model = Addendum - fields = '__all__' # or list specific fields here - -class LetterOfIntentDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = LetterOfIntentDetails - fields = '__all__' # or list specific fields here - -class PageOneDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = PageOneDetails - fields = '__all__' # or list specific fields here - -class PageTwoDetailsSerializer(serializers.ModelSerializer): - class Meta: - model = PageTwoDetails - fields = '__all__' # or list specific fields here \ No newline at end of file + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'status', 'workCompleted'] \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index 1e96232ef..7caba1060 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -16,7 +16,7 @@ path('work-order-form/', views.workOrderForm, name='workOrderForm'), path('agreement-input/', views.AgreementInput, name='AgreementInput'), path('milestones-form/', views.milestonesForm, name='milestonesForm'), - path('page3-1/', views.page3_1, name='page3_1'), + path('page3-1/', views.page3_1, name='page3_1'), path('extension-of-time-form/', views.ExtensionOfTimeForm, name='ExtensionOfTimeForm'), path('page1-view/', views.page1View, name='page1View'), path('page2-view/', views.page2View, name='page2View'), @@ -32,5 +32,22 @@ path('milestone-view/', views.milestoneView, name='milestoneView'), path('page3-view/', views.page3View, name='page3View'), path('extension-form-view/', views.extensionFormView, name='extensionFormView'), + path('fetch-designations/', views.fetchDesignations, name='fetchDesignations'), + path('requests-view/', views.requestsView, name='requestsView'), + path('created-requests-view/', views.created_requests_view, name='createdRequests'), + path('view-file/', views.view_file_api, name='viewFile'), + path('handle-engineer-process-requests/', views.handleEngineerProcessRequests, name='handleEngineerProcessRequests'), + path('rejected-requests-view/', views.rejectedRequests, name='rejectedRequests'), + path('update-rejected-requests/', views.updateRejectedRequests, name='updateRejectedRequests'), + path('handle-update-requests/', views.handleUpdateRequests, name='handleUpdateRequests'), + path('issue-work-order/', views.issueWorkOrder, name='issueWorkOrder'), + path('fetch-request/', views.fetchRequest, name='fetchRequest'), + path('work-order/', views.workOrder, name='workOrder'), + path('requests-status/', views.requestsStatus, name='requestsStatus'), + path('requests-in-progress/', views.requestsInProgress, name='requestsInProgress'), + path('generate-final-bill/', views.generateFinalBill, name='generateFinalBill'), + path('view-budget/', views.viewBudget, name='viewBudget'), + path('add-budget/', views.addBudget, name='addBudget'), + path('edit-budget/', views.editBudget, name='editBudget'), ] diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index ebee4a721..26c38fc98 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -1,9 +1,22 @@ -from rest_framework.decorators import api_view +from rest_framework.decorators import api_view, permission_classes from rest_framework.response import Response from rest_framework import status -from applications.globals.models import HoldsDesignation +from rest_framework.permissions import IsAuthenticated +from applications.globals.models import * from applications.iwdModuleV2.models import * +from applications.ps1.models import * +from applications.filetracking.sdk.methods import * +from notification.views import iwd_notif from .serializers import * +from django.shortcuts import get_object_or_404 +from django.contrib import messages +from reportlab.lib.pagesizes import letter +from reportlab.pdfgen import canvas +from reportlab.platypus import Table, TableStyle +from reportlab.lib import colors +from io import BytesIO +from django.http import HttpResponse +from django.core.exceptions import ObjectDoesNotExist @api_view(['GET']) def dashboard(request): @@ -14,113 +27,105 @@ def dashboard(request): @api_view(['POST']) def page1_1(request): - if request.method == 'POST': - project_id = request.data.get('name') - request.session['projectId'] = project_id - project = Projects(id=project_id) - project.save() + project_id = request.data.get('name') + request.session['projectId'] = project_id + project = Projects(id=project_id) + project.save() - serializer = PageOneDetailsSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(id=project) # Assign the project instance - return Response({'message': 'Page One Details Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + serializer = PageOneDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(id=project) # Assign the project instance + return Response({'message': 'Page One Details Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) def AESForm(request): - if request.method == 'POST': - serializer = AESDetailsSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(key=Projects.objects.get(id=request.session['projectId'])) - return Response({'message': 'AES Details Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + serializer = AESDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'AES Details Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) def page2_1(request): - if request.method == 'POST': - request.session['projectId'] = request.data.get('id') - serializer = PageTwoDetailsSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(id=Projects.objects.get(id=request.session['projectId'])) - return Response({'message': 'Page Two Details Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + request.session['projectId'] = request.data.get('id') + serializer = PageTwoDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(id=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Page Two Details Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) def corrigendumInput(request): - if request.method == 'POST': - existingObject = CorrigendumTable.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) - if existingObject.count() == 1: - existingObject.delete() + existingObject = CorrigendumTable.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() - serializer = CorrigendumTableSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(key=Projects.objects.get(id=request.session['projectId'])) - return Response({'message': 'Corrigendum Input Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + serializer = CorrigendumTableSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Corrigendum Input Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) def addendumInput(request): - if request.method == 'POST': - existingObject = Addendum.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) - if existingObject.count() == 1: - existingObject.delete() + existingObject = Addendum.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() - serializer = AddendumSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(key=Projects.objects.get(id=request.session['projectId'])) - return Response({'message': 'Addendum Input Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + serializer = AddendumSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Addendum Input Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) def PreBidForm(request): - if request.method == 'POST': - existingObject = PreBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) - if existingObject.count() == 1: - existingObject.delete() + existingObject = PreBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() - serializer = PreBidDetailsSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(key=Projects.objects.get(id=request.session['projectId'])) - return Response({'message': 'PreBid Form Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + serializer = PreBidDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'PreBid Form Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) def noOfEntriesTechnicalBid(request): - if request.method == 'POST': - existingObject = NoOfTechnicalBidTimes.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) - if existingObject.count() == 1: - existingObject.delete() + existingObject = NoOfTechnicalBidTimes.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() - serializer = NoOfTechnicalBidTimesSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(key=Projects.objects.get(id=request.session['projectId'])) - return Response({'message': 'Number of Entries for Technical Bid Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + serializer = NoOfTechnicalBidTimesSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Number of Entries for Technical Bid Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) def TechnicalBidForm(request): - if request.method == 'POST': - numberOfTechnicalBidTimes = NoOfTechnicalBidTimes.objects.get(key=Projects.objects.get(id=request.session['projectId'])).number - existingObject = TechnicalBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) - if existingObject.count() == 1: - existingObject.delete() + numberOfTechnicalBidTimes = NoOfTechnicalBidTimes.objects.get(key=Projects.objects.get(id=request.session['projectId'])).number + existingObject = TechnicalBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() - serializer = TechnicalBidDetailsSerializer(data=request.data) - if serializer.is_valid(): - technical_bid = serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + serializer = TechnicalBidDetailsSerializer(data=request.data) + if serializer.is_valid(): + technical_bid = serializer.save(key=Projects.objects.get(id=request.session['projectId'])) - TechnicalBidContractorDetails.objects.filter(key=technical_bid).all().delete() - for w in range(numberOfTechnicalBidTimes): - contractor_serializer = TechnicalBidContractorDetailsSerializer(data={ - 'key': technical_bid, - 'name': request.data.get(f'{w}name'), - 'description': request.data.get(f'{w}Description'), - }) - if contractor_serializer.is_valid(): - contractor_serializer.save() + TechnicalBidContractorDetails.objects.filter(key=technical_bid).all().delete() + for w in range(numberOfTechnicalBidTimes): + contractor_serializer = TechnicalBidContractorDetailsSerializer(data={ + 'key': technical_bid, + 'name': request.data.get(f'{w}name'), + 'description': request.data.get(f'{w}Description'), + }) + if contractor_serializer.is_valid(): + contractor_serializer.save() - return Response({'message': 'Technical Bid Form Saved!'}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + return Response({'message': 'Technical Bid Form Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST', 'GET']) def noOfEntriesFinancialBid(request): @@ -347,3 +352,708 @@ def extensionFormView(request): extensionObjects = ExtensionOfTimeDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) serializer = ExtensionOfTimeDetailsSerializer(extensionObjects, many=True) return Response({'extension': serializer.data}, status=status.HTTP_200_OK) + +designations_list = ["Junior Engineer", "Executive Engineer (Civil)", "Electrical_AE", "Electrical_JE", "EE", "Civil_AE", "Civil_JE", "Dean (P&D)", "Director", "Accounts Admin", "Admin IWD", "Auditor"] + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def fetchDesignations(request): + holdsDesignations = [] + + designations = Designation.objects.filter(name__in=designations_list) + + for designation in designations: + holds = HoldsDesignation.objects.filter(designation=designation) + serializer = HoldsDesignationSerializer(holds, many=True) + holdsDesignations.extend(serializer.data) + + return Response({'holdsDesignations': holdsDesignations}, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def requestsView(request): + data = request.data + desg = request.session.get('currentDesignationSelected') + + # Create a formObject using the serializer + serializer = RequestsSerializer(data=data) + + if serializer.is_valid(): + formObject = serializer.save( + engineerProcessed=0, + directorApproval=0, + deanProcessed=0, + requestCreatedBy=request.user.username, + status="Pending", + issuedWorkOrder=0, + workCompleted=0, + billGenerated=0, + billProcessed=0, + billSettled=0 + ) + + request_object = Requests.objects.get(pk=formObject.pk) + receiver_user, receiver_desg = data.get('designation').split('|') + + # Call create_file function with parameters + create_file( + uploader=request.user.username, + uploader_designation=desg, + receiver=receiver_user, + receiver_designation=receiver_desg, + src_module="IWD", + src_object_id=str(request_object.id), + file_extra_JSON={"value": 2}, + attached_file=None + ) + + receiver_user_obj = User.objects.get(username=receiver_user) + + # Send notification + iwd_notif(request.user, receiver_user_obj, "Request_added") + + # Eligible value for response + eligible = request.session.get('currentDesignationSelected') + + # Return successful response + return Response({'message': "Request Successfully Created", 'eligible': eligible}, status=status.HTTP_201_CREATED) + + # If the serializer is invalid, return errors + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def created_requests_view(request): + obj = [] + desg = request.session.get('currentDesignationSelected') + + # Fetch inbox files based on username and designation + inbox_files = view_inbox( + username=request.user, + designation=desg, + src_module="IWD" + ) + + # Iterate through inbox files to find requests and related file info + for result in inbox_files: + src_object_id = result['src_object_id'] + + # Get the associated request object + request_object = Requests.objects.filter(id=src_object_id).first() + if request_object: + # Get the associated file object + file_obj = get_object_or_404(File, src_object_id=request_object.id, src_module="IWD") + + # Prepare the data to append to the response list + element = { + 'request_id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id + } + obj.append(element) + + # Return the response as JSON + return Response(obj, status=200) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def view_file_api(request, id, url): + # Get the File object using the provided ID or return 404 if not found + file1 = get_object_or_404(File, id=id) + + # Get the related tracking records + tracks = Tracking.objects.filter(file_id=file1) + + # Get the current user from the last tracking record + current_user = Tracking.objects.filter(file_id=file1).order_by('-receive_date').first().receiver_id + + # Fetch all designations + designations = Designation.objects.all() + + # Filter HoldsDesignation based on designations_list (assuming it comes from session or another source) + designations_list = request.session.get('designations_list', []) # assuming designations_list is stored in session + holds_designations = [] + + for d in designations: + if d.name in designations_list: + holds_designations_objs = HoldsDesignation.objects.filter(designation=d) + holds_designations += holds_designations_objs + + # Get the current eligible designation from session + eligible = request.session.get('currentDesignationSelected') + + # Serialize the data + file_serializer = FileSerializer(file1) + tracks_serializer = TrackingSerializer(tracks, many=True) + holds_designations_serializer = HoldsDesignationSerializer(holds_designations, many=True) + + # Return the serialized data as JSON + return Response({ + "file": file_serializer.data, + "tracks": tracks_serializer.data, + "current_user": current_user, + "holds_designations": holds_designations_serializer.data, + "url": url, + "eligible": eligible + }, status=200) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handleEngineerProcessRequests(request): + # Extract POST data and file from the request + file_id = request.data.get('fileid') + remarks = request.data.get('remarks') + attachment = request.FILES.get('attachment') + + # Get the file and corresponding request object + file_instance = get_object_or_404(File, id=file_id) + request_id = file_instance.src_object_id + + # Parse receiver user and designation from the request + receiver_user, receiver_desg = request.data.get('designation').split('|') + + # Forward the file with necessary details + forward_file( + file_id=file_id, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + # Update the request object after being processed by the engineer + Requests.objects.filter(id=request_id).update(engineerProcessed=1, status="Approved by the Engineer") + + # Fetch inbox files based on the current designation + desg = request.session.get('currentDesignationSelected') + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [] + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id).first() + if request_object: + file_obj = File.objects.get(src_object_id=request_object.id, src_module="IWD") + element = { + 'id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id + } + obj.append(element) + + # Send a notification to the receiver + receiver_user_obj = get_object_or_404(User, username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") + + # Return a success message and updated list of requests + return Response({ + "message": "File forwarded successfully", + "requests": obj + }, status=status.HTTP_200_OK) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def rejectedRequests(request): + obj = [] + desg = request.session.get('currentDesignationSelected') + + # Fetch inbox files for the current user and designation + inbox_files = view_inbox( + username=request.user, + designation=desg, + src_module="IWD" + ) + + # Collect requests where directorApproval is -1 (Rejected) + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id, directorApproval=-1).first() + if request_object: + element = { + 'id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy + } + obj.append(element) + + # Collect designations and holdsDesignations + designations = Designation.objects.all() + holdsDesignations = [] + + designations_list = request.session.get('designations_list', []) + + for d in designations: + if d.name in designations_list: + holds_list = HoldsDesignation.objects.filter(designation=d) + holdsDesignations.extend(holds_list) + + # Prepare and return the response with rejected requests and designations + return Response({ + "rejected_requests": obj, + "holds_designations": [ + { + "id": hold.id, + "designation": hold.designation.name, + "user": hold.user.username + } + for hold in holdsDesignations + ] + }, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def updateRejectedRequests(request): + request_id = request.data.get("id", 0) + + desg = request.session.get('currentDesignationSelected') + + # Fetch the inbox files for the current user and designation + inbox_files = view_inbox( + username=request.user, + designation=desg, + src_module="IWD" + ) + + # Iterate through the inbox and delete the relevant file + for p in inbox_files: + if p['src_object_id'] == request_id: + delete_file(file_id=p['id']) # Assuming delete_file handles file deletion + break + + # Fetch the request object by id + request_object = Requests.objects.get(id=request_id) + if not request_object: + return Response({"error": "Request not found"}, status=status.HTTP_404_NOT_FOUND) + + # Collect designations and HoldsDesignations + designations = Designation.objects.all() + holdsDesignations = [] + designations_list = request.session.get('designations_list', []) + + # Create a list of HoldsDesignations + for d in designations: + if d.name in designations_list: + holds_list = HoldsDesignation.objects.filter(designation=d) + holdsDesignations.extend(holds_list) + + # Prepare response data + obj = { + "id": request_object.id, + "name": request_object.name, + "description": request_object.description, + "area": request_object.area, + } + + holdsDesignations_data = [ + { + "id": hold.id, + "designation": hold.designation.name, + "user": hold.user.username + } + for hold in holdsDesignations + ] + + # Return JSON response with request and designations data + return Response({ + "request_details": obj, + "holds_designations": holdsDesignations_data + }, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handleUpdateRequests(request): + # Extract request data + request_id = request.data.get("id", 0) + desg = request.session.get('currentDesignationSelected') + + # Split receiver information + receiver_user, receiver_desg = request.data['designation'].split('|') + + # Update the request object + Requests.objects.filter(id=request_id).update( + name=request.data.get('name'), + description=request.data.get('description'), + area=request.data.get('area'), + engineerProcessed=0, + directorApproval=0, + deanProcessed=0, + requestCreatedBy=request.user.username, + status="Pending", + issuedWorkOrder=0, + workCompleted=0, + billGenerated=0, + billProcessed=0, + billSettled=0 + ) + + # Create a file using the utility function + create_file( + uploader=request.user.username, + uploader_designation=desg, + receiver=receiver_user, + receiver_designation=receiver_desg, + src_module="IWD", + src_object_id=str(request_id), + file_extra_JSON={"value": 2}, + attached_file=None # Adjust if attachments are allowed + ) + + # Notify the receiver user + receiver_user_obj = User.objects.get(username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "Request_added") + + # Return a success response + return Response({"message": "Request updated successfully"}, status=status.HTTP_200_OK) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def issueWorkOrder(request): + obj = [] + desg = request.session.get('currentDesignationSelected') + + # Retrieve inbox files + inbox_files = view_inbox( + username=request.user, + designation=desg, + src_module="IWD" + ) + + # Iterate over the inbox files and filter for relevant requests + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter( + id=src_object_id, + directorApproval=1, + issuedWorkOrder=0 + ).first() + + if request_object: + element = { + "id": request_object.id, + "name": request_object.name, + "area": request_object.area, + "description": request_object.description, + "requestCreatedBy": request_object.requestCreatedBy + } + obj.append(element) + + # Return a JSON response with the filtered requests + return Response({"requests": obj}, status=status.HTTP_200_OK) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def fetchRequest(request): + request_id = request.query_params.get("id", None) + + # Retrieve the request object or return a 404 if not found + req_request = get_object_or_404(Requests, id=request_id) + + # Prepare the response data + response_data = { + "id": req_request.id, + "name": req_request.name, + "description": req_request.description, + "area": req_request.area, + "engineerProcessed": req_request.engineerProcessed, + "directorApproval": req_request.directorApproval, + "deanProcessed": req_request.deanProcessed, + "requestCreatedBy": req_request.requestCreatedBy, + "status": req_request.status, + "issuedWorkOrder": req_request.issuedWorkOrder, + "workCompleted": req_request.workCompleted, + "billGenerated": req_request.billGenerated, + "billProcessed": req_request.billProcessed, + "billSettled": req_request.billSettled, + } + + return Response(response_data, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def workOrder(request): + # Retrieve data from request + request_id = request.data.get('id') + request_instance = get_object_or_404(Requests, pk=request_id) + + # Use the serializer to validate and save the WorkOrder instance + serializer = WorkOrderFormSerializer(data=request.data) + if serializer.is_valid(): + # Create the WorkOrder instance with validated data + work_order = serializer.save(request_id=request_instance) + + # Update the Requests instance + request_instance.status = "Work Order issued" + request_instance.issuedWorkOrder = 1 + request_instance.save() + + # Fetch inbox files + desg = request.session.get('currentDesignationSelected') # Consider passing this in a different way for REST + inbox_files = view_inbox( + username=request.user.username, + designation=desg, + src_module="IWD" + ) + + obj = [] + + # Build the response object + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id).first() + if request_object and request_object.issuedWorkOrder == 0: + element = { + "id": request_object.id, + "name": request_object.name, + "area": request_object.area, + "description": request_object.description, + "requestCreatedBy": request_object.requestCreatedBy + } + obj.append(element) + + messages.success(request, "Work Order Issued") + return Response({'obj': obj}, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def requestsStatus(request): + requestsObject = Requests.objects.all() + serializer = RequestsSerializer(requestsObject, many=True) + return Response({'obj': serializer.data}, status=200) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def requestsInProgress(request): + requestsObject = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) + serializer = RequestsSerializer(requestsObject, many=True) + return Response({'obj': serializer.data}, status=200) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def generateFinalBill(request): + request_id = request.data.get("id", 0) + + # Fetch the related work order + work_order = WorkOrder.objects.get(request_id=request_id) + + # Fetch IWD items + iwd_items = StockItem.objects.filter(department=34) + + items_list = [] + + # Collecting items related to the request + for x in iwd_items: + stock_entry_id = x.StockEntryId.item_id.file_info + indent_file_objects = IndentFile.objects.filter(file_info=stock_entry_id) + for item in indent_file_objects: + if item.purpose == request_id: + element = [item.item_name, item.quantity, item.estimated_cost, item.file_info.upload_date] + items_list.append(element) + + filename = f"Request_id_{request_id}_final_bill.pdf" + + buffer = BytesIO() + c = canvas.Canvas(buffer, pagesize=letter) + c.setFont("Helvetica", 12) + + y_position = 750 + rid = f"Request Id : {request_id}" + agency = f"Agency : {work_order.agency}" + + c.drawString(100, y_position, rid) + y_position -= 20 + c.drawString(100, y_position, agency) + y_position -= 20 + c.drawString(100, y_position - 40, "Items:") + + # Prepare data for the table + data = [["Item Name", "Quantity", "Cost (in Rupees)", "Date of Purchase", "Total Amount"]] + for item in items_list: + data.append([item[0], str(item[1]), "{:.2f}".format(item[2]), item[3], "{:.2f}".format(item[1] * item[2])]) + + total_amount_to_be_paid = sum(item[1] * item[2] for item in items_list) + c.drawString(100, y_position - 80, f"Total Amount (in Rupees): {total_amount_to_be_paid:.2f}") + + # Create a table for the PDF + table = Table(data) + table.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, 0), colors.grey), + ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), + ('ALIGN', (0, 0), (-1, -1), 'CENTER'), + ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), + ('BOTTOMPADDING', (0, 0), (-1, 0), 12), + ('BACKGROUND', (0, 1), (-1, -1), colors.beige), + ('GRID', (0, 0), (-1, -1), 1, colors.black)])) + + table.wrapOn(c, 400, 600) + table.drawOn(c, 100, y_position - 60) + c.save() + + buffer.seek(0) + + response = HttpResponse(content_type='application/pdf') + response['Content-Disposition'] = f'attachment; filename="{filename}"' + response.write(buffer.getvalue()) + + return response + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handleBillGeneratedRequests(request): + request_id = request.data.get("id", 0) + if request_id: + Requests.objects.filter(id=request_id).update(status="Bill Generated", billGenerated=1) + + requests_object = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) + obj = [] + for x in requests_object: + element = { + "id": x.id, + "name": x.name, + "area": x.area, + "description": x.description, + "requestCreatedBy": x.requestCreatedBy, + "workCompleted": x.workCompleted, + } + obj.append(element) + + return Response({'obj': obj}, status=status.HTTP_200_OK) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def generatedBillsView(request): + request_objects = Requests.objects.filter(billGenerated=1) + obj = [] + for x in request_objects: + try: + file_obj = File.objects.get(src_object_id=x.id, src_module="IWD") + element = { + "id": x.id, + "name": x.name, + "description": x.description, + "area": x.area, + "requestCreatedBy": x.requestCreatedBy, + "file_id": file_obj.id, + } + obj.append(element) + except File.DoesNotExist: + continue # Skip if no file exists for this request + + return Response({'obj': obj}, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handleProcessedBills(request): + obj = request.data + + fileid = obj.get('fileid') + try: + request_id = File.objects.get(id=fileid).src_object_id + except ObjectDoesNotExist: + return Response({'error': 'File not found.'}, status=status.HTTP_404_NOT_FOUND) + + remarks = obj.get('remarks') + attachment = request.FILES.get('attachment') + receiver_user, receiver_desg = obj['designation'].split('|') + + # Call to forward_file should be defined elsewhere + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + Requests.objects.filter(id=request_id).update(billProcessed=1, status="Final Bill Processed") + + request_instance = Requests.objects.get(pk=request_id) + + formObject = Bills() + formObject.request_id = request_instance + formObject.file = attachment + formObject.save() + + req_objects = Requests.objects.filter(billGenerated=1) + obj = [] + + for result in req_objects: + request_object = Requests.objects.filter(id=result.id).first() + try: + file_obj = File.objects.get(src_object_id=result.id, src_module="IWD") + if request_object: + element = { + "id": request_object.id, + "name": request_object.name, + "area": request_object.area, + "description": request_object.description, + "requestCreatedBy": request_object.requestCreatedBy, + "file_id": file_obj.id, + } + obj.append(element) + except File.DoesNotExist: + continue # Skip if no file exists for this request + + messages.success(request, "Bill processed") + receiver_user_obj = User.objects.get(username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") + + return Response({'obj': obj}, status=status.HTTP_200_OK) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def viewBudget(request): + budget_objects = Budget.objects.all() + obj = [] + + for x in budget_objects: + element = { + "id": x.id, + "name": x.name, + "budgetIssued": x.budgetIssued + } + obj.append(element) + + return Response({'obj': obj}, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def addBudget(request): + if request.method == 'POST': + name = request.data.get('name') + budget_issued = request.data.get('budget') + + if name and budget_issued: + formObject = Budget(name=name, budgetIssued=budget_issued) + formObject.save() + return Response({'message': 'Budget added successfully.'}, status=status.HTTP_201_CREATED) + else: + return Response({'error': 'Name and budget are required.'}, status=status.HTTP_400_BAD_REQUEST) + + return Response({'error': 'Invalid request method.'}, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def editBudget(request): + if request.method == "POST": + budget_id = request.data.get('id') + budget_name = request.data.get('name') + budget_issued = request.data.get('budget') + + if budget_id and budget_name and budget_issued: + Budget.objects.filter(id=budget_id).update(name=budget_name, budgetIssued=budget_issued) + return Response({'message': 'Budget updated successfully.'}, status=status.HTTP_200_OK) + else: + return Response({'error': 'ID, name, and budget are required.'}, status=status.HTTP_400_BAD_REQUEST) + + return Response({'error': 'Invalid request method.'}, status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file diff --git a/FusionIIIT/applications/online_cms/migrations/0002_auto_20241010_1836.py b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241010_1836.py new file mode 100644 index 000000000..98459ac4a --- /dev/null +++ b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241010_1836.py @@ -0,0 +1,40 @@ +# Generated by Django 3.1.5 on 2024-10-10 18:36 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('academic_information', '0001_initial'), + ('online_cms', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='attendance', + name='no_of_attendance', + field=models.IntegerField(default=1), + ), + migrations.AlterField( + model_name='attendance', + name='present', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='gradingscheme', + name='type_of_evaluation', + field=models.CharField(max_length=100), + ), + migrations.CreateModel( + name='StudentEvaluation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('marks', models.DecimalField(decimal_places=2, max_digits=10, null=True)), + ('total_marks', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('evaluation_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='online_cms.gradingscheme')), + ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), + ], + ), + ] diff --git a/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241010_1836.py b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241010_1836.py new file mode 100644 index 000000000..1c456395f --- /dev/null +++ b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241010_1836.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.5 on 2024-10-10 18:36 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('research_procedures', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='staff_allocations', + name='start_date', + field=models.DateField(default=datetime.date(2024, 10, 10)), + ), + ] From 25e012a2bd6376a9f042ce5e040955da4d08e87d Mon Sep 17 00:00:00 2001 From: Abhijeet Date: Thu, 17 Oct 2024 23:07:48 +0530 Subject: [PATCH 2/2] Added additional endpoints in API folder in iwdModuleV2 --- .../applications/iwdModuleV2/api/urls.py | 12 + .../applications/iwdModuleV2/api/views.py | 249 ++++++++++++++++++ 2 files changed, 261 insertions(+) diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index 7caba1060..24ae97006 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -37,6 +37,10 @@ path('created-requests-view/', views.created_requests_view, name='createdRequests'), path('view-file/', views.view_file_api, name='viewFile'), path('handle-engineer-process-requests/', views.handleEngineerProcessRequests, name='handleEngineerProcessRequests'), + path('engineer-processed-requests/', views.engineer_processed_requests, name='engineerProcessedRequests'), + path('handle-dean-process-requests/', views.handle_dean_process_requests, name='handleDeanProcessRequests'), + path('dean-processed-requests/', views.dean_processed_requests, name='deanProcessedRequests'), + path('handle-director-approval-requests/', views.handle_director_approval_requests, name='handleDirectorApprovalRequests'), path('rejected-requests-view/', views.rejectedRequests, name='rejectedRequests'), path('update-rejected-requests/', views.updateRejectedRequests, name='updateRejectedRequests'), path('handle-update-requests/', views.handleUpdateRequests, name='handleUpdateRequests'), @@ -45,7 +49,15 @@ path('work-order/', views.workOrder, name='workOrder'), path('requests-status/', views.requestsStatus, name='requestsStatus'), path('requests-in-progress/', views.requestsInProgress, name='requestsInProgress'), + path('work-completed/', views.work_completed, name='workCompleted'), path('generate-final-bill/', views.generateFinalBill, name='generateFinalBill'), + path('handle-bill-generated-requests/', views.handleBillGeneratedRequests, name='handleBillGeneratedRequests'), + path('generated-bills-view/', views.generatedBillsView, name='generatedBillsView'), + path('handle-processed-bills/', views.handleProcessedBills, name='handleProcessedBills'), + path('audit-document-view/', views.audit_document_view, name='auditDocumentView'), + path('audit-document/', views.audit_document, name='auditDocument'), + path('settle-bills-view/', views.settle_bills_view, name='settleBillsView'), + path('handle-settle-bill-request/', views.handle_settle_bill_requests, name='handleSettleBillRequest'), path('view-budget/', views.viewBudget, name='viewBudget'), path('add-budget/', views.addBudget, name='addBudget'), path('edit-budget/', views.editBudget, name='editBudget'), diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 26c38fc98..2c1aac4f3 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -558,6 +558,119 @@ def handleEngineerProcessRequests(request): "requests": obj }, status=status.HTTP_200_OK) +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def engineer_processed_requests(request): + obj = [] + desg = request.session.get('currentDesignationSelected') + + inbox_files = view_inbox( + username=request.user.username, + designation=desg, + src_module="IWD" + ) + + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id).first() + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + if request_object: + element = { + 'id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id + } + obj.append(element) + + return Response(obj) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_dean_process_requests(request): + data = request.data + fileid = data.get('fileid') + request_id = File.objects.get(id=fileid).src_object_id + + remarks = data.get('remarks') + attachment = request.FILES.get('attachment') + receiver_user, receiver_desg = data['designation'].split('|') + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + Requests.objects.filter(id=request_id).update(deanProcessed=1, status="Approved by the dean") + + return Response({'message': 'File Forwarded'}, status=200) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def dean_processed_requests(request): + obj = [] + desg = request.session.get('currentDesignationSelected') + + inbox_files = view_inbox( + username=request.user.username, + designation=desg, + src_module="IWD" + ) + + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id).first() + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + if request_object: + element = { + 'id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id + } + obj.append(element) + + return Response(obj) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_director_approval_requests(request): + data = request.data + fileid = data.get('fileid') + request_id = File.objects.get(id=fileid).src_object_id + + remarks = data.get('remarks') + attachment = request.FILES.get('attachment') + receiver_user, receiver_desg = data['designation'].split('|') + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + message = "" + + if data.get('action') == 'approve': + message = "Request_approved" + Requests.objects.filter(id=request_id).update(directorApproval=1, status="Approved by the director") + else: + message = "Request_rejected" + Requests.objects.filter(id=request_id).update(directorApproval=-1, status="Rejected by the director") + + return Response({'message': message}) + @api_view(['GET']) @permission_classes([IsAuthenticated]) def rejectedRequests(request): @@ -838,6 +951,40 @@ def requestsInProgress(request): serializer = RequestsSerializer(requestsObject, many=True) return Response({'obj': serializer.data}, status=200) +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def work_completed(request): + # Get the request ID from the POST data + request_id = request.data.get('id') + + # Update the workCompleted and status fields + Requests.objects.filter(id=request_id).update(workCompleted=1, status="Work Completed") + + # Fetch the requests that have an issued work order but the bill is not generated yet + requests_object = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) + obj = [] + + # Construct the response object with the request details + for request_obj in requests_object: + element = { + 'id': request_obj.id, + 'name': request_obj.name, + 'area': request_obj.area, + 'description': request_obj.description, + 'requestCreatedBy': request_obj.requestCreatedBy, + 'workCompleted': request_obj.workCompleted + } + obj.append(element) + + # Return a JSON response with a success message and the updated list of requests + return Response( + { + 'message': 'Work Completed', + 'data': obj + }, + status=status.HTTP_200_OK + ) + @api_view(['POST']) @permission_classes([IsAuthenticated]) def generateFinalBill(request): @@ -1010,6 +1157,108 @@ def handleProcessedBills(request): return Response({'obj': obj}, status=status.HTTP_200_OK) +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def audit_document_view(request): + desg = request.session.get('currentDesignationSelected') + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [ + { + 'requestId': x['src_object_id'], + 'file': Bills.objects.get(request_id=x['src_object_id']).file, + 'fileUrl': Bills.objects.get(request_id=x['src_object_id']).file.url, + 'fileId': File.objects.get(src_object_id=x['src_object_id'], src_module="IWD").id + } + for x in inbox_files + ] + + return Response({'data': obj}, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def audit_document(request): + fileid = request.data.get('fileid') + remarks = request.data.get('remarks') + attachment = request.FILES.get('attachment') + receiver_user, receiver_desg = request.data['designation'].split('|') + + if fileid: + request_id = File.objects.get(id=fileid).src_object_id + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + Requests.objects.filter(id=request_id).update(status="Bill Audited") + + # Fetch files again + desg = request.session.get('currentDesignationSelected') + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [ + { + 'requestId': x['src_object_id'], + 'file': Bills.objects.get(request_id=x['src_object_id']).file, + 'fileUrl': Bills.objects.get(request_id=x['src_object_id']).file.url, + 'fileId': File.objects.get(src_object_id=x['src_object_id'], src_module="IWD").id + } + for x in inbox_files + ] + + return Response({'message': "File Audit done", 'data': obj}, status=status.HTTP_200_OK) + + return Response({'error': 'File ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def settle_bills_view(request): + desg = request.session.get('currentDesignationSelected') + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [ + { + 'requestId': x['src_object_id'], + 'file': Bills.objects.get(request_id=x['src_object_id']).file, + 'fileUrl': Bills.objects.get(request_id=x['src_object_id']).file.url, + 'billSettled': Requests.objects.get(id=x['src_object_id']).billSettled, + 'fileId': File.objects.get(src_object_id=x['src_object_id'], src_module="IWD").id + } + for x in inbox_files + ] + + return Response({'data': obj}, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_settle_bill_requests(request): + request_id = request.data.get('id') + if request_id: + Requests.objects.filter(id=request_id).update(status="Final Bill Settled", billSettled=1) + + desg = request.session.get('currentDesignationSelected') + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [ + { + 'requestId': x['src_object_id'], + 'file': Bills.objects.get(request_id=x['src_object_id']).file, + 'fileUrl': Bills.objects.get(request_id=x['src_object_id']).file.url, + 'billSettled': Requests.objects.get(id=x['src_object_id']).billSettled, + 'fileId': File.objects.get(src_object_id=x['src_object_id'], src_module="IWD").id + } + for x in inbox_files + ] + + return Response({'message': "Final Bill settled", 'data': obj}, status=status.HTTP_200_OK) + + return Response({'error': 'Request ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + @api_view(['GET']) @permission_classes([IsAuthenticated]) def viewBudget(request):