django-ledger 0.6.0.1__py3-none-any.whl → 0.6.1__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.
- assets/node_modules/node-gyp/update-gyp.py +0 -0
- django_ledger/__init__.py +1 -1
- django_ledger/admin/ledger.py +3 -1
- django_ledger/io/__init__.py +1 -3
- django_ledger/io/{io_digest.py → io_context.py} +8 -0
- django_ledger/io/io_core.py +19 -6
- django_ledger/io/io_library.py +79 -30
- django_ledger/io/roles.py +80 -86
- django_ledger/migrations/0016_remove_accountmodel_django_ledg_coa_mod_e19964_idx_and_more.py +44 -0
- django_ledger/models/accounts.py +73 -43
- django_ledger/models/bill.py +2 -0
- django_ledger/models/coa.py +2 -0
- django_ledger/models/entity.py +5 -3
- django_ledger/models/invoice.py +2 -1
- django_ledger/models/items.py +4 -2
- django_ledger/models/ledger.py +24 -12
- django_ledger/models/mixins.py +11 -7
- django_ledger/models/transactions.py +4 -35
- django_ledger/settings.py +1 -0
- django_ledger/urls/entity.py +1 -1
- django_ledger/urls/unit.py +1 -1
- django_ledger/views/entity.py +18 -12
- django_ledger/views/ledger.py +0 -1
- django_ledger/views/mixins.py +60 -30
- {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/METADATA +10 -8
- {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/RECORD +29 -28
- {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/top_level.txt +1 -0
- {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/LICENSE +0 -0
- {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/WHEEL +0 -0
|
File without changes
|
django_ledger/__init__.py
CHANGED
django_ledger/admin/ledger.py
CHANGED
django_ledger/io/__init__.py
CHANGED
|
@@ -6,9 +6,7 @@ Contributions to this module:
|
|
|
6
6
|
Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
from django_ledger.io.
|
|
9
|
+
from django_ledger.io.io_context import *
|
|
10
10
|
from django_ledger.io.io_middleware import *
|
|
11
11
|
from django_ledger.io.ratios import *
|
|
12
12
|
from django_ledger.io.roles import *
|
|
13
|
-
# due to circular import
|
|
14
|
-
# from django_ledger.io.io_library import IOLibrary
|
|
@@ -38,6 +38,10 @@ class IODigestContextManager:
|
|
|
38
38
|
def get_strftime_format(self):
|
|
39
39
|
return self.STRFTIME_FORMAT
|
|
40
40
|
|
|
41
|
+
@property
|
|
42
|
+
def from_datetime(self):
|
|
43
|
+
return self.get_from_datetime()
|
|
44
|
+
|
|
41
45
|
def get_from_datetime(self, as_str: bool = False, fmt=None) -> Optional[datetime]:
|
|
42
46
|
from_date = self.IO_DATA['from_date']
|
|
43
47
|
if from_date:
|
|
@@ -47,6 +51,10 @@ class IODigestContextManager:
|
|
|
47
51
|
return from_date.strftime(fmt)
|
|
48
52
|
return from_date
|
|
49
53
|
|
|
54
|
+
@property
|
|
55
|
+
def to_datetime(self):
|
|
56
|
+
return self.get_to_datetime()
|
|
57
|
+
|
|
50
58
|
def get_to_datetime(self, as_str: bool = False, fmt=None) -> datetime:
|
|
51
59
|
if as_str:
|
|
52
60
|
if not fmt:
|
django_ledger/io/io_core.py
CHANGED
|
@@ -36,7 +36,7 @@ from django.utils.translation import gettext_lazy as _
|
|
|
36
36
|
from django_ledger import settings
|
|
37
37
|
from django_ledger.exceptions import InvalidDateInputError, TransactionNotInBalanceError
|
|
38
38
|
from django_ledger.io import roles as roles_module
|
|
39
|
-
from django_ledger.io.
|
|
39
|
+
from django_ledger.io.io_context import IODigestContextManager
|
|
40
40
|
from django_ledger.io.io_middleware import (
|
|
41
41
|
AccountRoleIOMiddleware,
|
|
42
42
|
AccountGroupIOMiddleware,
|
|
@@ -259,6 +259,9 @@ class IODatabaseMixIn:
|
|
|
259
259
|
helps minimize the number of transactions to aggregate for a given request.
|
|
260
260
|
"""
|
|
261
261
|
|
|
262
|
+
TRANSACTION_MODEL_CLASS = None
|
|
263
|
+
JOURNAL_ENTRY_MODEL_CLASS = None
|
|
264
|
+
|
|
262
265
|
def is_entity_model(self):
|
|
263
266
|
return isinstance(self, lazy_loader.get_entity_model())
|
|
264
267
|
|
|
@@ -276,6 +279,16 @@ class IODatabaseMixIn:
|
|
|
276
279
|
elif self.is_entity_unit_model():
|
|
277
280
|
return self.entity
|
|
278
281
|
|
|
282
|
+
def get_transaction_model(self):
|
|
283
|
+
if self.TRANSACTION_MODEL_CLASS is not None:
|
|
284
|
+
return self.TRANSACTION_MODEL_CLASS
|
|
285
|
+
return lazy_loader.get_txs_model()
|
|
286
|
+
|
|
287
|
+
def get_journal_entry_model(self):
|
|
288
|
+
if self.JOURNAL_ENTRY_MODEL_CLASS is not None:
|
|
289
|
+
return self.JOURNAL_ENTRY_MODEL_CLASS
|
|
290
|
+
return lazy_loader.get_journal_entry_model()
|
|
291
|
+
|
|
279
292
|
def database_digest(self,
|
|
280
293
|
entity_slug: Optional[str] = None,
|
|
281
294
|
unit_slug: Optional[str] = None,
|
|
@@ -337,7 +350,7 @@ class IODatabaseMixIn:
|
|
|
337
350
|
IOResult
|
|
338
351
|
"""
|
|
339
352
|
|
|
340
|
-
TransactionModel =
|
|
353
|
+
TransactionModel = self.get_transaction_model()
|
|
341
354
|
|
|
342
355
|
# get_initial txs_queryset... where the IO model is operating from??...
|
|
343
356
|
if self.is_entity_model():
|
|
@@ -604,7 +617,7 @@ class IODatabaseMixIn:
|
|
|
604
617
|
use_closing_entries=use_closing_entries,
|
|
605
618
|
**kwargs)
|
|
606
619
|
|
|
607
|
-
TransactionModel =
|
|
620
|
+
TransactionModel = self.get_transaction_model()
|
|
608
621
|
|
|
609
622
|
for tx_model in io_result.txs_queryset:
|
|
610
623
|
if tx_model['account__balance_type'] != tx_model['tx_type']:
|
|
@@ -801,8 +814,8 @@ class IODatabaseMixIn:
|
|
|
801
814
|
force_je_retrieval: bool = False,
|
|
802
815
|
**kwargs):
|
|
803
816
|
|
|
804
|
-
|
|
805
|
-
|
|
817
|
+
TransactionModel = self.get_transaction_model()
|
|
818
|
+
JournalEntryModel = self.get_journal_entry_model()
|
|
806
819
|
|
|
807
820
|
# Validates that credits/debits balance.
|
|
808
821
|
check_tx_balance(je_txs, perform_correction=False)
|
|
@@ -897,7 +910,7 @@ class IODatabaseMixIn:
|
|
|
897
910
|
if staged_tx_model:
|
|
898
911
|
staged_tx_model.transaction_model = tx
|
|
899
912
|
|
|
900
|
-
txs_models =
|
|
913
|
+
txs_models = TransactionModel.objects.bulk_create(i[0] for i in txs_models)
|
|
901
914
|
je_model.save(verify=True, post_on_verify=je_posted)
|
|
902
915
|
return je_model, txs_models
|
|
903
916
|
|
django_ledger/io/io_library.py
CHANGED
|
@@ -7,12 +7,13 @@ Contributions to this module:
|
|
|
7
7
|
|
|
8
8
|
This module contains classes and functions used to document, dispatch and commit new transaction into the database.
|
|
9
9
|
"""
|
|
10
|
+
import enum
|
|
10
11
|
from collections import defaultdict
|
|
11
12
|
from dataclasses import dataclass
|
|
12
13
|
from datetime import date, datetime
|
|
13
14
|
from decimal import Decimal
|
|
14
15
|
from itertools import chain
|
|
15
|
-
from typing import Union, Dict, Callable, Optional, List
|
|
16
|
+
from typing import Union, Dict, Callable, Optional, List, Set
|
|
16
17
|
from uuid import UUID
|
|
17
18
|
|
|
18
19
|
from django.core.exceptions import ValidationError
|
|
@@ -63,6 +64,11 @@ class IOCursorValidationError(ValidationError):
|
|
|
63
64
|
pass
|
|
64
65
|
|
|
65
66
|
|
|
67
|
+
class IOCursorMode(enum.Enum):
|
|
68
|
+
STRICT = 'strict'
|
|
69
|
+
PERMISSIVE = 'permissive'
|
|
70
|
+
|
|
71
|
+
|
|
66
72
|
class IOCursor:
|
|
67
73
|
"""
|
|
68
74
|
Represents a Django Ledger cursor capable of dispatching transactions to the database.
|
|
@@ -86,18 +92,20 @@ class IOCursor:
|
|
|
86
92
|
io_library,
|
|
87
93
|
entity_model: EntityModel,
|
|
88
94
|
user_model,
|
|
95
|
+
mode: IOCursorMode = IOCursorMode.PERMISSIVE,
|
|
89
96
|
coa_model: Optional[Union[ChartOfAccountModel, UUID, str]] = None):
|
|
90
97
|
self.IO_LIBRARY = io_library
|
|
98
|
+
self.MODE = mode
|
|
91
99
|
self.ENTITY_MODEL = entity_model
|
|
92
100
|
self.USER_MODEL = user_model
|
|
93
101
|
self.COA_MODEL = coa_model
|
|
94
|
-
self.__COMMITTED: bool = False
|
|
95
102
|
self.blueprints = defaultdict(list)
|
|
96
103
|
self.ledger_model_qs: Optional[LedgerModelQuerySet] = None
|
|
97
104
|
self.account_model_qs: Optional[AccountModelQuerySet] = None
|
|
98
105
|
self.ledger_map = dict()
|
|
99
106
|
self.commit_plan = dict()
|
|
100
107
|
self.instructions = None
|
|
108
|
+
self.__COMMITTED: bool = False
|
|
101
109
|
|
|
102
110
|
def get_ledger_model_qs(self) -> LedgerModelQuerySet:
|
|
103
111
|
"""
|
|
@@ -122,9 +130,9 @@ class IOCursor:
|
|
|
122
130
|
"""
|
|
123
131
|
return self.ENTITY_MODEL.get_coa_accounts(
|
|
124
132
|
coa_model=self.COA_MODEL
|
|
125
|
-
)
|
|
133
|
+
).can_transact()
|
|
126
134
|
|
|
127
|
-
def resolve_account_model_qs(self, codes:
|
|
135
|
+
def resolve_account_model_qs(self, codes: Set[str]) -> AccountModelQuerySet:
|
|
128
136
|
"""
|
|
129
137
|
Resolves the final AccountModelQuerySet associated with the given account codes used by the blueprint.
|
|
130
138
|
|
|
@@ -164,6 +172,12 @@ class IOCursor:
|
|
|
164
172
|
)
|
|
165
173
|
return self.ledger_model_qs
|
|
166
174
|
|
|
175
|
+
def is_permissive(self) -> bool:
|
|
176
|
+
return self.MODE == IOCursorMode.PERMISSIVE
|
|
177
|
+
|
|
178
|
+
def is_strict(self) -> bool:
|
|
179
|
+
return self.MODE == IOCursorMode.STRICT
|
|
180
|
+
|
|
167
181
|
def dispatch(self,
|
|
168
182
|
name,
|
|
169
183
|
ledger_model: Optional[Union[str, LedgerModel, UUID]] = None,
|
|
@@ -183,13 +197,14 @@ class IOCursor:
|
|
|
183
197
|
The keyword arguments to be passed to the blueprint function.
|
|
184
198
|
"""
|
|
185
199
|
|
|
186
|
-
if
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
200
|
+
if ledger_model is not None:
|
|
201
|
+
if not isinstance(ledger_model, (str, UUID, LedgerModel)):
|
|
202
|
+
raise IOCursorValidationError(
|
|
203
|
+
message=_('Ledger Model must be a string or UUID or LedgerModel')
|
|
204
|
+
)
|
|
190
205
|
|
|
191
|
-
|
|
192
|
-
|
|
206
|
+
if isinstance(ledger_model, LedgerModel):
|
|
207
|
+
self.ENTITY_MODEL.validate_ledger_model_for_entity(ledger_model)
|
|
193
208
|
|
|
194
209
|
blueprint_func = self.IO_LIBRARY.get_blueprint(name)
|
|
195
210
|
blueprint_txs = blueprint_func(**kwargs)
|
|
@@ -238,6 +253,7 @@ class IOCursor:
|
|
|
238
253
|
|
|
239
254
|
def commit(self,
|
|
240
255
|
je_timestamp: Optional[Union[datetime, date, str]] = None,
|
|
256
|
+
je_description: Optional[str] = None,
|
|
241
257
|
post_new_ledgers: bool = False,
|
|
242
258
|
post_journal_entries: bool = False,
|
|
243
259
|
**kwargs):
|
|
@@ -251,6 +267,8 @@ class IOCursor:
|
|
|
251
267
|
----------
|
|
252
268
|
je_timestamp: Optional[Union[datetime, date, str]]
|
|
253
269
|
The date or timestamp used for the committed journal entries. If none, localtime will be used.
|
|
270
|
+
je_description: Optional[str]
|
|
271
|
+
The description of the journal entries. If none, no description will be used.
|
|
254
272
|
post_new_ledgers: bool
|
|
255
273
|
If a new ledger is created, the ledger model will be posted to the database.
|
|
256
274
|
post_journal_entries: bool
|
|
@@ -275,29 +293,39 @@ class IOCursor:
|
|
|
275
293
|
for k, txs in self.blueprints.items():
|
|
276
294
|
if k is None:
|
|
277
295
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
self.
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
296
|
+
if self.is_permissive():
|
|
297
|
+
# no specified xid, ledger or UUID... create one...
|
|
298
|
+
self.commit_plan[
|
|
299
|
+
self.ENTITY_MODEL.create_ledger(
|
|
300
|
+
name='Blueprint Commitment',
|
|
301
|
+
commit=False,
|
|
302
|
+
posted=post_new_ledgers
|
|
303
|
+
)
|
|
304
|
+
] = txs
|
|
305
|
+
else:
|
|
306
|
+
raise IOCursorValidationError(
|
|
307
|
+
message=_('Cannot commit transactions to a non-existing ledger')
|
|
284
308
|
)
|
|
285
|
-
] = txs
|
|
286
309
|
|
|
287
310
|
elif isinstance(k, str):
|
|
288
311
|
try:
|
|
289
312
|
# ledger with xid already exists...
|
|
290
313
|
self.commit_plan[self.ledger_map[k]] = txs
|
|
291
314
|
except KeyError:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
self.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
315
|
+
if self.is_permissive():
|
|
316
|
+
# create ledger with xid provided...
|
|
317
|
+
self.commit_plan[
|
|
318
|
+
self.ENTITY_MODEL.create_ledger(
|
|
319
|
+
name=f'Blueprint Commitment {k}',
|
|
320
|
+
ledger_xid=k,
|
|
321
|
+
commit=False,
|
|
322
|
+
posted=post_new_ledgers
|
|
323
|
+
)
|
|
324
|
+
] = txs
|
|
325
|
+
else:
|
|
326
|
+
raise IOCursorValidationError(
|
|
327
|
+
message=_(f'Cannot commit transactions to a non-existing ledger_xid {k}')
|
|
299
328
|
)
|
|
300
|
-
] = txs
|
|
301
329
|
|
|
302
330
|
elif isinstance(k, UUID):
|
|
303
331
|
try:
|
|
@@ -315,12 +343,18 @@ class IOCursor:
|
|
|
315
343
|
|
|
316
344
|
instructions = self.compile_instructions()
|
|
317
345
|
account_codes = set(tx.account_code for tx in chain.from_iterable(tr for _, tr in instructions.items()))
|
|
346
|
+
account_model_qs = self.resolve_account_model_qs(codes=account_codes)
|
|
318
347
|
account_models = {
|
|
319
|
-
acc.code: acc for acc in
|
|
348
|
+
acc.code: acc for acc in account_model_qs
|
|
320
349
|
}
|
|
321
350
|
|
|
322
351
|
for tx in chain.from_iterable(tr for _, tr in instructions.items()):
|
|
323
|
-
|
|
352
|
+
try:
|
|
353
|
+
tx.account_model = account_models[tx.account_code]
|
|
354
|
+
except KeyError:
|
|
355
|
+
raise IOCursorValidationError(
|
|
356
|
+
message=_(f'Account code {tx.account_code} not found. Is account available and not locked?')
|
|
357
|
+
)
|
|
324
358
|
|
|
325
359
|
results = dict()
|
|
326
360
|
for ledger_model, tr_items in instructions.items():
|
|
@@ -333,15 +367,20 @@ class IOCursor:
|
|
|
333
367
|
je_timestamp=je_timestamp if je_timestamp else get_localtime(),
|
|
334
368
|
je_txs=je_txs,
|
|
335
369
|
je_posted=post_journal_entries,
|
|
370
|
+
je_desc=je_description,
|
|
336
371
|
**kwargs
|
|
337
372
|
)
|
|
338
373
|
|
|
374
|
+
je.txs_models = txs_models
|
|
375
|
+
|
|
339
376
|
results[ledger_model] = {
|
|
377
|
+
'ledger_model': ledger_model,
|
|
340
378
|
'journal_entry': je,
|
|
341
379
|
'txs_models': txs_models,
|
|
342
|
-
'instructions': tr_items
|
|
380
|
+
'instructions': tr_items,
|
|
381
|
+
'account_model_qs': self.account_model_qs
|
|
343
382
|
}
|
|
344
|
-
|
|
383
|
+
|
|
345
384
|
self.__COMMITTED = True
|
|
346
385
|
return results
|
|
347
386
|
|
|
@@ -518,6 +557,8 @@ class IOLibrary:
|
|
|
518
557
|
The human-readable name of the library (i.e. PayRoll, Expenses, Rentals, etc...)
|
|
519
558
|
"""
|
|
520
559
|
|
|
560
|
+
IO_CURSOR_CLASS = IOCursor
|
|
561
|
+
|
|
521
562
|
def __init__(self, name: str):
|
|
522
563
|
self.name = name
|
|
523
564
|
self.registry: Dict[str, Callable] = {}
|
|
@@ -545,10 +586,14 @@ class IOLibrary:
|
|
|
545
586
|
raise IOLibraryError(message=f'Function "{name}" is not registered in IO library {self.name}')
|
|
546
587
|
return self.registry[name]
|
|
547
588
|
|
|
589
|
+
def get_io_cursor_class(self):
|
|
590
|
+
return self.IO_CURSOR_CLASS
|
|
591
|
+
|
|
548
592
|
def get_cursor(
|
|
549
593
|
self,
|
|
550
594
|
entity_model: EntityModel,
|
|
551
595
|
user_model,
|
|
596
|
+
mode: IOCursorMode = IOCursorMode.PERMISSIVE,
|
|
552
597
|
coa_model: Optional[Union[ChartOfAccountModel, UUID, str]] = None
|
|
553
598
|
) -> IOCursor:
|
|
554
599
|
"""
|
|
@@ -562,14 +607,18 @@ class IOLibrary:
|
|
|
562
607
|
The user model instance executing the transactions.
|
|
563
608
|
coa_model: ChartOfAccountModel or UUID or str, optional
|
|
564
609
|
The ChartOfAccountsModel instance or identifier used to determine the AccountModelQuerySet used for the transactions.
|
|
610
|
+
mode: IOCursorMode
|
|
611
|
+
The Mode of the cursor instance. Defaults to IOCursorMode.PERMISSIVE.
|
|
565
612
|
|
|
566
613
|
Returns
|
|
567
614
|
-------
|
|
568
615
|
IOCursor
|
|
569
616
|
"""
|
|
570
|
-
|
|
617
|
+
io_cursor_class = self.get_io_cursor_class()
|
|
618
|
+
return io_cursor_class(
|
|
571
619
|
io_library=self,
|
|
572
620
|
entity_model=entity_model,
|
|
573
621
|
user_model=user_model,
|
|
574
622
|
coa_model=coa_model,
|
|
623
|
+
mode=mode
|
|
575
624
|
)
|
django_ledger/io/roles.py
CHANGED
|
@@ -517,92 +517,86 @@ ACCOUNT_ROLE_CHOICES = [
|
|
|
517
517
|
))
|
|
518
518
|
]
|
|
519
519
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
#
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
#
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
#
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
#
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
#
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
#
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
#
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
#
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
#
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
#
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
# (ROOT_CAPITAL, 'Capital Root Account'),
|
|
601
|
-
# (ROOT_INCOME, 'Income Root Account'),
|
|
602
|
-
# (ROOT_COGS, 'COGS Root Account'),
|
|
603
|
-
# (ROOT_EXPENSES, 'Expenses Root Account'),
|
|
604
|
-
# ))
|
|
605
|
-
# ]
|
|
520
|
+
ACCOUNT_ROLE_CHOICES_FOR_FORMS = [
|
|
521
|
+
('Asset', (
|
|
522
|
+
# CURRENT ASSETS ----
|
|
523
|
+
(ASSET_CA_CASH, _('Current Asset')),
|
|
524
|
+
(ASSET_CA_MKT_SECURITIES, _('Marketable Securities')),
|
|
525
|
+
(ASSET_CA_RECEIVABLES, _('Receivables')),
|
|
526
|
+
(ASSET_CA_INVENTORY, _('Inventory')),
|
|
527
|
+
(ASSET_CA_UNCOLLECTIBLES, _('Uncollectibles')),
|
|
528
|
+
(ASSET_CA_PREPAID, _('Prepaid')),
|
|
529
|
+
(ASSET_CA_OTHER, _('Other Liquid Assets')),
|
|
530
|
+
|
|
531
|
+
# LONG TERM INVESTMENTS ---
|
|
532
|
+
(ASSET_LTI_NOTES_RECEIVABLE, _('Notes Receivable')),
|
|
533
|
+
(ASSET_LTI_LAND, _('Land')),
|
|
534
|
+
(ASSET_LTI_SECURITIES, _('Securities')),
|
|
535
|
+
|
|
536
|
+
# PPE ...
|
|
537
|
+
(ASSET_PPE_BUILDINGS, _('Buildings')),
|
|
538
|
+
(ASSET_PPE_BUILDINGS_ACCUM_DEPRECIATION, _('Buildings - Accum. Depreciation')),
|
|
539
|
+
(ASSET_PPE_PLANT, _('Plant')),
|
|
540
|
+
(ASSET_PPE_PLANT_ACCUM_DEPRECIATION, _('Plant - Accum. Depreciation')),
|
|
541
|
+
(ASSET_PPE_EQUIPMENT, _('Equipment')),
|
|
542
|
+
(ASSET_PPE_EQUIPMENT_ACCUM_DEPRECIATION, _('Equipment - Accum. Depreciation')),
|
|
543
|
+
|
|
544
|
+
# Other Assets ...
|
|
545
|
+
(ASSET_INTANGIBLE_ASSETS, _('Intangible Assets')),
|
|
546
|
+
(ASSET_INTANGIBLE_ASSETS_ACCUM_AMORTIZATION, _('Intangible Assets - Accum. Amortization')),
|
|
547
|
+
(ASSET_ADJUSTMENTS, _('Other Assets')),
|
|
548
|
+
)),
|
|
549
|
+
('Liabilities', (
|
|
550
|
+
|
|
551
|
+
# CURRENT LIABILITIES ---
|
|
552
|
+
(LIABILITY_CL_ACC_PAYABLE, _('Accounts Payable')),
|
|
553
|
+
(LIABILITY_CL_WAGES_PAYABLE, _('Wages Payable')),
|
|
554
|
+
(LIABILITY_CL_INTEREST_PAYABLE, _('Interest Payable')),
|
|
555
|
+
(LIABILITY_CL_TAXES_PAYABLE, _('Taxes Payable')),
|
|
556
|
+
(LIABILITY_CL_ST_NOTES_PAYABLE, _('Short Term Notes Payable')),
|
|
557
|
+
(LIABILITY_CL_LTD_MATURITIES, _('Current Maturities of Long Tern Debt')),
|
|
558
|
+
(LIABILITY_CL_DEFERRED_REVENUE, _('Deferred Revenue')),
|
|
559
|
+
(LIABILITY_CL_OTHER, _('Other Liabilities')),
|
|
560
|
+
|
|
561
|
+
# LONG TERM LIABILITIES ----
|
|
562
|
+
(LIABILITY_LTL_NOTES_PAYABLE, _('Long Term Notes Payable')),
|
|
563
|
+
(LIABILITY_LTL_BONDS_PAYABLE, _('Bonds Payable')),
|
|
564
|
+
(LIABILITY_LTL_MORTGAGE_PAYABLE, _('Mortgage Payable')),
|
|
565
|
+
)),
|
|
566
|
+
('Capital', (
|
|
567
|
+
|
|
568
|
+
# EQUITY ---
|
|
569
|
+
(EQUITY_CAPITAL, _('Capital')),
|
|
570
|
+
(EQUITY_COMMON_STOCK, _('Common Stock')),
|
|
571
|
+
(EQUITY_PREFERRED_STOCK, _('Preferred Stock')),
|
|
572
|
+
(EQUITY_ADJUSTMENT, _('Other Equity Adjustments')),
|
|
573
|
+
(EQUITY_DIVIDENDS, _('Dividends & Distributions to Shareholders')),
|
|
574
|
+
)),
|
|
575
|
+
|
|
576
|
+
('Income', (
|
|
577
|
+
# INCOME ---
|
|
578
|
+
(INCOME_OPERATIONAL, _('Operational Income')),
|
|
579
|
+
(INCOME_PASSIVE, _('Investing/Passive Income')),
|
|
580
|
+
(INCOME_INTEREST, _('Interest Income')),
|
|
581
|
+
(INCOME_CAPITAL_GAIN_LOSS, _('Capital Gain/Loss Income')),
|
|
582
|
+
(INCOME_OTHER, _('Other Income')),
|
|
583
|
+
)),
|
|
584
|
+
|
|
585
|
+
('Expense', (
|
|
586
|
+
# COGS ----
|
|
587
|
+
(COGS, _('Cost of Goods Sold')),
|
|
588
|
+
|
|
589
|
+
# EXPENSES ----
|
|
590
|
+
(EXPENSE_OPERATIONAL, _('Regular Expense')),
|
|
591
|
+
(EXPENSE_INTEREST_ST, _('Interest Expense - Short Term Debt')),
|
|
592
|
+
(EXPENSE_INTEREST_LT, _('Interest Expense - Long Term Debt')),
|
|
593
|
+
(EXPENSE_TAXES, _('Tax Expense')),
|
|
594
|
+
(EXPENSE_CAPITAL, _('Capital Expense')),
|
|
595
|
+
(EXPENSE_DEPRECIATION, _('Depreciation Expense')),
|
|
596
|
+
(EXPENSE_AMORTIZATION, _('Amortization Expense')),
|
|
597
|
+
(EXPENSE_OTHER, _('Other Expense')),
|
|
598
|
+
))
|
|
599
|
+
]
|
|
606
600
|
|
|
607
601
|
ACCOUNT_CHOICES_NO_ROOT = [c for c in ACCOUNT_ROLE_CHOICES if c[0] != 'Root']
|
|
608
602
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Generated by Django 5.0.4 on 2024-04-25 13:41
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('django_ledger', '0015_remove_chartofaccountmodel_locked_and_more'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.RemoveIndex(
|
|
15
|
+
model_name='accountmodel',
|
|
16
|
+
name='django_ledg_coa_mod_e19964_idx',
|
|
17
|
+
),
|
|
18
|
+
migrations.AlterField(
|
|
19
|
+
model_name='ledgermodel',
|
|
20
|
+
name='entity',
|
|
21
|
+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='django_ledger.entitymodel', verbose_name='Ledger Entity'),
|
|
22
|
+
),
|
|
23
|
+
migrations.AlterField(
|
|
24
|
+
model_name='ledgermodel',
|
|
25
|
+
name='ledger_xid',
|
|
26
|
+
field=models.SlugField(allow_unicode=True, blank=True, help_text='User Defined Ledger ID', max_length=150, null=True, verbose_name='Ledger External ID'),
|
|
27
|
+
),
|
|
28
|
+
migrations.AddIndex(
|
|
29
|
+
model_name='accountmodel',
|
|
30
|
+
index=models.Index(fields=['coa_model', 'code'], name='django_ledg_coa_mod_e073bc_idx'),
|
|
31
|
+
),
|
|
32
|
+
migrations.AddIndex(
|
|
33
|
+
model_name='accountmodel',
|
|
34
|
+
index=models.Index(fields=['code'], name='django_ledg_code_081adc_idx'),
|
|
35
|
+
),
|
|
36
|
+
migrations.AddIndex(
|
|
37
|
+
model_name='ledgermodel',
|
|
38
|
+
index=models.Index(fields=['entity', 'ledger_xid'], name='django_ledg_entity__7be095_idx'),
|
|
39
|
+
),
|
|
40
|
+
migrations.AddIndex(
|
|
41
|
+
model_name='ledgermodel',
|
|
42
|
+
index=models.Index(fields=['ledger_xid'], name='django_ledg_ledger__05f099_idx'),
|
|
43
|
+
),
|
|
44
|
+
]
|