From c54886d586e4aca0cc5b4caa89e3a891a99ec471 Mon Sep 17 00:00:00 2001 From: behruz-dev Date: Tue, 11 Nov 2025 19:43:46 +0500 Subject: [PATCH] fix --- config/urls.py | 1 + .../migrations/0004_alter_contract_folder.py | 19 +++++++++++++ core/apps/contracts/models/contract.py | 2 +- core/apps/contracts/serializers/contract.py | 14 +++++++++- core/apps/contracts/serializers/folder.py | 13 ++++++++- core/apps/contracts/urls.py | 2 ++ core/apps/contracts/views/contract.py | 18 ++++++++++++- core/apps/contracts/views/folder.py | 11 ++++++++ core/apps/shared/admins/__init__.py | 2 ++ core/apps/shared/admins/contact_us.py | 6 +++++ core/apps/shared/apps.py | 2 +- core/apps/shared/migrations/0002_contactus.py | 27 +++++++++++++++++++ core/apps/shared/models/__init__.py | 3 ++- core/apps/shared/models/contact_us.py | 12 +++++++++ core/apps/shared/serializers/contact_us.py | 9 +++++++ core/apps/shared/urls.py | 8 ++++++ core/apps/shared/views/contact_us.py | 18 +++++++++++++ 17 files changed, 161 insertions(+), 6 deletions(-) create mode 100644 core/apps/contracts/migrations/0004_alter_contract_folder.py create mode 100644 core/apps/shared/admins/contact_us.py create mode 100644 core/apps/shared/migrations/0002_contactus.py create mode 100644 core/apps/shared/models/contact_us.py create mode 100644 core/apps/shared/serializers/contact_us.py create mode 100644 core/apps/shared/urls.py create mode 100644 core/apps/shared/views/contact_us.py diff --git a/config/urls.py b/config/urls.py index 224251d..80a3bef 100644 --- a/config/urls.py +++ b/config/urls.py @@ -27,6 +27,7 @@ urlpatterns = [ [ path('', include('core.apps.accounts.urls')), path('contracts/', include('core.apps.contracts.urls')), + path('shared/', include('core.apps.shared.urls')), ] )), ] diff --git a/core/apps/contracts/migrations/0004_alter_contract_folder.py b/core/apps/contracts/migrations/0004_alter_contract_folder.py new file mode 100644 index 0000000..816ef16 --- /dev/null +++ b/core/apps/contracts/migrations/0004_alter_contract_folder.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2 on 2025-11-11 19:20 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contracts', '0003_alter_folder_options_folder_user'), + ] + + operations = [ + migrations.AlterField( + model_name='contract', + name='folder', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='contracts', to='contracts.folder'), + ), + ] diff --git a/core/apps/contracts/models/contract.py b/core/apps/contracts/models/contract.py index 28f0afd..10cd4c5 100644 --- a/core/apps/contracts/models/contract.py +++ b/core/apps/contracts/models/contract.py @@ -26,7 +26,7 @@ class Contract(BaseModel): add_notification = models.BooleanField(default=False) company = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name='contracts') - folder = models.ForeignKey(Folder, on_delete=models.SET_NULL, null=True, blank=True, related_name='countracts') + folder = models.ForeignKey(Folder, on_delete=models.SET_NULL, null=True, blank=True, related_name='contracts') def __str__(self): return f'{self.name}' diff --git a/core/apps/contracts/serializers/contract.py b/core/apps/contracts/serializers/contract.py index d3f469d..b7aabda 100644 --- a/core/apps/contracts/serializers/contract.py +++ b/core/apps/contracts/serializers/contract.py @@ -40,6 +40,7 @@ class ContractCreateSerializer(serializers.Serializer): company=user, folder=validated_data.get('folder'), ) + return contract.id @@ -58,4 +59,15 @@ class ContractDetailSerializer(serializers.ModelSerializer): model = Contract fields = [ 'id', 'name', 'file', 'status', 'contract_number', 'contract_sides', - ] \ No newline at end of file + ] + + +class ContractUpdateSerializer(serializers.ModelSerializer): + class Meta: + model = Contract + fields = ['folder'] + + def update(self, instance, validated_data): + instance.folder = validated_data.get('folder', instance.folder) + instance.save() + return instance \ No newline at end of file diff --git a/core/apps/contracts/serializers/folder.py b/core/apps/contracts/serializers/folder.py index 16636e4..cf6fec7 100644 --- a/core/apps/contracts/serializers/folder.py +++ b/core/apps/contracts/serializers/folder.py @@ -1,6 +1,7 @@ from rest_framework import serializers from core.apps.contracts.models import Folder +from core.apps.contracts.serializers.contract import ContractListSerializer class FolderListSerializer(serializers.ModelSerializer): @@ -28,4 +29,14 @@ class FolderSerializer(serializers.ModelSerializer): def update(self, instance, validated_data): instance.name = validated_data.get('name', instance.name) instance.save() - return instance \ No newline at end of file + return instance + + +class FolderDetailSerializer(serializers.ModelSerializer): + contracts = ContractListSerializer(many=True) + + class Meta: + model = Folder + fields = [ + 'id', 'name', 'contracts' + ] diff --git a/core/apps/contracts/urls.py b/core/apps/contracts/urls.py index 5cc84ed..0781992 100644 --- a/core/apps/contracts/urls.py +++ b/core/apps/contracts/urls.py @@ -11,6 +11,7 @@ urlpatterns = [ path('create/', contract_views.ContractCreateApiView.as_view(), name='create-contract'), path('list/', contract_views.ContractListApiView.as_view(), name='list-contract'), path('/', contract_views.ContractDetailApiView.as_view(), name='detail-contract'), + path('/update/', contract_views.ContractUpdateApiView.as_view()), ] )), path('contract_side/', include([ @@ -28,6 +29,7 @@ urlpatterns = [ path('list/', folder_views.FolderListApiView.as_view()), path('create/', folder_views.FolderCreateApiView.as_view()), path('/update/', folder_views.FolderUpdateApiView.as_view()), + path('/contracts/', folder_views.ContractListApiView.as_view()), ] )), ] \ No newline at end of file diff --git a/core/apps/contracts/views/contract.py b/core/apps/contracts/views/contract.py index 493f5b1..3c90c1e 100644 --- a/core/apps/contracts/views/contract.py +++ b/core/apps/contracts/views/contract.py @@ -1,3 +1,5 @@ +from django.shortcuts import get_object_or_404 + from rest_framework import generics, views, status, permissions, parsers from rest_framework.response import Response @@ -37,4 +39,18 @@ class ContractDetailApiView(views.APIView): if not contract: return error_message("Contract not found", 404) serializer = contract_serializer.ContractDetailSerializer(contract) - return Response(serializer.data, status=200) \ No newline at end of file + return Response(serializer.data, status=200) + + +class ContractUpdateApiView(generics.GenericAPIView): + serializer_class = contract_serializer.ContractUpdateSerializer + queryset = Contract.objects.all() + permission_classes = [permissions.IsAuthenticated] + + def patch(self, request, id): + contract = get_object_or_404(Contract, id=id) + serializer = self.serializer_class(data=request.data, instance=contract) + if serializer.is_valid(raise_exception=True): + serializer.save() + return Response({"success": True, 'message': 'updated'}, status=200) + return Response({'success': False, 'message': serializer.errors}, status=400) diff --git a/core/apps/contracts/views/folder.py b/core/apps/contracts/views/folder.py index e0bdd58..2e1300c 100644 --- a/core/apps/contracts/views/folder.py +++ b/core/apps/contracts/views/folder.py @@ -44,3 +44,14 @@ class FolderUpdateApiView(generics.GenericAPIView): serializer.save() return Response({"message":"Folder tahrirlandi"}, status=200) return Response(serializer.errors, status=400) + + +class ContractListApiView(generics.GenericAPIView): + serializer_class = serializers.FolderDetailSerializer + queryset = Folder.objects.all() + permission_classes = [IsAuthenticated] + + def get(self, request, id): + folder = get_object_or_404(Folder, id=id, user=request.user) + serializer = self.serializer_class(folder) + return Response(serializer.data) \ No newline at end of file diff --git a/core/apps/shared/admins/__init__.py b/core/apps/shared/admins/__init__.py index e69de29..90b0b97 100644 --- a/core/apps/shared/admins/__init__.py +++ b/core/apps/shared/admins/__init__.py @@ -0,0 +1,2 @@ +from .contact_us import * +from .folder import * \ No newline at end of file diff --git a/core/apps/shared/admins/contact_us.py b/core/apps/shared/admins/contact_us.py new file mode 100644 index 0000000..773df17 --- /dev/null +++ b/core/apps/shared/admins/contact_us.py @@ -0,0 +1,6 @@ +from django.contrib import admin + +from core.apps.shared.models import ContactUs + + +admin.site.register(ContactUs) \ No newline at end of file diff --git a/core/apps/shared/apps.py b/core/apps/shared/apps.py index 1ed748d..1044ca2 100644 --- a/core/apps/shared/apps.py +++ b/core/apps/shared/apps.py @@ -6,4 +6,4 @@ class SharedConfig(AppConfig): name = 'core.apps.shared' def ready(self): - import core.apps.shared.admins.folder \ No newline at end of file + import core.apps.shared.admins \ No newline at end of file diff --git a/core/apps/shared/migrations/0002_contactus.py b/core/apps/shared/migrations/0002_contactus.py new file mode 100644 index 0000000..a86f665 --- /dev/null +++ b/core/apps/shared/migrations/0002_contactus.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2 on 2025-11-11 19:26 + +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('shared', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='ContactUs', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('phone_number', models.CharField(max_length=20)), + ('telegram_url', models.URLField()), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/core/apps/shared/models/__init__.py b/core/apps/shared/models/__init__.py index 59c3224..50ad3c4 100644 --- a/core/apps/shared/models/__init__.py +++ b/core/apps/shared/models/__init__.py @@ -1,2 +1,3 @@ from .base import * -from .folder import * \ No newline at end of file +from .folder import * +from .contact_us import * \ No newline at end of file diff --git a/core/apps/shared/models/contact_us.py b/core/apps/shared/models/contact_us.py new file mode 100644 index 0000000..9b142ee --- /dev/null +++ b/core/apps/shared/models/contact_us.py @@ -0,0 +1,12 @@ +from django.db import models + +from core.apps.shared.models.base import BaseModel + + +class ContactUs(BaseModel): + phone_number = models.CharField(max_length=20) + telegram_url = models.URLField() + + def __str__(self): + return self.phone_number + \ No newline at end of file diff --git a/core/apps/shared/serializers/contact_us.py b/core/apps/shared/serializers/contact_us.py new file mode 100644 index 0000000..049d3b5 --- /dev/null +++ b/core/apps/shared/serializers/contact_us.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from core.apps.shared.models.contact_us import ContactUs + + +class ContactUsSerializer(serializers.ModelSerializer): + class Meta: + model = ContactUs + fields = '__all__' \ No newline at end of file diff --git a/core/apps/shared/urls.py b/core/apps/shared/urls.py new file mode 100644 index 0000000..8d38a99 --- /dev/null +++ b/core/apps/shared/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from core.apps.shared.views.contact_us import ContactUsApiView + + +urlpatterns = [ + path('contact_us/', ContactUsApiView.as_view()), +] \ No newline at end of file diff --git a/core/apps/shared/views/contact_us.py b/core/apps/shared/views/contact_us.py new file mode 100644 index 0000000..13f0b12 --- /dev/null +++ b/core/apps/shared/views/contact_us.py @@ -0,0 +1,18 @@ +from rest_framework import generics +from rest_framework.response import Response +from rest_framework.permissions import IsAuthenticated + +from core.apps.shared.utils.response import success_message, error_message +from core.apps.shared.serializers.contact_us import ContactUsSerializer +from core.apps.shared.models import ContactUs + + +class ContactUsApiView(generics.GenericAPIView): + permission_classes = [IsAuthenticated] + queryset = ContactUs.objects.first() + serializer_class = ContactUsSerializer + + def get(self, request): + obj = ContactUs.objects.first() + serializer = self.serializer_class(obj) + return Response(serializer.data, status=200)