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.

Files changed (30) hide show
  1. assets/node_modules/node-gyp/update-gyp.py +0 -0
  2. django_ledger/__init__.py +1 -1
  3. django_ledger/admin/ledger.py +3 -1
  4. django_ledger/io/__init__.py +1 -3
  5. django_ledger/io/{io_digest.py → io_context.py} +8 -0
  6. django_ledger/io/io_core.py +19 -6
  7. django_ledger/io/io_library.py +79 -30
  8. django_ledger/io/roles.py +80 -86
  9. django_ledger/migrations/0016_remove_accountmodel_django_ledg_coa_mod_e19964_idx_and_more.py +44 -0
  10. django_ledger/models/accounts.py +73 -43
  11. django_ledger/models/bill.py +2 -0
  12. django_ledger/models/coa.py +2 -0
  13. django_ledger/models/entity.py +5 -3
  14. django_ledger/models/invoice.py +2 -1
  15. django_ledger/models/items.py +4 -2
  16. django_ledger/models/ledger.py +24 -12
  17. django_ledger/models/mixins.py +11 -7
  18. django_ledger/models/transactions.py +4 -35
  19. django_ledger/settings.py +1 -0
  20. django_ledger/urls/entity.py +1 -1
  21. django_ledger/urls/unit.py +1 -1
  22. django_ledger/views/entity.py +18 -12
  23. django_ledger/views/ledger.py +0 -1
  24. django_ledger/views/mixins.py +60 -30
  25. {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/METADATA +10 -8
  26. {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/RECORD +29 -28
  27. {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/top_level.txt +1 -0
  28. {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/AUTHORS.md +0 -0
  29. {django_ledger-0.6.0.1.dist-info → django_ledger-0.6.1.dist-info}/LICENSE +0 -0
  30. {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
@@ -9,7 +9,7 @@ Contributions to this module:
9
9
  default_app_config = 'django_ledger.apps.DjangoLedgerConfig'
10
10
 
11
11
  """Django Ledger"""
12
- __version__ = '0.6.0.1'
12
+ __version__ = '0.6.1'
13
13
  __license__ = 'GPLv3 License'
14
14
 
15
15
  __author__ = 'Miguel Sanda'
@@ -115,7 +115,9 @@ class LedgerModelAdmin(ModelAdmin):
115
115
  'is_locked',
116
116
  'is_extended',
117
117
  'journal_entry_count',
118
- 'earliest_journal_entry'
118
+ 'earliest_journal_entry',
119
+ 'created',
120
+ 'updated'
119
121
  ]
120
122
  actions = [
121
123
  'post',
@@ -6,9 +6,7 @@ Contributions to this module:
6
6
  Miguel Sanda <msanda@arrobalytics.com>
7
7
  """
8
8
 
9
- from django_ledger.io.io_digest import *
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:
@@ -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.io_digest import IODigestContextManager
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 = lazy_loader.get_txs_model()
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 = lazy_loader.get_txs_model()
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
- JournalEntryModel = lazy_loader.get_journal_entry_model()
805
- TransactionModel = lazy_loader.get_txs_model()
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 = je_model.transactionmodel_set.bulk_create(i[0] for i in 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
 
@@ -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: List[str]) -> AccountModelQuerySet:
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 not isinstance(ledger_model, (str, UUID, LedgerModel)):
187
- raise IOCursorValidationError(
188
- message=_('Ledger Model must be a string or UUID or LedgerModel')
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
- if isinstance(ledger_model, LedgerModel):
192
- self.ENTITY_MODEL.validate_ledger_model_for_entity(ledger_model)
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
- # no specified xid, ledger or UUID... create one...
279
- self.commit_plan[
280
- self.ENTITY_MODEL.create_ledger(
281
- name='Blueprint Commitment',
282
- commit=False,
283
- posted=post_new_ledgers
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
- # create ledger with xid provided...
293
- self.commit_plan[
294
- self.ENTITY_MODEL.create_ledger(
295
- name=f'Blueprint Commitment {k}',
296
- ledger_xid=k,
297
- commit=False,
298
- posted=post_new_ledgers
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 self.resolve_account_model_qs(codes=account_codes)
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
- tx.account_model = account_models[tx.account_code]
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
- results['account_model_qs'] = self.account_model_qs
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
- return IOCursor(
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
- # ACCOUNT_ROLE_CHOICES = [
521
- # (BS_ASSET_ROLE.capitalize(), (
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
- # (BS_LIABILITIES_ROLE.capitalize(), (
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
- # (BS_EQUITY_ROLE.capitalize(), (
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
- # ('Income', (
576
- # # INCOME ---
577
- # (INCOME_OPERATIONAL, _('Operational Income')),
578
- # (INCOME_INVESTING, _('Investing/Passive Income')),
579
- # (INCOME_INTEREST, _('Interest Income')),
580
- # (INCOME_CAPITAL_GAIN_LOSS, _('Capital Gain/Loss Income')),
581
- # (INCOME_OTHER, _('Other Income')),
582
- # )),
583
- # ('Expenses', (
584
- # # COGS ----
585
- # (COGS, _('Cost of Goods Sold')),
586
- #
587
- # # EXPENSES ----
588
- # (EXPENSE_REGULAR, _('Regular Expense')),
589
- # (EXPENSE_INTEREST, _('Interest Expense')),
590
- # (EXPENSE_TAXES, _('Tax Expense')),
591
- # (EXPENSE_CAPITAL, _('Capital Expense')),
592
- # (EXPENSE_DEPRECIATION, _('Depreciation Expense')),
593
- # (EXPENSE_AMORTIZATION, _('Amortization Expense')),
594
- # (EXPENSE_OTHER, _('Other Expense')),
595
- # )),
596
- # ('Root', (
597
- # (ROOT_COA, 'CoA Root Account'),
598
- # (ROOT_ASSETS, 'Assets Root Account'),
599
- # (ROOT_LIABILITIES, 'Liabilities Root Account'),
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
+ ]