This commit is contained in:
behruz-dev
2025-08-06 13:59:45 +05:00
parent 7e0eb3ec57
commit 18ff76aaa6
15 changed files with 144 additions and 41 deletions

View File

@@ -1,6 +0,0 @@
from .jazzmin import *
from .drf_yasg import *
from .redis import *
from .rest_framework import *
from .rest_framework_simplejwt import *
from .cors_headers import *

View File

@@ -1,22 +1,3 @@
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="UyQur API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="xoliqberdiyevbehru12@gmail.com"),
license=openapi.License(name="Felix IT Solutions License"),
),
public=True,
permission_classes=(permissions.IsAuthenticated,),
)
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'Basic': {

View File

@@ -1,7 +1,7 @@
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_PAGINATION_CLASS': 'core.apps.shared.paginations.custom.CustomPageNumberPagination',

View File

@@ -1,3 +1,4 @@
from datetime import timedelta
from pathlib import Path
from config.env import env
@@ -151,4 +152,11 @@ AUTH_USER_MODEL = 'accounts.User'
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
from config.conf import *
from config.conf.rest_framework import *
from config.conf.rest_framework_simplejwt import *
from config.conf.logs import *
from config.conf.cors_headers import *
from config.conf.drf_yasg import *
from config.conf.jazzmin import *
from config.conf.redis import *

View File

@@ -3,7 +3,20 @@ from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from config.conf.drf_yasg import schema_view
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="UyQur API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="xoliqberdiyevbehru12@gmail.com"),
license=openapi.License(name="Felix IT Solutions License"),
),
public=True,
)
urlpatterns = [

View File

@@ -10,7 +10,9 @@ class UserAdmin(DjangoUserAdmin):
change_user_password_template = None
fieldsets = (
(None, {"fields": ("username", "password")}),
(_("Personal info"), {"fields": ("first_name", "last_name", "email", "role")}),
(_("Personal info"), {"fields": (
"full_name", 'phone_number', "role", 'profile_image', 'is_blocked'
)}),
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
)
add_fieldsets = (
@@ -22,7 +24,7 @@ class UserAdmin(DjangoUserAdmin):
},
),
)
list_display = ("username", "email", "first_name", "last_name", "is_staff")
list_filter = ("is_staff", "is_superuser", "is_active", "groups")
search_fields = ("username", "first_name", "last_name", "email")
list_display = ("username", "phone_number", "full_name", "is_blocked", "is_staff")
list_filter = ("is_staff", "is_superuser", "is_active", "is_blocked")
search_fields = ("username", "full_name", "phone_number")
ordering = ("username",)

View File

@@ -0,0 +1,36 @@
# Generated by Django 5.2.4 on 2025-08-06 12:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0003_alter_role_permissions'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='first_name',
),
migrations.RemoveField(
model_name='user',
name='last_name',
),
migrations.AddField(
model_name='user',
name='full_name',
field=models.CharField(max_length=200, null=True),
),
migrations.AddField(
model_name='user',
name='is_blocked',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='user',
name='phone_number',
field=models.CharField(max_length=15, null=True),
),
]

View File

@@ -11,7 +11,12 @@ class User(BaseModel, AbstractUser):
upload_to="users/profile_images/", null=True, blank=True, verbose_name=_('profil rasmi')
)
role = models.ForeignKey(Role, on_delete=models.DO_NOTHING, null=True, related_name="users")
full_name = models.CharField(max_length=200, null=True)
is_blocked = models.BooleanField(default=False)
phone_number = models.CharField(max_length=15, null=True)
first_name = None
last_name = None
REQUIRED_FIELDS = []
def __str__(self):

View File

@@ -9,10 +9,10 @@ class HasRolePermission(BasePermission):
required_permissions = getattr(view, 'required_permissions', [])
if not required_permissions:
return True
return True
if user.role:
user_permissions = user.role.permissions.values_list('code', flat=True)
return all(perm in user_permissions for perm in required_permissions)
return any(perm in user_permissions for perm in required_permissions)
return False

View File

@@ -9,7 +9,7 @@ class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'id', 'first_name', 'last_name', 'username', 'role', 'profile_image', 'permissions'
'id', 'full_name', 'username', 'phone_number', 'is_blocked', 'role', 'profile_image', 'permissions'
]
extra_kwargs = {'role': {'read_only': True}, "permissions": {'read_only': True}}

View File

@@ -18,8 +18,8 @@ class LoginApiView(generics.GenericAPIView):
user = serializer.validated_data.get('user')
token = RefreshToken.for_user(user)
user_data = {
'role': user.role.name,
'permissions': user.role.permissions.values_list('code', flat=True),
'role': user.role.name if user.role else None,
'permissions': user.role.permissions.values_list('code', flat=True) if user.role else None,
}
return Response(
{"access": str(token.access_token), "refresh": str(token), 'user_data': user_data},

View File

@@ -1,11 +1,58 @@
from django.db import transaction
from rest_framework import serializers
from core.apps.finance.models import CashTransaction
from core.apps.accounts.models import User
from core.apps.finance.models import PaymentType
class CashTransactionEmployeeListSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'id', 'profile_image', 'first_name', 'last_name', 'username'
]
class CashTransactionListSerializer(serializers.ModelSerializer):
payment_type = serializers.SerializerMethodField(method_name='get_payment_type')
employees = CashTransactionEmployeeListSerializer(many=True)
class Meta:
model = CashTransaction
fields = [
'id', 'name'
]
'id', 'name', 'payment_type', 'employees', 'status'
]
def get_payment_type(self, obj):
return {
"id": obj.payment_type.id,
"name": obj.payment_type.name
}
class CashTransactionCreateSerializer(serializers.Serializer):
payment_type_id = serializers.UUIDField()
employee_ids = serializers.ListSerializer(child=serializers.UUIDField())
name = serializers.CharField()
status = serializers.BooleanField()
def validate(self, data):
payment_type = PaymentType.objects.filter(id=data['id']).first()
if payment_type:
raise serializers.ValidationError("Payment Type not found")
data['payment_type'] = payment_type
return data
def create(self, validated_data):
with transaction.atomic():
employee_ids = validated_data.pop('employee_ids')
cash_transaction = CashTransaction.objects.create(
name=validated_data.get('name'),
payment_type=validated_data.get('payment_type'),
status=validated_data.get('status')
)
cash_transaction.employees.set(employee_ids)
cash_transaction.save()
return cash_transaction

View File

@@ -7,6 +7,7 @@ urlpatterns = [
path('cash_transaction/', include(
[
path('list/', cash_views.CashTransactionListApiView.as_view()),
path('create/', cash_views.CashTransactionCreateApiView.as_view()),
]
))
]

View File

@@ -10,5 +10,12 @@ class CashTransactionListApiView(generics.ListAPIView):
permission_classes = [HasRolePermission]
required_permissions = []
serializer_class = serializers.CashTransactionListSerializer
queryset = CashTransaction.objects.select_related('payment_type').prefetch_related('employees')
pagination_class = CustomPageNumberPagination
class CashTransactionCreateApiView(generics.GenericAPIView):
serializer_class = serializers.CashTransactionCreateSerializer
queryset = CashTransaction.objects.all()
pagination_class = CustomPageNumberPagination
permission_classes = [HasRolePermission]
required_permissions = ['project', 'project_folder']

View File

@@ -0,0 +1,9 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from core.apps.shared.models import BaseModel
from core.apps.projects.models import Project
class ProjectEstimate(BaseModel):
...