From 68739b38373ab8f748114344cdc1b3cc8836e30f Mon Sep 17 00:00:00 2001 From: Bhargavzz Date: Thu, 17 Oct 2024 17:31:19 +0530 Subject: [PATCH 01/20] Added API folder in iwdModuleV2 --- FusionIIIT/Fusion/urls.py | 4 + .../iwdModuleV2/api/serializers.py | 190 ++++++++++ .../applications/iwdModuleV2/api/urls.py | 36 ++ .../applications/iwdModuleV2/api/views.py | 349 ++++++++++++++++++ 4 files changed, 579 insertions(+) create mode 100644 FusionIIIT/applications/iwdModuleV2/api/serializers.py create mode 100644 FusionIIIT/applications/iwdModuleV2/api/urls.py create mode 100644 FusionIIIT/applications/iwdModuleV2/api/views.py diff --git a/FusionIIIT/Fusion/urls.py b/FusionIIIT/Fusion/urls.py index b9c03eeb8..8de4cbf11 100755 --- a/FusionIIIT/Fusion/urls.py +++ b/FusionIIIT/Fusion/urls.py @@ -37,6 +37,10 @@ url(r'^__debug__/', include(debug_toolbar.urls)), url(r'^research_procedures/', include('applications.research_procedures.urls')), url(r'^accounts/', include('allauth.urls')), + + + url(r'^api/', include('applications.iwdModuleV2.api.urls')), + url(r'^eis/', include('applications.eis.urls')), diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py new file mode 100644 index 000000000..2b6f6c37a --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -0,0 +1,190 @@ +from rest_framework import serializers +from applications.iwdModuleV2.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 Meta: + model = AESDetails + fields = '__all__' # or list specific fields here + +class FinancialBidDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = FinancialBidDetails + fields = '__all__' # or list specific fields here + +class TechnicalBidDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = TechnicalBidDetails + fields = '__all__' # or list specific fields here + +class FinancialContractorDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = FinancialContractorDetails + fields = '__all__' # or list specific fields here + +class TechnicalBidContractorDetailsSerializer(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 diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py new file mode 100644 index 000000000..1e96232ef --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -0,0 +1,36 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('dashboard/', views.dashboard, name='dashboard'), + path('page1-1/', views.page1_1, name='page1_1'), + path('aes-form/', views.AESForm, name='AESForm'), + path('page2-1/', views.page2_1, name='page2_1'), + path('corrigendum-input/', views.corrigendumInput, name='corrigendumInput'), + path('addendum-input/', views.addendumInput, name='addendumInput'), + path('pre-bid-form/', views.PreBidForm, name='PreBidForm'), + path('no-of-entries-technical-bid/', views.noOfEntriesTechnicalBid, name='noOfEntriesTechnicalBid'), + path('technical-bid-form/', views.TechnicalBidForm, name='TechnicalBidForm'), + path('no-of-entries-financial-bid/', views.noOfEntriesFinancialBid, name='noOfEntriesFinancialBid'), + path('letter-of-intent/', views.letterOfIntent, name='letterOfIntent'), + 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('extension-of-time-form/', views.ExtensionOfTimeForm, name='ExtensionOfTimeForm'), + path('page1-view/', views.page1View, name='page1View'), + path('page2-view/', views.page2View, name='page2View'), + path('aes-view/', views.AESView, name='AESView'), + path('financial-bid-view/', views.financialBidView, name='financialBidView'), + path('technical-bid-view/', views.technicalBidView, name='technicalBidView'), + path('pre-bid-details-view/', views.preBidDetailsView, name='preBidDetailsView'), + path('corrigendum-view/', views.corrigendumView, name='corrigendumView'), + path('addendum-view/', views.addendumView, name='addendumView'), + path('letter-of-intent-view/', views.letterOfIntentView, name='letterOfIntentView'), + path('work-order-form-view/', views.workOrderFormView, name='workOrderFormView'), + path('agreement-view/', views.agreementView, name='agreementView'), + path('milestone-view/', views.milestoneView, name='milestoneView'), + path('page3-view/', views.page3View, name='page3View'), + path('extension-form-view/', views.extensionFormView, name='extensionFormView'), +] + diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py new file mode 100644 index 000000000..ebee4a721 --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -0,0 +1,349 @@ +from rest_framework.decorators import api_view +from rest_framework.response import Response +from rest_framework import status +from applications.globals.models import HoldsDesignation +from applications.iwdModuleV2.models import * +from .serializers import * + +@api_view(['GET']) +def dashboard(request): + userObj = request.user + userDesignationObjects = HoldsDesignation.objects.filter(user=userObj) + eligible = any(p.designation.name == 'Admin IWD' for p in userDesignationObjects) + return Response({'eligible': eligible}) + +@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() + + 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) + +@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) + +@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() + + 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() + + 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() + + 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() + + 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() + + 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() + + 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): + project_id = request.session['projectId'] + objectTechnicalBid = TechnicalBidDetails.objects.get(key=Projects.objects.get(id=project_id)) + objects = TechnicalBidContractorDetails.objects.filter(key=objectTechnicalBid) + + listOfContractors = [t.name for t in objects] + + if request.method == 'POST': + existingObject = FinancialBidDetails.objects.filter(key=Projects.objects.get(id=project_id)) + if existingObject.count() == 1: + existingObject.delete() + + serializer = FinancialBidDetailsSerializer(data=request.data) + if serializer.is_valid(): + financial_bid = serializer.save(key=Projects.objects.get(id=project_id)) + for contractor in listOfContractors: + contractor_serializer = FinancialContractorDetailsSerializer(data={ + 'key': financial_bid, + 'name': contractor, + 'totalCost': request.data[contractor + 'totalCost'], + 'estimatedCost': request.data[contractor + 'estimatedCost'], + 'percentageRelCost': request.data[contractor + 'percentageRelCost'], + 'perFigures': request.data[contractor + 'perFigures'], + }) + if contractor_serializer.is_valid(): + contractor_serializer.save() + return Response({"message": "Financial bid details saved successfully."}, status=status.HTTP_201_CREATED) + + return Response({'list': listOfContractors}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def letterOfIntent(request): + if request.method == 'POST': + existingObject = LetterOfIntentDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() + + serializer = LetterOfIntentDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({"message": "Letter of Intent saved successfully."}, status=status.HTTP_201_CREATED) + + return Response({}, status=status.HTTP_200_OK) + + +@api_view(['POST', 'GET']) +def workOrderForm(request): + project_id = request.session.get('projectId') + if request.method == 'POST': + existingObject = WorkOrderForm.objects.filter(key=Projects.objects.get(id=project_id)) + if existingObject.exists(): + existingObject.delete() + + serializer = WorkOrderFormSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=project_id)) + return Response({"message": "Work order saved successfully."}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def AgreementInput(request): + project_id = request.session.get('projectId') + if request.method == 'POST': + existingObject = Agreement.objects.filter(key=Projects.objects.get(id=project_id)) + if existingObject.exists(): + existingObject.delete() + + serializer = AgreementSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=project_id)) + return Response({"message": "Agreement saved successfully."}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def milestonesForm(request): + project_id = request.session.get('projectId') + if request.method == 'POST': + serializer = MilestonesSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=project_id)) + return Response({"message": "Milestone saved successfully."}, status=status.HTTP_201_CREATED) + + Milestones.objects.filter(key=Projects.objects.get(id=project_id)).delete() + return Response({}, status=status.HTTP_200_OK) + + +@api_view(['POST', 'GET']) +def page3_1(request): + if request.method == 'POST': + request.session['projectId'] = request.data['id'] + serializer = PageThreeDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(id=Projects.objects.get(id=request.session['projectId'])) + return Response({"message": "Page 3 details saved successfully."}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def ExtensionOfTimeForm(request): + project_id = request.session.get('projectId') + if request.method == 'POST': + serializer = ExtensionOfTimeDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=project_id)) + return Response({"message": "Extension of Time details saved successfully."}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST']) +def page1View(request): + request.session['projectId'] = request.data['id'] + projectPageOne = PageOneDetails.objects.get(id=Projects.objects.get(id=request.session['projectId'])) + return Response({'x': projectPageOne}, status=status.HTTP_200_OK) + +@api_view(['POST']) +def page2View(request): + projectPageTwo = PageTwoDetails.objects.get(id=Projects.objects.get(id=request.session['projectId'])) + return Response({'x': projectPageTwo}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def AESView(request): + objects = AESDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = AESDetailsSerializer(objects, many=True) + return Response({'AES': serializer.data}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def financialBidView(request): + elements = [] + objects = FinancialBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + for f in objects: + contractorObjects = FinancialContractorDetails.objects.filter(key=f) + for w in contractorObjects: + obj = [f.sNo, f.description, w.name, w.estimatedCost, w.percentageRelCost, w.perFigures, w.totalCost] + elements.append(obj) + return Response({'financial': elements}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def technicalBidView(request): + elements = [] + objects = TechnicalBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + for f in objects: + contractorObjects = TechnicalBidContractorDetails.objects.filter(key=f) + for w in contractorObjects: + obj = [f.sNo, f.requirements, w.name, w.description] + elements.append(obj) + return Response({'technical': elements}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def preBidDetailsView(request): + preBidObjects = PreBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = PreBidDetailsSerializer(preBidObjects, many=True) + return Response({'preBidDetails': serializer.data}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def corrigendumView(request): + try: + corrigendumObject = CorrigendumTable.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = CorrigendumTableSerializer(corrigendumObject) + return Response({'corrigendum': serializer.data}, status=status.HTTP_200_OK) + except CorrigendumTable.DoesNotExist: + return Response({'error': 'Corrigendum not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def addendumView(request): + try: + addendumObject = Addendum.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = AddendumSerializer(addendumObject) + return Response({'addendum': serializer.data}, status=status.HTTP_200_OK) + except Addendum.DoesNotExist: + return Response({'error': 'Addendum not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def letterOfIntentView(request): + try: + letterOfIntentObject = LetterOfIntentDetails.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = LetterOfIntentDetailsSerializer(letterOfIntentObject) + return Response({'letterOfIntent': serializer.data}, status=status.HTTP_200_OK) + except LetterOfIntentDetails.DoesNotExist: + return Response({'error': 'Letter of Intent not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def workOrderFormView(request): + try: + workOrderFormObject = WorkOrderForm.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = WorkOrderFormSerializer(workOrderFormObject) + return Response({'workOrderForm': serializer.data}, status=status.HTTP_200_OK) + except WorkOrderForm.DoesNotExist: + return Response({'error': 'Work Order Form not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def agreementView(request): + try: + agreementObject = Agreement.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = AgreementSerializer(agreementObject) + return Response({'agreement': serializer.data}, status=status.HTTP_200_OK) + except Agreement.DoesNotExist: + return Response({'error': 'Agreement not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def milestoneView(request): + milestoneObjects = Milestones.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = MilestonesSerializer(milestoneObjects, many=True) + return Response({'milestones': serializer.data}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def page3View(request): + try: + pageThreeDetails = PageThreeDetails.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = PageThreeDetailsSerializer(pageThreeDetails) + return Response({'pageThreeDetails': serializer.data}, status=status.HTTP_200_OK) + except PageThreeDetails.DoesNotExist: + return Response({'error': 'Page Three Details not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +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) From baef7d5608b74fbd8747579be61ecf31ab6adc07 Mon Sep 17 00:00:00 2001 From: Abhijeet Date: Thu, 17 Oct 2024 22:33:28 +0530 Subject: [PATCH 02/20] 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 9ddf20de2c078831a736b307e1161a5b5b38d6d9 Mon Sep 17 00:00:00 2001 From: Abhijeet Date: Thu, 17 Oct 2024 23:07:48 +0530 Subject: [PATCH 03/20] 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): From 55886bfb5c55b5714eec945a8b21a65c228129b4 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Fri, 18 Oct 2024 13:02:10 +0545 Subject: [PATCH 04/20] fix[api] : fetchdesignation, requestview --- FusionIIIT/Fusion/urls.py | 4 +- ...012_1459.py => 0002_auto_20241015_1451.py} | 2 +- ...007_2302.py => 0002_auto_20241015_1451.py} | 2 +- .../iwdModuleV2/api/serializers.py | 19 +++++++-- .../applications/iwdModuleV2/api/views.py | 39 +++++++------------ ...012_1459.py => 0002_auto_20241015_1451.py} | 2 +- FusionIIIT/applications/iwdModuleV2/urls.py | 2 +- ...012_1459.py => 0002_auto_20241015_1451.py} | 2 +- ...012_1459.py => 0002_auto_20241015_1451.py} | 2 +- 9 files changed, 37 insertions(+), 37 deletions(-) rename FusionIIIT/applications/central_mess/migrations/{0002_auto_20241012_1459.py => 0002_auto_20241015_1451.py} (90%) rename FusionIIIT/applications/globals/migrations/{0002_auto_20241007_2302.py => 0002_auto_20241015_1451.py} (97%) rename FusionIIIT/applications/iwdModuleV2/migrations/{0002_auto_20241012_1459.py => 0002_auto_20241015_1451.py} (98%) rename FusionIIIT/applications/online_cms/migrations/{0002_auto_20241012_1459.py => 0002_auto_20241015_1451.py} (96%) rename FusionIIIT/applications/research_procedures/migrations/{0002_auto_20241012_1459.py => 0002_auto_20241015_1451.py} (88%) diff --git a/FusionIIIT/Fusion/urls.py b/FusionIIIT/Fusion/urls.py index 8de4cbf11..9227e1e60 100755 --- a/FusionIIIT/Fusion/urls.py +++ b/FusionIIIT/Fusion/urls.py @@ -38,9 +38,7 @@ url(r'^research_procedures/', include('applications.research_procedures.urls')), url(r'^accounts/', include('allauth.urls')), - - url(r'^api/', include('applications.iwdModuleV2.api.urls')), - + # url(r'^api/iwdModuleV2/', include('applications.iwdModuleV2.api.urls')), url(r'^eis/', include('applications.eis.urls')), diff --git a/FusionIIIT/applications/central_mess/migrations/0002_auto_20241012_1459.py b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241015_1451.py similarity index 90% rename from FusionIIIT/applications/central_mess/migrations/0002_auto_20241012_1459.py rename to FusionIIIT/applications/central_mess/migrations/0002_auto_20241015_1451.py index fd5b1d205..45c592388 100644 --- a/FusionIIIT/applications/central_mess/migrations/0002_auto_20241012_1459.py +++ b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241015_1451.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2024-10-12 14:59 +# Generated by Django 3.1.5 on 2024-10-15 14:51 import datetime from django.db import migrations, models diff --git a/FusionIIIT/applications/globals/migrations/0002_auto_20241007_2302.py b/FusionIIIT/applications/globals/migrations/0002_auto_20241015_1451.py similarity index 97% rename from FusionIIIT/applications/globals/migrations/0002_auto_20241007_2302.py rename to FusionIIIT/applications/globals/migrations/0002_auto_20241015_1451.py index 0cf484df2..46d64993b 100644 --- a/FusionIIIT/applications/globals/migrations/0002_auto_20241007_2302.py +++ b/FusionIIIT/applications/globals/migrations/0002_auto_20241015_1451.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2024-10-07 23:02 +# Generated by Django 3.1.5 on 2024-10-15 14:51 from django.db import migrations, models diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index e96d2d4b9..b03d96eca 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -100,11 +100,11 @@ class Meta: class HoldsDesignationSerializer(serializers.ModelSerializer): designation = DesignationSerializer() + username = serializers.CharField(source='user.username') class Meta: model = HoldsDesignation - fields = ['id', 'designation', 'user'] - + fields = ['id', 'designation', 'username'] # class RequestsSerializer(serializers.ModelSerializer): # class Meta: # model = Requests @@ -113,4 +113,17 @@ class Meta: class RequestsSerializer(serializers.ModelSerializer): class Meta: model = Requests - fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'status', 'workCompleted'] \ No newline at end of file + fields = ['id', 'name', 'area', 'description'] + + def create(self, validated_data): + validated_data['engineerProcessed'] = 0 + validated_data['directorApproval'] = 0 + validated_data['deanProcessed'] = 0 + validated_data['status'] = "Pending" + validated_data['issuedWorkOrder'] = 0 + validated_data['workCompleted'] = 0 + validated_data['billGenerated'] = 0 + validated_data['billProcessed'] = 0 + validated_data['billSettled'] = 0 + validated_data['requestCreatedBy'] = "" + return super().create(validated_data) \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 2c1aac4f3..b28a6c26c 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -373,32 +373,23 @@ def fetchDesignations(request): @permission_classes([IsAuthenticated]) def requestsView(request): data = request.data - desg = request.session.get('currentDesignationSelected') - - # Create a formObject using the serializer - serializer = RequestsSerializer(data=data) + serializer = RequestsSerializer(data=data, context={'request': request}) + print("WOW1", 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 - ) - + formObject = serializer.save() + print(formObject) request_object = Requests.objects.get(pk=formObject.pk) - receiver_user, receiver_desg = data.get('designation').split('|') - - # Call create_file function with parameters + receiver_desg, receiver_user = data.get('designation').split('|') + print("WOW", receiver_desg, receiver_user, data) + try: + receiver_user_obj = User.objects.get(username=receiver_user) + except User.DoesNotExist: + print("hahahaha") + return Response({'error': 'Receiver user does not exist'}, status=status.HTTP_400_BAD_REQUEST) create_file( uploader=request.user.username, - uploader_designation=desg, + uploader_designation=data.get('role'), receiver=receiver_user, receiver_designation=receiver_desg, src_module="IWD", @@ -407,18 +398,16 @@ def requestsView(request): 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') + # eligible = request.session.get('currentDesignationSelected') # Return successful response - return Response({'message': "Request Successfully Created", 'eligible': eligible}, status=status.HTTP_201_CREATED) + return Response({'message': "Request Successfully Created"}, 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']) diff --git a/FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241012_1459.py b/FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241015_1451.py similarity index 98% rename from FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241012_1459.py rename to FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241015_1451.py index 546d6c629..8a5daed35 100644 --- a/FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241012_1459.py +++ b/FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241015_1451.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2024-10-12 14:59 +# Generated by Django 3.1.5 on 2024-10-15 14:51 from django.db import migrations, models import django.db.models.deletion diff --git a/FusionIIIT/applications/iwdModuleV2/urls.py b/FusionIIIT/applications/iwdModuleV2/urls.py index e976034d3..ea025ea14 100644 --- a/FusionIIIT/applications/iwdModuleV2/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/urls.py @@ -6,7 +6,7 @@ urlpatterns = [ - + url(r'^api/', include('applications.iwdModuleV2.api.urls')), url(r'^$', views.dashboard, name='IWD Dashboard'), url(r'^page1_1/$', views.page1_1, name='IWD Page1.1'), url(r'page2_1/$', views.page2_1, name='IWD Page2.1'), diff --git a/FusionIIIT/applications/online_cms/migrations/0002_auto_20241012_1459.py b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241015_1451.py similarity index 96% rename from FusionIIIT/applications/online_cms/migrations/0002_auto_20241012_1459.py rename to FusionIIIT/applications/online_cms/migrations/0002_auto_20241015_1451.py index d689e8177..acc78b661 100644 --- a/FusionIIIT/applications/online_cms/migrations/0002_auto_20241012_1459.py +++ b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241015_1451.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2024-10-12 14:59 +# Generated by Django 3.1.5 on 2024-10-15 14:51 from django.db import migrations, models import django.db.models.deletion diff --git a/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241012_1459.py b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241015_1451.py similarity index 88% rename from FusionIIIT/applications/research_procedures/migrations/0002_auto_20241012_1459.py rename to FusionIIIT/applications/research_procedures/migrations/0002_auto_20241015_1451.py index eebc5845e..e975e3b02 100644 --- a/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241012_1459.py +++ b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241015_1451.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2024-10-12 14:59 +# Generated by Django 3.1.5 on 2024-10-15 14:51 import datetime from django.db import migrations, models From 2e83db6f7a2a3990b78be35ccbc636766a09db13 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Tue, 22 Oct 2024 05:34:34 +0545 Subject: [PATCH 05/20] fix : view file endpoint --- .../iwdModuleV2/api/serializers.py | 3 +- .../applications/iwdModuleV2/api/urls.py | 1 + .../applications/iwdModuleV2/api/views.py | 49 +++---------------- 3 files changed, 11 insertions(+), 42 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index b03d96eca..adeaad132 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -126,4 +126,5 @@ def create(self, validated_data): validated_data['billProcessed'] = 0 validated_data['billSettled'] = 0 validated_data['requestCreatedBy'] = "" - return super().create(validated_data) \ No newline at end of file + return super().create(validated_data) + \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index 24ae97006..0c1dae50b 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -36,6 +36,7 @@ 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('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'), diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index b28a6c26c..4d12d800a 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -374,18 +374,15 @@ def fetchDesignations(request): def requestsView(request): data = request.data serializer = RequestsSerializer(data=data, context={'request': request}) - print("WOW1", data) if serializer.is_valid(): formObject = serializer.save() print(formObject) request_object = Requests.objects.get(pk=formObject.pk) receiver_desg, receiver_user = data.get('designation').split('|') - print("WOW", receiver_desg, receiver_user, data) try: receiver_user_obj = User.objects.get(username=receiver_user) except User.DoesNotExist: - print("hahahaha") return Response({'error': 'Receiver user does not exist'}, status=status.HTTP_400_BAD_REQUEST) create_file( uploader=request.user.username, @@ -413,27 +410,19 @@ def requestsView(request): @api_view(['GET']) @permission_classes([IsAuthenticated]) def created_requests_view(request): + # print("REQUESTT:", request) + params = request.query_params obj = [] - desg = request.session.get('currentDesignationSelected') - - # Fetch inbox files based on username and designation inbox_files = view_inbox( username=request.user, - designation=desg, + designation=params.get('role'), 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, @@ -444,48 +433,26 @@ def created_requests_view(request): } 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 +def view_file_api(request): + params = request.query_params + id = params.get('file_id') + print(id) 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, + "url": "url", "eligible": eligible }, status=200) From 4a2ed5831dc736234bf9b939d5bb1ec510cada35 Mon Sep 17 00:00:00 2001 From: dotniiko <115548274+dotniiko@users.noreply.github.com> Date: Wed, 23 Oct 2024 03:25:19 +0530 Subject: [PATCH 06/20] minor updates while updating the issue-work-order table (#4) --- .../central_mess/migrations/0001_initial.py | 22 +++++----- .../migrations/0002_auto_20241021_2042.py | 23 +++++++++++ .../applications/iwdModuleV2/api/views.py | 7 ++-- .../migrations/0002_auto_20241021_2042.py | 40 +++++++++++++++++++ .../migrations/0002_auto_20241021_2042.py | 19 +++++++++ 5 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 FusionIIIT/applications/central_mess/migrations/0002_auto_20241021_2042.py create mode 100644 FusionIIIT/applications/online_cms/migrations/0002_auto_20241021_2042.py create mode 100644 FusionIIIT/applications/research_procedures/migrations/0002_auto_20241021_2042.py diff --git a/FusionIIIT/applications/central_mess/migrations/0001_initial.py b/FusionIIIT/applications/central_mess/migrations/0001_initial.py index 7e80bedf5..b392627e5 100644 --- a/FusionIIIT/applications/central_mess/migrations/0001_initial.py +++ b/FusionIIIT/applications/central_mess/migrations/0001_initial.py @@ -149,17 +149,17 @@ class Migration(migrations.Migration): ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), ], ), - migrations.CreateModel( - name='Payments', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('amount_paid', models.IntegerField(default=0)), - ('payment_month', models.CharField(default=applications.central_mess.models.current_month, max_length=20)), - ('payment_year', models.IntegerField(default=applications.central_mess.models.current_year)), - ('payment_date', models.DateField(default=datetime.date(2024, 6, 19))), - ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), - ], - ), + # migrations.CreateModel( + # name='Payments', + # fields=[ + # ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + # ('amount_paid', models.IntegerField(default=0)), + # ('payment_month', models.CharField(default=applications.central_mess.models.current_month, max_length=20)), + # ('payment_year', models.IntegerField(default=applications.central_mess.models.current_year)), + # ('payment_date', models.DateField(default=datetime.date(2024, 6, 19))), + # ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), + # ], + # ), migrations.CreateModel( name='Mess_minutes', fields=[ diff --git a/FusionIIIT/applications/central_mess/migrations/0002_auto_20241021_2042.py b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241021_2042.py new file mode 100644 index 000000000..d550199fa --- /dev/null +++ b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241021_2042.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.5 on 2024-10-21 20:42 + +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, 21)), + ), + migrations.AlterUniqueTogether( + name='payments', + unique_together=set(), + ), + ] diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 4d12d800a..73edf2c10 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -787,7 +787,8 @@ def handleUpdateRequests(request): @permission_classes([IsAuthenticated]) def issueWorkOrder(request): obj = [] - desg = request.session.get('currentDesignationSelected') + params = request.query_params + desg = params.get('role') # Retrieve inbox files inbox_files = view_inbox( @@ -801,10 +802,10 @@ def issueWorkOrder(request): src_object_id = result['src_object_id'] request_object = Requests.objects.filter( id=src_object_id, - directorApproval=1, + # directorApproval=1, issuedWorkOrder=0 ).first() - + print(request_object, 11) if request_object: element = { "id": request_object.id, diff --git a/FusionIIIT/applications/online_cms/migrations/0002_auto_20241021_2042.py b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241021_2042.py new file mode 100644 index 000000000..19fbf8d5f --- /dev/null +++ b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241021_2042.py @@ -0,0 +1,40 @@ +# Generated by Django 3.1.5 on 2024-10-21 20:42 + +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_20241021_2042.py b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241021_2042.py new file mode 100644 index 000000000..2214841bb --- /dev/null +++ b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241021_2042.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.5 on 2024-10-21 20:42 + +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, 21)), + ), + ] From e2860d57f1a52040a972ccaf97a6f864b1b57fb9 Mon Sep 17 00:00:00 2001 From: Dhruv Ratmele <129955117+Somgester@users.noreply.github.com> Date: Wed, 23 Oct 2024 03:35:15 +0530 Subject: [PATCH 07/20] minor changes (#5) * minor changes * minor changes --- FusionIIIT/applications/iwdModuleV2/api/views.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 73edf2c10..0375e7a0f 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -571,8 +571,8 @@ def handle_dean_process_requests(request): @permission_classes([IsAuthenticated]) def dean_processed_requests(request): obj = [] - desg = request.session.get('currentDesignationSelected') - + params = request.query_params + desg = params.get('role') inbox_files = view_inbox( username=request.user.username, designation=desg, @@ -631,7 +631,7 @@ def handle_director_approval_requests(request): @permission_classes([IsAuthenticated]) def rejectedRequests(request): obj = [] - desg = request.session.get('currentDesignationSelected') + desg = request.query_params.get('role') # Fetch inbox files for the current user and designation inbox_files = view_inbox( @@ -682,8 +682,7 @@ def rejectedRequests(request): @permission_classes([IsAuthenticated]) def updateRejectedRequests(request): request_id = request.data.get("id", 0) - - desg = request.session.get('currentDesignationSelected') + desg = request.data.get("role", "") # Fetch the inbox files for the current user and designation inbox_files = view_inbox( From 543aa3cfc368eeba3186caa3db5df9ba4f46a1a1 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Wed, 23 Oct 2024 05:13:24 +0545 Subject: [PATCH 08/20] approve/reject and view file --- FusionIIIT/applications/iwdModuleV2/api/urls.py | 1 - .../applications/iwdModuleV2/api/views.py | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index 0c1dae50b..24ae97006 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -36,7 +36,6 @@ 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('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'), diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 0375e7a0f..9db3a1781 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -429,7 +429,8 @@ def created_requests_view(request): 'area': request_object.area, 'description': request_object.description, 'requestCreatedBy': request_object.requestCreatedBy, - 'file_id': file_obj.id + 'file_id': file_obj.id, + 'processed_by_director': request_object.directorApproval, } obj.append(element) @@ -552,7 +553,7 @@ def handle_dean_process_requests(request): remarks = data.get('remarks') attachment = request.FILES.get('attachment') - receiver_user, receiver_desg = data['designation'].split('|') + receiver_desg, receiver_user = data.get('designation').split('|') forward_file( file_id=fileid, @@ -573,6 +574,7 @@ def dean_processed_requests(request): obj = [] params = request.query_params desg = params.get('role') + inbox_files = view_inbox( username=request.user.username, designation=desg, @@ -581,16 +583,17 @@ def dean_processed_requests(request): for result in inbox_files: src_object_id = result['src_object_id'] - request_object = Requests.objects.filter(id=src_object_id).first() + request_object = Requests.objects.filter(id=src_object_id, directorApproval=0).first() file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") if request_object: element = { - 'id': request_object.id, + '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 + 'file_id': file_obj.id, + 'processed_by_director': request_object.directorApproval, } obj.append(element) @@ -604,8 +607,8 @@ def handle_director_approval_requests(request): 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('|') + attachment = request.FILES.get('file') + receiver_desg, receiver_user = data.get('designation').split('|') forward_file( file_id=fileid, From 4e8294733a7d14a8ac5810679891345f2a88362f Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Wed, 23 Oct 2024 11:13:44 +0545 Subject: [PATCH 09/20] fix: work order --- .../migrations/0003_merge_20241023_0545.py | 15 +++ .../iwdModuleV2/api/serializers.py | 2 +- .../applications/iwdModuleV2/api/views.py | 104 +++++++----------- .../migrations/0003_merge_20241023_0545.py | 15 +++ .../migrations/0003_merge_20241023_0545.py | 15 +++ 5 files changed, 87 insertions(+), 64 deletions(-) create mode 100644 FusionIIIT/applications/central_mess/migrations/0003_merge_20241023_0545.py create mode 100644 FusionIIIT/applications/online_cms/migrations/0003_merge_20241023_0545.py create mode 100644 FusionIIIT/applications/research_procedures/migrations/0003_merge_20241023_0545.py diff --git a/FusionIIIT/applications/central_mess/migrations/0003_merge_20241023_0545.py b/FusionIIIT/applications/central_mess/migrations/0003_merge_20241023_0545.py new file mode 100644 index 000000000..1312bc992 --- /dev/null +++ b/FusionIIIT/applications/central_mess/migrations/0003_merge_20241023_0545.py @@ -0,0 +1,15 @@ +# Generated by Django 3.1.5 on 2024-10-23 05:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('central_mess', '0002_auto_20241010_1836'), + ('central_mess', '0002_auto_20241021_2042'), + ('central_mess', '0002_auto_20241015_1451'), + ] + + operations = [ + ] diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index adeaad132..3488574f0 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -70,7 +70,7 @@ class Meta: class WorkOrderFormSerializer(serializers.ModelSerializer): class Meta: - model = WorkOrderForm + model = WorkOrder fields = '__all__' class AgreementSerializer(serializers.ModelSerializer): diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 9db3a1781..40fcf98ca 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -620,9 +620,10 @@ def handle_director_approval_requests(request): ) message = "" - + print(data) if data.get('action') == 'approve': message = "Request_approved" + print(message) Requests.objects.filter(id=request_id).update(directorApproval=1, status="Approved by the director") else: message = "Request_rejected" @@ -636,7 +637,6 @@ def rejectedRequests(request): obj = [] desg = request.query_params.get('role') - # Fetch inbox files for the current user and designation inbox_files = view_inbox( username=request.user, designation=desg, @@ -657,28 +657,9 @@ def rejectedRequests(request): } 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 + # Prepare and return the response with rejected requests 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']) @@ -739,17 +720,14 @@ def updateRejectedRequests(request): "holds_designations": holdsDesignations_data }, status=status.HTTP_200_OK) -@api_view(['POST']) +@api_view(['PATCH']) @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('|') + data = request.data + request_id = data.get("id", 0) + desg = data.get('role') + receiver_desg, receiver_user = data.get('designation').split('|') - # Update the request object Requests.objects.filter(id=request_id).update( name=request.data.get('name'), description=request.data.get('description'), @@ -765,8 +743,9 @@ def handleUpdateRequests(request): billProcessed=0, billSettled=0 ) - - # Create a file using the utility function + file_obj = File.objects.get(src_object_id=request_id, src_module="IWD") + if file_obj: + delete_file(file_obj.id) create_file( uploader=request.user.username, uploader_designation=desg, @@ -775,14 +754,12 @@ def handleUpdateRequests(request): src_module="IWD", src_object_id=str(request_id), file_extra_JSON={"value": 2}, - attached_file=None # Adjust if attachments are allowed + attached_file=None ) - # 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']) @@ -807,8 +784,7 @@ def issueWorkOrder(request): # directorApproval=1, issuedWorkOrder=0 ).first() - print(request_object, 11) - if request_object: + if request_object and request_object.directorApproval==1: element = { "id": request_object.id, "name": request_object.name, @@ -853,11 +829,13 @@ def fetchRequest(request): @permission_classes([IsAuthenticated]) def workOrder(request): # Retrieve data from request - request_id = request.data.get('id') + request_id = request.data.get('request_id') + print(request_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) + print(serializer) if serializer.is_valid(): # Create the WorkOrder instance with validated data work_order = serializer.save(request_id=request_instance) @@ -867,32 +845,32 @@ def workOrder(request): 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) + # # 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) + return Response(status=status.HTTP_200_OK) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) diff --git a/FusionIIIT/applications/online_cms/migrations/0003_merge_20241023_0545.py b/FusionIIIT/applications/online_cms/migrations/0003_merge_20241023_0545.py new file mode 100644 index 000000000..52edb4db8 --- /dev/null +++ b/FusionIIIT/applications/online_cms/migrations/0003_merge_20241023_0545.py @@ -0,0 +1,15 @@ +# Generated by Django 3.1.5 on 2024-10-23 05:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('online_cms', '0002_auto_20241010_1836'), + ('online_cms', '0002_auto_20241021_2042'), + ('online_cms', '0002_auto_20241015_1451'), + ] + + operations = [ + ] diff --git a/FusionIIIT/applications/research_procedures/migrations/0003_merge_20241023_0545.py b/FusionIIIT/applications/research_procedures/migrations/0003_merge_20241023_0545.py new file mode 100644 index 000000000..b62b06637 --- /dev/null +++ b/FusionIIIT/applications/research_procedures/migrations/0003_merge_20241023_0545.py @@ -0,0 +1,15 @@ +# Generated by Django 3.1.5 on 2024-10-23 05:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('research_procedures', '0002_auto_20241010_1836'), + ('research_procedures', '0002_auto_20241021_2042'), + ('research_procedures', '0002_auto_20241015_1451'), + ] + + operations = [ + ] From a5c89fd05cf738ce2a44eec356c23f81d40433c6 Mon Sep 17 00:00:00 2001 From: Abhijeet Patil <133658873+abhiJeetP10@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:41:14 +0530 Subject: [PATCH 10/20] Minor changes in addBudget and editBudget endpoints (#6) --- .../applications/iwdModuleV2/api/views.py | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 40fcf98ca..1056db0a4 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -1215,31 +1215,25 @@ def viewBudget(request): @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) + name = request.data.get('name') + budget_issued = request.data.get('budget') - return Response({'error': 'Invalid request method.'}, status=status.HTTP_400_BAD_REQUEST) + 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) @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 + 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) \ No newline at end of file From cb344e0ce840b66811ddde8a6729305a3ce89067 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Thu, 7 Nov 2024 20:25:53 +0530 Subject: [PATCH 11/20] fix : serializer --- .../iwdModuleV2/api/serializers.py | 17 ++++++++ .../applications/iwdModuleV2/api/views.py | 39 +++++++------------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index 3488574f0..d5607ff8b 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -127,4 +127,21 @@ def create(self, validated_data): validated_data['billSettled'] = 0 validated_data['requestCreatedBy'] = "" return super().create(validated_data) + +class RequestsInProgressSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'workCompleted'] + + def create(self, validated_data): + validated_data['engineerProcessed'] = 0 + validated_data['directorApproval'] = 0 + validated_data['deanProcessed'] = 0 + validated_data['status'] = "Pending" + validated_data['issuedWorkOrder'] = 0 + validated_data['workCompleted'] = 0 + validated_data['billGenerated'] = 0 + validated_data['billProcessed'] = 0 + validated_data['billSettled'] = 0 + return super().create(validated_data) \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 1056db0a4..fda483318 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -885,39 +885,30 @@ def requestsStatus(request): @permission_classes([IsAuthenticated]) def requestsInProgress(request): requestsObject = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) - serializer = RequestsSerializer(requestsObject, many=True) + serializer = RequestsInProgressSerializer(requestsObject, many=True) return Response({'obj': serializer.data}, status=200) -@api_view(['POST']) +@api_view(['PATCH']) @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") + return Response( + { + 'message': 'Work Completed', + }, + status=status.HTTP_200_OK + ) - # 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 +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def getCompletedWork(request): + requestsObject= Requests.objects.filter(workCompleted=1) + serializer = RequestsSerializer(requestsObject, many=True) return Response( { 'message': 'Work Completed', - 'data': obj + 'response': serializer, }, status=status.HTTP_200_OK ) @@ -996,7 +987,7 @@ 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: From e1d13be0ff4d83b26d7c4cbbf2d9f94617e36b13 Mon Sep 17 00:00:00 2001 From: Bhargavzz <133690080+Bhargavzz@users.noreply.github.com> Date: Thu, 14 Nov 2024 20:42:45 +0530 Subject: [PATCH 12/20] modified views related to audit document view (#7) * Added API folder in iwdModuleV2 * modified views related to audit document view --- FusionIIIT/applications/iwdModuleV2/api/views.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index fda483318..35b775c33 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -1088,9 +1088,13 @@ def handleProcessedBills(request): @api_view(['GET']) @permission_classes([IsAuthenticated]) def audit_document_view(request): - desg = request.session.get('currentDesignationSelected') + params = request.query_params + desg = params.get('role') + if not desg: + return Response({"error": "Designation not provided"}, status=status.HTTP_400_BAD_REQUEST) + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") - + obj = [ { 'requestId': x['src_object_id'], @@ -1100,9 +1104,10 @@ def audit_document_view(request): } for x in inbox_files ] - + return Response({'data': obj}, status=status.HTTP_200_OK) + @api_view(['POST']) @permission_classes([IsAuthenticated]) def audit_document(request): From de7a5b6dff510bc0672f4593f4c0ae8241cd6cc1 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Mon, 18 Nov 2024 18:09:52 +0530 Subject: [PATCH 13/20] fixed apis --- .../applications/iwdModuleV2/api/urls.py | 76 +- .../applications/iwdModuleV2/api/views.py | 855 ++++++++++-------- 2 files changed, 507 insertions(+), 424 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index 24ae97006..f6a70b7d9 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -1,8 +1,49 @@ from django.urls import path from . import views - +# TODO: handle-update-request should be available to the author before any review... new feature +# TODO: update-rejected-request should be used to updated the request data for rejected requests urlpatterns = [ - path('dashboard/', views.dashboard, name='dashboard'), + + # fully implemented + + # path('dashboard/', views.dashboard, name='dashboard'), + path('fetch-designations/', views.fetch_designations, name='fetch_designations'), + path('create-request/', views.create_request, name='create_request'), + path('created-requests/', views.created_requests, name='created_requests'), + path('view-file/', views.view_file, name='viewFile'), + path('dean-processed-requests/', views.dean_processed_requests, name='deanProcessedRequests'), + path('handle-director-approval-requests/', views.handle_director_approval, name='handle_director_approval'), + path('rejected-requests-view/', views.rejected_requests, name='rejectedRequests'), + path('handle-update-requests/', views.handle_update_requests, name='handleUpdateRequests'), + path('director-approved-requests/', views.director_approved_requests, name='issueWorkOrder'), + path('issue-work-order/', views.issue_work_order, name='workOrder'), + path('requests-in-progress/', views.requests_in_progress, name='requestsInProgress'), + path('work-completed/', views.work_completed, name='workCompleted'), + path('view-budget/', views.view_budget, name='viewBudget'), + path('add-budget/', views.add_budget, name='addBudget'), + path('edit-budget/', views.edit_budget, name='editBudget'), + + # partially integrated on frontend + + path('engineer-processed-requests/', views.engineer_processed_requests, name='engineerProcessedRequests'), + path('handle-engineer-process-requests/', views.handleEngineerProcessRequests, name='handleEngineerProcessRequests'), + path('handle-dean-process-requests/', views.handle_dean_process_requests, name='handleDeanProcessRequests'), + path('update-rejected-requests/', views.updateRejectedRequests, name='updateRejectedRequests'), + path('requests-status/', views.requestsStatus, name='requestsStatus'), + path('fetch-request/', views.fetchRequest, name='fetchRequest'), + 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'), + + # Unsure about use or depricated + + path('work-order-form/', views.workOrderForm, name='workOrderForm'), + path('work-order-form-view/', views.workOrderFormView, name='workOrderFormView'), path('page1-1/', views.page1_1, name='page1_1'), path('aes-form/', views.AESForm, name='AESForm'), path('page2-1/', views.page2_1, name='page2_1'), @@ -13,7 +54,6 @@ path('technical-bid-form/', views.TechnicalBidForm, name='TechnicalBidForm'), path('no-of-entries-financial-bid/', views.noOfEntriesFinancialBid, name='noOfEntriesFinancialBid'), path('letter-of-intent/', views.letterOfIntent, name='letterOfIntent'), - 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'), @@ -27,39 +67,9 @@ path('corrigendum-view/', views.corrigendumView, name='corrigendumView'), path('addendum-view/', views.addendumView, name='addendumView'), path('letter-of-intent-view/', views.letterOfIntentView, name='letterOfIntentView'), - path('work-order-form-view/', views.workOrderFormView, name='workOrderFormView'), path('agreement-view/', views.agreementView, name='agreementView'), 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('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'), - 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('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 35b775c33..aba9a1644 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -18,12 +18,452 @@ from django.http import HttpResponse from django.core.exceptions import ObjectDoesNotExist +# @api_view(['GET']) +# def dashboard(request): +# userObj = request.user +# userDesignationObjects = HoldsDesignation.objects.filter(user=userObj) +# eligible = any(p.designation.name == 'Admin IWD' for p in userDesignationObjects) +# return Response({'eligible': eligible}) + +''' + Fully Implemented +''' + @api_view(['GET']) -def dashboard(request): - userObj = request.user - userDesignationObjects = HoldsDesignation.objects.filter(user=userObj) - eligible = any(p.designation.name == 'Admin IWD' for p in userDesignationObjects) - return Response({'eligible': eligible}) +@permission_classes([IsAuthenticated]) +def fetch_designations(request): + ''' + to return a list of cincerned designations in the module's scope + ''' + 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 create_request(request): + + ''' + to create a new request + ''' + + data = request.data + serializer = RequestsSerializer(data=data, context={'request': request}) + + if serializer.is_valid(): + formObject = serializer.save() + print(formObject) + request_object = Requests.objects.get(pk=formObject.pk) + receiver_desg, receiver_user = data.get('designation').split('|') + try: + receiver_user_obj = User.objects.get(username=receiver_user) + except User.DoesNotExist: + return Response({'error': 'Receiver user does not exist'}, status=status.HTTP_400_BAD_REQUEST) + create_file( + uploader=request.user.username, + uploader_designation=data.get('role'), + 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 + ) + + + iwd_notif(request.user, receiver_user_obj, "Request_added") + + return Response({'message': "Request Successfully Created"}, status=status.HTTP_201_CREATED) + + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def created_requests(request): + + ''' + to get a list of requests in current user's inbox + ''' + + params = request.query_params + obj = [] + inbox_files = view_inbox( + username=request.user, + designation=params.get('role'), + 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() + if request_object: + file_obj = get_object_or_404(File, src_object_id=request_object.id, src_module="IWD") + 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, + 'processed_by_director': request_object.directorApproval, + } + obj.append(element) + + return Response(obj, status=200) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def view_file(request): + + ''' + get complete file data and track records + ''' + + params = request.query_params + id = params.get('file_id') + print(id) + file1 = get_object_or_404(File, id=id) + + tracks = Tracking.objects.filter(file_id=file1) + + eligible = request.session.get('currentDesignationSelected') + + file_serializer = FileSerializer(file1) + tracks_serializer = TrackingSerializer(tracks, many=True) + return Response({ + "file": file_serializer.data, + "tracks": tracks_serializer.data, + "url": "url", + "eligible": eligible + }, status=200) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def dean_processed_requests(request): + + ''' + to get requests that have been processed through the dean and are ready for director's approval + ''' + + obj = [] + params = request.query_params + desg = params.get('role') + + 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, directorApproval=0).first() + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + if request_object: + 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, + 'processed_by_director': request_object.directorApproval, + } + obj.append(element) + + return Response(obj) + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_director_approval(request): + + ''' + approve or reject file based on director's action + ''' + + 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('file') + receiver_desg, receiver_user = data.get('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 = "" + print(data) + if data.get('action') == 'approve': + message = "Request_approved" + print(message) + 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 rejected_requests(request): + + ''' + get requests rejected by director (-1) + ''' + + obj = [] + desg = request.query_params.get('role') + + inbox_files = view_inbox( + username=request.user, + 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, 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) + + return Response({ + "rejected_requests": obj, + }, status=status.HTTP_200_OK) + + +@api_view(['PATCH']) +@permission_classes([IsAuthenticated]) +def handle_update_requests(request): + + ''' + to update an old request(delete and make a new one) + ''' + + data = request.data + request_id = data.get("id", 0) + desg = data.get('role') + receiver_desg, receiver_user = data.get('designation').split('|') + + 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 + ) + file_obj = File.objects.get(src_object_id=request_id, src_module="IWD") + if file_obj: + delete_file(file_obj.id) + 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 + ) + + receiver_user_obj = User.objects.get(username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "Request_added") + + return Response({"message": "Request updated successfully"}, status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def director_approved_requests(request): + + ''' + requests approved by director and can issue work order + ''' + + obj = [] + params = request.query_params + desg = params.get('role') + + inbox_files = view_inbox( + username=request.user, + 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, + directorApproval=1, + issuedWorkOrder=0 + ).first() + if request_object and request_object.directorApproval==1: + 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 Response({"requests": obj}, status=status.HTTP_200_OK) + + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def issue_work_order(request): + + ''' + issue work order + ''' + + request_id = request.data.get('request_id') + print(request_id) + request_instance = get_object_or_404(Requests, pk=request_id) + + serializer = WorkOrderFormSerializer(data=request.data) + print(serializer) + if serializer.is_valid(): + work_order = serializer.save(request_id=request_instance) + + request_instance.status = "Work Order issued" + request_instance.issuedWorkOrder = 1 + request_instance.save() + + messages.success(request, "Work Order Issued") + return Response(status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def requests_in_progress(request): + + ''' + work order issued but not completed + ''' + + requestsObject = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) + serializer = RequestsInProgressSerializer(requestsObject, many=True) + return Response({'obj': serializer.data}, status=200) + + + +@api_view(['PATCH']) +@permission_classes([IsAuthenticated]) +def work_completed(request): + + ''' + to mark the work as completed + ''' + + request_id = request.data.get('id') + Requests.objects.filter(id=request_id).update(workCompleted=1, status="Work Completed") + return Response( + { + 'message': 'Work Completed', + }, + status=status.HTTP_200_OK + ) + + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def view_budget(request): + + ''' + view budget list + ''' + + 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 add_budget(request): + ''' + add new budget + ''' + 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) + + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def edit_budget(request): + + ''' + edit an existing budget + ''' + + 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) + + + @api_view(['POST']) def page1_1(request): @@ -334,145 +774,44 @@ def agreementView(request): @api_view(['GET']) def milestoneView(request): - milestoneObjects = Milestones.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) - serializer = MilestonesSerializer(milestoneObjects, many=True) - return Response({'milestones': serializer.data}, status=status.HTTP_200_OK) - -@api_view(['GET']) -def page3View(request): - try: - pageThreeDetails = PageThreeDetails.objects.get(key=Projects.objects.get(id=request.session['projectId'])) - serializer = PageThreeDetailsSerializer(pageThreeDetails) - return Response({'pageThreeDetails': serializer.data}, status=status.HTTP_200_OK) - except PageThreeDetails.DoesNotExist: - return Response({'error': 'Page Three Details not found.'}, status=status.HTTP_404_NOT_FOUND) - -@api_view(['GET']) -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 - serializer = RequestsSerializer(data=data, context={'request': request}) - - if serializer.is_valid(): - formObject = serializer.save() - print(formObject) - request_object = Requests.objects.get(pk=formObject.pk) - receiver_desg, receiver_user = data.get('designation').split('|') - try: - receiver_user_obj = User.objects.get(username=receiver_user) - except User.DoesNotExist: - return Response({'error': 'Receiver user does not exist'}, status=status.HTTP_400_BAD_REQUEST) - create_file( - uploader=request.user.username, - uploader_designation=data.get('role'), - 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 - ) - - - # 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"}, status=status.HTTP_201_CREATED) - - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -def created_requests_view(request): - # print("REQUESTT:", request) - params = request.query_params - obj = [] - inbox_files = view_inbox( - username=request.user, - designation=params.get('role'), - 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() - if request_object: - file_obj = get_object_or_404(File, src_object_id=request_object.id, src_module="IWD") - 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, - 'processed_by_director': request_object.directorApproval, - } - obj.append(element) + milestoneObjects = Milestones.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = MilestonesSerializer(milestoneObjects, many=True) + return Response({'milestones': serializer.data}, status=status.HTTP_200_OK) - return Response(obj, status=200) +@api_view(['GET']) +def page3View(request): + try: + pageThreeDetails = PageThreeDetails.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = PageThreeDetailsSerializer(pageThreeDetails) + return Response({'pageThreeDetails': serializer.data}, status=status.HTTP_200_OK) + except PageThreeDetails.DoesNotExist: + return Response({'error': 'Page Three Details not found.'}, status=status.HTTP_404_NOT_FOUND) @api_view(['GET']) -@permission_classes([IsAuthenticated]) -def view_file_api(request): - params = request.query_params - id = params.get('file_id') - print(id) - file1 = get_object_or_404(File, id=id) +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"] + + - tracks = Tracking.objects.filter(file_id=file1) - eligible = request.session.get('currentDesignationSelected') - file_serializer = FileSerializer(file1) - tracks_serializer = TrackingSerializer(tracks, many=True) - return Response({ - "file": file_serializer.data, - "tracks": tracks_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, @@ -482,10 +821,8 @@ def handleEngineerProcessRequests(request): 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") @@ -568,99 +905,12 @@ def handle_dean_process_requests(request): return Response({'message': 'File Forwarded'}, status=200) -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -def dean_processed_requests(request): - obj = [] - params = request.query_params - desg = params.get('role') - - 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, directorApproval=0).first() - file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") - if request_object: - 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, - 'processed_by_director': request_object.directorApproval, - } - 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('file') - receiver_desg, receiver_user = data.get('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 = "" - print(data) - if data.get('action') == 'approve': - message = "Request_approved" - print(message) - 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): - obj = [] - desg = request.query_params.get('role') - 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) - # Prepare and return the response with rejected requests - return Response({ - "rejected_requests": obj, - }, status=status.HTTP_200_OK) @api_view(['POST']) @permission_classes([IsAuthenticated]) @@ -720,82 +970,8 @@ def updateRejectedRequests(request): "holds_designations": holdsDesignations_data }, status=status.HTTP_200_OK) -@api_view(['PATCH']) -@permission_classes([IsAuthenticated]) -def handleUpdateRequests(request): - data = request.data - request_id = data.get("id", 0) - desg = data.get('role') - receiver_desg, receiver_user = data.get('designation').split('|') - - 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 - ) - file_obj = File.objects.get(src_object_id=request_id, src_module="IWD") - if file_obj: - delete_file(file_obj.id) - 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 - ) - - receiver_user_obj = User.objects.get(username=receiver_user) - iwd_notif(request.user, receiver_user_obj, "Request_added") - - return Response({"message": "Request updated successfully"}, status=status.HTTP_200_OK) - -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -def issueWorkOrder(request): - obj = [] - params = request.query_params - desg = params.get('role') - - # 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 and request_object.directorApproval==1: - 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]) @@ -825,54 +1001,7 @@ def fetchRequest(request): 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('request_id') - print(request_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) - print(serializer) - 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(status=status.HTTP_200_OK) - else: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @api_view(['GET']) @permission_classes([IsAuthenticated]) @@ -881,24 +1010,7 @@ def requestsStatus(request): 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 = RequestsInProgressSerializer(requestsObject, many=True) - return Response({'obj': serializer.data}, status=200) -@api_view(['PATCH']) -@permission_classes([IsAuthenticated]) -def work_completed(request): - request_id = request.data.get('id') - Requests.objects.filter(id=request_id).update(workCompleted=1, status="Work Completed") - return Response( - { - 'message': 'Work Completed', - }, - status=status.HTTP_200_OK - ) @api_view(['GET']) @permission_classes([IsAuthenticated]) @@ -1192,44 +1304,5 @@ def handle_settle_bill_requests(request): return Response({'error': 'Request ID not provided'}, status=status.HTTP_400_BAD_REQUEST) -@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): - 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) -@api_view(['POST']) -@permission_classes([IsAuthenticated]) -def editBudget(request): - 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) \ No newline at end of file From de9680866166048b831217753c9e607360f05d40 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Tue, 19 Nov 2024 00:11:29 +0530 Subject: [PATCH 14/20] fix: serializer overriding requestCreatedBdBy value --- .../iwdModuleV2/api/serializers.py | 140 +++++++++--------- .../applications/iwdModuleV2/api/urls.py | 3 +- .../applications/iwdModuleV2/api/views.py | 39 ++++- 3 files changed, 104 insertions(+), 78 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index d5607ff8b..5e040b15d 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -3,71 +3,6 @@ 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 = WorkOrder @@ -105,15 +40,11 @@ class HoldsDesignationSerializer(serializers.ModelSerializer): class Meta: model = HoldsDesignation fields = ['id', 'designation', 'username'] -# class RequestsSerializer(serializers.ModelSerializer): -# class Meta: -# model = Requests -# fields = ['name', 'description', 'area'] class RequestsSerializer(serializers.ModelSerializer): class Meta: model = Requests - fields = ['id', 'name', 'area', 'description'] + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy'] def create(self, validated_data): validated_data['engineerProcessed'] = 0 @@ -125,7 +56,6 @@ def create(self, validated_data): validated_data['billGenerated'] = 0 validated_data['billProcessed'] = 0 validated_data['billSettled'] = 0 - validated_data['requestCreatedBy'] = "" return super().create(validated_data) class RequestsInProgressSerializer(serializers.ModelSerializer): @@ -144,4 +74,70 @@ def create(self, validated_data): validated_data['billProcessed'] = 0 validated_data['billSettled'] = 0 return super().create(validated_data) - \ No newline at end of file + + + +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__' \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index f6a70b7d9..86ff0c4c6 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -22,6 +22,7 @@ path('view-budget/', views.view_budget, name='viewBudget'), path('add-budget/', views.add_budget, name='addBudget'), path('edit-budget/', views.edit_budget, name='editBudget'), + path('requests-status/', views.requests_status, name='requestsStatus'), # partially integrated on frontend @@ -29,7 +30,7 @@ path('handle-engineer-process-requests/', views.handleEngineerProcessRequests, name='handleEngineerProcessRequests'), path('handle-dean-process-requests/', views.handle_dean_process_requests, name='handleDeanProcessRequests'), path('update-rejected-requests/', views.updateRejectedRequests, name='updateRejectedRequests'), - path('requests-status/', views.requestsStatus, name='requestsStatus'), + path('get-all-requests/', views.getAllRequests, name='requestsStatus'), path('fetch-request/', views.fetchRequest, name='fetchRequest'), path('generate-final-bill/', views.generateFinalBill, name='generateFinalBill'), path('handle-bill-generated-requests/', views.handleBillGeneratedRequests, name='handleBillGeneratedRequests'), diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index aba9a1644..99625ed3d 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -53,13 +53,13 @@ def create_request(request): ''' to create a new request ''' - data = request.data + data['requestCreatedBy'] = request.user.username serializer = RequestsSerializer(data=data, context={'request': request}) if serializer.is_valid(): formObject = serializer.save() - print(formObject) + print(formObject.requestCreatedBy) request_object = Requests.objects.get(pk=formObject.pk) receiver_desg, receiver_user = data.get('designation').split('|') try: @@ -462,6 +462,36 @@ def edit_budget(request): else: return Response({'error': 'ID, name, and budget are required.'}, status=status.HTTP_400_BAD_REQUEST) +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def requests_status(request): + + ''' + this api will get status of all the requests in outbox of user + ''' + + params = request.query_params + desg = params.get('role') + outbox_files = view_outbox(username=request.user, designation=desg, src_module="IWD") + obj = [] + for result in outbox_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") + print(request_object) + if request_object: + 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, + 'processed_by_director': request_object.directorApproval, + } + obj.append(element) + return Response(obj, status=200) + @@ -842,11 +872,10 @@ def handleEngineerProcessRequests(request): } 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 @@ -1005,7 +1034,7 @@ def fetchRequest(request): @api_view(['GET']) @permission_classes([IsAuthenticated]) -def requestsStatus(request): +def getAllRequests(request): requestsObject = Requests.objects.all() serializer = RequestsSerializer(requestsObject, many=True) return Response({'obj': serializer.data}, status=200) From 447308d65c30ffb21ed11d68a181e63ef9b5624a Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Tue, 19 Nov 2024 00:11:29 +0530 Subject: [PATCH 15/20] fix: serializer overriding requestCreatedBdBy value --- .../applications/iwdModuleV2/api/views.py | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 99625ed3d..ed3c1f7a7 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -55,6 +55,7 @@ def create_request(request): ''' data = request.data data['requestCreatedBy'] = request.user.username + data['requestCreatedBy'] = request.user.username serializer = RequestsSerializer(data=data, context={'request': request}) if serializer.is_valid(): @@ -462,36 +463,6 @@ def edit_budget(request): else: return Response({'error': 'ID, name, and budget are required.'}, status=status.HTTP_400_BAD_REQUEST) -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -def requests_status(request): - - ''' - this api will get status of all the requests in outbox of user - ''' - - params = request.query_params - desg = params.get('role') - outbox_files = view_outbox(username=request.user, designation=desg, src_module="IWD") - obj = [] - for result in outbox_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") - print(request_object) - if request_object: - 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, - 'processed_by_director': request_object.directorApproval, - } - obj.append(element) - return Response(obj, status=200) - From 093080068ce51ac61e172c5275c3032c49aec01b Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Tue, 19 Nov 2024 01:30:53 +0530 Subject: [PATCH 16/20] fix api --- .../applications/iwdModuleV2/api/views.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index ed3c1f7a7..cdf866cb4 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -463,6 +463,37 @@ def edit_budget(request): else: return Response({'error': 'ID, name, and budget are required.'}, status=status.HTTP_400_BAD_REQUEST) +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def requests_status(request): + + ''' + this api will get status of all the requests in outbox of user + ''' + + params = request.query_params + desg = params.get('role') + outbox_files = view_outbox(username=request.user, designation=desg, src_module="IWD") + obj = [] + for result in outbox_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") + print(request_object) + if request_object: + 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, + 'processed_by_director': request_object.directorApproval, + 'status': request_object.status, + } + obj.append(element) + return Response(obj, status=200) + From bfe1e254bdbbca840ecde2567dd7d6642870ff83 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Tue, 19 Nov 2024 06:21:42 +0530 Subject: [PATCH 17/20] chore: made handlers consistent --- FusionIIIT/applications/iwdModuleV2/api/views.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index cdf866cb4..93bb72d59 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -251,9 +251,7 @@ def rejected_requests(request): } obj.append(element) - return Response({ - "rejected_requests": obj, - }, status=status.HTTP_200_OK) + return Response(obj, status=status.HTTP_200_OK) @api_view(['PATCH']) @@ -339,7 +337,7 @@ def director_approved_requests(request): } obj.append(element) - return Response({"requests": obj}, status=status.HTTP_200_OK) + return Response(obj, status=status.HTTP_200_OK) @@ -381,7 +379,7 @@ def requests_in_progress(request): requestsObject = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) serializer = RequestsInProgressSerializer(requestsObject, many=True) - return Response({'obj': serializer.data}, status=200) + return Response(serializer.data, status=200) From 5c0ac8b97643d1c5b7a2fd5e3f763667c2af57e8 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Wed, 20 Nov 2024 22:42:27 +0530 Subject: [PATCH 18/20] major fixes --- .../iwdModuleV2/api/serializers.py | 27 +- .../applications/iwdModuleV2/api/urls.py | 78 ++- .../applications/iwdModuleV2/api/views.py | 574 +++++++----------- FusionIIIT/applications/iwdModuleV2/models.py | 7 +- 4 files changed, 267 insertions(+), 419 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index 5e040b15d..1b4e04b4a 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -41,7 +41,7 @@ class Meta: model = HoldsDesignation fields = ['id', 'designation', 'username'] -class RequestsSerializer(serializers.ModelSerializer): +class CreateRequestsSerializer(serializers.ModelSerializer): class Meta: model = Requests fields = ['id', 'name', 'area', 'description', 'requestCreatedBy'] @@ -58,24 +58,21 @@ def create(self, validated_data): validated_data['billSettled'] = 0 return super().create(validated_data) -class RequestsInProgressSerializer(serializers.ModelSerializer): +class DirectorApprovedRequestsSerializer(serializers.ModelSerializer): class Meta: model = Requests - fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'workCompleted'] + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy'] + +class WorkUnderProgressSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'issuedWorkOrder', 'workCompleted'] - def create(self, validated_data): - validated_data['engineerProcessed'] = 0 - validated_data['directorApproval'] = 0 - validated_data['deanProcessed'] = 0 - validated_data['status'] = "Pending" - validated_data['issuedWorkOrder'] = 0 - validated_data['workCompleted'] = 0 - validated_data['billGenerated'] = 0 - validated_data['billProcessed'] = 0 - validated_data['billSettled'] = 0 - return super().create(validated_data) - +class RequestsInProgressSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'issuedWorkOrder', 'workCompleted'] class PageOneDetailsSerializer(serializers.ModelSerializer): class Meta: diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index 86ff0c4c6..8eb4f67e8 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -1,76 +1,70 @@ from django.urls import path from . import views -# TODO: handle-update-request should be available to the author before any review... new feature -# TODO: update-rejected-request should be used to updated the request data for rejected requests urlpatterns = [ # fully implemented - # path('dashboard/', views.dashboard, name='dashboard'), + path('fetch-designations/', views.fetch_designations, name='fetch_designations'), path('fetch-designations/', views.fetch_designations, name='fetch_designations'), path('create-request/', views.create_request, name='create_request'), path('created-requests/', views.created_requests, name='created_requests'), - path('view-file/', views.view_file, name='viewFile'), - path('dean-processed-requests/', views.dean_processed_requests, name='deanProcessedRequests'), - path('handle-director-approval-requests/', views.handle_director_approval, name='handle_director_approval'), + path('view-file/', views.view_file, name='view_file'), + path('dean-processed-requests/', views.dean_processed_requests, name='dean_processed_requests'), + path('handle-director-approval/', views.handle_director_approval, name='handle_director_approval'), + path('handle-dean-process-request/', views.handle_dean_process_request, name='handleDeanProcessRequests'), path('rejected-requests-view/', views.rejected_requests, name='rejectedRequests'), path('handle-update-requests/', views.handle_update_requests, name='handleUpdateRequests'), path('director-approved-requests/', views.director_approved_requests, name='issueWorkOrder'), path('issue-work-order/', views.issue_work_order, name='workOrder'), path('requests-in-progress/', views.requests_in_progress, name='requestsInProgress'), + path('work-under-progress/', views.work_under_progress, name='workUnderProgress'), path('work-completed/', views.work_completed, name='workCompleted'), path('view-budget/', views.view_budget, name='viewBudget'), path('add-budget/', views.add_budget, name='addBudget'), path('edit-budget/', views.edit_budget, name='editBudget'), path('requests-status/', views.requests_status, name='requestsStatus'), + path('audit-document-view/', views.audit_document_view, name='auditDocumentView'), + path('audit-document/', views.handle_audit_document, name='auditDocument'), # partially integrated on frontend + path('handle-process-bills/', views.handle_process_bills, name='handleProcessedBills'), path('engineer-processed-requests/', views.engineer_processed_requests, name='engineerProcessedRequests'), path('handle-engineer-process-requests/', views.handleEngineerProcessRequests, name='handleEngineerProcessRequests'), - path('handle-dean-process-requests/', views.handle_dean_process_requests, name='handleDeanProcessRequests'), - path('update-rejected-requests/', views.updateRejectedRequests, name='updateRejectedRequests'), - path('get-all-requests/', views.getAllRequests, name='requestsStatus'), - path('fetch-request/', views.fetchRequest, name='fetchRequest'), 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'), # Unsure about use or depricated - path('work-order-form/', views.workOrderForm, name='workOrderForm'), - path('work-order-form-view/', views.workOrderFormView, name='workOrderFormView'), - path('page1-1/', views.page1_1, name='page1_1'), - path('aes-form/', views.AESForm, name='AESForm'), - path('page2-1/', views.page2_1, name='page2_1'), - path('corrigendum-input/', views.corrigendumInput, name='corrigendumInput'), - path('addendum-input/', views.addendumInput, name='addendumInput'), - path('pre-bid-form/', views.PreBidForm, name='PreBidForm'), - path('no-of-entries-technical-bid/', views.noOfEntriesTechnicalBid, name='noOfEntriesTechnicalBid'), - path('technical-bid-form/', views.TechnicalBidForm, name='TechnicalBidForm'), - path('no-of-entries-financial-bid/', views.noOfEntriesFinancialBid, name='noOfEntriesFinancialBid'), - path('letter-of-intent/', views.letterOfIntent, name='letterOfIntent'), - path('agreement-input/', views.AgreementInput, name='AgreementInput'), - path('milestones-form/', views.milestonesForm, name='milestonesForm'), - 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'), - path('aes-view/', views.AESView, name='AESView'), - path('financial-bid-view/', views.financialBidView, name='financialBidView'), - path('technical-bid-view/', views.technicalBidView, name='technicalBidView'), - path('pre-bid-details-view/', views.preBidDetailsView, name='preBidDetailsView'), - path('corrigendum-view/', views.corrigendumView, name='corrigendumView'), - path('addendum-view/', views.addendumView, name='addendumView'), - path('letter-of-intent-view/', views.letterOfIntentView, name='letterOfIntentView'), - path('agreement-view/', views.agreementView, name='agreementView'), - path('milestone-view/', views.milestoneView, name='milestoneView'), - path('page3-view/', views.page3View, name='page3View'), - path('extension-form-view/', views.extensionFormView, name='extensionFormView'), + # path('page1-1/', views.page1_1, name='page1_1'), + # path('aes-form/', views.AESForm, name='AESForm'), + # path('page2-1/', views.page2_1, name='page2_1'), + # path('corrigendum-input/', views.corrigendumInput, name='corrigendumInput'), + # path('addendum-input/', views.addendumInput, name='addendumInput'), + # path('pre-bid-form/', views.PreBidForm, name='PreBidForm'), + # path('no-of-entries-technical-bid/', views.noOfEntriesTechnicalBid, name='noOfEntriesTechnicalBid'), + # path('technical-bid-form/', views.TechnicalBidForm, name='TechnicalBidForm'), + # path('no-of-entries-financial-bid/', views.noOfEntriesFinancialBid, name='noOfEntriesFinancialBid'), + # path('letter-of-intent/', views.letterOfIntent, name='letterOfIntent'), + # path('agreement-input/', views.AgreementInput, name='AgreementInput'), + # path('milestones-form/', views.milestonesForm, name='milestonesForm'), + # 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'), + # path('aes-view/', views.AESView, name='AESView'), + # path('financial-bid-view/', views.financialBidView, name='financialBidView'), + # path('technical-bid-view/', views.technicalBidView, name='technicalBidView'), + # path('pre-bid-details-view/', views.preBidDetailsView, name='preBidDetailsView'), + # path('corrigendum-view/', views.corrigendumView, name='corrigendumView'), + # path('addendum-view/', views.addendumView, name='addendumView'), + # path('letter-of-intent-view/', views.letterOfIntentView, name='letterOfIntentView'), + # path('agreement-view/', views.agreementView, name='agreementView'), + # path('milestone-view/', views.milestoneView, name='milestoneView'), + # path('page3-view/', views.page3View, name='page3View'), + # path('extension-form-view/', views.extensionFormView, name='extensionFormView'), ] diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 93bb72d59..2f9efb3a4 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -56,7 +56,7 @@ def create_request(request): data = request.data data['requestCreatedBy'] = request.user.username data['requestCreatedBy'] = request.user.username - serializer = RequestsSerializer(data=data, context={'request': request}) + serializer = CreateRequestsSerializer(data=data, context={'request': request}) if serializer.is_valid(): formObject = serializer.save() @@ -113,7 +113,7 @@ def created_requests(request): 'description': request_object.description, 'requestCreatedBy': request_object.requestCreatedBy, 'file_id': file_obj.id, - 'processed_by_director': request_object.directorApproval, + 'directorApproval': request_object.directorApproval, } obj.append(element) @@ -134,15 +134,12 @@ def view_file(request): tracks = Tracking.objects.filter(file_id=file1) - eligible = request.session.get('currentDesignationSelected') - file_serializer = FileSerializer(file1) tracks_serializer = TrackingSerializer(tracks, many=True) return Response({ "file": file_serializer.data, "tracks": tracks_serializer.data, "url": "url", - "eligible": eligible }, status=200) @api_view(['GET']) @@ -175,19 +172,47 @@ def dean_processed_requests(request): 'description': request_object.description, 'requestCreatedBy': request_object.requestCreatedBy, 'file_id': file_obj.id, - 'processed_by_director': request_object.directorApproval, + 'directorApproval': request_object.directorApproval, } obj.append(element) return Response(obj) +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_dean_process_request(request): + + ''' + This api is made for the dean to process and forward the 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_desg, receiver_user = data.get('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", directorApproval=0) + + return Response({'message': 'File Forwarded'}, status=200) @api_view(['POST']) @permission_classes([IsAuthenticated]) def handle_director_approval(request): ''' - approve or reject file based on director's action + This api is to approve or reject file based on director's action ''' data = request.data @@ -198,6 +223,9 @@ def handle_director_approval(request): attachment = request.FILES.get('file') receiver_desg, receiver_user = data.get('designation').split('|') + if not fileid: + return Response({'error': 'File ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + forward_file( file_id=fileid, receiver=receiver_user, @@ -219,6 +247,36 @@ def handle_director_approval(request): return Response({'message': message}) +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_audit_document(request): + + ''' + This api is used to audit bill documents (with provided fileid) + ''' + + fileid = request.data.get('fileid') + remarks = request.data.get('remarks') + attachment = request.FILES.get('attachment') + receiver_desg, receiver_user = 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") + + return Response("Bill Audited", status=status.HTTP_200_OK) + + return Response({'error': 'File ID not provided'}, status=status.HTTP_400_BAD_REQUEST) @api_view(['GET']) @@ -240,6 +298,8 @@ def rejected_requests(request): for result in inbox_files: src_object_id = result['src_object_id'] + if src_object_id==None: + continue request_object = Requests.objects.filter(id=src_object_id, directorApproval=-1).first() if request_object: element = { @@ -254,16 +314,15 @@ def rejected_requests(request): return Response(obj, status=status.HTTP_200_OK) -@api_view(['PATCH']) +@api_view(['POST']) @permission_classes([IsAuthenticated]) def handle_update_requests(request): ''' to update an old request(delete and make a new one) ''' - data = request.data - request_id = data.get("id", 0) + request_id = data.get("id") desg = data.get('role') receiver_desg, receiver_user = data.get('designation').split('|') @@ -282,20 +341,27 @@ def handle_update_requests(request): billProcessed=0, billSettled=0 ) - file_obj = File.objects.get(src_object_id=request_id, src_module="IWD") - if file_obj: - delete_file(file_obj.id) - 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 - ) + try: + file_obj = File.objects.get(src_object_id=request_id, src_module="IWD") + if file_obj: + delete_file(file_obj.id) + except: + print("file doesnt exist") + if request_id: + 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 + ) + else: + print("request id is invalid") + receiver_user_obj = User.objects.get(username=receiver_user) iwd_notif(request.user, receiver_user_obj, "Request_added") @@ -309,36 +375,11 @@ def director_approved_requests(request): ''' requests approved by director and can issue work order ''' - - obj = [] - params = request.query_params - desg = params.get('role') - - inbox_files = view_inbox( - username=request.user, - 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, - directorApproval=1, - issuedWorkOrder=0 - ).first() - if request_object and request_object.directorApproval==1: - 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 Response(obj, status=status.HTTP_200_OK) + requestsObject = Requests.objects.filter(directorApproval=1, issuedWorkOrder=0) + serializer = DirectorApprovedRequestsSerializer(requestsObject, many=True) + print(serializer.data) + return Response(serializer.data, status=status.HTTP_200_OK) @api_view(['POST']) @@ -350,9 +391,7 @@ def issue_work_order(request): ''' request_id = request.data.get('request_id') - print(request_id) request_instance = get_object_or_404(Requests, pk=request_id) - serializer = WorkOrderFormSerializer(data=request.data) print(serializer) if serializer.is_valid(): @@ -367,7 +406,35 @@ def issue_work_order(request): else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def work_under_progress(request): + + ''' + This api is used to get all requests under progress + ''' + + obj = [] + requestsObject = Requests.objects.filter(issuedWorkOrder=1, workCompleted=0) + serializer = WorkUnderProgressSerializer(requestsObject, many=True) + print(serializer.data) + for result in serializer.data: + src_object_id = result['id'] + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + if file_obj: + element = { + 'id': result['id'], + 'file_id': file_obj.id, + 'name': result['name'], + 'area': result['area'], + 'description': result['description'], + 'issuedWorkOrder': result['issuedWorkOrder'], + 'workCompleted': result['workCompleted'], + 'requestCreatedBy': result['requestCreatedBy'] + } + obj.append(element) + return Response(obj, status=status.HTTP_200_OK) @api_view(['GET']) @permission_classes([IsAuthenticated]) @@ -377,7 +444,7 @@ def requests_in_progress(request): work order issued but not completed ''' - requestsObject = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) + requestsObject = Requests.objects.filter(issuedWorkOrder=1) serializer = RequestsInProgressSerializer(requestsObject, many=True) return Response(serializer.data, status=200) @@ -493,6 +560,82 @@ def requests_status(request): return Response(obj, status=200) +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def audit_document_view(request): + + ''' + This api is used to get a list of all the bills those are required to be audited + ''' + + params = request.query_params + desg = params.get('role') + if not desg: + return Response({"error": "Designation not provided"}, status=status.HTTP_400_BAD_REQUEST) + + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [] + for x in inbox_files: + try: + bill = Bills.objects.get(request_id=x['src_object_id']) # Efficient single query + file_obj = File.objects.get(src_object_id=x['src_object_id'], src_module="IWD") # Ensure this object exists + obj.append({ + 'request_id': x['src_object_id'], + 'file': bill.file, + 'fileUrl': bill.file.url, + 'file_id': file_obj.id + }) + except Bills.DoesNotExist: + print('bill with request_id ', x['src_object_id'], " not found") + except File.DoesNotExist: + print('file with request_id ', x['src_object_id'], " not found") + + print(obj) + return Response(obj, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_process_bills(request): + + ''' + This api is used to submit (process) a bill + ''' + + 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_desg, receiver_user = obj['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(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() + 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(['POST']) @@ -642,23 +785,6 @@ def letterOfIntent(request): return Response({}, status=status.HTTP_200_OK) - -@api_view(['POST', 'GET']) -def workOrderForm(request): - project_id = request.session.get('projectId') - if request.method == 'POST': - existingObject = WorkOrderForm.objects.filter(key=Projects.objects.get(id=project_id)) - if existingObject.exists(): - existingObject.delete() - - serializer = WorkOrderFormSerializer(data=request.data) - if serializer.is_valid(): - serializer.save(key=Projects.objects.get(id=project_id)) - return Response({"message": "Work order saved successfully."}, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - return Response({}, status=status.HTTP_200_OK) - @api_view(['POST', 'GET']) def AgreementInput(request): project_id = request.session.get('projectId') @@ -784,14 +910,6 @@ def letterOfIntentView(request): except LetterOfIntentDetails.DoesNotExist: return Response({'error': 'Letter of Intent not found.'}, status=status.HTTP_404_NOT_FOUND) -@api_view(['GET']) -def workOrderFormView(request): - try: - workOrderFormObject = WorkOrderForm.objects.get(key=Projects.objects.get(id=request.session['projectId'])) - serializer = WorkOrderFormSerializer(workOrderFormObject) - return Response({'workOrderForm': serializer.data}, status=status.HTTP_200_OK) - except WorkOrderForm.DoesNotExist: - return Response({'error': 'Work Order Form not found.'}, status=status.HTTP_404_NOT_FOUND) @api_view(['GET']) def agreementView(request): @@ -910,149 +1028,6 @@ def engineer_processed_requests(request): 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_desg, receiver_user = data.get('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(['POST']) -@permission_classes([IsAuthenticated]) -def updateRejectedRequests(request): - request_id = request.data.get("id", 0) - desg = request.data.get("role", "") - - # 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(['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(['GET']) -@permission_classes([IsAuthenticated]) -def getAllRequests(request): - requestsObject = Requests.objects.all() - serializer = RequestsSerializer(requestsObject, many=True) - return Response({'obj': serializer.data}, status=200) - - - -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -def getCompletedWork(request): - requestsObject= Requests.objects.filter(workCompleted=1) - serializer = RequestsSerializer(requestsObject, many=True) - return Response( - { - 'message': 'Work Completed', - 'response': serializer, - }, - status=status.HTTP_200_OK - ) @api_view(['POST']) @permission_classes([IsAuthenticated]) @@ -1126,23 +1101,24 @@ def generateFinalBill(request): @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) + # 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) + # 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) - return Response({'obj': obj}, status=status.HTTP_200_OK) @api_view(['GET']) @permission_classes([IsAuthenticated]) @@ -1162,132 +1138,12 @@ def generatedBillsView(request): } 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") + continue return Response({'obj': obj}, status=status.HTTP_200_OK) -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -def audit_document_view(request): - params = request.query_params - desg = params.get('role') - if not desg: - return Response({"error": "Designation not provided"}, status=status.HTTP_400_BAD_REQUEST) - - 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]) diff --git a/FusionIIIT/applications/iwdModuleV2/models.py b/FusionIIIT/applications/iwdModuleV2/models.py index 9c79aa21c..b78b7b3ef 100644 --- a/FusionIIIT/applications/iwdModuleV2/models.py +++ b/FusionIIIT/applications/iwdModuleV2/models.py @@ -162,7 +162,7 @@ class NoOfTechnicalBidTimes(models.Model): class Requests(models.Model): name = models.CharField(max_length=200) - description = models.CharField(max_length=200) + description = models.CharField(max_length=1000) area = models.CharField(max_length=200) requestCreatedBy = models.CharField(max_length=200) engineerProcessed = models.IntegerField(default=0) @@ -176,7 +176,6 @@ class Requests(models.Model): billSettled = models.IntegerField(default=0) class WorkOrder(models.Model): - # request_id = models.IntegerField() request_id = models.ForeignKey(Requests, on_delete=models.CASCADE) name = models.CharField(max_length=200) date = models.DateField(default=date.today) @@ -188,9 +187,11 @@ class WorkOrder(models.Model): completion_date = models.DateField() class Bills(models.Model): - # requestId = models.IntegerField() request_id = models.ForeignKey(Requests, on_delete=models.CASCADE) file = models.FileField() + # item = models.CharField(max_length=200) + # quantity = models.IntegerField(default=1) + class Budget(models.Model): name = models.CharField(max_length=200) From e2e2256525f4d6779b6b6629b9431cc7fd7b01c9 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Tue, 7 Jan 2025 22:39:26 +0530 Subject: [PATCH 19/20] fix: handle dean process request file attachment upload --- FusionIIIT/applications/iwdModuleV2/api/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 2f9efb3a4..016428807 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -114,6 +114,7 @@ def created_requests(request): 'requestCreatedBy': request_object.requestCreatedBy, 'file_id': file_obj.id, 'directorApproval': request_object.directorApproval, + 'processed_by_dean': request_object.deanProcessed, } obj.append(element) @@ -191,7 +192,7 @@ def handle_dean_process_request(request): request_id = File.objects.get(id=fileid).src_object_id remarks = data.get('remarks') - attachment = request.FILES.get('attachment') + attachment = request.FILES.get('file') receiver_desg, receiver_user = data.get('designation').split('|') forward_file( @@ -554,6 +555,7 @@ def requests_status(request): 'requestCreatedBy': request_object.requestCreatedBy, 'file_id': file_obj.id, 'processed_by_director': request_object.directorApproval, + 'processed_by_dean': request_object.deanProcessed, 'status': request_object.status, } obj.append(element) From 375d0b86181896715ec472f48acdd11ffb0907a7 Mon Sep 17 00:00:00 2001 From: dcoder13 Date: Wed, 8 Jan 2025 12:24:23 +0530 Subject: [PATCH 20/20] fix : forward file --- .../applications/iwdModuleV2/api/urls.py | 2 +- .../applications/iwdModuleV2/api/views.py | 85 +++++++------------ 2 files changed, 34 insertions(+), 53 deletions(-) diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index 8eb4f67e8..5b0bd02a8 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -11,6 +11,7 @@ path('view-file/', views.view_file, name='view_file'), path('dean-processed-requests/', views.dean_processed_requests, name='dean_processed_requests'), path('handle-director-approval/', views.handle_director_approval, name='handle_director_approval'), + path('handle-engineer-process/', views.handle_engineer_process_requests, name='handle_engineer_process_requests'), path('handle-dean-process-request/', views.handle_dean_process_request, name='handleDeanProcessRequests'), path('rejected-requests-view/', views.rejected_requests, name='rejectedRequests'), path('handle-update-requests/', views.handle_update_requests, name='handleUpdateRequests'), @@ -30,7 +31,6 @@ path('handle-process-bills/', views.handle_process_bills, name='handleProcessedBills'), path('engineer-processed-requests/', views.engineer_processed_requests, name='engineerProcessedRequests'), - path('handle-engineer-process-requests/', views.handleEngineerProcessRequests, name='handleEngineerProcessRequests'), 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'), diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 016428807..069b3fda0 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -205,9 +205,39 @@ def handle_dean_process_request(request): ) Requests.objects.filter(id=request_id).update(deanProcessed=1, status="Approved by the dean", directorApproval=0) - + receiver_user_obj = get_object_or_404(User, username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") return Response({'message': 'File Forwarded'}, status=200) +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_engineer_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('file') + receiver_desg, receiver_user = data.get('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(engineerProcessed=1) + receiver_user_obj = get_object_or_404(User, username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") + + return Response({ + "message": "File forwarded successfully", + }, status=status.HTTP_200_OK) + + @api_view(['POST']) @permission_classes([IsAuthenticated]) def handle_director_approval(request): @@ -235,7 +265,8 @@ def handle_director_approval(request): remarks=remarks, file_attachment=attachment, ) - + receiver_user_obj = get_object_or_404(User, username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") message = "" print(data) if data.get('action') == 'approve': @@ -950,56 +981,6 @@ def extensionFormView(request): -@api_view(['POST']) -@permission_classes([IsAuthenticated]) -def handleEngineerProcessRequests(request): - file_id = request.data.get('fileid') - remarks = request.data.get('remarks') - attachment = request.FILES.get('attachment') - - file_instance = get_object_or_404(File, id=file_id) - request_id = file_instance.src_object_id - - receiver_user, receiver_desg = request.data.get('designation').split('|') - - forward_file( - file_id=file_id, - 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(engineerProcessed=1, status="Approved by the Engineer") - - 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) - - receiver_user_obj = get_object_or_404(User, username=receiver_user) - iwd_notif(request.user, receiver_user_obj, "file_forward") - - - return Response({ - "message": "File forwarded successfully", - "requests": obj - }, status=status.HTTP_200_OK) @api_view(['GET']) @permission_classes([IsAuthenticated])