add: income-expence delete api
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from core.apps.finance.models import Expence
|
||||
from core.apps.finance.models import Expence, DeletedExpence
|
||||
|
||||
|
||||
@admin.register(Expence)
|
||||
class ExpenceAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'price', 'cash_transaction', 'status']
|
||||
|
||||
|
||||
@admin.register(DeletedExpence)
|
||||
class DeletedExpenceAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'comment', 'expence']
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from core.apps.finance.models import Income
|
||||
from core.apps.finance.models import Income, DeletedIncome
|
||||
|
||||
|
||||
@admin.register(Income)
|
||||
class IncomeAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'price', 'cash_transaction']
|
||||
list_filter = ['cash_transaction', 'payment_type']
|
||||
|
||||
|
||||
@admin.register(DeletedIncome)
|
||||
class DeletedIncomeAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'comment', 'income']
|
||||
|
||||
29
core/apps/finance/migrations/0025_deletedexpence.py
Normal file
29
core/apps/finance/migrations/0025_deletedexpence.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.2.4 on 2025-09-25 16:10
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('finance', '0024_expence_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DeletedExpence',
|
||||
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)),
|
||||
('comment', models.CharField(max_length=200)),
|
||||
('expence', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='deleted_expences', to='finance.expence')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "O'chirilgan chiqim",
|
||||
'verbose_name_plural': "O'chirilgan chiqim",
|
||||
},
|
||||
),
|
||||
]
|
||||
18
core/apps/finance/migrations/0026_expence_is_deleted.py
Normal file
18
core/apps/finance/migrations/0026_expence_is_deleted.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.4 on 2025-09-25 16:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('finance', '0025_deletedexpence'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='expence',
|
||||
name='is_deleted',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
29
core/apps/finance/migrations/0027_deletedincome.py
Normal file
29
core/apps/finance/migrations/0027_deletedincome.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.2.4 on 2025-09-25 16:30
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('finance', '0026_expence_is_deleted'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DeletedIncome',
|
||||
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)),
|
||||
('comment', models.CharField(max_length=200)),
|
||||
('income', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='deleted_incomes', to='finance.income')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "O'chirilgan kirim",
|
||||
'verbose_name_plural': "O'chirilgan kirimlar",
|
||||
},
|
||||
),
|
||||
]
|
||||
18
core/apps/finance/migrations/0028_income_is_deleted.py
Normal file
18
core/apps/finance/migrations/0028_income_is_deleted.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.4 on 2025-09-25 16:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('finance', '0027_deletedincome'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='income',
|
||||
name='is_deleted',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
@@ -41,6 +41,7 @@ class Expence(BaseModel):
|
||||
audit = models.CharField(max_length=200, null=True, blank=True)
|
||||
file = models.FileField(null=True, blank=True, upload_to='finance/expence/files/')
|
||||
status = models.CharField(max_length=20, choices=STATUS, default='PENDING', null=True, blank=True)
|
||||
is_deleted = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.cash_transaction} kassa uchun chiqim {self.price}'
|
||||
@@ -49,3 +50,14 @@ class Expence(BaseModel):
|
||||
verbose_name = 'chiqim'
|
||||
verbose_name_plural = 'chiqimlar'
|
||||
|
||||
|
||||
class DeletedExpence(BaseModel):
|
||||
expence = models.ForeignKey(Expence, on_delete=models.CASCADE, related_name='deleted_expences')
|
||||
comment = models.CharField(max_length=200)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.expence} is deleted'
|
||||
|
||||
class Meta:
|
||||
verbose_name = "O'chirilgan chiqim"
|
||||
verbose_name_plural = "O'chirilgan chiqim"
|
||||
@@ -32,6 +32,7 @@ class Income(BaseModel):
|
||||
comment = models.TextField(null=True, blank=True)
|
||||
file = models.FileField(upload_to='finance/income/file/', null=True, blank=True)
|
||||
audit = models.CharField(max_length=200, null=True, blank=True)
|
||||
is_deleted = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.cash_transaction} kassa uchun kirim {self.price}'
|
||||
@@ -41,3 +42,13 @@ class Income(BaseModel):
|
||||
verbose_name_plural = 'kirimlar'
|
||||
|
||||
|
||||
class DeletedIncome(BaseModel):
|
||||
income = models.ForeignKey(Income, on_delete=models.CASCADE, related_name='deleted_incomes')
|
||||
comment = models.CharField(max_length=200)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.income} is deleted'
|
||||
|
||||
class Meta:
|
||||
verbose_name = "O'chirilgan kirim"
|
||||
verbose_name_plural = "O'chirilgan kirimlar"
|
||||
@@ -133,3 +133,7 @@ class ExpenceListSerializer(serializers.ModelSerializer):
|
||||
'id': obj.expence_type.id,
|
||||
'name': obj.expence_type.name
|
||||
} if obj.expence_type else None
|
||||
|
||||
|
||||
class ExpenceDeleteSerializer(serializers.Serializer):
|
||||
comment = serializers.CharField()
|
||||
@@ -130,4 +130,8 @@ class IncomeCreateSerializer(serializers.ModelSerializer):
|
||||
|
||||
cash_transaction.save()
|
||||
payment_type.save()
|
||||
return income
|
||||
return income
|
||||
|
||||
|
||||
class IncomeDeleteSerializer(serializers.Serializer):
|
||||
comment = serializers.CharField()
|
||||
@@ -50,6 +50,7 @@ urlpatterns = [
|
||||
path('list/', income_views.IncomeListApiView.as_view()),
|
||||
path('create/', income_views.IncomeCreateApiView.as_view()),
|
||||
path('<uuid:counterparty_id>/list/', income_views.CounterpartyIncomeListApiView.as_view()),
|
||||
path('<uuid:id>/delete/', income_views.IncomeDeleteApiView.as_view()),
|
||||
]
|
||||
)),
|
||||
path('expence_type/', include(
|
||||
@@ -66,6 +67,7 @@ urlpatterns = [
|
||||
path('create/', expence_views.ExpenceCreateApiView.as_view()),
|
||||
path('<uuid:counterparty_id>/list/', expence_views.CounterpartyExpenceListApiView.as_view()),
|
||||
path('<uuid:id>/change-status/', expence_views.ChangeExpenceStatusApiView.as_view()),
|
||||
path('<uuid:id>/delete/', expence_views.ExpenceDeleteApiView.as_view()),
|
||||
]
|
||||
)),
|
||||
path('income_contract/', include(
|
||||
|
||||
@@ -6,7 +6,7 @@ from rest_framework.response import Response
|
||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||
|
||||
from core.apps.accounts.permissions.permissions import HasRolePermission
|
||||
from core.apps.finance.models import Expence
|
||||
from core.apps.finance.models import Expence, DeletedExpence
|
||||
from core.apps.finance.serializers import expence as serializers
|
||||
from core.apps.finance.filters.expence import ExpenceFilter
|
||||
from core.apps.counterparty.models import Counterparty
|
||||
@@ -107,4 +107,39 @@ class ChangeExpenceStatusApiView(views.APIView):
|
||||
'message': 'expence status successfully updated',
|
||||
},
|
||||
status=200
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class ExpenceDeleteApiView(generics.GenericAPIView):
|
||||
serializer_class = serializers.ExpenceDeleteSerializer
|
||||
queryset = Expence.objects.all()
|
||||
permission_classes = [HasRolePermission]
|
||||
|
||||
def post(self, request, id):
|
||||
expence = get_object_or_404(Expence, id=id)
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid(raise_exception=True):
|
||||
comment = serializer.validated_data.get('comment')
|
||||
DeletedExpence.objects.create(
|
||||
expence=expence,
|
||||
comment=comment
|
||||
)
|
||||
expence.is_deleted = True
|
||||
if expence.currency == 'uzs':
|
||||
expence.cash_transaction.expence_balance_uzs += expence.price
|
||||
expence.cash_transaction.total_balance_uzs += expence.price
|
||||
expence.payment_type.total_uzs += expence.price
|
||||
else:
|
||||
expence.cash_transaction.expence_balance_usd += expence.price
|
||||
expence.cash_transaction.total_balance_usd += expence.price
|
||||
expence.payment_type.total_usd += expence.price
|
||||
|
||||
expence.cash_transaction.save()
|
||||
expence.payment_type.save()
|
||||
expence.save()
|
||||
return Response(
|
||||
{
|
||||
'success': True,
|
||||
'message': 'Expence deleted',
|
||||
}, status=200
|
||||
)
|
||||
@@ -5,7 +5,7 @@ from rest_framework.response import Response
|
||||
|
||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||
|
||||
from core.apps.finance.models import Income
|
||||
from core.apps.finance.models import Income, DeletedIncome
|
||||
from core.apps.finance.serializers import income as serializers
|
||||
from core.apps.accounts.permissions.permissions import HasRolePermission
|
||||
from core.apps.finance.filters.income import IncomeFilter
|
||||
@@ -76,4 +76,38 @@ class CounterpartyIncomeListApiView(generics.GenericAPIView):
|
||||
if page is not None:
|
||||
ser = self.serializer_class(page, many=True)
|
||||
return self.get_paginated_response(ser.data)
|
||||
|
||||
|
||||
|
||||
class IncomeDeleteApiView(generics.GenericAPIView):
|
||||
serializer_class = serializers.IncomeDeleteSerializer
|
||||
queryset = Income.objects.all()
|
||||
permission_classes = [HasRolePermission]
|
||||
|
||||
def post(self, request, id):
|
||||
income = get_object_or_404(Income, id=id)
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid(raise_exception=True):
|
||||
comment = serializer.validated_data.get('comment')
|
||||
DeletedIncome.objects.create(
|
||||
income=income,
|
||||
comment=comment
|
||||
)
|
||||
income.is_deleted = True
|
||||
if income.currency == 'uzs':
|
||||
income.cash_transaction.expence_balance_uzs -= income.price
|
||||
income.cash_transaction.total_balance_uzs -= income.price
|
||||
income.payment_type.total_uzs -= income.price
|
||||
else:
|
||||
income.cash_transaction.expence_balance_usd -= income.price
|
||||
income.cash_transaction.total_balance_usd -= income.price
|
||||
income.payment_type.total_usd -= income.price
|
||||
|
||||
income.cash_transaction.save()
|
||||
income.payment_type.save()
|
||||
income.save()
|
||||
return Response(
|
||||
{
|
||||
'success': True,
|
||||
'message': 'Income deleted',
|
||||
}, status=200
|
||||
)
|
||||
Reference in New Issue
Block a user