diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py index 0956048f0..b6be08448 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/serializers.py +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -2,7 +2,7 @@ from applications.globals.models import * from applications.iwdModuleV2.models import * from applications.ps1.models import * - +from decimal import Decimal class WorkOrderFormSerializer(serializers.ModelSerializer): class Meta: model = WorkOrder @@ -48,6 +48,7 @@ class Meta: def create(self, validated_data): validated_data['engineerProcessed'] = 0 + validated_data['iwdAdminApproval'] = 0 validated_data['directorApproval'] = 0 validated_data['deanProcessed'] = 0 validated_data['status'] = "Pending" @@ -58,6 +59,11 @@ def create(self, validated_data): validated_data['billSettled'] = 0 return super().create(validated_data) +class IWDAdminApprovedRequestsSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy'] + class DirectorApprovedRequestsSerializer(serializers.ModelSerializer): class Meta: model = Requests @@ -142,50 +148,37 @@ class Meta: class ItemSerializer(serializers.ModelSerializer): class Meta: model = Item - fields = ['name', 'description', 'unit', 'price_per_unit', 'quantity', 'docs', 'total_price'] + fields = ['id', 'name', 'description', 'unit', 'price_per_unit', 'quantity', 'docs', 'total_price'] class ProposalSerializer(serializers.ModelSerializer): - items = ItemSerializer(many=True) + class Meta: model = Proposal fields = '__all__' def create(self, validated_data): - items_data = validated_data.pop('items', []) + items = ItemSerializer(many=True) + items_data = validated_data.pop('items', []) proposal = Proposal.objects.create(**validated_data) - total_budget = 0 + + total_budget = Decimal(0) + items = [] + for item_data in items_data: - print(item_data) - item_data['total_price'] = item_data['quantity'] * item_data['price_per_unit'] - total_budget += item_data['total_price'] - item = Item.objects.create(proposal=proposal, **item_data) + try: + quantity = item_data['quantity'] + price_per_unit = item_data['price_per_unit'] + total_price = quantity * price_per_unit + total_budget += total_price + items.append(Item(proposal=proposal, total_price=total_price, **item_data)) + + except (ValueError, TypeError) as e: + print(f"Error processing item: {item_data}, Error: {e}") + continue - proposal.proposal_budget = total_budget + if items: + Item.objects.bulk_create(items) + + proposal.proposal_budget = total_budget proposal.save() - return proposal - - # def update(self, instance, validated_data): - # items_data = validated_data.pop('items') - # instance.supporting_documents = validated_data.get('supporting_documents', instance.supporting_documents) - # instance.status = validated_data.get('status', instance.status) - # instance.save() - - # total_budget = 0 - # for item_data in items_data: - # item_id = item_data.get('id') - # if item_id: - # item = Item.objects.get(id=item_id, proposal=instance) - # item.name = item_data.get('name', item.name) - # item.description = item_data.get('description', item.description) - # item.unit = item_data.get('unit', item.unit) - # item.price_per_unit = item_data.get('price_per_unit', item.price_per_unit) - # item.quantity = item_data.get('quantity', item.quantity) - # item.total_price = item_data.get('total_price', item.total_price) - # item.docs = item_data.get('docs', item.docs) - # item.save() - # else: - # item = Item.objects.create(proposal=instance, **item_data) - # total_budget += item.total_price - - # instance.proposal_budget = total_budget - # instance.save() - # return instance \ No newline at end of file + + return proposal \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py index b909a4947..59c26be53 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -12,7 +12,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('forward-request/', views.forward_request, 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'), @@ -29,6 +29,7 @@ path('audit-document/', views.handle_audit_document, name='auditDocument'), path('get-proposals/', views.get_proposals, name='getProposals'), path('get-items/', views.get_items, name='getItems'), + path('handle-admin-approval/', views.handle_admin_approval, name='handleAdminApproval'), # partially integrated on frontend diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py index 8902cf7bd..726e86839 100644 --- a/FusionIIIT/applications/iwdModuleV2/api/views.py +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -61,7 +61,9 @@ def create_request(request): formObject = serializer.save() print(formObject.requestCreatedBy) request_object = Requests.objects.get(pk=formObject.pk) - receiver_desg, receiver_user = data.get('designation').split('|') + receiver_desg = "Admin IWD" + receiver_user = "kunal" + # receiver_desg, receiver_user = data.get('designation').split('|') try: receiver_user_obj = User.objects.get(username=receiver_user) except User.DoesNotExist: @@ -213,7 +215,7 @@ def handle_dean_process_request(request): @api_view(['POST']) @permission_classes([IsAuthenticated]) -def handle_engineer_process_requests(request): +def forward_request(request): data = request.data fileid = data.get('fileid') request_id = File.objects.get(id=fileid).src_object_id @@ -231,7 +233,6 @@ def handle_engineer_process_requests(request): 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") @@ -239,26 +240,36 @@ def handle_engineer_process_requests(request): "message": "File forwarded successfully", }, status=status.HTTP_200_OK) - @api_view(['POST']) @permission_classes([IsAuthenticated]) def handle_director_approval(request): - - ''' - This api is to approve or reject file based on director's action - ''' - + """ + Approve or reject a request by the director. + """ data = request.data fileid = data.get('fileid') - request_id = File.objects.get(id=fileid).src_object_id + action = data.get('action') + + if not fileid or not action: + return Response({'error': 'File ID and action are required'}, status=status.HTTP_400_BAD_REQUEST) + + try: + request_id = File.objects.get(id=fileid).src_object_id + except File.DoesNotExist: + return Response({'error': 'File not found'}, status=status.HTTP_404_NOT_FOUND) + + request_instance = Requests.objects.filter(id=request_id, iwdAdminApproval=True).first() + if not request_instance: + return Response({'error': 'Request not approved by IWD Admin'}, status=status.HTTP_400_BAD_REQUEST) + + proposal_instance = Proposal.objects.filter(request_id=request_id).first() + if not proposal_instance: + return Response({'error': 'No proposal exists for this request'}, status=status.HTTP_400_BAD_REQUEST) remarks = data.get('remarks') 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, @@ -269,17 +280,15 @@ def handle_director_approval(request): ) 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': - 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}) + if action == "approve": + Requests.objects.filter(id=request_id).update(directorApproval=1, status="Approved by Director") + return Response({'message': 'Request approved by Director'}, status=status.HTTP_200_OK) + elif action == "reject": + Requests.objects.filter(id=request_id).update(directorApproval=-1, status="Rejected by Director") + return Response({'message': 'Request rejected by Director'}, status=status.HTTP_200_OK) + else: + return Response({'error': 'Invalid action'}, status=status.HTTP_400_BAD_REQUEST) @api_view(['POST']) @permission_classes([IsAuthenticated]) @@ -596,6 +605,7 @@ def requests_status(request): 'description': request_object.description, 'requestCreatedBy': request_object.requestCreatedBy, 'file_id': file_obj.id, + 'processed_by_admin': request_object.iwdAdminApproval, 'processed_by_director': request_object.directorApproval, 'work_order': request_object.issuedWorkOrder, 'work_completed': request_object.workCompleted, @@ -604,7 +614,6 @@ def requests_status(request): 'active_proposal': request_object.activeProposal, } obj.append(element) - print(type(element['request_id'])) return Response(obj, status=200) @@ -1191,16 +1200,23 @@ def handle_settle_bill_requests(request): @permission_classes([IsAuthenticated]) def create_proposal(request): data = request.data.copy() + request_id = data.get('id') + + request_instance = Requests.objects.filter(id=request_id, iwdAdminApproval=True).first() + if not request_instance: + return Response({'error': 'Request not approved by IWD Admin'}, status=status.HTTP_400_BAD_REQUEST) + data["created_by"] = str(request.user) data["request"] = data.get('id') - print(data) receiver_desg, receiver_user = data.get('designation').split('|') serializer = ProposalSerializer(data=data) + print(serializer) if serializer.is_valid(): - print(serializer) + # print(serializer) + print("wowowowow ") proposal = serializer.save() - # proposal.save() - Requests.objects.filter(id=proposal.id).update(activeProposal=proposal.id) + print(proposal, "wowowowow ", proposal.id) + Requests.objects.filter(id=request_id).update(activeProposal=proposal.id) receiver_user_obj = User.objects.get(username=receiver_user) iwd_notif(request.user, receiver_user_obj, "Proposal_added") return Response(serializer.data, status=status.HTTP_201_CREATED) @@ -1218,14 +1234,56 @@ def get_proposals(request): @api_view(['GET']) @permission_classes([IsAuthenticated]) def get_items(request): - print(1) try: - data = request.query_params - print(data) + proposal = Proposal.objects.filter(id = data['proposal_id']).first() items = Item.objects.filter(proposal=data['proposal_id']) - serializer = ItemSerializer(items, many=True) - return Response(serializer.data, status=status.HTTP_200_OK) + itemsdata = ItemSerializer(items, many=True) + proposaldata = ProposalSerializer(proposal) + return Response({"itemsList": itemsdata.data, "proposal":proposaldata.data}, status=status.HTTP_200_OK) except Proposal.DoesNotExist: - print("1trq3t3\n\n\n\n\n12q") - return Response({'error': 'Proposal not found'}, status=status.HTTP_404_NOT_FOUND) \ No newline at end of file + return Response({'error': 'Proposal not found'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_admin_approval(request): + """ + Approve or reject a request by the IWD Admin. + """ + data = request.data + action = data.get('action') + + 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('|') + + if not fileid: + return Response({'error': 'File ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + 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 not request_id or not action: + return Response({'error': 'Request ID and action are required'}, status=status.HTTP_400_BAD_REQUEST) + + if action == "approve": + Requests.objects.filter(id=request_id).update(iwdAdminApproval=1, status="Approved by IWD Admin") + return Response({'message': 'Request approved by IWD Admin'}, status=status.HTTP_200_OK) + elif action == "reject": + Requests.objects.filter(id=request_id).update(iwdAdminApproval=-1, status="Rejected by IWD Admin") + return Response({'message': 'Request rejected by IWD Admin'}, status=status.HTTP_200_OK) + else: + return Response({'error': 'Invalid action'}, status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/migrations/0002_requests_iwdadminapproval.py b/FusionIIIT/applications/iwdModuleV2/migrations/0002_requests_iwdadminapproval.py new file mode 100644 index 000000000..8d4e594a1 --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/migrations/0002_requests_iwdadminapproval.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2025-03-28 18:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('iwdModuleV2', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='requests', + name='iwdAdminApproval', + field=models.IntegerField(default=0), + ), + ] diff --git a/FusionIIIT/applications/iwdModuleV2/models.py b/FusionIIIT/applications/iwdModuleV2/models.py index 186ca532f..30970ad6d 100644 --- a/FusionIIIT/applications/iwdModuleV2/models.py +++ b/FusionIIIT/applications/iwdModuleV2/models.py @@ -168,6 +168,7 @@ class Requests(models.Model): area = models.CharField(max_length=200) requestCreatedBy = models.CharField(max_length=200) engineerProcessed = models.IntegerField(default=0) + iwdAdminApproval = models.IntegerField(default=0) directorApproval = models.IntegerField(default=0) deanProcessed = models.IntegerField(default=0) status = models.CharField(max_length=200)