first base of project-changed apps: Herd-livestock-tag-log-elasticsearch-

This commit is contained in:
2025-05-24 15:01:55 +03:30
parent eab40af15d
commit 90a46e493c
129 changed files with 3844 additions and 187 deletions

View File

@@ -1,35 +1,197 @@
import typing
from apps.authentication.api.v1.serializers.jwt import CustomizedTokenObtainPairSerializer
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.decorators import action, permission_classes
from apps.authentication import permissions as auth_permissions
from apps.authentication.api.v1.serializers.serializer import (
CitySerializer,
ProvinceSerializer,
OrganizationTypeSerializer,
OrganizationSerializer,
UserSerializer,
BankAccountSerializer
)
from rest_framework_simplejwt.views import TokenObtainPairView
from apps.authorization.api.v1 import api as authorize_view
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from apps.authentication.models import User
from rest_framework.views import APIView
from apps.authentication.models import (
User,
City,
Province,
Organization,
OrganizationType,
BankAccountInformation
)
from django.db import transaction
from rest_framework.response import Response
from common.tools import CustomOperations
from rest_framework import status
class CustomizedTokenObtainPairView(TokenObtainPairView):
""" Generate Customize token """
serializer_class = CustomizedTokenObtainPairSerializer
# Example Code
class Authentication(ModelViewSet):
queryset = User
serializer_class = ''
permission_classes = ''
authentication_classes = [JWTAuthentication]
@action(
methods=['post', ],
detail=False,
name='login',
url_name='login',
url_path='login'
)
@transaction.atomic
def login(self, request):
pass
class UserViewSet(ModelViewSet):
pass
""" Crud operations for user model """
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [
auth_permissions.CreateUser,
]
@transaction.atomic
def create(self, request, *args, **kwargs):
"""
Customizing create user & bank account information with
permission levels
"""
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
user = serializer.save()
if 'organization' in request.data.keys():
organization = CustomOperations().custom_create( # create organization for user
request=request,
view=OrganizationViewSet(),
data_key='organization'
)
else:
organization = {}
if 'user_relations' in request.data.keys():
user_relations = CustomOperations().custom_create( # create user relations
user=user,
request=request,
view=authorize_view.UserRelationViewSet(),
data_key='user_relations',
additional_data={'organization': organization['id']} # noqa
)
else:
user_relations = {}
if 'bank_account' in request.data.keys():
bank_account = CustomOperations().custom_create( # create user bank account info
user=user,
request=request,
view=BankAccountViewSet(),
data_key='bank_account'
)
else:
bank_account = {}
serializer_data = serializer.data
serializer_data.update({
'organization': organization,
'user_relations': user_relations, # noqa
'bank_account': bank_account # noqa
})
return Response(serializer_data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)
@transaction.atomic
def update(self, request, pk=None, *args, **kwargs):
"""
Customizing update user & bank account info with
permission levels
"""
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
user = serializer.update(self.queryset.get(id=pk), validated_data=request.data)
if 'organization' in request.data.keys(): # noqa
organization = CustomOperations().custom_update( # update organization for user
request=request,
view=OrganizationViewSet(),
data_key='organization',
obj_id=request.data['organization']['id']
)
else:
organization = {}
if 'user_relations' in request.data.keys():
user_relations = CustomOperations().custom_update( # update user relations
user=user,
request=request,
view=authorize_view.UserRelationViewSet(),
data_key='user_relations',
additional_data={'organization': request.data['organization']['id']}, # noqa
obj_id=request.data['user_relations']['id']
)
else:
user_relations = {}
if 'bank_account' in request.data.keys():
bank_account = CustomOperations().custom_update( # update user bank account info
user=user,
request=request,
view=BankAccountViewSet(),
data_key='bank_account',
obj_id=request.data['bank_account']['id']
)
else:
bank_account = {}
serializer_data = serializer.data
serializer_data.update({
'organization': organization,
'user_relations': user_relations, # noqa
'bank_account': bank_account # noqa
})
return Response(serializer_data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)
class CityViewSet(ModelViewSet):
""" Crud operations for city model """ #
queryset = City.objects.all()
serializer_class = CitySerializer
class ProvinceViewSet(ModelViewSet):
""" Crud operations for province model """ #
queryset = Province.objects.all()
serializer_class = ProvinceSerializer
class OrganizationTypeViewSet(ModelViewSet):
""" Crud operations for Organization Type model """ #
queryset = OrganizationType.objects.all()
serializer_class = OrganizationTypeSerializer
class OrganizationViewSet(ModelViewSet):
""" Crud operations for organization model """ #
queryset = Organization.objects.all()
serializer_class = OrganizationSerializer
permission_classes = [auth_permissions.CreateOrganization]
@transaction.atomic
def create(self, request, *args, **kwargs):
"""
@create Organization by user
"""
serializer = self.serializer_class(data=request.data['organization'])
if serializer.is_valid():
organization = serializer.save()
if 'user_relations' in request.data.keys():
user_relations = CustomOperations().custom_create( # create user relations
request=request,
view=authorize_view.UserRelationViewSet(),
data_key='user_relations',
additional_data={'organization': organization.id} # noqa
)
serializer_data = serializer.data
serializer_data.update(
{'user_relations': user_relations}
)
return Response(serializer_data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_406_NOT_ACCEPTABLE)
class BankAccountViewSet(ModelViewSet):
""" Crud operations for bank account model """ #
queryset = BankAccountInformation.objects.all()
serializer_class = BankAccountSerializer

View File

@@ -1,53 +1,53 @@
from apps.authentication.api.v1.serializers.serializer import UserSerializer
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.viewsets import ModelViewSet, ViewSet
from apps.authentication.documents import UserDocument
from rest_framework.response import Response
from django.http.response import HttpResponse
from apps.authentication.models import User
from rest_framework.views import APIView
from elasticsearch_dsl.query import Q
import abc
class PaginatedElasticSearchApiView(APIView, LimitOffsetPagination):
"""Base ApiView Class for elasticsearch views with pagination
Other ApiView classes should inherit from this class"""
serializer_class = None
document_class = None
@abc.abstractmethod
def generate_q_expression(self, query):
"""This method should be overridden
and return a Q() expression."""
def get(self, request, query):
try:
q = self.generate_q_expression(query)
search = self.document_class.search().query(q)
response = search.execute()
print(f"Found {response.hits.total.value} hit(s) for query: '{query}'")
results = self.paginate_queryset(response, request, view=self) # noqa
serializer = self.serializer_class(results, many=True)
return self.get_paginated_response(serializer.data)
except Exception as e:
return HttpResponse(e, status=500)
class SearchUsersApiView(PaginatedElasticSearchApiView): # noqa
"""Search in Users"""
serializer_class = UserSerializer
document_class = UserDocument
def generate_q_expression(self, query):
return Q(
'multi_match',
query=query,
fields=[
'username',
'mobile'
], fuzziness='auto'
)
# from apps.authentication.api.v1.serializers.serializer import UserSerializer
# from rest_framework.pagination import LimitOffsetPagination
# from rest_framework.viewsets import ModelViewSet, ViewSet
# from apps.authentication.document import UserDocument
# from rest_framework.response import Response
# from django.http.response import HttpResponse
# from apps.authentication.models import User
# from rest_framework.views import APIView
# from elasticsearch_dsl.query import Q
# import abc
#
#
# class PaginatedElasticSearchApiView(APIView, LimitOffsetPagination):
# """Base ApiView Class for elasticsearch views with pagination,
# Other ApiView classes should inherit from this class"""
# serializer_class = None
# document_class = None
#
# @abc.abstractmethod
# def generate_q_expression(self, query):
# """This method should be overridden
# and return a Q() expression."""
#
# def get(self, request, query):
# try:
# q = self.generate_q_expression(query)
# search = self.document_class.search().query(q)
# response = search.execute()
#
# print(f"Found {response.hits.total.value} hit(s) for query: '{query}'")
#
# results = self.paginate_queryset(response, request, view=self) # noqa
# serializer = self.serializer_class(results, many=True)
# return self.get_paginated_response(serializer.data)
# except Exception as e:
# return HttpResponse(e, status=500)
#
#
# class SearchUsersApiView(PaginatedElasticSearchApiView): # noqa
# """Search in Users"""
#
# serializer_class = UserSerializer
# document_class = UserDocument
#
# def generate_q_expression(self, query):
# return Q(
# 'multi_match',
# query=query,
# fields=[
# 'username',
# 'mobile'
# ], fuzziness='auto'
# )

View File

@@ -1,11 +1,179 @@
from apps.authorization.api.v1.serializers import UserRelationSerializer
from rest_framework.response import Response
from rest_framework import serializers
from apps.authentication.models import User
from apps.authentication.models import (
User,
City,
Province,
Organization,
OrganizationType,
BankAccountInformation
)
from apps.authorization import models as authorize_models
import typing
class CitySerializer(serializers.ModelSerializer):
class Meta:
model = City
fields = [
'id',
'name'
]
class ProvinceSerializer(serializers.ModelSerializer):
class Meta:
model = Province
fields = [
'id',
'name'
]
class BankAccountSerializer(serializers.ModelSerializer):
class Meta:
model = BankAccountInformation
fields = [
'id',
'user',
'account',
'name',
'card',
'sheba'
]
extra_kwargs = {
'user': {'required': False},
'account': {'required': False},
'card': {'required': False},
'sheba': {'required': False}
}
def update(self, instance, validated_data):
""" update user bank account information """
instance.name = validated_data.get('name', instance.name)
instance.account = validated_data.get('account', instance.account)
instance.card = validated_data.get('card', instance.card)
instance.sheba = validated_data.get('sheba', instance.sheba)
instance.save()
return instance
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'id',
'username',
'mobile'
'password',
'first_name',
'last_name',
'is_active',
'mobile',
'phone',
'national_code',
'birthdate',
'nationality',
'ownership',
'address',
'photo',
'province',
'city',
'otp_status',
]
def update(self, instance, validated_data):
""" update user instance """
instance.username = validated_data.get('username', instance.username)
instance.password = validated_data.get('password', instance.password)
instance.first_name = validated_data.get('first_name')
instance.last_name = validated_data.get('last_name')
instance.is_active = validated_data.get('is_active')
instance.mobile = validated_data.get('mobile')
instance.phone = validated_data.get('phone')
instance.national_code = validated_data.get('national_code')
instance.birthdate = validated_data.get('birthdate')
instance.nationality = validated_data.get('nationality')
instance.ownership = validated_data.get('ownership')
instance.address = validated_data.get('address')
instance.photo = validated_data.get('photo')
instance.province = Province.objects.get(id=validated_data.get('province'))
instance.city = City.objects.get(id=validated_data.get('city'))
instance.otp_status = validated_data.get('otp_status')
instance.save()
return instance
@staticmethod
def update_relations(user: object, relation_data: dict, bank_data: dict) -> typing.Any:
"""
update user relations & bank account for user
"""
user_relation = UserRelationSerializer(data=relation_data) # Create user relation
if user_relation.is_valid(raise_exception=True):
user_relation_obj = user_relation.update(
authorize_models.UserRelations.objects.get(user=user),
validated_data=relation_data
)
bank_info = BankAccountSerializer(data=bank_data) # Create user bank information
if bank_info.is_valid(raise_exception=True):
bank_obj = bank_info.update(
BankAccountInformation.objects.get(id=bank_data['id']),
validated_data=bank_data
)
return user_relation_obj, bank_obj # noqa
class OrganizationTypeSerializer(serializers.ModelSerializer):
class Meta:
model = OrganizationType
fields = [
'id',
'key',
'name',
]
class OrganizationSerializer(serializers.ModelSerializer):
class Meta:
model = Organization
fields = [
'id',
'name',
'type',
'province',
'city',
'parent_organization',
'national_unique_id'
]
extra_kwargs = {}
def to_representation(self, instance):
representation = super().to_representation(instance)
if isinstance(instance, Organization):
representation['province'] = ProvinceSerializer(instance.province).data
representation['city'] = CitySerializer(instance.city).data
representation['type'] = OrganizationTypeSerializer(instance.type).data
if instance.parent_organization:
representation['parent_organization'] = OrganizationSerializer(instance.parent_organization).data
return representation
def update(self, instance, validated_data):
""" update user organization information """ # noqa
instance.name = validated_data.get('name', instance.name)
if validated_data.get('type'):
instance.type = OrganizationType.objects.get(id=validated_data.get('type', instance.type))
if validated_data.get('province'):
instance.province = Province.objects.get(id=validated_data.get('province', instance.province))
if validated_data.get('city'):
instance.city = City.objects.get(id=validated_data.get('city', instance.city))
if validated_data.get('parent_organization'):
instance.parent_organization = Organization.objects.get(
id=validated_data.get('parent_organization', instance.parent_organization)
)
instance.national_unique_id = validated_data.get('national_unique_id', instance.national_unique_id)
instance.save()
return instance

View File

@@ -3,16 +3,29 @@ from rest_framework.routers import DefaultRouter
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView
TokenVerifyView,
TokenBlacklistView
)
from .api import (
CustomizedTokenObtainPairView
CustomizedTokenObtainPairView,
UserViewSet,
CityViewSet,
ProvinceViewSet,
OrganizationViewSet,
OrganizationTypeViewSet
)
from .search_view import SearchUsersApiView
router = DefaultRouter()
router.register(r'user', UserViewSet, basename='user')
router.register(r'city', CityViewSet, basename='city')
router.register(r'province', ProvinceViewSet, basename='province')
router.register(r'organization', OrganizationViewSet, basename='organization')
router.register(r'organization-type', OrganizationTypeViewSet, basename='organization_type')
urlpatterns = [
path('login/', CustomizedTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('search_user/<str:query>', SearchUsersApiView.as_view(), name='search_user'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify/', TokenVerifyView.as_view(), name='token_verify'),
path('token/revoke/', TokenBlacklistView.as_view(), name='revoke_token'),
path('', include(router.urls))
]

View File

@@ -1,24 +1,24 @@
from .models import User, Province
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
@registry.register_document
class UserDocument(Document):
"""ElasticSearch Document for indexing users"""
class Index:
name = 'users'
settings = {
'number_of_shards': 1,
'number_of_replicas': 0 # number of copies from data in document
}
class Django:
model = User
fields = [
"id",
"username",
"mobile",
"nationality"
]
# from .models import User, Province
# from django_elasticsearch_dsl import Document, fields
# from django_elasticsearch_dsl.registries import registry
#
#
# @registry.register_document
# class UserDocument(Document):
# """ElasticSearch Document for indexing users"""
#
# class Index:
# name = 'users'
# settings = {
# 'number_of_shards': 1,
# 'number_of_replicas': 0 # number of copies from data in document
# }
#
# class Django:
# model = User
# fields = [
# "id",
# "username",
# "mobile",
# "nationality"
# ]

View File

@@ -0,0 +1,18 @@
from django.db import models
from typing import Any
from apps.authentication import models as authentication_models
from apps.authorization import models as authorization_models
class UserManager(models.Manager):
@staticmethod
def get_user_information(self, user_id: int) -> Any:
""" get user information in 3 models and return 3 objects """
user = super().get_queryset().get(id=user_id)
yield user
bank = authentication_models.BankAccountInformation.objects.get(user_id=user_id)
yield bank
user_relation = authorization_models.objects.get(user_id=user_id)
yield user_relation

View File

@@ -0,0 +1,35 @@
# Generated by Django 4.2.20 on 2025-05-10 08:51
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('authentication', '0007_user_ownership'),
]
operations = [
migrations.RemoveField(
model_name='organization',
name='type',
),
migrations.CreateModel(
name='OrganizationType',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_date', models.DateTimeField(auto_now_add=True)),
('modify_date', models.DateTimeField(auto_now=True)),
('trash', models.BooleanField(default=False)),
('key', models.CharField(choices=[('J', 'Jihad'), ('U', 'Union'), ('CO', 'Cooperative'), ('CMP', 'Companies')], max_length=3)),
('name', models.CharField(max_length=50, null=True)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)),
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 4.2.20 on 2025-05-10 08:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('authentication', '0008_remove_organization_type_organizationtype'),
]
operations = [
migrations.AddField(
model_name='organization',
name='type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='organization_type', to='authentication.organizationtype'),
),
]

View File

@@ -0,0 +1,49 @@
# Generated by Django 4.2.20 on 2025-05-13 06:28
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('authentication', '0009_organization_type'),
]
operations = [
migrations.AddField(
model_name='organization',
name='company_code',
field=models.CharField(default='empty', max_length=30),
),
migrations.AddField(
model_name='organization',
name='field_of_activity',
field=models.CharField(choices=[('CO', 'Country'), ('PR', 'Province'), ('CI', 'City')], default='EM', max_length=2),
),
migrations.AddField(
model_name='user',
name='is_herd_owner',
field=models.BooleanField(default=False),
),
migrations.CreateModel(
name='BankAccountInformation',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_date', models.DateTimeField(auto_now_add=True)),
('modify_date', models.DateTimeField(auto_now=True)),
('trash', models.BooleanField(default=False)),
('name', models.CharField(max_length=150)),
('card', models.CharField(max_length=25, unique=True)),
('account', models.CharField(max_length=25, unique=True)),
('sheba', models.CharField(max_length=30, unique=True)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)),
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bank_information', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.20 on 2025-05-13 06:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0010_organization_company_code_and_more'),
]
operations = [
migrations.AddField(
model_name='organization',
name='national_unique_id',
field=models.CharField(default='0', max_length=30),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.20 on 2025-05-13 07:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0011_organization_national_unique_id'),
]
operations = [
migrations.AlterField(
model_name='organization',
name='national_unique_id',
field=models.CharField(default='0', max_length=30, unique=True),
),
]

View File

@@ -0,0 +1,61 @@
# Generated by Django 4.2.20 on 2025-05-17 06:01
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('authentication', '0012_alter_organization_national_unique_id'),
]
operations = [
migrations.RemoveField(
model_name='bankaccountinformation',
name='created_by',
),
migrations.RemoveField(
model_name='bankaccountinformation',
name='modified_by',
),
migrations.RemoveField(
model_name='city',
name='created_by',
),
migrations.RemoveField(
model_name='city',
name='modified_by',
),
migrations.RemoveField(
model_name='organization',
name='created_by',
),
migrations.RemoveField(
model_name='organization',
name='modified_by',
),
migrations.RemoveField(
model_name='organizationtype',
name='created_by',
),
migrations.RemoveField(
model_name='organizationtype',
name='modified_by',
),
migrations.RemoveField(
model_name='province',
name='created_by',
),
migrations.RemoveField(
model_name='province',
name='modified_by',
),
migrations.RemoveField(
model_name='user',
name='created_by',
),
migrations.RemoveField(
model_name='user',
name='modified_by',
),
]

View File

@@ -0,0 +1,73 @@
# Generated by Django 4.2.20 on 2025-05-17 06:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0013_remove_bankaccountinformation_created_by_and_more'),
]
operations = [
migrations.AddField(
model_name='bankaccountinformation',
name='created_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='bankaccountinformation',
name='modified_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='city',
name='created_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='city',
name='modified_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='organization',
name='created_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='organization',
name='modified_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='organizationtype',
name='created_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='organizationtype',
name='modified_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='province',
name='created_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='province',
name='modified_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='user',
name='created_by',
field=models.CharField(max_length=50, null=True),
),
migrations.AddField(
model_name='user',
name='modified_by',
field=models.CharField(max_length=50, null=True),
),
]

View File

@@ -0,0 +1,61 @@
# Generated by Django 4.2.20 on 2025-05-17 06:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('authentication', '0014_bankaccountinformation_created_by_and_more'),
]
operations = [
migrations.RemoveField(
model_name='bankaccountinformation',
name='created_by',
),
migrations.RemoveField(
model_name='bankaccountinformation',
name='modified_by',
),
migrations.RemoveField(
model_name='city',
name='created_by',
),
migrations.RemoveField(
model_name='city',
name='modified_by',
),
migrations.RemoveField(
model_name='organization',
name='created_by',
),
migrations.RemoveField(
model_name='organization',
name='modified_by',
),
migrations.RemoveField(
model_name='organizationtype',
name='created_by',
),
migrations.RemoveField(
model_name='organizationtype',
name='modified_by',
),
migrations.RemoveField(
model_name='province',
name='created_by',
),
migrations.RemoveField(
model_name='province',
name='modified_by',
),
migrations.RemoveField(
model_name='user',
name='created_by',
),
migrations.RemoveField(
model_name='user',
name='modified_by',
),
]

View File

@@ -0,0 +1,75 @@
# Generated by Django 4.2.20 on 2025-05-17 06:29
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('authentication', '0015_remove_bankaccountinformation_created_by_and_more'),
]
operations = [
migrations.AddField(
model_name='bankaccountinformation',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='bankaccountinformation',
name='modified_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='city',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='city',
name='modified_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='organization',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='organization',
name='modified_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='organizationtype',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='organizationtype',
name='modified_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='province',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='province',
name='modified_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='user',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='user',
name='modified_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -0,0 +1,73 @@
# Generated by Django 4.2.20 on 2025-05-17 06:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0016_bankaccountinformation_created_by_and_more'),
]
operations = [
migrations.AddField(
model_name='bankaccountinformation',
name='creator_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='bankaccountinformation',
name='modifier_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='city',
name='creator_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='city',
name='modifier_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='organization',
name='creator_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='organization',
name='modifier_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='organizationtype',
name='creator_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='organizationtype',
name='modifier_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='province',
name='creator_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='province',
name='modifier_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='user',
name='creator_info',
field=models.CharField(max_length=100, null=True),
),
migrations.AddField(
model_name='user',
name='modifier_info',
field=models.CharField(max_length=100, null=True),
),
]

View File

@@ -1,8 +1,9 @@
from django.db import models
from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import (
AbstractUser
)
from apps.core.models import BaseModel
from django.db import models
class User(AbstractUser, BaseModel):
@@ -36,15 +37,17 @@ class User(AbstractUser, BaseModel):
null=True
)
otp_status = models.BooleanField(default=False)
is_herd_owner = models.BooleanField(default=False)
def __str__(self):
return f'{self.username} {self.last_name}-{self.last_login}'
def save(self, *args, **kwargs):
self.password = make_password(self.password)
super(User, self).save(*args, **kwargs)
class Province(BaseModel):
class Province(BaseModel): # noqa
name = models.CharField(max_length=50)
def __str__(self):
@@ -64,9 +67,39 @@ class City(BaseModel):
super(City, self).save(*args, **kwargs)
class OrganizationType(BaseModel):
organization_keys = (
('J', 'Jihad'),
('U', 'Union'),
('CO', 'Cooperative'),
('CMP', 'Companies')
)
key = models.CharField(choices=organization_keys, max_length=3)
name = models.CharField(max_length=50, null=True)
def __str__(self):
return f'{self.key}-{self.name}'
def save(self, *args, **kwargs):
super(OrganizationType, self).save(*args, **kwargs)
class Organization(BaseModel):
name = models.CharField(max_length=50)
type = models.CharField(max_length=50)
type = models.ForeignKey(
'OrganizationType',
on_delete=models.CASCADE,
related_name="organization_type",
null=True
)
national_unique_id = models.CharField(max_length=30, default="0", unique=True)
activity_fields = (
('CO', 'Country'),
('PR', 'Province'),
('CI', 'City')
)
field_of_activity = models.CharField(max_length=2, choices=activity_fields, default='EM')
company_code = models.CharField(max_length=30, default="empty")
province = models.ForeignKey(
Province,
on_delete=models.CASCADE,
@@ -91,3 +124,21 @@ class Organization(BaseModel):
def save(self, *args, **kwargs):
super(Organization, self).save(*args, **kwargs)
class BankAccountInformation(BaseModel):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="bank_information"
)
name = models.CharField(max_length=150)
card = models.CharField(max_length=25, unique=True)
account = models.CharField(max_length=25, unique=True)
sheba = models.CharField(max_length=30, unique=True)
def __str__(self):
return f'{self.name}-{self.card}'
def save(self, *args, **kwargs):
super(BankAccountInformation, self).save(*args, **kwargs)

View File

@@ -0,0 +1,57 @@
from apps.authorization import models as authorize_models
from apps.authentication.models import OrganizationType
from apps.core import permissions
class CreateUser(permissions.BasePermission):
"""
@permission: superuser can add users
"""
def has_permission(self, request, view):
user_level_info = self.get_user_permissions(request, view)
if 'superuser' in user_level_info['permissions']:
if 'organization' in request.data.keys():
org_type = OrganizationType.objects.get( # noqa
id=request.data['organization']['type']
)
print(org_type.key)
if 'J' in user_level_info['organization_type']:
return True
if 'U' in user_level_info['organization_type']:
if org_type.key == 'J' or org_type.key == 'U':
return False
else:
return True
if 'CO' in user_level_info['organization_type']:
if org_type.key == 'J' or org_type.key == 'U' or org_type.key == 'CO':
return False
else:
return True
return True
class CreateOrganization(permissions.BasePermission):
"""
@permission for adding organization
"""
def has_permission(self, request, view):
user_level_info = self.get_user_permissions(request, view)
if 'superuser' in user_level_info['permissions']:
org_type = OrganizationType.objects.get( # noqa
id=request.data['organization']['type']
)
print(org_type.key)
if 'J' in user_level_info['organization_type']:
return True
if 'U' in user_level_info['organization_type']:
if org_type.key == 'J' or org_type.key == 'U':
return False
else:
return True
if 'CO' in user_level_info['organization_type']:
if org_type.key == 'J' or org_type.key == 'U' or org_type.key == 'CO':
return False
else:
return True