add finance app

This commit is contained in:
behruz-dev
2025-08-04 13:35:22 +05:00
parent 1dffabde44
commit bb8fbd4ca7
32 changed files with 336 additions and 69 deletions

View File

View File

@@ -0,0 +1 @@
from .cash_transaction import *

View File

@@ -0,0 +1,9 @@
from django.contrib import admin
from core.apps.finance.models import CashTransaction
@admin.register(CashTransaction)
class CachTransaction(admin.ModelAdmin):
list_display = ['id', 'name']
search_fields = ['name']

View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class FinanceConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'core.apps.finance'

View File

@@ -0,0 +1,28 @@
# Generated by Django 5.2.4 on 2025-08-04 11:58
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='CashTransaction',
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)),
('name', models.CharField(max_length=200, unique=True)),
],
options={
'verbose_name': 'Kassa',
'verbose_name_plural': 'Kassalar',
},
),
]

View File

View File

@@ -0,0 +1 @@
from .cash_transaction import *

View File

@@ -0,0 +1,16 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from core.apps.shared.models import BaseModel
class CashTransaction(BaseModel):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return self.name
class Meta:
verbose_name = _('Kassa')
verbose_name_plural = _('Kassalar')

View File

@@ -0,0 +1,11 @@
from rest_framework import serializers
from core.apps.finance.models import CashTransaction
class CashTransactionListSerializer(serializers.ModelSerializer):
class Meta:
model = CashTransaction
fields = [
'id', 'name'
]

12
core/apps/finance/urls.py Normal file
View File

@@ -0,0 +1,12 @@
from django.urls import path, include
from core.apps.finance.views import cash_transaction as cash_views
urlpatterns = [
path('cash_transaction/', include(
[
path('list/', cash_views.CashTransactionListApiView.as_view()),
]
))
]

View File

View File

@@ -0,0 +1,14 @@
from rest_framework import generics
from core.apps.finance.models import CashTransaction
from core.apps.finance.serializers import cash_transaction as serializers
from core.apps.accounts.permissions.permissions import HasRolePermission
from core.apps.shared.paginations.custom import CustomPageNumberPagination
class CashTransactionListApiView(generics.ListAPIView):
permission_classes = [HasRolePermission]
required_permissions = []
serializer_class = serializers.CashTransactionListSerializer
queryset = CashTransaction.objects.all()
pagination_class = CustomPageNumberPagination

View File

@@ -0,0 +1,29 @@
# Generated by Django 5.2.4 on 2025-08-04 11:12
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orders', '0003_delete_orderapplication'),
('projects', '0003_alter_project_folder'),
]
operations = [
migrations.RemoveField(
model_name='order',
name='project_department',
),
migrations.AddField(
model_name='order',
name='project_folder',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='order', to='projects.projectfolder'),
),
migrations.AlterField(
model_name='order',
name='project',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='orders', to='projects.project'),
),
]

View File

@@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
from core.apps.shared.models import BaseModel
from core.apps.products.models import Product, Unity
from core.apps.projects.models import Project, ProjectDepartment
from core.apps.projects.models import Project, ProjectFolder
from core.apps.accounts.models import User
from core.apps.wherehouse.models import WhereHouse
@@ -21,11 +21,11 @@ class Order(BaseModel):
unity = models.ForeignKey(
Unity, on_delete=models.CASCADE, related_name='orders'
)
project = models.ForeignKey(
Project, on_delete=models.CASCADE, related_name='orders'
project_folder = models.ForeignKey(
ProjectFolder, on_delete=models.CASCADE, related_name='order', null=True
)
project_department = models.ForeignKey(
ProjectDepartment, on_delete=models.DO_NOTHING, null=True, blank=True
project = models.ForeignKey(
Project, on_delete=models.SET_NULL, related_name='orders', null=True, blank=True
)
wherehouse = models.ForeignKey(
WhereHouse, on_delete=models.CASCADE, related_name='orders'

View File

@@ -11,11 +11,8 @@ from core.apps.products.serializers.unity import UnityListSerializer
from core.apps.wherehouse.models import WhereHouse
from core.apps.wherehouse.serializers.wherehouse import WhereHouseListSerializer
# projects
from core.apps.projects.models import Project, ProjectDepartment
from core.apps.projects.serializers.project import (
ProjectListSerializer,
ProjectDepartmentListSerializer
)
from core.apps.projects.models import Project, ProjectFolder
from core.apps.projects.serializers.project import ProjectListSerializer
@@ -24,8 +21,8 @@ class OrderCreateSerializer(serializers.Serializer):
unity_id = serializers.UUIDField()
quantity = serializers.IntegerField()
wherehouse_id = serializers.UUIDField()
project_id = serializers.UUIDField()
project_department_id = serializers.UUIDField(required=False)
project_id = serializers.UUIDField(required=False)
project_folder_id = serializers.UUIDField()
date = serializers.DateField()
def validate(self, data):
@@ -33,10 +30,10 @@ class OrderCreateSerializer(serializers.Serializer):
product = Product.objects.get(id=data['product_id'])
unity = Unity.objects.get(id=data['unity_id'])
wherehouse = WhereHouse.objects.get(id=data['wherehouse_id'])
project = Project.objects.get(id=data['project_id'])
if data.get('project_department_id'):
ProjectDepartment.objects.get(
id=data['project_department_id']
project_folder = ProjectFolder.objects.get(id=data['project_folder_id'])
if data.get('project_id'):
Project.objects.get(
id=data['project_id']
)
except Product.DoesNotExist:
raise serializers.ValidationError("Product not found")
@@ -44,18 +41,18 @@ class OrderCreateSerializer(serializers.Serializer):
raise serializers.ValidationError("Unity not found")
except WhereHouse.DoesNotExist:
raise serializers.ValidationError("Where House not found")
except ProjectFolder.DoesNotExist:
raise serializers.ValidationError("Project Folder not found")
try:
if data.get('project_id'):
data['project'] = Project.objects.get(id=data['project_id'])
except Project.DoesNotExist:
raise serializers.ValidationError("Project not found")
try:
if data.get('project_department_id'):
data['project_department'] = ProjectDepartment.objects.get(id=data['project_department_id'])
except ProjectDepartment.DoesNotExist:
raise serializers.ValidationError("Project Department not found")
data['product'] = product
data['unity'] = unity
data['wherehouse'] = wherehouse
data['project'] = project
data['project_folder'] = project_folder
return data
def create(self, validated_data):
@@ -64,8 +61,8 @@ class OrderCreateSerializer(serializers.Serializer):
product=validated_data.get('product'),
unity=validated_data.get('unity'),
wherehouse=validated_data.get('wherehouse'),
project_folder=validated_data.get('project_folder'),
project=validated_data.get('project'),
project_department=validated_data.get('project_department'),
quantity=validated_data.get('quantity'),
date=validated_data.get('date')
)
@@ -76,12 +73,12 @@ class OrderListSerializer(serializers.ModelSerializer):
product = ProductListSerializer()
unity = UnityListSerializer()
project = ProjectListSerializer()
project_department = ProjectDepartmentListSerializer()
wherehouse = WhereHouseListSerializer()
project_folder = ProjectFolder()
class Meta:
model = Order
fields = [
'id', 'product', 'unity', 'quantity', 'project', 'project_department',
'id', 'product', 'unity', 'quantity', 'project', 'project_folder',
'wherehouse', 'date', 'status', 'employee'
]

View File

@@ -10,7 +10,7 @@ from core.apps.shared.paginations.custom import CustomPageNumberPagination
class OrderListApiView(generics.ListAPIView):
serializer_class = serializers.OrderListSerializer
queryset = Order.objects.select_related(
'product', 'unity', 'project', 'project_department', 'wherehouse'
'product', 'unity', 'project', 'project_folder', 'wherehouse'
)
permission_classes = [HasRolePermission]
required_permissions = []

View File

@@ -1 +1,2 @@
from .project import *
from .project import *
from .builder import *

View File

@@ -0,0 +1,9 @@
from django.contrib import admin
from core.apps.projects.models import Builder
@admin.register(Builder)
class BuilderAdmin(admin.ModelAdmin):
list_display = ['id', 'name']

View File

@@ -1,24 +1,14 @@
from django.contrib import admin
from core.apps.projects.models.project import ProjectDepartment, Project, ProjectFolder
from core.apps.projects.models.project import Project, ProjectFolder
class ProjectDepartmentInline(admin.TabularInline):
model = ProjectDepartment
extra = 0
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
list_display = ['name', 'location', 'start_date', 'end_date']
search_fields = ['name']
inlines = [ProjectDepartmentInline]
@admin.register(ProjectDepartment)
class ProjectDepartmentAdmin(admin.ModelAdmin):
list_display = ['name', 'project']
search_fields = ['name']
inlines = []
@admin.register(ProjectFolder)

View File

@@ -0,0 +1,17 @@
# Generated by Django 5.2.4 on 2025-08-04 11:12
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('orders', '0004_remove_order_project_department_order_project_folder_and_more'),
('projects', '0003_alter_project_folder'),
]
operations = [
migrations.DeleteModel(
name='ProjectDepartment',
),
]

View File

@@ -0,0 +1,77 @@
# Generated by Django 5.2.4 on 2025-08-04 11:58
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('finance', '0001_initial'),
('projects', '0004_delete_projectdepartment'),
('wherehouse', '0002_stockmovemend'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Builder',
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)),
('name', models.CharField(max_length=200, unique=True)),
],
options={
'verbose_name': 'Quruvchi',
'verbose_name_plural': 'Quruvchilar',
},
),
migrations.AddField(
model_name='project',
name='area',
field=models.PositiveBigIntegerField(null=True),
),
migrations.AddField(
model_name='project',
name='benifit_plan',
field=models.PositiveBigIntegerField(null=True),
),
migrations.AddField(
model_name='project',
name='boss',
field=models.ManyToManyField(related_name='project_bosses', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='project',
name='cash_transaction',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='finance.cashtransaction'),
),
migrations.AddField(
model_name='project',
name='currency',
field=models.CharField(choices=[('usd', 'usd'), ('uzs', 'uzs')], default='uzs', max_length=3),
),
migrations.AddField(
model_name='project',
name='foreman',
field=models.ManyToManyField(related_name='project_foremans', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='project',
name='other_members',
field=models.ManyToManyField(related_name='project_members', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='project',
name='wherehouse',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='wherehouse.wherehouse'),
),
migrations.AddField(
model_name='project',
name='builder',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='projects.builder'),
),
]

View File

@@ -1 +1,2 @@
from .project import *
from .project import *
from .builder import *

View File

@@ -0,0 +1,15 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from core.apps.shared.models import BaseModel
class Builder(BaseModel):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return self.name
class Meta:
verbose_name = _('Quruvchi')
verbose_name_plural = _('Quruvchilar')

View File

@@ -2,6 +2,10 @@ 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.builder import Builder
from core.apps.accounts.models.user import User
from core.apps.wherehouse.models.wherehouse import WhereHouse
from core.apps.finance.models import CashTransaction
class ProjectFolder(BaseModel):
@@ -23,24 +27,29 @@ class Project(BaseModel):
folder = models.ForeignKey(
ProjectFolder, on_delete=models.SET_NULL, null=True, blank=True, related_name='projects'
)
builder = models.ForeignKey(
Builder, on_delete=models.CASCADE, related_name='projects', null=True
)
area = models.PositiveBigIntegerField(null=True)
# project workers
boss = models.ManyToManyField(User, related_name='project_bosses')
foreman = models.ManyToManyField(User, related_name='project_foremans')
other_members = models.ManyToManyField(User, related_name='project_members')
# project settings
wherehouse = models.ForeignKey(
WhereHouse, on_delete=models.CASCADE, related_name='projects', null=True
)
cash_transaction = models.ForeignKey(
CashTransaction, on_delete=models.CASCADE, related_name='projects', null=True
)
currency = models.CharField(choices=[('usd', 'usd'),('uzs','uzs')], max_length=3, default='uzs')
benifit_plan = models.PositiveBigIntegerField(null=True)
def __str__(self):
return self.name
class Meta:
verbose_name = _('Loyiha')
verbose_name_plural = _('Loyihalar')
class ProjectDepartment(BaseModel):
project = models.ForeignKey(
Project, on_delete=models.CASCADE, related_name='project_departments'
)
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Meta:
verbose_name = _("Loyiha Bo'limi")
verbose_name_plural = _("Loyiha Bo'limlari")
verbose_name_plural = _('Loyihalar')

View File

@@ -0,0 +1,9 @@
from rest_framework import serializers
from core.apps.projects.models import Builder
class BuilderListSerializer(serializers.ModelSerializer):
class Meta:
model = Builder
fields = ['id', 'name']

View File

@@ -2,15 +2,7 @@ from django.db import transaction
from rest_framework import serializers
from core.apps.projects.models.project import Project, ProjectDepartment, ProjectFolder
class ProjectDepartmentListSerializer(serializers.ModelSerializer):
class Meta:
model = ProjectDepartment
fields = [
'id', 'name'
]
from core.apps.projects.models.project import Project, ProjectFolder
class ProjectListSerializer(serializers.ModelSerializer):
@@ -22,12 +14,10 @@ class ProjectListSerializer(serializers.ModelSerializer):
class ProjectDetailSerialzier(serializers.ModelSerializer):
project_departments = ProjectDepartmentListSerializer(many=True)
class Meta:
model = Project
fields = [
'id', 'name', 'location', 'start_date', 'end_date', 'project_departments'
'id', 'name', 'location', 'start_date', 'end_date',
]

View File

@@ -1,6 +1,7 @@
from django.urls import path, include
from core.apps.projects.views import project as project_views
from core.apps.projects.views import builder as builder_views
urlpatterns = [
path('project/', include(
@@ -16,5 +17,10 @@ urlpatterns = [
path('list/', project_views.ProjectFolderListApiView.as_view()),
path('create/project/', project_views.ProjectFolderCreateProjectApiView.as_view()),
]
)),
path('builder/', include(
[
path('list/', builder_views.BuilderListApiView.as_view()),
]
))
]

View File

@@ -0,0 +1,17 @@
from rest_framework import generics
from core.apps.projects.models import Builder
from core.apps.projects.serializers import builder as serializers
from core.apps.accounts.permissions.permissions import HasRolePermission
from core.apps.shared.paginations.custom import CustomPageNumberPagination
class BuilderListApiView(generics.ListAPIView):
serializer_class = serializers.BuilderListSerializer
queryset = Builder.objects.all()
permission_classes = [HasRolePermission]
required_permissions = []
pagination_class = CustomPageNumberPagination

View File

@@ -1,7 +1,7 @@
from rest_framework import generics, status
from rest_framework.response import Response
from core.apps.projects.models.project import Project, ProjectDepartment, ProjectFolder
from core.apps.projects.models.project import Project, ProjectFolder
from core.apps.projects.serializers import project as serializers
from core.apps.accounts.permissions.permissions import HasRolePermission
from core.apps.shared.paginations.custom import CustomPageNumberPagination
@@ -17,7 +17,7 @@ class ProjectListApiView(generics.ListAPIView):
class ProjectDetailApiView(generics.RetrieveAPIView):
serializer_class = serializers.ProjectDetailSerialzier
queryset = Project.objects.prefetch_related('project_departments')
queryset = Project.objects.all()
permission_classes = [HasRolePermission]
required_permissions = []
lookup_field = 'id'