fix project create api
This commit is contained in:
@@ -33,4 +33,4 @@ urlpatterns = [
|
|||||||
# Media and Static Files
|
# Media and Static Files
|
||||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
urlpatterns += [path('silk/', include('silk.urls', namespace='silk'))]
|
# urlpatterns += [path('silk/', include('silk.urls', namespace='silk'))]
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
permissions = [
|
permissions = [
|
||||||
{"code": "can_see_product_wherehouse", "name": "permission for see wherehouse list"},
|
{"code": "project", "name": "project all access"},
|
||||||
{
|
{
|
||||||
"code": "can_add_product_wherehouse",
|
"code": "project_folder",
|
||||||
"name": "permission for add product in wherehouse"
|
"name": "project folder all access"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
18
core/apps/accounts/migrations/0003_alter_role_permissions.py
Normal file
18
core/apps/accounts/migrations/0003_alter_role_permissions.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.2.4 on 2025-08-05 10:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounts', '0002_permission_role_user_role'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='role',
|
||||||
|
name='permissions',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='roles', to='accounts.permission'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -7,7 +7,7 @@ from core.apps.accounts.models.permission import Permission
|
|||||||
|
|
||||||
class Role(BaseModel):
|
class Role(BaseModel):
|
||||||
name = models.CharField(max_length=200, unique=True)
|
name = models.CharField(max_length=200, unique=True)
|
||||||
permissions = models.ManyToManyField(Permission, related_name='roles')
|
permissions = models.ManyToManyField(Permission, related_name='roles', blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Generated by Django 5.2.4 on 2025-08-05 09:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('finance', '0002_paymenttype_cashtransaction_employees_and_more'),
|
||||||
|
('projects', '0005_builder_project_area_project_benifit_plan_and_more'),
|
||||||
|
('wherehouse', '0002_stockmovemend'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='project',
|
||||||
|
name='cash_transaction',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='project',
|
||||||
|
name='wherehouse',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='project',
|
||||||
|
name='cash_transaction',
|
||||||
|
field=models.ManyToManyField(null=True, related_name='projects', to='finance.cashtransaction'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='project',
|
||||||
|
name='wherehouse',
|
||||||
|
field=models.ManyToManyField(related_name='projects', to='wherehouse.wherehouse'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.2.4 on 2025-08-05 09:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('finance', '0002_paymenttype_cashtransaction_employees_and_more'),
|
||||||
|
('projects', '0006_remove_project_cash_transaction_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='project',
|
||||||
|
name='cash_transaction',
|
||||||
|
field=models.ManyToManyField(related_name='projects', to='finance.cashtransaction'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
core/apps/projects/migrations/0008_projectfolder_color.py
Normal file
18
core/apps/projects/migrations/0008_projectfolder_color.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.2.4 on 2025-08-05 09:37
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('projects', '0007_alter_project_cash_transaction'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='projectfolder',
|
||||||
|
name='color',
|
||||||
|
field=models.CharField(choices=[('ORANGE', 'orange'), ('GREEN', 'green'), ('BLUE', 'blue'), ('PURPLE', 'purple'), ('RED', 'red')], default='ORANGE', max_length=10),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
core/apps/projects/migrations/0009_project_status.py
Normal file
18
core/apps/projects/migrations/0009_project_status.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.2.4 on 2025-08-05 10:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('projects', '0008_projectfolder_color'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='project',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(choices=[('PLANNED', 'planned'), ('IN_PROGRESS', 'in progress'), ('FINISHED', 'finished'), ('SUSPENDED', 'suspended')], default='PLANNED', max_length=20),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -9,7 +9,15 @@ from core.apps.finance.models import CashTransaction
|
|||||||
|
|
||||||
|
|
||||||
class ProjectFolder(BaseModel):
|
class ProjectFolder(BaseModel):
|
||||||
|
COLORS = (
|
||||||
|
('ORANGE', 'orange'),
|
||||||
|
('GREEN', 'green'),
|
||||||
|
('BLUE', 'blue'),
|
||||||
|
('PURPLE', 'purple'),
|
||||||
|
('RED', 'red')
|
||||||
|
)
|
||||||
name = models.CharField(max_length=200)
|
name = models.CharField(max_length=200)
|
||||||
|
color = models.CharField(max_length=10, choices=COLORS, default='ORANGE')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -20,6 +28,13 @@ class ProjectFolder(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class Project(BaseModel):
|
class Project(BaseModel):
|
||||||
|
STATUS = (
|
||||||
|
('PLANNED', 'planned'),
|
||||||
|
('IN_PROGRESS', 'in progress'),
|
||||||
|
('FINISHED', 'finished'),
|
||||||
|
('SUSPENDED', 'suspended'),
|
||||||
|
)
|
||||||
|
|
||||||
name = models.CharField(max_length=200)
|
name = models.CharField(max_length=200)
|
||||||
location = models.CharField(max_length=200)
|
location = models.CharField(max_length=200)
|
||||||
start_date = models.DateField()
|
start_date = models.DateField()
|
||||||
@@ -42,10 +57,11 @@ class Project(BaseModel):
|
|||||||
WhereHouse, related_name='projects'
|
WhereHouse, related_name='projects'
|
||||||
)
|
)
|
||||||
cash_transaction = models.ManyToManyField(
|
cash_transaction = models.ManyToManyField(
|
||||||
CashTransaction, related_name='projects', null=True
|
CashTransaction, related_name='projects'
|
||||||
)
|
)
|
||||||
currency = models.CharField(choices=[('usd', 'usd'),('uzs','uzs')], max_length=3, default='uzs')
|
currency = models.CharField(choices=[('usd', 'usd'),('uzs','uzs')], max_length=3, default='uzs')
|
||||||
benifit_plan = models.PositiveBigIntegerField(null=True)
|
benifit_plan = models.PositiveBigIntegerField(null=True)
|
||||||
|
status = models.CharField(max_length=20, choices=STATUS, default='PLANNED')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class ProjectDetailSerialzier(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Project
|
model = Project
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'name', 'location', 'start_date', 'end_date',
|
'id', 'name', 'location', 'start_date', 'end_date', 'status', 'benifit_plan'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -27,16 +27,47 @@ class ProjectCreateSerializer(serializers.Serializer):
|
|||||||
end_date = serializers.DateField()
|
end_date = serializers.DateField()
|
||||||
name = serializers.CharField()
|
name = serializers.CharField()
|
||||||
|
|
||||||
|
builder_id = serializers.UUIDField()
|
||||||
|
area = serializers.IntegerField()
|
||||||
|
|
||||||
|
boss = serializers.ListSerializer(child=serializers.UUIDField())
|
||||||
|
foreman = serializers.ListSerializer(child=serializers.UUIDField())
|
||||||
|
other_members = serializers.ListSerializer(child=serializers.UUIDField())
|
||||||
|
|
||||||
|
wherehouse = serializers.ListSerializer(child=serializers.UUIDField())
|
||||||
|
cash_transaction = serializers.ListSerializer(child=serializers.UUIDField())
|
||||||
|
currency = serializers.ChoiceField(choices=[('uzs', 'uzs'), ('usd', 'usd')])
|
||||||
|
benifit_plan = serializers.IntegerField()
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
|
boss_ids = validated_data.pop('boss')
|
||||||
|
foreman_ids = validated_data.pop('foreman')
|
||||||
|
other_member_ids = validated_data.pop('other_members')
|
||||||
|
warehouse_ids = validated_data.pop('wherehouse')
|
||||||
|
cash_transaction_ids = validated_data.pop('cash_transaction')
|
||||||
|
builder_id = validated_data.pop('builder_id')
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
return Project.objects.create(
|
project = Project.objects.create(
|
||||||
name=validated_data.get('name'),
|
name=validated_data.get('name'),
|
||||||
start_date=validated_data.get('start_date'),
|
start_date=validated_data.get('start_date'),
|
||||||
end_date=validated_data.get('end_date'),
|
end_date=validated_data.get('end_date'),
|
||||||
location=validated_data.get('location')
|
location=validated_data.get('location'),
|
||||||
|
area=validated_data.get('area'),
|
||||||
|
currency=validated_data.get('currency'),
|
||||||
|
benifit_plan=validated_data.get('benifit_plan'),
|
||||||
|
builder_id=builder_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
project.boss.set(boss_ids)
|
||||||
|
project.foreman.set(foreman_ids)
|
||||||
|
project.other_members.set(other_member_ids)
|
||||||
|
project.wherehouse.set(warehouse_ids)
|
||||||
|
project.cash_transaction.set(cash_transaction_ids)
|
||||||
|
|
||||||
|
return project
|
||||||
|
|
||||||
|
# Project Folder
|
||||||
class ProjectFolderCreateSerializer(serializers.Serializer):
|
class ProjectFolderCreateSerializer(serializers.Serializer):
|
||||||
name = serializers.CharField()
|
name = serializers.CharField()
|
||||||
|
|
||||||
@@ -80,3 +111,30 @@ class ProjectFolderProjectCreateSerializer(serializers.Serializer):
|
|||||||
end_date=validated_data.get('end_date')
|
end_date=validated_data.get('end_date')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectFolderUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = ProjectFolder
|
||||||
|
fields = [
|
||||||
|
'name', 'color'
|
||||||
|
]
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
instance.name = validated_data.get('name', instance.name)
|
||||||
|
instance.color = validated_data.get('color', instance.color)
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectFolderDetailSerializer(serializers.ModelSerializer):
|
||||||
|
projects = ProjectListSerializer(many=True)
|
||||||
|
projects_count = serializers.SerializerMethodField(method_name='get_projects_count')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = ProjectFolder
|
||||||
|
fields = [
|
||||||
|
'id', 'name', 'color', 'projects_count', 'projects'
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_projects_count(self, obj):
|
||||||
|
return obj.projects.count()
|
||||||
@@ -16,6 +16,9 @@ urlpatterns = [
|
|||||||
path('create/', project_views.ProjectFolderCreateApiView.as_view()),
|
path('create/', project_views.ProjectFolderCreateApiView.as_view()),
|
||||||
path('list/', project_views.ProjectFolderListApiView.as_view()),
|
path('list/', project_views.ProjectFolderListApiView.as_view()),
|
||||||
path('create/project/', project_views.ProjectFolderCreateProjectApiView.as_view()),
|
path('create/project/', project_views.ProjectFolderCreateProjectApiView.as_view()),
|
||||||
|
path('<uuid:id>/update/', project_views.ProjectFolderUpdateApiView.as_view()),
|
||||||
|
path('<uuid:id>/', project_views.ProjectFolderDetailApiView.as_view()),
|
||||||
|
path('<uuid:id>/delete/', project_views.ProjectFolderDeleteApiView.as_view()),
|
||||||
]
|
]
|
||||||
)),
|
)),
|
||||||
path('builder/', include(
|
path('builder/', include(
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
from rest_framework import generics, status
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from rest_framework import generics, status, views
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from core.apps.projects.models.project import Project, ProjectFolder
|
from core.apps.projects.models.project import Project, ProjectFolder
|
||||||
@@ -11,15 +13,18 @@ class ProjectListApiView(generics.ListAPIView):
|
|||||||
serializer_class = serializers.ProjectListSerializer
|
serializer_class = serializers.ProjectListSerializer
|
||||||
queryset = Project.objects.all()
|
queryset = Project.objects.all()
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
required_permissions = []
|
required_permissions = ['project']
|
||||||
pagination_class = CustomPageNumberPagination
|
pagination_class = CustomPageNumberPagination
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Project.objects.exclude(folder__isnull=False)
|
||||||
|
|
||||||
|
|
||||||
class ProjectDetailApiView(generics.RetrieveAPIView):
|
class ProjectDetailApiView(generics.RetrieveAPIView):
|
||||||
serializer_class = serializers.ProjectDetailSerialzier
|
serializer_class = serializers.ProjectDetailSerialzier
|
||||||
queryset = Project.objects.all()
|
queryset = Project.objects.all()
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
required_permissions = []
|
required_permissions = ['project']
|
||||||
lookup_field = 'id'
|
lookup_field = 'id'
|
||||||
|
|
||||||
|
|
||||||
@@ -27,7 +32,7 @@ class ProjectCreateApiView(generics.CreateAPIView):
|
|||||||
serializer_class = serializers.ProjectCreateSerializer
|
serializer_class = serializers.ProjectCreateSerializer
|
||||||
queryset = Project.objects.all()
|
queryset = Project.objects.all()
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
required_permissions = []
|
required_permissions = ['project']
|
||||||
|
|
||||||
|
|
||||||
# Project Folder
|
# Project Folder
|
||||||
@@ -35,14 +40,14 @@ class ProjectFolderCreateApiView(generics.CreateAPIView):
|
|||||||
serializer_class = serializers.ProjectFolderCreateSerializer
|
serializer_class = serializers.ProjectFolderCreateSerializer
|
||||||
queryset = ProjectFolder.objects.all()
|
queryset = ProjectFolder.objects.all()
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
required_permissions = []
|
required_permissions = ['project_folder']
|
||||||
|
|
||||||
|
|
||||||
class ProjectFolderListApiView(generics.ListAPIView):
|
class ProjectFolderListApiView(generics.ListAPIView):
|
||||||
serializer_class = serializers.ProjectFolderListSerializer
|
serializer_class = serializers.ProjectFolderListSerializer
|
||||||
queryset = ProjectFolder.objects.prefetch_related('projects')
|
queryset = ProjectFolder.objects.prefetch_related('projects')
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
required_permissions = []
|
required_permissions = ['project_folder']
|
||||||
pagination_class = CustomPageNumberPagination
|
pagination_class = CustomPageNumberPagination
|
||||||
|
|
||||||
|
|
||||||
@@ -50,4 +55,41 @@ class ProjectFolderCreateProjectApiView(generics.CreateAPIView):
|
|||||||
serializer_class = serializers.ProjectFolderProjectCreateSerializer
|
serializer_class = serializers.ProjectFolderProjectCreateSerializer
|
||||||
queryset = Project.objects.all()
|
queryset = Project.objects.all()
|
||||||
permission_classes = [HasRolePermission]
|
permission_classes = [HasRolePermission]
|
||||||
required_permissions = []
|
required_permissions = ['project_folder']
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectFolderUpdateApiView(generics.GenericAPIView):
|
||||||
|
serializer_class = serializers.ProjectFolderUpdateSerializer
|
||||||
|
queryset = ProjectFolder.objects.all()
|
||||||
|
permission_classes = [HasRolePermission]
|
||||||
|
required_permissions = ['project_folder']
|
||||||
|
|
||||||
|
def put(self, request, id):
|
||||||
|
folder = get_object_or_404(ProjectFolder, id=id)
|
||||||
|
serializer = self.serializer_class(data=request.data, instance=folder)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return Response({'success':True, 'message': "Folder updated!"}, status=200)
|
||||||
|
return Response({"success": False, 'message': serializer.errors}, status=400)
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectFolderDetailApiView(generics.GenericAPIView):
|
||||||
|
serializer_class = serializers.ProjectFolderDetailSerializer
|
||||||
|
queryset = ProjectFolder.objects.select_related('projects')
|
||||||
|
permission_classes = [HasRolePermission]
|
||||||
|
required_permissions = ['project_folder']
|
||||||
|
|
||||||
|
def get(self, request, id):
|
||||||
|
folder = get_object_or_404(ProjectFolder, id=id)
|
||||||
|
serializer = self.serializer_class(folder)
|
||||||
|
return Response(serializer.data, status=200)
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectFolderDeleteApiView(views.APIView):
|
||||||
|
permission_classes = [HasRolePermission]
|
||||||
|
required_permissions = ['project_folder']
|
||||||
|
|
||||||
|
def delete(self, request, id):
|
||||||
|
folder = get_object_or_404(ProjectFolder, id=id)
|
||||||
|
folder.delete()
|
||||||
|
return Response({"success": True, "message": 'deleted!'}, status=204)
|
||||||
Reference in New Issue
Block a user