diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6ba69809..d56657ad 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/.idea/unicoding.iml b/.idea/unicoding.iml
index 3e4215da..09dec57c 100644
--- a/.idea/unicoding.iml
+++ b/.idea/unicoding.iml
@@ -13,8 +13,10 @@
-
-
+
+
+
+
diff --git a/accounting/api/account.py b/accounting/api/account.py
index e843e616..053dee32 100644
--- a/accounting/api/account.py
+++ b/accounting/api/account.py
@@ -57,8 +57,6 @@ def get_account_balances(request):
return status.HTTP_200_OK, result
-
-
class Balance:
def __init__(self, balances):
balance1 = balances[0]
@@ -85,3 +83,23 @@ def __add__(self, other):
'sum': self.balanceIQD
}]
+ def __sub__(self, other):
+ self.balanceIQD -= other.balanceIQD
+ self.balanceUSD -= other.balanceUSD
+ return [{
+ 'currency': 'USD',
+ 'sum': self.balanceUSD
+ }, {
+ 'currency': 'IQD',
+ 'sum': self.balanceIQD
+ }]
+
+ def __gt__(self, other):
+ return self.balanceUSD > other.balanceUSD, self.balanceIQD > other.balanceIQD
+
+ def __lt__(self, other):
+ return self.balanceUSD < other.balanceUSD, self.balanceIQD < other.balanceIQD
+
+ def is_zero(self):
+ return self.balanceUSD == 0 and self.balanceIQD == 0
+
diff --git a/accounting/migrations/0001_initial.py b/accounting/migrations/0001_initial.py
index ee702c1f..49f26655 100644
--- a/accounting/migrations/0001_initial.py
+++ b/accounting/migrations/0001_initial.py
@@ -1,7 +1,8 @@
-# Generated by Django 4.0.6 on 2022-07-20 14:33
+# Generated by Django 4.0.6 on 2022-08-02 19:21
from django.db import migrations, models
import django.db.models.deletion
+import mptt.fields
class Migration(migrations.Migration):
@@ -16,17 +17,26 @@ class Migration(migrations.Migration):
name='Account',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('type', models.CharField(choices=[('ASSETS', 'ASSETS'), ('LIABILITIES', 'LIABILITIES'), ('INCOME', 'INCOME'), ('EXPENSES', 'EXPENSES')], max_length=255)),
- ('code', models.CharField(max_length=20)),
- ('full_code', models.CharField(max_length=25)),
- ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='accounting.account')),
+ ('type', models.CharField(choices=[('ASSETS', 'Assets'), ('LIABILITIES', 'Liabilities'), ('INCOME', 'Income'), ('EXPENSES', 'Expenses')], max_length=255)),
+ ('name', models.CharField(max_length=255)),
+ ('code', models.CharField(blank=True, max_length=20, null=True)),
+ ('full_code', models.CharField(blank=True, max_length=25, null=True)),
+ ('extra', models.JSONField(blank=True, default=dict, null=True)),
+ ('lft', models.PositiveIntegerField(editable=False)),
+ ('rght', models.PositiveIntegerField(editable=False)),
+ ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
+ ('level', models.PositiveIntegerField(editable=False)),
+ ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='accounting.account')),
],
+ options={
+ 'abstract': False,
+ },
),
migrations.CreateModel(
name='Transaction',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('type', models.CharField(choices=[('invoice', 'invoice'), ('income', 'income'), ('expense', 'expense'), ('bill', 'bill')], max_length=255)),
+ ('type', models.CharField(choices=[('invoice', 'Invoice'), ('income', 'Income'), ('expense', 'Expense'), ('bill', 'Bill')], max_length=255)),
('description', models.CharField(max_length=255)),
],
),
@@ -36,8 +46,11 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('amount', models.DecimalField(decimal_places=2, max_digits=19)),
('currency', models.CharField(choices=[('USD', 'USD'), ('IQD', 'IQD')], max_length=3)),
- ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounting.account')),
- ('transaction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounting.transaction')),
+ ('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='journal_entries', to='accounting.account')),
+ ('transaction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='journal_entries', to='accounting.transaction')),
],
+ options={
+ 'verbose_name_plural': 'Journal Entries',
+ },
),
]
diff --git a/accounting/migrations/0002_alter_journalentry_options_account_name.py b/accounting/migrations/0002_alter_journalentry_options_account_name.py
deleted file mode 100644
index 5b499031..00000000
--- a/accounting/migrations/0002_alter_journalentry_options_account_name.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.0.6 on 2022-07-20 14:46
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('accounting', '0001_initial'),
- ]
-
- operations = [
- migrations.AlterModelOptions(
- name='journalentry',
- options={'verbose_name_plural': 'Journal Entries'},
- ),
- migrations.AddField(
- model_name='account',
- name='name',
- field=models.CharField(default='', max_length=255),
- preserve_default=False,
- ),
- ]
diff --git a/accounting/migrations/0003_account_extra_alter_account_type.py b/accounting/migrations/0003_account_extra_alter_account_type.py
deleted file mode 100644
index a06b8aa7..00000000
--- a/accounting/migrations/0003_account_extra_alter_account_type.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 4.0.6 on 2022-07-20 16:12
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('accounting', '0002_alter_journalentry_options_account_name'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='account',
- name='extra',
- field=models.JSONField(default=dict),
- ),
- migrations.AlterField(
- model_name='account',
- name='type',
- field=models.CharField(choices=[('ASSETS', 'Assets'), ('LIABILITIES', 'Liabilities'), ('INCOME', 'Income'), ('EXPENSES', 'Expenses')], max_length=255),
- ),
- ]
diff --git a/accounting/migrations/0004_alter_account_extra.py b/accounting/migrations/0004_alter_account_extra.py
deleted file mode 100644
index 6944ee6d..00000000
--- a/accounting/migrations/0004_alter_account_extra.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 4.0.6 on 2022-07-23 10:57
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('accounting', '0003_account_extra_alter_account_type'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='account',
- name='extra',
- field=models.JSONField(default=dict, null=True),
- ),
- ]
diff --git a/accounting/migrations/0005_alter_account_extra_alter_journalentry_account_and_more.py b/accounting/migrations/0005_alter_account_extra_alter_journalentry_account_and_more.py
deleted file mode 100644
index 2c929883..00000000
--- a/accounting/migrations/0005_alter_account_extra_alter_journalentry_account_and_more.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Generated by Django 4.0.6 on 2022-07-25 14:57
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('accounting', '0004_alter_account_extra'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='account',
- name='extra',
- field=models.JSONField(blank=True, default=dict, null=True),
- ),
- migrations.AlterField(
- model_name='journalentry',
- name='account',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='journal_entries', to='accounting.account'),
- ),
- migrations.AlterField(
- model_name='transaction',
- name='type',
- field=models.CharField(choices=[('invoice', 'Invoice'), ('income', 'Income'), ('expense', 'Expense'), ('bill', 'Bill')], max_length=255),
- ),
- ]
diff --git a/accounting/migrations/0006_alter_account_code_alter_account_full_code_and_more.py b/accounting/migrations/0006_alter_account_code_alter_account_full_code_and_more.py
deleted file mode 100644
index ff9ec80e..00000000
--- a/accounting/migrations/0006_alter_account_code_alter_account_full_code_and_more.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Generated by Django 4.0.6 on 2022-07-26 14:44
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('accounting', '0005_alter_account_extra_alter_journalentry_account_and_more'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='account',
- name='code',
- field=models.CharField(blank=True, max_length=20, null=True),
- ),
- migrations.AlterField(
- model_name='account',
- name='full_code',
- field=models.CharField(blank=True, max_length=25, null=True),
- ),
- migrations.AlterField(
- model_name='journalentry',
- name='transaction',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='journal_entries', to='accounting.transaction'),
- ),
- ]
diff --git a/accounting/models.py b/accounting/models.py
index a7d49b7f..f4e5c66c 100644
--- a/accounting/models.py
+++ b/accounting/models.py
@@ -3,6 +3,7 @@
from django.dispatch import receiver
from django.db.models.signals import post_save
from accounting.exceptions import AccountingEquationError
+from mptt.models import MPTTModel, TreeForeignKey
'''
@@ -48,8 +49,8 @@ class CurrencyChoices(models.TextChoices):
IQD = 'IQD', 'IQD'
-class Account(models.Model):
- parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
+class Account(MPTTModel):
+ parent = TreeForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
type = models.CharField(max_length=255, choices=AccountTypeChoices.choices)
name = models.CharField(max_length=255)
code = models.CharField(max_length=20, null=True, blank=True)
@@ -60,7 +61,11 @@ def __str__(self):
return f'{self.full_code} - {self.name}'
def balance(self):
- return self.journal_entries.values('currency').annotate(sum=Sum('amount')).order_by()
+ result = [
+ account.journal_entries.values('currency').annotate(sum=Sum('amount')).order_by()
+ for account in self.get_descendants(include_self=True)
+ ]
+ return Sum(result)
# def save(
# self, force_insert=False, force_update=False, using=None, update_fields=None
diff --git a/requirements.txt b/requirements.txt
index d1d09d01..e69de29b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,18 +0,0 @@
-asgiref==3.5.2
-Django==4.0.6
-django-ninja==0.19.0
-django-rest-framework==0.1.0
-djangorestframework==3.13.1
-dnspython==2.2.1
-ecdsa==0.18.0
-email-validator==1.2.1
-idna==3.3
-psycopg2-binary==2.9.3
-pyasn1==0.4.8
-pydantic==1.9.1
-python-jose==3.3.0
-pytz==2022.1
-rsa==4.9
-six==1.16.0
-sqlparse==0.4.2
-typing_extensions==4.3.0