fix
This commit is contained in:
@@ -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 *
|
|
||||||
@@ -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 = {
|
SWAGGER_SETTINGS = {
|
||||||
'SECURITY_DEFINITIONS': {
|
'SECURITY_DEFINITIONS': {
|
||||||
'Basic': {
|
'Basic': {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
"DEFAULT_AUTHENTICATION_CLASSES": [
|
"DEFAULT_AUTHENTICATION_CLASSES": [
|
||||||
'rest_framework.authentication.SessionAuthentication',
|
# 'rest_framework.authentication.SessionAuthentication',
|
||||||
'rest_framework.authentication.BasicAuthentication',
|
# 'rest_framework.authentication.BasicAuthentication',
|
||||||
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
||||||
],
|
],
|
||||||
'DEFAULT_PAGINATION_CLASS': 'core.apps.shared.paginations.custom.CustomPageNumberPagination',
|
'DEFAULT_PAGINATION_CLASS': 'core.apps.shared.paginations.custom.CustomPageNumberPagination',
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from datetime import timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from config.env import env
|
from config.env import env
|
||||||
@@ -151,4 +152,11 @@ AUTH_USER_MODEL = 'accounts.User'
|
|||||||
|
|
||||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
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 *
|
||||||
@@ -3,7 +3,20 @@ from django.urls import path, include
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls.static import static
|
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 = [
|
urlpatterns = [
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ class UserAdmin(DjangoUserAdmin):
|
|||||||
change_user_password_template = None
|
change_user_password_template = None
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {"fields": ("username", "password")}),
|
(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")}),
|
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
|
||||||
)
|
)
|
||||||
add_fieldsets = (
|
add_fieldsets = (
|
||||||
@@ -22,7 +24,7 @@ class UserAdmin(DjangoUserAdmin):
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
list_display = ("username", "email", "first_name", "last_name", "is_staff")
|
list_display = ("username", "phone_number", "full_name", "is_blocked", "is_staff")
|
||||||
list_filter = ("is_staff", "is_superuser", "is_active", "groups")
|
list_filter = ("is_staff", "is_superuser", "is_active", "is_blocked")
|
||||||
search_fields = ("username", "first_name", "last_name", "email")
|
search_fields = ("username", "full_name", "phone_number")
|
||||||
ordering = ("username",)
|
ordering = ("username",)
|
||||||
@@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -11,7 +11,12 @@ class User(BaseModel, AbstractUser):
|
|||||||
upload_to="users/profile_images/", null=True, blank=True, verbose_name=_('profil rasmi')
|
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")
|
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 = []
|
REQUIRED_FIELDS = []
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ class HasRolePermission(BasePermission):
|
|||||||
|
|
||||||
if user.role:
|
if user.role:
|
||||||
user_permissions = user.role.permissions.values_list('code', flat=True)
|
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
|
return False
|
||||||
@@ -9,7 +9,7 @@ class UserProfileSerializer(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = [
|
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}}
|
extra_kwargs = {'role': {'read_only': True}, "permissions": {'read_only': True}}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class LoginApiView(generics.GenericAPIView):
|
|||||||
user = serializer.validated_data.get('user')
|
user = serializer.validated_data.get('user')
|
||||||
token = RefreshToken.for_user(user)
|
token = RefreshToken.for_user(user)
|
||||||
user_data = {
|
user_data = {
|
||||||
'role': user.role.name,
|
'role': user.role.name if user.role else None,
|
||||||
'permissions': user.role.permissions.values_list('code', flat=True),
|
'permissions': user.role.permissions.values_list('code', flat=True) if user.role else None,
|
||||||
}
|
}
|
||||||
return Response(
|
return Response(
|
||||||
{"access": str(token.access_token), "refresh": str(token), 'user_data': user_data},
|
{"access": str(token.access_token), "refresh": str(token), 'user_data': user_data},
|
||||||
|
|||||||
@@ -1,11 +1,58 @@
|
|||||||
|
from django.db import transaction
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from core.apps.finance.models import CashTransaction
|
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):
|
class CashTransactionListSerializer(serializers.ModelSerializer):
|
||||||
|
payment_type = serializers.SerializerMethodField(method_name='get_payment_type')
|
||||||
|
employees = CashTransactionEmployeeListSerializer(many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CashTransaction
|
model = CashTransaction
|
||||||
fields = [
|
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
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ urlpatterns = [
|
|||||||
path('cash_transaction/', include(
|
path('cash_transaction/', include(
|
||||||
[
|
[
|
||||||
path('list/', cash_views.CashTransactionListApiView.as_view()),
|
path('list/', cash_views.CashTransactionListApiView.as_view()),
|
||||||
|
path('create/', cash_views.CashTransactionCreateApiView.as_view()),
|
||||||
]
|
]
|
||||||
))
|
))
|
||||||
]
|
]
|
||||||
@@ -10,5 +10,12 @@ class CashTransactionListApiView(generics.ListAPIView):
|
|||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
required_permissions = []
|
required_permissions = []
|
||||||
serializer_class = serializers.CashTransactionListSerializer
|
serializer_class = serializers.CashTransactionListSerializer
|
||||||
queryset = CashTransaction.objects.all()
|
queryset = CashTransaction.objects.select_related('payment_type').prefetch_related('employees')
|
||||||
pagination_class = CustomPageNumberPagination
|
pagination_class = CustomPageNumberPagination
|
||||||
|
|
||||||
|
|
||||||
|
class CashTransactionCreateApiView(generics.GenericAPIView):
|
||||||
|
serializer_class = serializers.CashTransactionCreateSerializer
|
||||||
|
queryset = CashTransaction.objects.all()
|
||||||
|
permission_classes = [HasRolePermission]
|
||||||
|
required_permissions = ['project', 'project_folder']
|
||||||
9
core/apps/projects/models/project_estimate.py
Normal file
9
core/apps/projects/models/project_estimate.py
Normal 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):
|
||||||
|
...
|
||||||
Reference in New Issue
Block a user