Add sales types, party adjustments, FunZone party fields, and treasury fee support
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
78
accounting/migrations/0003_sales_module.py
Normal file
78
accounting/migrations/0003_sales_module.py
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Generated manually for sales module extensions
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounting', '0002_seed_chart_of_accounts'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SalesType',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||||
|
('code', models.CharField(db_index=True, max_length=50)),
|
||||||
|
('name', models.CharField(max_length=150)),
|
||||||
|
('description', models.TextField(blank=True, default='')),
|
||||||
|
('active', models.BooleanField(default=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'accounting_sales_types',
|
||||||
|
'ordering': ['code'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='PartyAdjustment',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||||
|
('number', models.PositiveIntegerField(default=0)),
|
||||||
|
('kind', models.CharField(choices=[('debit', 'Debit'), ('credit', 'Credit')], max_length=20)),
|
||||||
|
('date', models.DateField()),
|
||||||
|
('amount', models.FloatField(default=0)),
|
||||||
|
('description', models.TextField(blank=True, default='')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('party', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='adjustments', to='accounting.party')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'accounting_party_adjustments',
|
||||||
|
'ordering': ['-date', '-number'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invoice',
|
||||||
|
name='document_type',
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[('proforma', 'Proforma'), ('invoice', 'Invoice'), ('return', 'Return')],
|
||||||
|
default='invoice',
|
||||||
|
max_length=20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invoice',
|
||||||
|
name='related_invoice',
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name='derived_docs',
|
||||||
|
to='accounting.invoice',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invoice',
|
||||||
|
name='sales_type',
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name='invoices',
|
||||||
|
to='accounting.salestype',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
84
accounting/migrations/0004_party_funzone_fields.py
Normal file
84
accounting/migrations/0004_party_funzone_fields.py
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounting', '0003_sales_module'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='external_id',
|
||||||
|
field=models.UUIDField(blank=True, db_index=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='external_source',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=30),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='first_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=100),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='last_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=100),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='username',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=100),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='email',
|
||||||
|
field=models.EmailField(blank=True, default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='national_code',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=20),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='iban',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=34),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='wallet_balance',
|
||||||
|
field=models.FloatField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='is_active',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='is_verified',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='birthday',
|
||||||
|
field=models.DateField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='party',
|
||||||
|
name='venues',
|
||||||
|
field=models.JSONField(blank=True, default=list),
|
||||||
|
),
|
||||||
|
migrations.AddConstraint(
|
||||||
|
model_name='party',
|
||||||
|
constraint=models.UniqueConstraint(
|
||||||
|
condition=models.Q(external_id__isnull=False),
|
||||||
|
fields=('external_id', 'external_source'),
|
||||||
|
name='unique_external_party',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
16
accounting/migrations/0005_treasury_source.py
Normal file
16
accounting/migrations/0005_treasury_source.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounting', '0004_party_funzone_fields'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='treasurytxn',
|
||||||
|
name='source',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=120),
|
||||||
|
),
|
||||||
|
]
|
||||||
26
accounting/migrations/0006_treasury_fee_fields.py
Normal file
26
accounting/migrations/0006_treasury_fee_fields.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounting', '0005_treasury_source'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='treasurytxn',
|
||||||
|
name='tax_amount',
|
||||||
|
field=models.FloatField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='treasurytxn',
|
||||||
|
name='platform_profit_amount',
|
||||||
|
field=models.FloatField(default=0),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='treasurytxn',
|
||||||
|
name='owner_net_amount',
|
||||||
|
field=models.FloatField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -40,6 +40,11 @@ class Party(models.Model):
|
|||||||
('customer', 'Customer'),
|
('customer', 'Customer'),
|
||||||
('supplier', 'Supplier'),
|
('supplier', 'Supplier'),
|
||||||
]
|
]
|
||||||
|
EXTERNAL_SOURCES = [
|
||||||
|
('', 'Manual'),
|
||||||
|
('funzone_customer', 'FunZone Customer'),
|
||||||
|
('funzone_owner', 'FunZone Owner'),
|
||||||
|
]
|
||||||
|
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
kind = models.CharField(max_length=20, choices=PARTY_KINDS)
|
kind = models.CharField(max_length=20, choices=PARTY_KINDS)
|
||||||
@@ -48,11 +53,33 @@ class Party(models.Model):
|
|||||||
economic_code = models.CharField(max_length=50, blank=True, default='')
|
economic_code = models.CharField(max_length=50, blank=True, default='')
|
||||||
address = models.TextField(blank=True, default='')
|
address = models.TextField(blank=True, default='')
|
||||||
opening_balance = models.FloatField(default=0)
|
opening_balance = models.FloatField(default=0)
|
||||||
|
external_id = models.UUIDField(null=True, blank=True, db_index=True)
|
||||||
|
external_source = models.CharField(
|
||||||
|
max_length=30, choices=EXTERNAL_SOURCES, blank=True, default=''
|
||||||
|
)
|
||||||
|
first_name = models.CharField(max_length=100, blank=True, default='')
|
||||||
|
last_name = models.CharField(max_length=100, blank=True, default='')
|
||||||
|
username = models.CharField(max_length=100, blank=True, default='')
|
||||||
|
email = models.EmailField(blank=True, default='')
|
||||||
|
national_code = models.CharField(max_length=20, blank=True, default='')
|
||||||
|
iban = models.CharField(max_length=34, blank=True, default='')
|
||||||
|
wallet_balance = models.FloatField(default=0)
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
is_verified = models.BooleanField(default=False)
|
||||||
|
birthday = models.DateField(null=True, blank=True)
|
||||||
|
venues = models.JSONField(default=list, blank=True)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'accounting_parties'
|
db_table = 'accounting_parties'
|
||||||
ordering = ['name']
|
ordering = ['name']
|
||||||
|
constraints = [
|
||||||
|
models.UniqueConstraint(
|
||||||
|
fields=['external_id', 'external_source'],
|
||||||
|
condition=models.Q(external_id__isnull=False),
|
||||||
|
name='unique_external_party',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -120,6 +147,51 @@ class VoucherLine(models.Model):
|
|||||||
return f"Line {self.account_id} D:{self.debit} C:{self.credit}"
|
return f"Line {self.account_id} D:{self.debit} C:{self.credit}"
|
||||||
|
|
||||||
|
|
||||||
|
class SalesType(models.Model):
|
||||||
|
"""A sales category (نوع فروش) referenced by sales documents."""
|
||||||
|
|
||||||
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
|
code = models.CharField(max_length=50, db_index=True)
|
||||||
|
name = models.CharField(max_length=150)
|
||||||
|
description = models.TextField(blank=True, default='')
|
||||||
|
active = models.BooleanField(default=True)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'accounting_sales_types'
|
||||||
|
ordering = ['code']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.code} - {self.name}"
|
||||||
|
|
||||||
|
|
||||||
|
class PartyAdjustment(models.Model):
|
||||||
|
"""Debit/credit notice adjusting a customer receivable (اعلامیه بدهکار/بستانکار)."""
|
||||||
|
|
||||||
|
ADJUSTMENT_KINDS = [
|
||||||
|
('debit', 'Debit'),
|
||||||
|
('credit', 'Credit'),
|
||||||
|
]
|
||||||
|
|
||||||
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
|
number = models.PositiveIntegerField(default=0)
|
||||||
|
party = models.ForeignKey(
|
||||||
|
Party, on_delete=models.CASCADE, related_name='adjustments'
|
||||||
|
)
|
||||||
|
kind = models.CharField(max_length=20, choices=ADJUSTMENT_KINDS)
|
||||||
|
date = models.DateField()
|
||||||
|
amount = models.FloatField(default=0)
|
||||||
|
description = models.TextField(blank=True, default='')
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'accounting_party_adjustments'
|
||||||
|
ordering = ['-date', '-number']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.kind} notice #{self.number}"
|
||||||
|
|
||||||
|
|
||||||
class Invoice(models.Model):
|
class Invoice(models.Model):
|
||||||
"""A sales or purchase invoice (فاکتور)."""
|
"""A sales or purchase invoice (فاکتور)."""
|
||||||
|
|
||||||
@@ -127,6 +199,11 @@ class Invoice(models.Model):
|
|||||||
('sale', 'Sale'),
|
('sale', 'Sale'),
|
||||||
('purchase', 'Purchase'),
|
('purchase', 'Purchase'),
|
||||||
]
|
]
|
||||||
|
DOCUMENT_TYPES = [
|
||||||
|
('proforma', 'Proforma'),
|
||||||
|
('invoice', 'Invoice'),
|
||||||
|
('return', 'Return'),
|
||||||
|
]
|
||||||
STATUS_CHOICES = [
|
STATUS_CHOICES = [
|
||||||
('draft', 'Draft'),
|
('draft', 'Draft'),
|
||||||
('confirmed', 'Confirmed'),
|
('confirmed', 'Confirmed'),
|
||||||
@@ -135,10 +212,19 @@ class Invoice(models.Model):
|
|||||||
|
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
kind = models.CharField(max_length=20, choices=INVOICE_KINDS)
|
kind = models.CharField(max_length=20, choices=INVOICE_KINDS)
|
||||||
|
document_type = models.CharField(
|
||||||
|
max_length=20, choices=DOCUMENT_TYPES, default='invoice'
|
||||||
|
)
|
||||||
number = models.PositiveIntegerField(default=0)
|
number = models.PositiveIntegerField(default=0)
|
||||||
party = models.ForeignKey(
|
party = models.ForeignKey(
|
||||||
Party, on_delete=models.SET_NULL, null=True, blank=True, related_name='invoices'
|
Party, on_delete=models.SET_NULL, null=True, blank=True, related_name='invoices'
|
||||||
)
|
)
|
||||||
|
sales_type = models.ForeignKey(
|
||||||
|
SalesType, on_delete=models.SET_NULL, null=True, blank=True, related_name='invoices'
|
||||||
|
)
|
||||||
|
related_invoice = models.ForeignKey(
|
||||||
|
'self', on_delete=models.SET_NULL, null=True, blank=True, related_name='derived_docs'
|
||||||
|
)
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft')
|
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft')
|
||||||
note = models.TextField(blank=True, default='')
|
note = models.TextField(blank=True, default='')
|
||||||
@@ -194,8 +280,12 @@ class TreasuryTxn(models.Model):
|
|||||||
Party, on_delete=models.SET_NULL, null=True, blank=True, related_name='treasury_txns'
|
Party, on_delete=models.SET_NULL, null=True, blank=True, related_name='treasury_txns'
|
||||||
)
|
)
|
||||||
amount = models.FloatField(default=0)
|
amount = models.FloatField(default=0)
|
||||||
|
tax_amount = models.FloatField(default=0)
|
||||||
|
platform_profit_amount = models.FloatField(default=0)
|
||||||
|
owner_net_amount = models.FloatField(default=0)
|
||||||
reference = models.CharField(max_length=120, blank=True, default='')
|
reference = models.CharField(max_length=120, blank=True, default='')
|
||||||
description = models.TextField(blank=True, default='')
|
description = models.TextField(blank=True, default='')
|
||||||
|
source = models.CharField(max_length=120, blank=True, default='')
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ from .models import (
|
|||||||
Invoice,
|
Invoice,
|
||||||
InvoiceLine,
|
InvoiceLine,
|
||||||
Party,
|
Party,
|
||||||
|
PartyAdjustment,
|
||||||
Payslip,
|
Payslip,
|
||||||
Product,
|
Product,
|
||||||
|
SalesType,
|
||||||
TreasuryTxn,
|
TreasuryTxn,
|
||||||
Voucher,
|
Voucher,
|
||||||
VoucherLine,
|
VoucherLine,
|
||||||
@@ -31,10 +33,22 @@ class AccountSerializer(serializers.ModelSerializer):
|
|||||||
class PartySerializer(serializers.ModelSerializer):
|
class PartySerializer(serializers.ModelSerializer):
|
||||||
economicCode = serializers.CharField(source='economic_code', required=False, allow_blank=True)
|
economicCode = serializers.CharField(source='economic_code', required=False, allow_blank=True)
|
||||||
openingBalance = serializers.FloatField(source='opening_balance', required=False)
|
openingBalance = serializers.FloatField(source='opening_balance', required=False)
|
||||||
|
externalId = serializers.UUIDField(source='external_id', required=False, allow_null=True)
|
||||||
|
externalSource = serializers.CharField(source='external_source', required=False, allow_blank=True)
|
||||||
|
firstName = serializers.CharField(source='first_name', required=False, allow_blank=True)
|
||||||
|
lastName = serializers.CharField(source='last_name', required=False, allow_blank=True)
|
||||||
|
nationalCode = serializers.CharField(source='national_code', required=False, allow_blank=True)
|
||||||
|
walletBalance = serializers.FloatField(source='wallet_balance', required=False)
|
||||||
|
isActive = serializers.BooleanField(source='is_active', required=False)
|
||||||
|
isVerified = serializers.BooleanField(source='is_verified', required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Party
|
model = Party
|
||||||
fields = ['id', 'kind', 'name', 'phone', 'economicCode', 'address', 'openingBalance']
|
fields = [
|
||||||
|
'id', 'kind', 'name', 'phone', 'economicCode', 'address', 'openingBalance',
|
||||||
|
'externalId', 'externalSource', 'firstName', 'lastName', 'username', 'email',
|
||||||
|
'nationalCode', 'iban', 'walletBalance', 'isActive', 'isVerified', 'birthday', 'venues',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class ProductSerializer(serializers.ModelSerializer):
|
class ProductSerializer(serializers.ModelSerializer):
|
||||||
@@ -87,6 +101,20 @@ class VoucherSerializer(serializers.ModelSerializer):
|
|||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
class SalesTypeSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = SalesType
|
||||||
|
fields = ['id', 'code', 'name', 'description', 'active']
|
||||||
|
|
||||||
|
|
||||||
|
class PartyAdjustmentSerializer(serializers.ModelSerializer):
|
||||||
|
partyId = serializers.PrimaryKeyRelatedField(source='party', queryset=Party.objects.all())
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = PartyAdjustment
|
||||||
|
fields = ['id', 'number', 'partyId', 'kind', 'date', 'amount', 'description']
|
||||||
|
|
||||||
|
|
||||||
class InvoiceLineSerializer(serializers.ModelSerializer):
|
class InvoiceLineSerializer(serializers.ModelSerializer):
|
||||||
# Lenient: accepts client-generated ids (ignored on write, recreated server-side).
|
# Lenient: accepts client-generated ids (ignored on write, recreated server-side).
|
||||||
id = serializers.CharField(required=False)
|
id = serializers.CharField(required=False)
|
||||||
@@ -105,11 +133,21 @@ class InvoiceSerializer(serializers.ModelSerializer):
|
|||||||
partyId = serializers.PrimaryKeyRelatedField(
|
partyId = serializers.PrimaryKeyRelatedField(
|
||||||
source='party', queryset=Party.objects.all(), allow_null=True, required=False
|
source='party', queryset=Party.objects.all(), allow_null=True, required=False
|
||||||
)
|
)
|
||||||
|
documentType = serializers.CharField(source='document_type', required=False)
|
||||||
|
salesTypeId = serializers.PrimaryKeyRelatedField(
|
||||||
|
source='sales_type', queryset=SalesType.objects.all(), allow_null=True, required=False
|
||||||
|
)
|
||||||
|
relatedInvoiceId = serializers.PrimaryKeyRelatedField(
|
||||||
|
source='related_invoice', queryset=Invoice.objects.all(), allow_null=True, required=False
|
||||||
|
)
|
||||||
lines = InvoiceLineSerializer(many=True)
|
lines = InvoiceLineSerializer(many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Invoice
|
model = Invoice
|
||||||
fields = ['id', 'kind', 'number', 'partyId', 'date', 'status', 'note', 'lines']
|
fields = [
|
||||||
|
'id', 'kind', 'documentType', 'number', 'partyId', 'salesTypeId',
|
||||||
|
'relatedInvoiceId', 'date', 'status', 'note', 'lines',
|
||||||
|
]
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
@@ -139,9 +177,18 @@ class TreasuryTxnSerializer(serializers.ModelSerializer):
|
|||||||
source='party', queryset=Party.objects.all(), allow_null=True, required=False
|
source='party', queryset=Party.objects.all(), allow_null=True, required=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
amount = serializers.FloatField(required=False)
|
||||||
|
taxAmount = serializers.FloatField(source='tax_amount', required=False)
|
||||||
|
platformProfitAmount = serializers.FloatField(source='platform_profit_amount', required=False)
|
||||||
|
ownerNetAmount = serializers.FloatField(source='owner_net_amount', required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TreasuryTxn
|
model = TreasuryTxn
|
||||||
fields = ['id', 'number', 'kind', 'method', 'date', 'partyId', 'amount', 'reference', 'description']
|
fields = [
|
||||||
|
'id', 'number', 'kind', 'method', 'date', 'partyId', 'amount',
|
||||||
|
'taxAmount', 'platformProfitAmount', 'ownerNetAmount',
|
||||||
|
'reference', 'description', 'source',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class EmployeeSerializer(serializers.ModelSerializer):
|
class EmployeeSerializer(serializers.ModelSerializer):
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ from .views import (
|
|||||||
CompanySettingsView,
|
CompanySettingsView,
|
||||||
EmployeeViewSet,
|
EmployeeViewSet,
|
||||||
InvoiceViewSet,
|
InvoiceViewSet,
|
||||||
|
PartyAdjustmentViewSet,
|
||||||
PartyViewSet,
|
PartyViewSet,
|
||||||
PayslipViewSet,
|
PayslipViewSet,
|
||||||
ProductViewSet,
|
ProductViewSet,
|
||||||
|
SalesTypeViewSet,
|
||||||
TreasuryTxnViewSet,
|
TreasuryTxnViewSet,
|
||||||
VoucherViewSet,
|
VoucherViewSet,
|
||||||
reset_accounting_data,
|
reset_accounting_data,
|
||||||
@@ -20,6 +22,8 @@ router.register(r'parties', PartyViewSet, basename='accounting-party')
|
|||||||
router.register(r'products', ProductViewSet, basename='accounting-product')
|
router.register(r'products', ProductViewSet, basename='accounting-product')
|
||||||
router.register(r'vouchers', VoucherViewSet, basename='accounting-voucher')
|
router.register(r'vouchers', VoucherViewSet, basename='accounting-voucher')
|
||||||
router.register(r'invoices', InvoiceViewSet, basename='accounting-invoice')
|
router.register(r'invoices', InvoiceViewSet, basename='accounting-invoice')
|
||||||
|
router.register(r'sales-types', SalesTypeViewSet, basename='accounting-sales-type')
|
||||||
|
router.register(r'party-adjustments', PartyAdjustmentViewSet, basename='accounting-party-adjustment')
|
||||||
router.register(r'treasury', TreasuryTxnViewSet, basename='accounting-treasury')
|
router.register(r'treasury', TreasuryTxnViewSet, basename='accounting-treasury')
|
||||||
router.register(r'employees', EmployeeViewSet, basename='accounting-employee')
|
router.register(r'employees', EmployeeViewSet, basename='accounting-employee')
|
||||||
router.register(r'payslips', PayslipViewSet, basename='accounting-payslip')
|
router.register(r'payslips', PayslipViewSet, basename='accounting-payslip')
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ from .models import (
|
|||||||
Employee,
|
Employee,
|
||||||
Invoice,
|
Invoice,
|
||||||
Party,
|
Party,
|
||||||
|
PartyAdjustment,
|
||||||
Payslip,
|
Payslip,
|
||||||
Product,
|
Product,
|
||||||
|
SalesType,
|
||||||
TreasuryTxn,
|
TreasuryTxn,
|
||||||
Voucher,
|
Voucher,
|
||||||
)
|
)
|
||||||
@@ -22,9 +24,11 @@ from .serializers import (
|
|||||||
CompanySettingsSerializer,
|
CompanySettingsSerializer,
|
||||||
EmployeeSerializer,
|
EmployeeSerializer,
|
||||||
InvoiceSerializer,
|
InvoiceSerializer,
|
||||||
|
PartyAdjustmentSerializer,
|
||||||
PartySerializer,
|
PartySerializer,
|
||||||
PayslipSerializer,
|
PayslipSerializer,
|
||||||
ProductSerializer,
|
ProductSerializer,
|
||||||
|
SalesTypeSerializer,
|
||||||
TreasuryTxnSerializer,
|
TreasuryTxnSerializer,
|
||||||
VoucherSerializer,
|
VoucherSerializer,
|
||||||
)
|
)
|
||||||
@@ -66,6 +70,18 @@ class InvoiceViewSet(_AdminModelViewSet):
|
|||||||
pagination_class = None
|
pagination_class = None
|
||||||
|
|
||||||
|
|
||||||
|
class SalesTypeViewSet(_AdminModelViewSet):
|
||||||
|
queryset = SalesType.objects.all()
|
||||||
|
serializer_class = SalesTypeSerializer
|
||||||
|
pagination_class = None
|
||||||
|
|
||||||
|
|
||||||
|
class PartyAdjustmentViewSet(_AdminModelViewSet):
|
||||||
|
queryset = PartyAdjustment.objects.all()
|
||||||
|
serializer_class = PartyAdjustmentSerializer
|
||||||
|
pagination_class = None
|
||||||
|
|
||||||
|
|
||||||
class TreasuryTxnViewSet(_AdminModelViewSet):
|
class TreasuryTxnViewSet(_AdminModelViewSet):
|
||||||
queryset = TreasuryTxn.objects.all()
|
queryset = TreasuryTxn.objects.all()
|
||||||
serializer_class = TreasuryTxnSerializer
|
serializer_class = TreasuryTxnSerializer
|
||||||
@@ -117,6 +133,8 @@ def reset_accounting_data(request):
|
|||||||
"""Wipes all accounting data and recreates a clean, zeroed starting point."""
|
"""Wipes all accounting data and recreates a clean, zeroed starting point."""
|
||||||
Voucher.objects.all().delete()
|
Voucher.objects.all().delete()
|
||||||
Invoice.objects.all().delete()
|
Invoice.objects.all().delete()
|
||||||
|
PartyAdjustment.objects.all().delete()
|
||||||
|
SalesType.objects.all().delete()
|
||||||
TreasuryTxn.objects.all().delete()
|
TreasuryTxn.objects.all().delete()
|
||||||
Payslip.objects.all().delete()
|
Payslip.objects.all().delete()
|
||||||
Employee.objects.all().delete()
|
Employee.objects.all().delete()
|
||||||
|
|||||||
Reference in New Issue
Block a user