django-ledger 0.5.5.5__py3-none-any.whl → 0.5.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of django-ledger might be problematic. Click here for more details.
- django_ledger/__init__.py +1 -1
- django_ledger/admin/entity.py +16 -2
- django_ledger/admin/ledger.py +2 -1
- django_ledger/forms/entity.py +4 -12
- django_ledger/forms/ledger.py +19 -0
- django_ledger/forms/transactions.py +1 -1
- django_ledger/io/__init__.py +4 -1
- django_ledger/io/{io_mixin.py → io_core.py} +49 -28
- django_ledger/io/io_digest.py +7 -0
- django_ledger/io/{data_generator.py → io_generator.py} +51 -8
- django_ledger/io/io_library.py +317 -0
- django_ledger/io/{io_context.py → io_middleware.py} +16 -9
- django_ledger/migrations/0001_initial.py +413 -132
- django_ledger/migrations/0014_ledgermodel_ledger_xid_and_more.py +22 -0
- django_ledger/models/accounts.py +8 -7
- django_ledger/models/bank_account.py +12 -11
- django_ledger/models/bill.py +5 -9
- django_ledger/models/closing_entry.py +14 -14
- django_ledger/models/coa.py +1 -1
- django_ledger/models/customer.py +5 -11
- django_ledger/models/data_import.py +12 -6
- django_ledger/models/entity.py +88 -10
- django_ledger/models/estimate.py +12 -9
- django_ledger/models/invoice.py +10 -4
- django_ledger/models/items.py +11 -6
- django_ledger/models/journal_entry.py +6 -13
- django_ledger/models/ledger.py +65 -15
- django_ledger/models/mixins.py +2 -3
- django_ledger/models/purchase_order.py +11 -7
- django_ledger/models/transactions.py +3 -1
- django_ledger/models/unit.py +13 -14
- django_ledger/models/vendor.py +12 -11
- django_ledger/templates/django_ledger/journal_entry/je_list.html +3 -0
- django_ledger/templatetags/django_ledger.py +1 -1
- django_ledger/tests/base.py +1 -1
- django_ledger/urls/ledger.py +3 -0
- django_ledger/views/entity.py +9 -3
- django_ledger/views/ledger.py +14 -7
- django_ledger/views/mixins.py +9 -1
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/METADATA +8 -8
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/RECORD +45 -43
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/LICENSE +0 -0
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/WHEEL +0 -0
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Generated by Django 4.2.6 on 2024-01-15 13:11
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('django_ledger', '0013_stagedtransactionmodel_bundle_split'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name='ledgermodel',
|
|
15
|
+
name='ledger_xid',
|
|
16
|
+
field=models.SlugField(allow_unicode=True, blank=True, help_text='User Defined Ledger ID', max_length=150, null=True, verbose_name='Ledger Slug'),
|
|
17
|
+
),
|
|
18
|
+
migrations.AlterUniqueTogether(
|
|
19
|
+
name='ledgermodel',
|
|
20
|
+
unique_together={('entity', 'ledger_xid')},
|
|
21
|
+
),
|
|
22
|
+
]
|
django_ledger/models/accounts.py
CHANGED
|
@@ -44,8 +44,8 @@ from django_ledger.io.roles import (ACCOUNT_ROLE_CHOICES, BS_ROLES, GROUP_INVOIC
|
|
|
44
44
|
GROUP_LIABILITIES, GROUP_CAPITAL, GROUP_INCOME, GROUP_EXPENSES, GROUP_COGS,
|
|
45
45
|
ROOT_GROUP, BS_BUCKETS, ROOT_ASSETS, ROOT_LIABILITIES,
|
|
46
46
|
ROOT_CAPITAL, ROOT_INCOME, ROOT_EXPENSES, ROOT_COA)
|
|
47
|
-
from django_ledger.models import lazy_loader
|
|
48
47
|
from django_ledger.models.mixins import CreateUpdateMixIn
|
|
48
|
+
from django_ledger.models.utils import lazy_loader
|
|
49
49
|
from django_ledger.settings import DJANGO_LEDGER_ACCOUNT_CODE_GENERATE, DJANGO_LEDGER_ACCOUNT_CODE_USE_PREFIX
|
|
50
50
|
|
|
51
51
|
DEBIT = 'debit'
|
|
@@ -160,6 +160,11 @@ class AccountModelManager(MP_NodeManager):
|
|
|
160
160
|
"""
|
|
161
161
|
return AccountModelQuerySet(self.model).order_by('path')
|
|
162
162
|
|
|
163
|
+
def for_user(self, user_model):
|
|
164
|
+
qs = self.get_queryset()
|
|
165
|
+
if user_model.is_superuser:
|
|
166
|
+
return qs
|
|
167
|
+
|
|
163
168
|
# todo: search for uses and pass EntityModel whenever possible.
|
|
164
169
|
def for_entity(self,
|
|
165
170
|
user_model,
|
|
@@ -188,7 +193,7 @@ class AccountModelManager(MP_NodeManager):
|
|
|
188
193
|
AccountModelQuerySet
|
|
189
194
|
A QuerySet of all requested EntityModel Chart of Accounts.
|
|
190
195
|
"""
|
|
191
|
-
qs = self.
|
|
196
|
+
qs = self.for_user(user_model)
|
|
192
197
|
if select_coa_model:
|
|
193
198
|
qs = qs.select_related('coa_model')
|
|
194
199
|
|
|
@@ -203,11 +208,7 @@ class AccountModelManager(MP_NodeManager):
|
|
|
203
208
|
|
|
204
209
|
if coa_slug:
|
|
205
210
|
qs = qs.filter(coa_model__slug__exact=coa_slug)
|
|
206
|
-
|
|
207
|
-
return qs.filter(
|
|
208
|
-
Q(coa_model__entity__admin=user_model) |
|
|
209
|
-
Q(coa_model__entity__managers__in=[user_model])
|
|
210
|
-
).order_by('coa_model')
|
|
211
|
+
return qs.order_by('coa_model')
|
|
211
212
|
|
|
212
213
|
def for_entity_available(self, user_model, entity_slug, coa_slug: Optional[str] = None) -> AccountModelQuerySet:
|
|
213
214
|
"""
|
|
@@ -64,6 +64,15 @@ class BankAccountModelManager(models.Manager):
|
|
|
64
64
|
Custom defined Model Manager for the BankAccountModel.
|
|
65
65
|
"""
|
|
66
66
|
|
|
67
|
+
def for_user(self, user_model):
|
|
68
|
+
qs = self.get_queryset()
|
|
69
|
+
if user_model.is_superuser:
|
|
70
|
+
return qs
|
|
71
|
+
return qs.filter(
|
|
72
|
+
Q(entity_model__admin=user_model) |
|
|
73
|
+
Q(entity_model__managers__in=[user_model])
|
|
74
|
+
)
|
|
75
|
+
|
|
67
76
|
def for_entity(self, entity_slug, user_model) -> BankAccountModelQuerySet:
|
|
68
77
|
"""
|
|
69
78
|
Allows only the authorized user to query the BankAccountModel for a given EntityModel.
|
|
@@ -76,21 +85,13 @@ class BankAccountModelManager(models.Manager):
|
|
|
76
85
|
user_model
|
|
77
86
|
Logged in and authenticated django UserModel instance.
|
|
78
87
|
"""
|
|
79
|
-
qs = self.
|
|
88
|
+
qs = self.for_user(user_model)
|
|
80
89
|
if isinstance(entity_slug, lazy_loader.get_entity_model()):
|
|
81
90
|
return qs.filter(
|
|
82
|
-
Q(entity_model=entity_slug)
|
|
83
|
-
(
|
|
84
|
-
Q(entity_model__admin=user_model) |
|
|
85
|
-
Q(entity_model__managers__in=[user_model])
|
|
86
|
-
)
|
|
91
|
+
Q(entity_model=entity_slug)
|
|
87
92
|
)
|
|
88
93
|
return qs.filter(
|
|
89
|
-
Q(entity_model__slug__exact=entity_slug)
|
|
90
|
-
(
|
|
91
|
-
Q(entity_model__admin=user_model) |
|
|
92
|
-
Q(entity_model__managers__in=[user_model])
|
|
93
|
-
)
|
|
94
|
+
Q(entity_model__slug__exact=entity_slug)
|
|
94
95
|
)
|
|
95
96
|
|
|
96
97
|
|
django_ledger/models/bill.py
CHANGED
|
@@ -205,6 +205,8 @@ class BillModelManager(models.Manager):
|
|
|
205
205
|
Returns a BillModelQuerySet with applied filters.
|
|
206
206
|
"""
|
|
207
207
|
qs = self.get_queryset()
|
|
208
|
+
if user_model.is_superuser:
|
|
209
|
+
return qs
|
|
208
210
|
return qs.filter(
|
|
209
211
|
Q(ledger__entity__admin=user_model) |
|
|
210
212
|
Q(ledger__entity__managers__in=[user_model])
|
|
@@ -233,20 +235,14 @@ class BillModelManager(models.Manager):
|
|
|
233
235
|
BillModelQuerySet
|
|
234
236
|
Returns a BillModelQuerySet with applied filters.
|
|
235
237
|
"""
|
|
236
|
-
qs = self.
|
|
238
|
+
qs = self.for_user(user_model)
|
|
237
239
|
if isinstance(entity_slug, EntityModel):
|
|
238
240
|
return qs.filter(
|
|
239
|
-
Q(ledger__entity=entity_slug)
|
|
240
|
-
Q(ledger__entity__admin=user_model) |
|
|
241
|
-
Q(ledger__entity__managers__in=[user_model])
|
|
242
|
-
)
|
|
241
|
+
Q(ledger__entity=entity_slug)
|
|
243
242
|
)
|
|
244
243
|
elif isinstance(entity_slug, str):
|
|
245
244
|
return qs.filter(
|
|
246
|
-
Q(ledger__entity__slug__exact=entity_slug)
|
|
247
|
-
Q(ledger__entity__admin=user_model) |
|
|
248
|
-
Q(ledger__entity__managers__in=[user_model])
|
|
249
|
-
)
|
|
245
|
+
Q(ledger__entity__slug__exact=entity_slug)
|
|
250
246
|
)
|
|
251
247
|
|
|
252
248
|
|
|
@@ -35,23 +35,23 @@ class ClosingEntryModelQuerySet(models.QuerySet):
|
|
|
35
35
|
|
|
36
36
|
class ClosingEntryModelManager(models.Manager):
|
|
37
37
|
|
|
38
|
+
def for_user(self, user_model):
|
|
39
|
+
qs = self.get_queryset()
|
|
40
|
+
if user_model.is_superuser:
|
|
41
|
+
return qs
|
|
42
|
+
return qs.filter(
|
|
43
|
+
Q(entity_model__admin=user_model) |
|
|
44
|
+
Q(entity_model__managers__in=[user_model])
|
|
45
|
+
)
|
|
46
|
+
|
|
38
47
|
def for_entity(self, entity_slug, user_model):
|
|
48
|
+
qs = self.for_user(user_model)
|
|
39
49
|
if isinstance(entity_slug, lazy_loader.get_entity_model()):
|
|
40
|
-
return
|
|
41
|
-
Q(entity_model=entity_slug)
|
|
42
|
-
(
|
|
43
|
-
Q(entity_model__admin=user_model) |
|
|
44
|
-
Q(entity_model__managers__in=[user_model])
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
)
|
|
48
|
-
return self.get_queryset().filter(
|
|
49
|
-
Q(entity_model__slug__exact=entity_slug) &
|
|
50
|
-
(
|
|
51
|
-
Q(entity_model__admin=user_model) |
|
|
52
|
-
Q(entity_model__managers__in=[user_model])
|
|
50
|
+
return qs.filter(
|
|
51
|
+
Q(entity_model=entity_slug)
|
|
53
52
|
)
|
|
54
|
-
|
|
53
|
+
return qs.filter(
|
|
54
|
+
Q(entity_model__slug__exact=entity_slug)
|
|
55
55
|
)
|
|
56
56
|
|
|
57
57
|
|
django_ledger/models/coa.py
CHANGED
|
@@ -233,7 +233,7 @@ class ChartOfAccountModelAbstract(SlugNameMixIn, CreateUpdateMixIn):
|
|
|
233
233
|
message=_(f'CoA {self.uuid} already has a slug')
|
|
234
234
|
)
|
|
235
235
|
return
|
|
236
|
-
self.slug = ''.join(choices(SLUG_SUFFIX, k=
|
|
236
|
+
self.slug = f'coa-{self.entity.slug[-5:]}-' + ''.join(choices(SLUG_SUFFIX, k=15))
|
|
237
237
|
|
|
238
238
|
def configure(self, raise_exception: bool = True):
|
|
239
239
|
|
django_ledger/models/customer.py
CHANGED
|
@@ -107,6 +107,8 @@ class CustomerModelManager(models.Manager):
|
|
|
107
107
|
>>> customer_model_qs = CustomerModel.objects.for_user(user_model=request_user)
|
|
108
108
|
"""
|
|
109
109
|
qs = self.get_queryset()
|
|
110
|
+
if user_model.is_superuser:
|
|
111
|
+
return qs
|
|
110
112
|
return qs.filter(
|
|
111
113
|
Q(entity__admin=user_model) |
|
|
112
114
|
Q(entity__managers__in=[user_model])
|
|
@@ -135,22 +137,14 @@ class CustomerModelManager(models.Manager):
|
|
|
135
137
|
CustomerModelQueryset
|
|
136
138
|
A filtered CustomerModel QuerySet.
|
|
137
139
|
"""
|
|
138
|
-
qs = self.
|
|
140
|
+
qs = self.for_user(user_model)
|
|
139
141
|
|
|
140
142
|
if isinstance(entity_slug, lazy_loader.get_entity_model()):
|
|
141
143
|
return qs.filter(
|
|
142
|
-
Q(entity_model=entity_slug)
|
|
143
|
-
(
|
|
144
|
-
Q(entity_model__admin=user_model) |
|
|
145
|
-
Q(entity_model__managers__in=[user_model])
|
|
146
|
-
)
|
|
144
|
+
Q(entity_model=entity_slug)
|
|
147
145
|
)
|
|
148
146
|
return qs.filter(
|
|
149
|
-
Q(entity_model__slug__exact=entity_slug)
|
|
150
|
-
(
|
|
151
|
-
Q(entity_model__admin=user_model) |
|
|
152
|
-
Q(entity_model__managers__in=[user_model])
|
|
153
|
-
)
|
|
147
|
+
Q(entity_model__slug__exact=entity_slug)
|
|
154
148
|
)
|
|
155
149
|
|
|
156
150
|
|
|
@@ -42,14 +42,20 @@ class ImportJobModelManager(models.Manager):
|
|
|
42
42
|
'ledger_model'
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
-
def
|
|
45
|
+
def for_user(self, user_model):
|
|
46
46
|
qs = self.get_queryset()
|
|
47
|
+
if user_model.is_superuser:
|
|
48
|
+
return qs
|
|
47
49
|
return qs.filter(
|
|
48
|
-
Q(
|
|
49
|
-
(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
Q(bank_account_model__entity_model__admin=user_model) |
|
|
51
|
+
Q(bank_account_model__entity_model__managers__in=[user_model])
|
|
52
|
+
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def for_entity(self, entity_slug: str, user_model):
|
|
56
|
+
qs = self.for_user(user_model)
|
|
57
|
+
return qs.filter(
|
|
58
|
+
Q(bank_account_model__entity_model__slug__exact=entity_slug)
|
|
53
59
|
)
|
|
54
60
|
|
|
55
61
|
|
django_ledger/models/entity.py
CHANGED
|
@@ -27,7 +27,7 @@ from decimal import Decimal
|
|
|
27
27
|
from itertools import zip_longest
|
|
28
28
|
from random import choices
|
|
29
29
|
from string import ascii_lowercase, digits
|
|
30
|
-
from typing import Tuple, Union, Optional, List, Dict
|
|
30
|
+
from typing import Tuple, Union, Optional, List, Dict, Set
|
|
31
31
|
from uuid import uuid4, UUID
|
|
32
32
|
|
|
33
33
|
from django.contrib.auth import get_user_model
|
|
@@ -45,7 +45,7 @@ from django.utils.translation import gettext_lazy as _
|
|
|
45
45
|
from treebeard.mp_tree import MP_Node, MP_NodeManager, MP_NodeQuerySet
|
|
46
46
|
|
|
47
47
|
from django_ledger.io import roles as roles_module, validate_roles, IODigestContextManager
|
|
48
|
-
from django_ledger.io.
|
|
48
|
+
from django_ledger.io.io_core import IOMixIn
|
|
49
49
|
from django_ledger.models.accounts import AccountModel, AccountModelQuerySet, DEBIT, CREDIT
|
|
50
50
|
from django_ledger.models.bank_account import BankAccountModelQuerySet, BankAccountModel
|
|
51
51
|
from django_ledger.models.coa import ChartOfAccountModel, ChartOfAccountModelQuerySet
|
|
@@ -114,7 +114,7 @@ class EntityModelManager(MP_NodeManager):
|
|
|
114
114
|
|
|
115
115
|
def get_queryset(self):
|
|
116
116
|
"""Sets the custom queryset as the default."""
|
|
117
|
-
qs =
|
|
117
|
+
qs = EntityModelQuerySet(self.model).order_by('path')
|
|
118
118
|
return qs.order_by('path').select_related('admin', 'default_coa')
|
|
119
119
|
|
|
120
120
|
def for_user(self, user_model):
|
|
@@ -135,6 +135,8 @@ class EntityModelManager(MP_NodeManager):
|
|
|
135
135
|
2. Is a manager.
|
|
136
136
|
"""
|
|
137
137
|
qs = self.get_queryset()
|
|
138
|
+
if user_model.is_superuser:
|
|
139
|
+
return qs
|
|
138
140
|
return qs.filter(
|
|
139
141
|
Q(admin=user_model) |
|
|
140
142
|
Q(managers__in=[user_model])
|
|
@@ -890,8 +892,15 @@ class EntityModelAbstract(MP_Node,
|
|
|
890
892
|
return user_model.id == self.admin_id
|
|
891
893
|
|
|
892
894
|
# #### LEDGER MANAGEMENT....
|
|
893
|
-
def create_ledger(self, name):
|
|
894
|
-
|
|
895
|
+
def create_ledger(self, name: str, ledger_xid: Optional[str] = None, posted: bool = False, commit: bool = True):
|
|
896
|
+
if commit:
|
|
897
|
+
return self.ledgermodel_set.create(name=name, ledger_xid=ledger_xid, posted=posted)
|
|
898
|
+
return LedgerModel(
|
|
899
|
+
entity=self,
|
|
900
|
+
posted=posted,
|
|
901
|
+
name=name,
|
|
902
|
+
ledger_xid=ledger_xid
|
|
903
|
+
)
|
|
895
904
|
|
|
896
905
|
# #### SLUG GENERATION ###
|
|
897
906
|
@staticmethod
|
|
@@ -1293,7 +1302,7 @@ class EntityModelAbstract(MP_Node,
|
|
|
1293
1302
|
return self.get_coa_accounts(active=active, order_by=order_by)
|
|
1294
1303
|
|
|
1295
1304
|
def get_accounts_with_codes(self,
|
|
1296
|
-
code_list: Union[str, List[str]],
|
|
1305
|
+
code_list: Union[str, List[str], Set[str]],
|
|
1297
1306
|
coa_model: Optional[Union[ChartOfAccountModel, UUID, str]] = None
|
|
1298
1307
|
) -> AccountModelQuerySet:
|
|
1299
1308
|
"""
|
|
@@ -1351,12 +1360,72 @@ class EntityModelAbstract(MP_Node,
|
|
|
1351
1360
|
return account_model_qs.get(role__exact=role)
|
|
1352
1361
|
|
|
1353
1362
|
def create_account(self,
|
|
1354
|
-
|
|
1363
|
+
code: str,
|
|
1364
|
+
role: str,
|
|
1365
|
+
name: str,
|
|
1366
|
+
balance_type: str,
|
|
1367
|
+
active: bool,
|
|
1355
1368
|
coa_model: Optional[Union[ChartOfAccountModel, UUID, str]] = None,
|
|
1356
|
-
raise_exception: bool = True) ->
|
|
1369
|
+
raise_exception: bool = True) -> AccountModel:
|
|
1357
1370
|
"""
|
|
1358
1371
|
Creates a new AccountModel for the EntityModel.
|
|
1359
1372
|
|
|
1373
|
+
Parameters
|
|
1374
|
+
----------
|
|
1375
|
+
code: str
|
|
1376
|
+
The AccountModel code of the new Account.
|
|
1377
|
+
role: str
|
|
1378
|
+
The choice of role that the new Account belongs to.
|
|
1379
|
+
name: str
|
|
1380
|
+
The name of the new Account.
|
|
1381
|
+
balance_type: str
|
|
1382
|
+
The balance type of the new account. Possible values are 'debit' or 'credit'.
|
|
1383
|
+
active: bool
|
|
1384
|
+
Active status of the new account.
|
|
1385
|
+
coa_model: ChartOfAccountModel, UUID, str
|
|
1386
|
+
The ChartOfAccountsModel UUID, model instance or slug to pull accounts from. Uses default Coa if not
|
|
1387
|
+
provided.
|
|
1388
|
+
raise_exception: bool
|
|
1389
|
+
Raises EntityModelValidationError if ChartOfAccountsModel is not valid for the EntityModel instance.
|
|
1390
|
+
|
|
1391
|
+
Returns
|
|
1392
|
+
-------
|
|
1393
|
+
A tuple of ChartOfAccountModel, AccountModel
|
|
1394
|
+
The ChartOfAccountModel and AccountModel instance just created.
|
|
1395
|
+
"""
|
|
1396
|
+
if coa_model:
|
|
1397
|
+
if isinstance(coa_model, UUID):
|
|
1398
|
+
coa_model = self.chartofaccountsmodel_set.get(uuid__exact=coa_model)
|
|
1399
|
+
elif isinstance(coa_model, str):
|
|
1400
|
+
coa_model = self.chartofaccountsmodel_set.get(slug__exact=coa_model)
|
|
1401
|
+
elif isinstance(coa_model, ChartOfAccountModel):
|
|
1402
|
+
self.validate_chart_of_accounts_for_entity(
|
|
1403
|
+
coa_model=coa_model,
|
|
1404
|
+
raise_exception=raise_exception
|
|
1405
|
+
)
|
|
1406
|
+
else:
|
|
1407
|
+
coa_model = self.default_coa
|
|
1408
|
+
|
|
1409
|
+
account_model = AccountModel(
|
|
1410
|
+
code=code,
|
|
1411
|
+
name=name,
|
|
1412
|
+
role=role,
|
|
1413
|
+
active=active,
|
|
1414
|
+
balance_type=balance_type
|
|
1415
|
+
)
|
|
1416
|
+
|
|
1417
|
+
account_model.clean()
|
|
1418
|
+
return coa_model.create_account(account_model=account_model)
|
|
1419
|
+
|
|
1420
|
+
def create_account_by_kwargs(self,
|
|
1421
|
+
account_model_kwargs: Dict,
|
|
1422
|
+
coa_model: Optional[Union[ChartOfAccountModel, UUID, str]] = None,
|
|
1423
|
+
raise_exception: bool = True) -> Tuple[ChartOfAccountModel, AccountModel]:
|
|
1424
|
+
"""
|
|
1425
|
+
Creates a new AccountModel for the EntityModel by passing AccountModel KWARGS.
|
|
1426
|
+
This is a legacy method for creating a new AccountModel for the EntityModel.
|
|
1427
|
+
Will be deprecated in favor of create_account().
|
|
1428
|
+
|
|
1360
1429
|
Parameters
|
|
1361
1430
|
----------
|
|
1362
1431
|
coa_model: ChartOfAccountModel, UUID, str
|
|
@@ -1378,7 +1447,10 @@ class EntityModelAbstract(MP_Node,
|
|
|
1378
1447
|
elif isinstance(coa_model, str):
|
|
1379
1448
|
coa_model = self.chartofaccountsmodel_set.get(slug__exact=coa_model)
|
|
1380
1449
|
elif isinstance(coa_model, ChartOfAccountModel):
|
|
1381
|
-
self.validate_chart_of_accounts_for_entity(
|
|
1450
|
+
self.validate_chart_of_accounts_for_entity(
|
|
1451
|
+
coa_model=coa_model,
|
|
1452
|
+
raise_exception=raise_exception
|
|
1453
|
+
)
|
|
1382
1454
|
else:
|
|
1383
1455
|
coa_model = self.default_coa
|
|
1384
1456
|
|
|
@@ -2692,6 +2764,12 @@ class EntityModelAbstract(MP_Node,
|
|
|
2692
2764
|
data_generator.populate_entity()
|
|
2693
2765
|
|
|
2694
2766
|
# URLS ----
|
|
2767
|
+
def get_absolute_url(self):
|
|
2768
|
+
return reverse(viewname='django_ledger:entity-dashboard',
|
|
2769
|
+
kwargs={
|
|
2770
|
+
'entity_slug': self.slug
|
|
2771
|
+
})
|
|
2772
|
+
|
|
2695
2773
|
def get_dashboard_url(self) -> str:
|
|
2696
2774
|
"""
|
|
2697
2775
|
The EntityModel Dashboard URL.
|
|
@@ -2954,7 +3032,7 @@ class EntityStateModelAbstract(models.Model):
|
|
|
2954
3032
|
]
|
|
2955
3033
|
|
|
2956
3034
|
def __str__(self):
|
|
2957
|
-
return f'{self.__class__.__name__} {self.
|
|
3035
|
+
return f'{self.__class__.__name__} {self.entity_model_id}: FY: {self.fiscal_year}, KEY: {self.get_key_display()}'
|
|
2958
3036
|
|
|
2959
3037
|
|
|
2960
3038
|
class EntityStateModel(EntityStateModelAbstract):
|
django_ledger/models/estimate.py
CHANGED
|
@@ -111,6 +111,15 @@ class EstimateModelManager(models.Manager):
|
|
|
111
111
|
A custom defined EstimateModelManager that that implements custom QuerySet methods related to the EstimateModel.
|
|
112
112
|
"""
|
|
113
113
|
|
|
114
|
+
def for_user(self, user_model):
|
|
115
|
+
qs = self.get_queryset()
|
|
116
|
+
if user_model.is_superuser:
|
|
117
|
+
return qs
|
|
118
|
+
return qs.filter(
|
|
119
|
+
Q(entity__admin=user_model) |
|
|
120
|
+
Q(entity__managers__in=[user_model])
|
|
121
|
+
)
|
|
122
|
+
|
|
114
123
|
def for_entity(self, entity_slug: Union[EntityModel, str], user_model):
|
|
115
124
|
"""
|
|
116
125
|
Fetches a QuerySet of EstimateModels associated with a specific EntityModel & UserModel.
|
|
@@ -134,19 +143,13 @@ class EstimateModelManager(models.Manager):
|
|
|
134
143
|
EstimateModelQuerySet
|
|
135
144
|
Returns a EstimateModelQuerySet with applied filters.
|
|
136
145
|
"""
|
|
137
|
-
qs = self.
|
|
146
|
+
qs = self.for_user(user_model)
|
|
138
147
|
if isinstance(entity_slug, EntityModel):
|
|
139
148
|
return qs.filter(
|
|
140
|
-
Q(entity=entity_slug)
|
|
141
|
-
Q(entity__admin=user_model) |
|
|
142
|
-
Q(entity__managers__in=[user_model])
|
|
143
|
-
)
|
|
149
|
+
Q(entity=entity_slug)
|
|
144
150
|
)
|
|
145
151
|
return qs.filter(
|
|
146
|
-
Q(entity__slug__exact=entity_slug)
|
|
147
|
-
Q(entity__admin=user_model) |
|
|
148
|
-
Q(entity__managers__in=[user_model])
|
|
149
|
-
)
|
|
152
|
+
Q(entity__slug__exact=entity_slug)
|
|
150
153
|
)
|
|
151
154
|
|
|
152
155
|
|
django_ledger/models/invoice.py
CHANGED
|
@@ -179,6 +179,15 @@ class InvoiceModelManager(models.Manager):
|
|
|
179
179
|
'ledger__entity'
|
|
180
180
|
)
|
|
181
181
|
|
|
182
|
+
def for_user(self, user_model):
|
|
183
|
+
qs = self.get_queryset()
|
|
184
|
+
if user_model.is_superuser:
|
|
185
|
+
return qs
|
|
186
|
+
return qs.filter(
|
|
187
|
+
Q(ledger__entity__admin=user_model) |
|
|
188
|
+
Q(ledger__entity__managers__in=[user_model])
|
|
189
|
+
)
|
|
190
|
+
|
|
182
191
|
def for_entity(self, entity_slug, user_model) -> InvoiceModelQuerySet:
|
|
183
192
|
"""
|
|
184
193
|
Returns a QuerySet of InvoiceModels associated with a specific EntityModel & UserModel.
|
|
@@ -196,10 +205,7 @@ class InvoiceModelManager(models.Manager):
|
|
|
196
205
|
InvoiceModelQuerySet
|
|
197
206
|
A Filtered InvoiceModelQuerySet.
|
|
198
207
|
"""
|
|
199
|
-
qs = self.
|
|
200
|
-
Q(ledger__entity__admin=user_model) |
|
|
201
|
-
Q(ledger__entity__managers__in=[user_model])
|
|
202
|
-
)
|
|
208
|
+
qs = self.for_user(user_model)
|
|
203
209
|
if isinstance(entity_slug, EntityModel):
|
|
204
210
|
return qs.filter(ledger__entity=entity_slug)
|
|
205
211
|
elif isinstance(entity_slug, str):
|
django_ledger/models/items.py
CHANGED
|
@@ -879,14 +879,19 @@ class ItemTransactionModelQuerySet(models.QuerySet):
|
|
|
879
879
|
|
|
880
880
|
class ItemTransactionModelManager(models.Manager):
|
|
881
881
|
|
|
882
|
-
def
|
|
882
|
+
def for_user(self, user_model):
|
|
883
883
|
qs = self.get_queryset()
|
|
884
|
+
if user_model.is_superuser:
|
|
885
|
+
return qs
|
|
884
886
|
return qs.filter(
|
|
885
|
-
Q(
|
|
886
|
-
(
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
887
|
+
Q(item_model__entity__admin=user_model) |
|
|
888
|
+
Q(item_model__entity__managers__in=[user_model])
|
|
889
|
+
)
|
|
890
|
+
|
|
891
|
+
def for_entity(self, user_model, entity_slug):
|
|
892
|
+
qs = self.for_user(user_model)
|
|
893
|
+
return qs.filter(
|
|
894
|
+
Q(item_model__entity__slug__exact=entity_slug)
|
|
890
895
|
)
|
|
891
896
|
|
|
892
897
|
def for_bill(self, user_model, entity_slug, bill_pk):
|
|
@@ -140,6 +140,8 @@ class JournalEntryModelManager(models.Manager):
|
|
|
140
140
|
|
|
141
141
|
def for_user(self, user_model):
|
|
142
142
|
qs = self.get_queryset()
|
|
143
|
+
if user_model.is_superuser:
|
|
144
|
+
return qs
|
|
143
145
|
return qs.filter(
|
|
144
146
|
Q(ledger__entity__admin=user_model) |
|
|
145
147
|
Q(ledger__entity__managers__in=[user_model])
|
|
@@ -168,22 +170,13 @@ class JournalEntryModelManager(models.Manager):
|
|
|
168
170
|
JournalEntryModelQuerySet
|
|
169
171
|
Returns a JournalEntryModelQuerySet with applied filters.
|
|
170
172
|
"""
|
|
173
|
+
qs = self.for_user(user_model)
|
|
171
174
|
if isinstance(entity_slug, lazy_loader.get_entity_model()):
|
|
172
|
-
return
|
|
173
|
-
Q(ledger__entity=entity_slug)
|
|
174
|
-
(
|
|
175
|
-
Q(ledger__entity__admin=user_model) |
|
|
176
|
-
Q(ledger__entity__managers__in=[user_model])
|
|
177
|
-
)
|
|
178
|
-
|
|
175
|
+
return qs.filter(
|
|
176
|
+
Q(ledger__entity=entity_slug)
|
|
179
177
|
)
|
|
180
178
|
return self.get_queryset().filter(
|
|
181
|
-
Q(ledger__entity__slug__iexact=entity_slug)
|
|
182
|
-
(
|
|
183
|
-
Q(ledger__entity__admin=user_model) |
|
|
184
|
-
Q(ledger__entity__managers__in=[user_model])
|
|
185
|
-
)
|
|
186
|
-
|
|
179
|
+
Q(ledger__entity__slug__iexact=entity_slug)
|
|
187
180
|
)
|
|
188
181
|
|
|
189
182
|
def for_ledger(self, ledger_pk: Union[str, UUID], entity_slug, user_model):
|