django-ledger 0.7.5.2__py3-none-any.whl → 0.7.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.
- django_ledger/__init__.py +1 -1
- django_ledger/forms/closing_entry.py +2 -1
- django_ledger/forms/journal_entry.py +1 -0
- django_ledger/io/io_context.py +10 -0
- django_ledger/io/io_core.py +22 -0
- django_ledger/models/accounts.py +40 -1
- django_ledger/models/bank_account.py +0 -1
- django_ledger/models/bill.py +0 -1
- django_ledger/models/chart_of_accounts.py +0 -1
- django_ledger/models/closing_entry.py +27 -13
- django_ledger/models/customer.py +0 -1
- django_ledger/models/data_import.py +0 -2
- django_ledger/models/entity.py +15 -3
- django_ledger/models/estimate.py +0 -1
- django_ledger/models/invoice.py +0 -1
- django_ledger/models/items.py +0 -3
- django_ledger/models/journal_entry.py +5 -3
- django_ledger/models/ledger.py +0 -1
- django_ledger/models/purchase_order.py +0 -1
- django_ledger/models/transactions.py +27 -4
- django_ledger/models/unit.py +0 -1
- django_ledger/models/vendor.py +0 -1
- django_ledger/settings.py +22 -21
- django_ledger/templates/django_ledger/layouts/base.html +6 -1
- django_ledger/urls/ledger.py +1 -1
- django_ledger/views/closing_entry.py +47 -40
- django_ledger/views/mixins.py +6 -0
- django_ledger/views/unit.py +11 -14
- django_ledger/views/vendor.py +10 -8
- {django_ledger-0.7.5.2.dist-info → django_ledger-0.7.6.1.dist-info}/METADATA +3 -1
- {django_ledger-0.7.5.2.dist-info → django_ledger-0.7.6.1.dist-info}/RECORD +35 -38
- {django_ledger-0.7.5.2.dist-info → django_ledger-0.7.6.1.dist-info}/WHEEL +1 -1
- {django_ledger-0.7.5.2.dist-info → django_ledger-0.7.6.1.dist-info}/top_level.txt +0 -1
- django_ledger/static/.DS_Store +0 -0
- django_ledger/static/django_ledger/.DS_Store +0 -0
- django_ledger/static/django_ledger/logo_2/.DS_Store +0 -0
- {django_ledger-0.7.5.2.dist-info → django_ledger-0.7.6.1.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.7.5.2.dist-info → django_ledger-0.7.6.1.dist-info}/LICENSE +0 -0
django_ledger/__init__.py
CHANGED
|
@@ -6,7 +6,7 @@ Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
|
6
6
|
default_app_config = 'django_ledger.apps.DjangoLedgerConfig'
|
|
7
7
|
|
|
8
8
|
"""Django Ledger"""
|
|
9
|
-
__version__ = '0.7.
|
|
9
|
+
__version__ = '0.7.6.1'
|
|
10
10
|
__license__ = 'GPLv3 License'
|
|
11
11
|
|
|
12
12
|
__author__ = 'Miguel Sanda'
|
|
@@ -26,7 +26,8 @@ class ClosingEntryCreateForm(ModelForm):
|
|
|
26
26
|
'closing_date': DateInput(attrs={
|
|
27
27
|
'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-large',
|
|
28
28
|
'placeholder': _('Closing Date (YYYY-MM-DD)...'),
|
|
29
|
-
'id': 'djl-datepicker'
|
|
29
|
+
'id': 'djl-datepicker',
|
|
30
|
+
'type': 'date'
|
|
30
31
|
})
|
|
31
32
|
}
|
|
32
33
|
labels = {
|
django_ledger/io/io_context.py
CHANGED
|
@@ -89,6 +89,16 @@ class IODigestContextManager:
|
|
|
89
89
|
def is_by_activity(self) -> bool:
|
|
90
90
|
return self.IO_DATA['by_activity']
|
|
91
91
|
|
|
92
|
+
# Account Information
|
|
93
|
+
def get_account_data(self, key_func=None) -> Dict:
|
|
94
|
+
if key_func:
|
|
95
|
+
return {
|
|
96
|
+
key_func(acc): acc for acc in self.IO_DATA['accounts']
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
acc['account_uuid']: acc for acc in self.IO_DATA['accounts']
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
# Balance Sheet Data...
|
|
93
103
|
def has_balance_sheet(self) -> bool:
|
|
94
104
|
return 'balance_sheet' in self.IO_DATA
|
django_ledger/io/io_core.py
CHANGED
|
@@ -847,6 +847,28 @@ class IODatabaseMixIn:
|
|
|
847
847
|
if role:
|
|
848
848
|
txs_queryset = txs_queryset.for_roles(role_list=role)
|
|
849
849
|
|
|
850
|
+
# Cleared transaction filter via KWARGS....
|
|
851
|
+
cleared_filter = kwargs.get('cleared')
|
|
852
|
+
if cleared_filter is not None:
|
|
853
|
+
if cleared_filter in [True, False]:
|
|
854
|
+
txs_queryset = txs_queryset.is_cleared() if cleared_filter else txs_queryset.not_cleared()
|
|
855
|
+
else:
|
|
856
|
+
raise IOValidationError(
|
|
857
|
+
message=f'Invalid value for cleared filter: {cleared_filter}. '
|
|
858
|
+
f'Valid values are True, False'
|
|
859
|
+
)
|
|
860
|
+
|
|
861
|
+
# Reconciled transaction filter via KWARGS....
|
|
862
|
+
reconciled_filter = kwargs.get('reconciled')
|
|
863
|
+
if reconciled_filter is not None:
|
|
864
|
+
if reconciled_filter in [True, False]:
|
|
865
|
+
txs_queryset = txs_queryset.is_reconciled() if reconciled_filter else txs_queryset.not_reconciled()
|
|
866
|
+
else:
|
|
867
|
+
raise IOValidationError(
|
|
868
|
+
message=f'Invalid value for reconciled filter: {reconciled_filter}. '
|
|
869
|
+
f'Valid values are True, False'
|
|
870
|
+
)
|
|
871
|
+
|
|
850
872
|
if io_result.is_bounded:
|
|
851
873
|
txs_queryset = txs_queryset.annotate(
|
|
852
874
|
amount_io=Case(
|
django_ledger/models/accounts.py
CHANGED
|
@@ -472,8 +472,35 @@ class AccountModelAbstract(MP_Node, CreateUpdateMixIn):
|
|
|
472
472
|
x5=self.code
|
|
473
473
|
)
|
|
474
474
|
|
|
475
|
+
def alt_str(self):
|
|
476
|
+
"""
|
|
477
|
+
Returns a formatted string representation of the object.
|
|
478
|
+
|
|
479
|
+
The formatted string includes the code, name, role, and balance type
|
|
480
|
+
of the object. The role is converted to uppercase for consistency,
|
|
481
|
+
and the balance type is displayed as is. This method provides a
|
|
482
|
+
concise textual representation for quick identification or display.
|
|
483
|
+
|
|
484
|
+
Returns:
|
|
485
|
+
str: A formatted string in the format 'code: name (ROLE/BALANCE_TYPE)'.
|
|
486
|
+
"""
|
|
487
|
+
return f'{self.code}: {self.name} ({self.role.upper()}/{self.balance_type})'
|
|
488
|
+
|
|
475
489
|
@property
|
|
476
490
|
def coa_slug(self):
|
|
491
|
+
"""
|
|
492
|
+
Property that retrieves the `coa_slug` attribute from the object. If the attribute
|
|
493
|
+
is not found, it fetches the `slug` attribute from the `coa_model`.
|
|
494
|
+
|
|
495
|
+
Attributes:
|
|
496
|
+
_coa_slug (str): Cached value of the `coa_slug` if it exists.
|
|
497
|
+
coa_model (Any): Object containing the `slug` attribute that serves
|
|
498
|
+
as a fallback when `_coa_slug` is not present.
|
|
499
|
+
|
|
500
|
+
Returns:
|
|
501
|
+
str: The value of `_coa_slug` if defined, or the `slug` attribute from
|
|
502
|
+
`coa_model` if `_coa_slug` is not available.
|
|
503
|
+
"""
|
|
477
504
|
try:
|
|
478
505
|
return getattr(self, '_coa_slug')
|
|
479
506
|
except AttributeError:
|
|
@@ -481,6 +508,19 @@ class AccountModelAbstract(MP_Node, CreateUpdateMixIn):
|
|
|
481
508
|
|
|
482
509
|
@property
|
|
483
510
|
def entity_slug(self):
|
|
511
|
+
"""
|
|
512
|
+
Retrieve the slug value associated with the entity.
|
|
513
|
+
|
|
514
|
+
This property method returns the value of the private attribute
|
|
515
|
+
'_entity_slug' for the current instance. The purpose of the
|
|
516
|
+
slug is typically to provide a URL-friendly string representing
|
|
517
|
+
the entity.
|
|
518
|
+
|
|
519
|
+
Returns
|
|
520
|
+
-------
|
|
521
|
+
Any
|
|
522
|
+
The value of the '_entity_slug' attribute.
|
|
523
|
+
"""
|
|
484
524
|
return getattr(self, '_entity_slug')
|
|
485
525
|
|
|
486
526
|
@classmethod
|
|
@@ -1059,7 +1099,6 @@ class AccountModel(AccountModelAbstract):
|
|
|
1059
1099
|
"""
|
|
1060
1100
|
|
|
1061
1101
|
class Meta(AccountModelAbstract.Meta):
|
|
1062
|
-
swappable = 'DJANGO_LEDGER_ACCOUNT_MODEL'
|
|
1063
1102
|
abstract = False
|
|
1064
1103
|
|
|
1065
1104
|
|
django_ledger/models/bill.py
CHANGED
|
@@ -9,11 +9,10 @@ from itertools import groupby, chain
|
|
|
9
9
|
from typing import Optional
|
|
10
10
|
from uuid import uuid4, UUID
|
|
11
11
|
|
|
12
|
-
from django.conf import settings
|
|
13
12
|
from django.core.exceptions import ValidationError
|
|
14
13
|
from django.core.validators import MinValueValidator
|
|
15
14
|
from django.db import models
|
|
16
|
-
from django.db.models import Q
|
|
15
|
+
from django.db.models import Q, Count
|
|
17
16
|
from django.db.models.signals import pre_save
|
|
18
17
|
from django.urls import reverse
|
|
19
18
|
from django.utils.timezone import make_aware
|
|
@@ -24,7 +23,6 @@ from django_ledger.models.ledger import LedgerModel
|
|
|
24
23
|
from django_ledger.models.mixins import CreateUpdateMixIn, MarkdownNotesMixIn
|
|
25
24
|
from django_ledger.models.transactions import TransactionModel
|
|
26
25
|
from django_ledger.models.utils import lazy_loader
|
|
27
|
-
from django_ledger.settings import DJANGO_LEDGER_LEDGER_MODEL
|
|
28
26
|
|
|
29
27
|
|
|
30
28
|
class ClosingEntryValidationError(ValidationError):
|
|
@@ -42,6 +40,12 @@ class ClosingEntryModelQuerySet(models.QuerySet):
|
|
|
42
40
|
|
|
43
41
|
class ClosingEntryModelManager(models.Manager):
|
|
44
42
|
|
|
43
|
+
def get_queryset(self):
|
|
44
|
+
qs = ClosingEntryModelQuerySet(self.model, using=self._db)
|
|
45
|
+
return qs.annotate(
|
|
46
|
+
ce_txs_count=Count('closingentrytransactionmodel')
|
|
47
|
+
)
|
|
48
|
+
|
|
45
49
|
def for_user(self, user_model):
|
|
46
50
|
qs = self.get_queryset()
|
|
47
51
|
if user_model.is_superuser:
|
|
@@ -102,6 +106,7 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
102
106
|
return make_aware(datetime.combine(self.closing_date, time.max))
|
|
103
107
|
|
|
104
108
|
def migrate(self):
|
|
109
|
+
|
|
105
110
|
ce_txs = self.closingentrytransactionmodel_set.all().select_related(
|
|
106
111
|
'account_model',
|
|
107
112
|
'unit_model'
|
|
@@ -118,8 +123,9 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
118
123
|
ce_txs_gb = groupby(ce_txs, key=lambda k: k.tx_type)
|
|
119
124
|
|
|
120
125
|
# adding DEBITS and CREDITS...
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
ce_txs_sum = {
|
|
127
|
+
k: sum(v.balance for v in l) for k, l in ce_txs_gb
|
|
128
|
+
}
|
|
123
129
|
|
|
124
130
|
if len(ce_txs_sum) and ce_txs_sum[TransactionModel.DEBIT] != ce_txs_sum[TransactionModel.CREDIT]:
|
|
125
131
|
raise ClosingEntryValidationError(
|
|
@@ -131,7 +137,9 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
131
137
|
|
|
132
138
|
ce_txs.sort(key=key_func)
|
|
133
139
|
ce_txs_gb = groupby(ce_txs, key=key_func)
|
|
134
|
-
ce_txs_gb = {
|
|
140
|
+
ce_txs_gb = {
|
|
141
|
+
unit_model_id: list(je_txs) for unit_model_id, je_txs in ce_txs_gb
|
|
142
|
+
}
|
|
135
143
|
|
|
136
144
|
ce_txs_journal_entries = {
|
|
137
145
|
(unit_model_id, activity): JournalEntryModel(
|
|
@@ -164,6 +172,8 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
164
172
|
for k, je_model in ce_txs_journal_entries.items():
|
|
165
173
|
je_model.save(verify=True)
|
|
166
174
|
|
|
175
|
+
self.ledger_model.lock(commit=True, raise_exception=True)
|
|
176
|
+
|
|
167
177
|
return ce_txs_journal_entries, ce_je_txs
|
|
168
178
|
|
|
169
179
|
def create_entry_ledger(self, commit: bool = False):
|
|
@@ -172,7 +182,7 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
172
182
|
name=f'Closing Entry {self.closing_date} Ledger',
|
|
173
183
|
entity_id=self.entity_model_id,
|
|
174
184
|
hidden=True,
|
|
175
|
-
locked=
|
|
185
|
+
locked=False,
|
|
176
186
|
posted=True
|
|
177
187
|
)
|
|
178
188
|
ledger_model.clean()
|
|
@@ -189,7 +199,7 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
189
199
|
def can_post(self) -> bool:
|
|
190
200
|
return not self.is_posted()
|
|
191
201
|
|
|
192
|
-
def mark_as_posted(self, commit: bool = False, update_entity_meta: bool =
|
|
202
|
+
def mark_as_posted(self, commit: bool = False, update_entity_meta: bool = True, **kwargs):
|
|
193
203
|
if not self.can_post():
|
|
194
204
|
raise ClosingEntryValidationError(
|
|
195
205
|
message=_(f'Closing Entry {self.closing_date} is already posted.')
|
|
@@ -226,11 +236,14 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
226
236
|
def can_unpost(self) -> bool:
|
|
227
237
|
return self.is_posted()
|
|
228
238
|
|
|
229
|
-
def mark_as_unposted(self, commit: bool = False, update_entity_meta: bool =
|
|
239
|
+
def mark_as_unposted(self, commit: bool = False, update_entity_meta: bool = True, **kwargs):
|
|
230
240
|
if not self.can_unpost():
|
|
231
241
|
raise ClosingEntryValidationError(
|
|
232
242
|
message=_(f'Closing Entry {self.closing_date} is not posted.')
|
|
233
243
|
)
|
|
244
|
+
|
|
245
|
+
self.ledger_model.unlock(commit=False, raise_exception=True)
|
|
246
|
+
self.ledger_model.save(update_fields=['posted', 'locked', 'updated'])
|
|
234
247
|
self.posted = False
|
|
235
248
|
|
|
236
249
|
TransactionModel.objects.for_entity(
|
|
@@ -305,6 +318,8 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
305
318
|
message=_('Cannot delete a posted Closing Entry')
|
|
306
319
|
)
|
|
307
320
|
|
|
321
|
+
self.ledger_model.unpost(commit=True, raise_exception=True)
|
|
322
|
+
|
|
308
323
|
TransactionModel.objects.for_entity(
|
|
309
324
|
entity_slug=self.entity_model_id
|
|
310
325
|
).for_ledger(ledger_model=self.ledger_model).delete()
|
|
@@ -343,12 +358,9 @@ class ClosingEntryModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn):
|
|
|
343
358
|
|
|
344
359
|
class ClosingEntryModel(ClosingEntryModelAbstract):
|
|
345
360
|
class Meta(ClosingEntryModelAbstract.Meta):
|
|
346
|
-
swappable = 'DJANGO_LEDGER_CLOSING_ENTRY_MODEL'
|
|
347
361
|
abstract = False
|
|
348
362
|
|
|
349
363
|
|
|
350
|
-
# todo: Remove this model!
|
|
351
|
-
|
|
352
364
|
class ClosingEntryTransactionModelQuerySet(models.QuerySet):
|
|
353
365
|
pass
|
|
354
366
|
|
|
@@ -433,7 +445,6 @@ class ClosingEntryTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
433
445
|
name='unique_ce_opt_3'
|
|
434
446
|
)
|
|
435
447
|
]
|
|
436
|
-
|
|
437
448
|
indexes = [
|
|
438
449
|
models.Index(fields=['closing_entry_model']),
|
|
439
450
|
models.Index(fields=['account_model'])
|
|
@@ -470,6 +481,9 @@ class ClosingEntryTransactionModel(ClosingEntryTransactionModelAbstract):
|
|
|
470
481
|
Base ClosingEntryModel Class
|
|
471
482
|
"""
|
|
472
483
|
|
|
484
|
+
class Meta(ClosingEntryTransactionModelAbstract.Meta):
|
|
485
|
+
abstract = False
|
|
486
|
+
|
|
473
487
|
|
|
474
488
|
def closingentrymodel_presave(instance: ClosingEntryModel, **kwargs):
|
|
475
489
|
instance.create_entry_ledger(commit=False)
|
django_ledger/models/customer.py
CHANGED
|
@@ -1176,7 +1176,6 @@ class ImportJobModel(ImportJobModelAbstract):
|
|
|
1176
1176
|
"""
|
|
1177
1177
|
|
|
1178
1178
|
class Meta(ImportJobModelAbstract.Meta):
|
|
1179
|
-
swappable = 'DJANGO_LEDGER_IMPORT_JOB_MODEL'
|
|
1180
1179
|
abstract = False
|
|
1181
1180
|
|
|
1182
1181
|
|
|
@@ -1197,5 +1196,4 @@ class StagedTransactionModel(StagedTransactionModelAbstract):
|
|
|
1197
1196
|
"""
|
|
1198
1197
|
|
|
1199
1198
|
class Meta(StagedTransactionModelAbstract.Meta):
|
|
1200
|
-
swappable = 'DJANGO_LEDGER_STAGED_TRANSACTION_MODEL'
|
|
1201
1199
|
abstract = False
|
django_ledger/models/entity.py
CHANGED
|
@@ -1517,6 +1517,20 @@ class EntityModelAbstract(MP_Node,
|
|
|
1517
1517
|
# account_model.clean()
|
|
1518
1518
|
return coa_model, coa_model.create_account(**account_model_kwargs)
|
|
1519
1519
|
|
|
1520
|
+
def get_account_balance(self,
|
|
1521
|
+
account_codes: List[str],
|
|
1522
|
+
to_date: Union[datetime, date, str],
|
|
1523
|
+
**kwargs):
|
|
1524
|
+
|
|
1525
|
+
io_context = self.digest(
|
|
1526
|
+
entity_model=self.slug,
|
|
1527
|
+
accounts=account_codes,
|
|
1528
|
+
to_date=to_date,
|
|
1529
|
+
**kwargs
|
|
1530
|
+
)
|
|
1531
|
+
|
|
1532
|
+
return io_context
|
|
1533
|
+
|
|
1520
1534
|
# ### LEDGER MANAGEMENT ####
|
|
1521
1535
|
def get_ledgers(self, posted: Optional[bool] = None):
|
|
1522
1536
|
if posted is not None:
|
|
@@ -3135,12 +3149,11 @@ class EntityModel(EntityModelAbstract):
|
|
|
3135
3149
|
"""
|
|
3136
3150
|
Entity Model Base Class From Abstract
|
|
3137
3151
|
"""
|
|
3152
|
+
|
|
3138
3153
|
class Meta(EntityModelAbstract.Meta):
|
|
3139
|
-
swappable = 'DJANGO_LEDGER_ENTITY_MODEL'
|
|
3140
3154
|
abstract = False
|
|
3141
3155
|
|
|
3142
3156
|
|
|
3143
|
-
|
|
3144
3157
|
# ## ENTITY STATE....
|
|
3145
3158
|
class EntityStateModelAbstract(Model):
|
|
3146
3159
|
KEY_JOURNAL_ENTRY = 'je'
|
|
@@ -3204,7 +3217,6 @@ class EntityStateModel(EntityStateModelAbstract):
|
|
|
3204
3217
|
"""
|
|
3205
3218
|
|
|
3206
3219
|
class Meta(EntityStateModelAbstract.Meta):
|
|
3207
|
-
swappable = 'DJANGO_LEDGER_ENTITY_STATE_MODEL'
|
|
3208
3220
|
abstract = False
|
|
3209
3221
|
|
|
3210
3222
|
|
django_ledger/models/estimate.py
CHANGED
django_ledger/models/invoice.py
CHANGED
django_ledger/models/items.py
CHANGED
|
@@ -1411,7 +1411,6 @@ class UnitOfMeasureModel(UnitOfMeasureModelAbstract):
|
|
|
1411
1411
|
|
|
1412
1412
|
class Meta(UnitOfMeasureModelAbstract.Meta):
|
|
1413
1413
|
abstract = False
|
|
1414
|
-
swappable = 'DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL'
|
|
1415
1414
|
|
|
1416
1415
|
|
|
1417
1416
|
class ItemTransactionModel(ItemTransactionModelAbstract):
|
|
@@ -1421,7 +1420,6 @@ class ItemTransactionModel(ItemTransactionModelAbstract):
|
|
|
1421
1420
|
|
|
1422
1421
|
class Meta(ItemTransactionModelAbstract.Meta):
|
|
1423
1422
|
abstract = False
|
|
1424
|
-
swappable = 'DJANGO_LEDGER_ITEM_TRANSACTION_MODEL'
|
|
1425
1423
|
|
|
1426
1424
|
|
|
1427
1425
|
class ItemModel(ItemModelAbstract):
|
|
@@ -1431,4 +1429,3 @@ class ItemModel(ItemModelAbstract):
|
|
|
1431
1429
|
|
|
1432
1430
|
class Meta(ItemModelAbstract.Meta):
|
|
1433
1431
|
abstract = False
|
|
1434
|
-
swappable = 'DJANGO_LEDGER_ITEM_MODEL'
|
|
@@ -1243,7 +1243,10 @@ class JournalEntryModelAbstract(CreateUpdateMixIn):
|
|
|
1243
1243
|
self.activity = None
|
|
1244
1244
|
else:
|
|
1245
1245
|
role_list = self.get_txs_roles(txs_qs, exclude_cash_role=True)
|
|
1246
|
-
self.activity = self.get_activity_from_roles(
|
|
1246
|
+
self.activity = self.get_activity_from_roles(
|
|
1247
|
+
role_set=role_list,
|
|
1248
|
+
raise_exception=raise_exception
|
|
1249
|
+
)
|
|
1247
1250
|
return self.activity
|
|
1248
1251
|
|
|
1249
1252
|
# todo: add entity_model as parameter on all functions...
|
|
@@ -1534,7 +1537,7 @@ class JournalEntryModelAbstract(CreateUpdateMixIn):
|
|
|
1534
1537
|
|
|
1535
1538
|
if verify:
|
|
1536
1539
|
txs_qs, is_verified = self.clean(verify=True)
|
|
1537
|
-
if
|
|
1540
|
+
if is_verified and post_on_verify:
|
|
1538
1541
|
# Mark as posted if verification succeeds and posting is requested
|
|
1539
1542
|
self.mark_as_posted(commit=False, verify=False, force_lock=True, raise_exception=True)
|
|
1540
1543
|
|
|
@@ -1762,7 +1765,6 @@ class JournalEntryModel(JournalEntryModelAbstract):
|
|
|
1762
1765
|
"""
|
|
1763
1766
|
|
|
1764
1767
|
class Meta(JournalEntryModelAbstract.Meta):
|
|
1765
|
-
swappable = 'DJANGO_LEDGER_JOURNAL_ENTRY_MODEL'
|
|
1766
1768
|
abstract = False
|
|
1767
1769
|
|
|
1768
1770
|
|
django_ledger/models/ledger.py
CHANGED
|
@@ -67,7 +67,7 @@ class TransactionModelQuerySet(QuerySet):
|
|
|
67
67
|
Q(journal_entry__ledger__posted=True)
|
|
68
68
|
)
|
|
69
69
|
|
|
70
|
-
def for_accounts(self, account_list: List[str
|
|
70
|
+
def for_accounts(self, account_list: List[Union[AccountModel, str, UUID]]):
|
|
71
71
|
"""
|
|
72
72
|
Filters transactions based on the accounts they are associated with.
|
|
73
73
|
|
|
@@ -82,9 +82,20 @@ class TransactionModelQuerySet(QuerySet):
|
|
|
82
82
|
TransactionModelQuerySet
|
|
83
83
|
A QuerySet filtered for transactions associated with the specified accounts.
|
|
84
84
|
"""
|
|
85
|
-
|
|
85
|
+
|
|
86
|
+
if not isinstance(account_list, list) or not len(account_list) > 0:
|
|
87
|
+
raise TransactionModelValidationError(
|
|
88
|
+
message=_('Account list must be a list of AccountModel, UUID or str objects (codes).')
|
|
89
|
+
)
|
|
90
|
+
if isinstance(account_list[0], str):
|
|
86
91
|
return self.filter(account__code__in=account_list)
|
|
87
|
-
|
|
92
|
+
elif isinstance(account_list[0], UUID):
|
|
93
|
+
return self.filter(account__uuid__in=account_list)
|
|
94
|
+
elif isinstance(account_list[0], AccountModel):
|
|
95
|
+
return self.filter(account__in=account_list)
|
|
96
|
+
raise TransactionModelValidationError(
|
|
97
|
+
message=_('Account list must be a list of AccountModel, UUID or str objects (codes).')
|
|
98
|
+
)
|
|
88
99
|
|
|
89
100
|
def for_roles(self, role_list: Union[str, List[str], Set[str]]):
|
|
90
101
|
"""
|
|
@@ -294,6 +305,18 @@ class TransactionModelQuerySet(QuerySet):
|
|
|
294
305
|
timestamp=F('journal_entry__timestamp'),
|
|
295
306
|
)
|
|
296
307
|
|
|
308
|
+
def is_cleared(self):
|
|
309
|
+
return self.filter(cleared=True)
|
|
310
|
+
|
|
311
|
+
def not_cleared(self):
|
|
312
|
+
return self.filter(cleared=False)
|
|
313
|
+
|
|
314
|
+
def is_reconciled(self):
|
|
315
|
+
return self.filter(reconciled=True)
|
|
316
|
+
|
|
317
|
+
def not_reconciled(self):
|
|
318
|
+
return self.filter(reconciled=False)
|
|
319
|
+
|
|
297
320
|
|
|
298
321
|
class TransactionModelManager(Manager):
|
|
299
322
|
"""
|
|
@@ -317,6 +340,7 @@ class TransactionModelManager(Manager):
|
|
|
317
340
|
"""
|
|
318
341
|
qs = TransactionModelQuerySet(self.model, using=self._db)
|
|
319
342
|
return qs.annotate(
|
|
343
|
+
timestamp=F('journal_entry__timestamp'),
|
|
320
344
|
_coa_id=F('account__coa_model_id') # Annotates the `coa_model_id` from the related `account`.
|
|
321
345
|
).select_related(
|
|
322
346
|
'journal_entry', # Pre-loads the related Journal Entry.
|
|
@@ -510,7 +534,6 @@ class TransactionModel(TransactionModelAbstract):
|
|
|
510
534
|
|
|
511
535
|
class Meta(TransactionModelAbstract.Meta):
|
|
512
536
|
abstract = False
|
|
513
|
-
swappable = 'DJANGO_LEDGER_TRANSACTION_MODEL'
|
|
514
537
|
|
|
515
538
|
|
|
516
539
|
def transactionmodel_presave(instance: TransactionModel, **kwargs):
|
django_ledger/models/unit.py
CHANGED
django_ledger/models/vendor.py
CHANGED
django_ledger/settings.py
CHANGED
|
@@ -30,27 +30,28 @@ logger.info(f'Django Ledger GraphQL Enabled: {DJANGO_LEDGER_GRAPHQL_SUPPORT_ENAB
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
## MODEL ABSTRACTS ##
|
|
33
|
-
DJANGO_LEDGER_ACCOUNT_MODEL = getattr(settings, 'DJANGO_LEDGER_ACCOUNT_MODEL', 'django_ledger.AccountModel')
|
|
34
|
-
DJANGO_LEDGER_CHART_OF_ACCOUNTS_MODEL = getattr(settings, 'DJANGO_LEDGER_ACCOUNT_MODEL', 'django_ledger.ChartOfAccountModel')
|
|
35
|
-
DJANGO_LEDGER_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_TRANSACTION_MODEL', 'django_ledger.TransactionModel')
|
|
36
|
-
DJANGO_LEDGER_JOURNAL_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_JOURNAL_ENTRY_MODEL', 'django_ledger.JournalEntryModel')
|
|
37
|
-
DJANGO_LEDGER_LEDGER_MODEL = getattr(settings, 'DJANGO_LEDGER_LEDGER_MODEL', 'django_ledger.LedgerModel')
|
|
38
|
-
DJANGO_LEDGER_ENTITY_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_MODEL', 'django_ledger.EntityModel')
|
|
39
|
-
DJANGO_LEDGER_ENTITY_STATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_STATE_MODEL', 'django_ledger.EntityStateModel')
|
|
40
|
-
DJANGO_LEDGER_ENTITY_UNIT_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_UNIT_MODEL', 'django_ledger.EntityUnitModel')
|
|
41
|
-
DJANGO_LEDGER_ESTIMATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ESTIMATE_MODEL', 'django_ledger.EstimateModel')
|
|
42
|
-
DJANGO_LEDGER_BILL_MODEL = getattr(settings, 'DJANGO_LEDGER_BILL_MODEL', 'django_ledger.BillModel')
|
|
43
|
-
DJANGO_LEDGER_INVOICE_MODEL = getattr(settings, 'DJANGO_LEDGER_INVOICE_MODEL', 'django_ledger.InvoiceModel')
|
|
44
|
-
DJANGO_LEDGER_PURCHASE_ORDER_MODEL = getattr(settings, 'DJANGO_LEDGER_PURCHASE_ORDER_MODEL', 'django_ledger.PurchaseOrderModel')
|
|
45
|
-
DJANGO_LEDGER_CUSTOMER_MODEL = getattr(settings, 'DJANGO_LEDGER_CUSTOMER_MODEL', 'django_ledger.CustomerModel')
|
|
46
|
-
DJANGO_LEDGER_VENDOR_MODEL = getattr(settings, 'DJANGO_LEDGER_VENDOR_MODEL', 'django_ledger.VendorModel')
|
|
47
|
-
DJANGO_LEDGER_BANK_ACCOUNT_MODEL = getattr(settings, 'DJANGO_LEDGER_BANK_ACCOUNT_MODEL', 'django_ledger.BankAccountModel')
|
|
48
|
-
DJANGO_LEDGER_CLOSING_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_CLOSING_ENTRY_MODEL', 'django_ledger.ClosingEntryModel')
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
33
|
+
# DJANGO_LEDGER_ACCOUNT_MODEL = getattr(settings, 'DJANGO_LEDGER_ACCOUNT_MODEL', 'django_ledger.AccountModel')
|
|
34
|
+
# DJANGO_LEDGER_CHART_OF_ACCOUNTS_MODEL = getattr(settings, 'DJANGO_LEDGER_ACCOUNT_MODEL', 'django_ledger.ChartOfAccountModel')
|
|
35
|
+
# DJANGO_LEDGER_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_TRANSACTION_MODEL', 'django_ledger.TransactionModel')
|
|
36
|
+
# DJANGO_LEDGER_JOURNAL_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_JOURNAL_ENTRY_MODEL', 'django_ledger.JournalEntryModel')
|
|
37
|
+
# DJANGO_LEDGER_LEDGER_MODEL = getattr(settings, 'DJANGO_LEDGER_LEDGER_MODEL', 'django_ledger.LedgerModel')
|
|
38
|
+
# DJANGO_LEDGER_ENTITY_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_MODEL', 'django_ledger.EntityModel')
|
|
39
|
+
# DJANGO_LEDGER_ENTITY_STATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_STATE_MODEL', 'django_ledger.EntityStateModel')
|
|
40
|
+
# DJANGO_LEDGER_ENTITY_UNIT_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_UNIT_MODEL', 'django_ledger.EntityUnitModel')
|
|
41
|
+
# DJANGO_LEDGER_ESTIMATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ESTIMATE_MODEL', 'django_ledger.EstimateModel')
|
|
42
|
+
# DJANGO_LEDGER_BILL_MODEL = getattr(settings, 'DJANGO_LEDGER_BILL_MODEL', 'django_ledger.BillModel')
|
|
43
|
+
# DJANGO_LEDGER_INVOICE_MODEL = getattr(settings, 'DJANGO_LEDGER_INVOICE_MODEL', 'django_ledger.InvoiceModel')
|
|
44
|
+
# DJANGO_LEDGER_PURCHASE_ORDER_MODEL = getattr(settings, 'DJANGO_LEDGER_PURCHASE_ORDER_MODEL', 'django_ledger.PurchaseOrderModel')
|
|
45
|
+
# DJANGO_LEDGER_CUSTOMER_MODEL = getattr(settings, 'DJANGO_LEDGER_CUSTOMER_MODEL', 'django_ledger.CustomerModel')
|
|
46
|
+
# DJANGO_LEDGER_VENDOR_MODEL = getattr(settings, 'DJANGO_LEDGER_VENDOR_MODEL', 'django_ledger.VendorModel')
|
|
47
|
+
# DJANGO_LEDGER_BANK_ACCOUNT_MODEL = getattr(settings, 'DJANGO_LEDGER_BANK_ACCOUNT_MODEL', 'django_ledger.BankAccountModel')
|
|
48
|
+
# DJANGO_LEDGER_CLOSING_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_CLOSING_ENTRY_MODEL', 'django_ledger.ClosingEntryModel')
|
|
49
|
+
# DJANGO_LEDGER_CLOSING_ENTRY_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_CLOSING_ENTRY_TRANSACTION_MODEL', 'django_ledger.ClosingEntryTransactionModel')
|
|
50
|
+
# DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL = getattr(settings, 'DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL', 'django_ledger.UnitOfMeasureModel')
|
|
51
|
+
# DJANGO_LEDGER_ITEM_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_ITEM_TRANSACTION_MODEL', 'django_ledger.ItemTransactionModel')
|
|
52
|
+
# DJANGO_LEDGER_ITEM_MODEL = getattr(settings, 'DJANGO_LEDGER_ITEM_MODEL', 'django_ledger.ItemModel')
|
|
53
|
+
# DJANGO_LEDGER_STAGED_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_STAGED_TRANSACTION_MODEL', 'django_ledger.StagedTransactionModel')
|
|
54
|
+
# DJANGO_LEDGER_IMPORT_JOB_MODEL = getattr(settings, 'DJANGO_LEDGER_IMPORT_JOB_MODEL', 'django_ledger.ImportJobModel')
|
|
54
55
|
|
|
55
56
|
DJANGO_LEDGER_USE_CLOSING_ENTRIES = getattr(settings, 'DJANGO_LEDGER_USE_CLOSING_ENTRIES', True)
|
|
56
57
|
DJANGO_LEDGER_DEFAULT_CLOSING_ENTRY_CACHE_TIMEOUT = getattr(settings,
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
<title>{% block page_title %}{% session_entity_name %} | {{ page_title }}{% endblock %}</title>
|
|
11
11
|
<script src="{% static 'django_ledger/bundle/styles.bundle.js' %}"></script>
|
|
12
12
|
<link rel="shortcut icon" type="image/jpg" href="{% static 'django_ledger/logo/favicon.png' %}">
|
|
13
|
+
|
|
14
|
+
{% block header_extra_js %}{% endblock %}
|
|
15
|
+
{% block header_extra_css %}{% endblock %}
|
|
16
|
+
|
|
13
17
|
</head>
|
|
14
18
|
|
|
15
19
|
<body>
|
|
@@ -50,8 +54,9 @@
|
|
|
50
54
|
datePickers.forEach(dp => djLedger.getCalendar(dp.attributes.id.value, dateNavigationUrl))
|
|
51
55
|
{% endif %}
|
|
52
56
|
</script>
|
|
53
|
-
|
|
54
57
|
{% endblock %}
|
|
55
58
|
|
|
59
|
+
{% block bottom_extra_js %}{% endblock %}
|
|
60
|
+
|
|
56
61
|
</body>
|
|
57
62
|
</html>
|
django_ledger/urls/ledger.py
CHANGED
|
@@ -14,7 +14,7 @@ urlpatterns = [
|
|
|
14
14
|
path('<slug:entity_slug>/list/year/<int:year>/',
|
|
15
15
|
views.LedgerModelYearListView.as_view(),
|
|
16
16
|
name='ledger-list-year'),
|
|
17
|
-
path('<slug:entity_slug>/list/month/<int:year>/<int:month
|
|
17
|
+
path('<slug:entity_slug>/list/month/<int:year>/<int:month>/',
|
|
18
18
|
views.LedgerModelMonthListView.as_view(),
|
|
19
19
|
name='ledger-list-month'),
|
|
20
20
|
path('<slug:entity_slug>/create/',
|
|
@@ -8,13 +8,15 @@ Contributions to this module:
|
|
|
8
8
|
|
|
9
9
|
from django.contrib import messages
|
|
10
10
|
from django.core.exceptions import ValidationError, ImproperlyConfigured
|
|
11
|
-
from django.db.models import Count
|
|
12
11
|
from django.http import HttpResponseRedirect
|
|
13
|
-
from django.shortcuts import get_object_or_404
|
|
14
12
|
from django.urls import reverse
|
|
15
13
|
from django.utils.translation import gettext_lazy as _
|
|
16
|
-
from django.views.generic import
|
|
17
|
-
|
|
14
|
+
from django.views.generic import (
|
|
15
|
+
ArchiveIndexView, YearArchiveView,
|
|
16
|
+
MonthArchiveView, DetailView,
|
|
17
|
+
RedirectView, CreateView,
|
|
18
|
+
DeleteView, UpdateView
|
|
19
|
+
)
|
|
18
20
|
from django.views.generic.detail import SingleObjectMixin
|
|
19
21
|
|
|
20
22
|
from django_ledger.forms.closing_entry import ClosingEntryCreateForm, ClosingEntryUpdateForm
|
|
@@ -24,25 +26,21 @@ from django_ledger.models.entity import EntityModel
|
|
|
24
26
|
from django_ledger.views import DjangoLedgerSecurityMixIn
|
|
25
27
|
|
|
26
28
|
|
|
27
|
-
class
|
|
29
|
+
class ClosingEntryModelBaseView(DjangoLedgerSecurityMixIn):
|
|
28
30
|
queryset = None
|
|
29
|
-
queryset_annotate_txs_count = False
|
|
30
31
|
|
|
31
32
|
def get_queryset(self):
|
|
32
33
|
if self.queryset is None:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class ClosingEntryModelListView(DjangoLedgerSecurityMixIn,
|
|
44
|
-
ClosingEntryModelViewQuerySetMixIn,
|
|
45
|
-
ArchiveIndexView):
|
|
34
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
35
|
+
closing_entry_model_qs = entity_model.closingentrymodel_set.all().select_related(
|
|
36
|
+
'entity_model',
|
|
37
|
+
'ledger_model'
|
|
38
|
+
).order_by('-closing_date')
|
|
39
|
+
self.queryset = closing_entry_model_qs
|
|
40
|
+
return self.queryset
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ClosingEntryModelListView(ClosingEntryModelBaseView, ArchiveIndexView):
|
|
46
44
|
template_name = 'django_ledger/closing_entry/closing_entry_list.html'
|
|
47
45
|
date_field = 'closing_date'
|
|
48
46
|
allow_future = False
|
|
@@ -56,23 +54,21 @@ class ClosingEntryModelListView(DjangoLedgerSecurityMixIn,
|
|
|
56
54
|
'header_title': PAGE_TITLE,
|
|
57
55
|
'header_subtitle_icon': 'file-icons:finaldraft'
|
|
58
56
|
}
|
|
59
|
-
queryset_annotate_txs_count = True
|
|
60
57
|
|
|
61
58
|
|
|
62
|
-
class ClosingEntryModelYearListView(
|
|
59
|
+
class ClosingEntryModelYearListView(ClosingEntryModelListView, YearArchiveView):
|
|
63
60
|
paginate_by = 10
|
|
64
61
|
make_object_list = True
|
|
65
62
|
|
|
66
63
|
|
|
67
|
-
class ClosingEntryModelMonthListView(
|
|
64
|
+
class ClosingEntryModelMonthListView(ClosingEntryModelListView, MonthArchiveView):
|
|
68
65
|
paginate_by = 10
|
|
69
66
|
month_format = '%m'
|
|
70
67
|
date_list_period = 'year'
|
|
71
68
|
|
|
72
69
|
|
|
73
|
-
class ClosingEntryModelCreateView(
|
|
70
|
+
class ClosingEntryModelCreateView(ClosingEntryModelBaseView, CreateView):
|
|
74
71
|
template_name = 'django_ledger/closing_entry/closing_entry_create.html'
|
|
75
|
-
form_class = ClosingEntryCreateForm
|
|
76
72
|
PAGE_TITLE = _('Create Closing Entry')
|
|
77
73
|
extra_context = {
|
|
78
74
|
'page_title': PAGE_TITLE,
|
|
@@ -85,23 +81,25 @@ class ClosingEntryModelCreateView(DjangoLedgerSecurityMixIn, ClosingEntryModelVi
|
|
|
85
81
|
'closing_date': get_localdate()
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
def
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
self.object = entity_model
|
|
93
|
-
return self.object
|
|
84
|
+
def get_form(self, form_class=None, **kwargs):
|
|
85
|
+
return ClosingEntryCreateForm(
|
|
86
|
+
**self.get_form_kwargs()
|
|
87
|
+
)
|
|
94
88
|
|
|
95
89
|
def get_context_data(self, **kwargs):
|
|
96
90
|
ctx = super().get_context_data(**kwargs)
|
|
97
|
-
entity_model = self.
|
|
91
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
98
92
|
ctx['header_subtitle'] = entity_model.name
|
|
99
93
|
return ctx
|
|
100
94
|
|
|
101
95
|
def form_valid(self, form):
|
|
102
96
|
closing_date = form.cleaned_data['closing_date']
|
|
103
|
-
entity_model: EntityModel = self.
|
|
104
|
-
ce_model, _ = entity_model.close_entity_books(
|
|
97
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
98
|
+
ce_model, _ = entity_model.close_entity_books(
|
|
99
|
+
closing_date=closing_date,
|
|
100
|
+
force_update=True,
|
|
101
|
+
post_closing_entry=False
|
|
102
|
+
)
|
|
105
103
|
self.ce_model = ce_model
|
|
106
104
|
return HttpResponseRedirect(self.get_success_url())
|
|
107
105
|
|
|
@@ -115,7 +113,7 @@ class ClosingEntryModelCreateView(DjangoLedgerSecurityMixIn, ClosingEntryModelVi
|
|
|
115
113
|
)
|
|
116
114
|
|
|
117
115
|
|
|
118
|
-
class ClosingEntryModelDetailView(
|
|
116
|
+
class ClosingEntryModelDetailView(ClosingEntryModelBaseView, DetailView):
|
|
119
117
|
template_name = 'django_ledger/closing_entry/closing_entry_detail.html'
|
|
120
118
|
pk_url_kwarg = 'closing_entry_pk'
|
|
121
119
|
context_object_name = 'closing_entry_model'
|
|
@@ -123,7 +121,6 @@ class ClosingEntryModelDetailView(DjangoLedgerSecurityMixIn, ClosingEntryModelVi
|
|
|
123
121
|
'header_title': 'Closing Entry Detail',
|
|
124
122
|
'header_subtitle_icon': 'file-icons:finaldraft'
|
|
125
123
|
}
|
|
126
|
-
queryset_annotate_txs_count = True
|
|
127
124
|
|
|
128
125
|
def get_context_data(self, **kwargs):
|
|
129
126
|
ctx = super().get_context_data(**kwargs)
|
|
@@ -135,12 +132,11 @@ class ClosingEntryModelDetailView(DjangoLedgerSecurityMixIn, ClosingEntryModelVi
|
|
|
135
132
|
return ctx
|
|
136
133
|
|
|
137
134
|
|
|
138
|
-
class ClosingEntryModelUpdateView(
|
|
135
|
+
class ClosingEntryModelUpdateView(ClosingEntryModelBaseView, UpdateView):
|
|
139
136
|
template_name = 'django_ledger/closing_entry/closing_entry_update.html'
|
|
140
137
|
pk_url_kwarg = 'closing_entry_pk'
|
|
141
138
|
form_class = ClosingEntryUpdateForm
|
|
142
139
|
context_object_name = 'closing_entry_model'
|
|
143
|
-
queryset_annotate_txs_count = True
|
|
144
140
|
extra_context = {
|
|
145
141
|
'header_title': 'Closing Entry Detail',
|
|
146
142
|
'header_subtitle_icon': 'file-icons:finaldraft'
|
|
@@ -165,10 +161,22 @@ class ClosingEntryModelUpdateView(DjangoLedgerSecurityMixIn, ClosingEntryModelVi
|
|
|
165
161
|
)
|
|
166
162
|
|
|
167
163
|
|
|
168
|
-
class ClosingEntryDeleteView(
|
|
164
|
+
class ClosingEntryDeleteView(ClosingEntryModelBaseView, DeleteView):
|
|
169
165
|
template_name = 'django_ledger/closing_entry/closing_entry_delete.html'
|
|
170
166
|
pk_url_kwarg = 'closing_entry_pk'
|
|
171
167
|
context_object_name = 'closing_entry'
|
|
168
|
+
extra_context = {
|
|
169
|
+
'header_title': _('Delete Closing Entry'),
|
|
170
|
+
'header_subtitle_icon': 'file-icons:finaldraft'
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
def get_context_data(self, **kwargs):
|
|
174
|
+
context = super().get_context_data(**kwargs)
|
|
175
|
+
closing_entry_model: ClosingEntryModel = self.object
|
|
176
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
177
|
+
context['page_title'] = 'Delete Closing Entry {}'.format(closing_entry_model.closing_date)
|
|
178
|
+
context['header_subtitle'] = entity_model.name
|
|
179
|
+
return context
|
|
172
180
|
|
|
173
181
|
def get_success_url(self):
|
|
174
182
|
return reverse(viewname='django_ledger:closing-entry-list',
|
|
@@ -177,9 +185,8 @@ class ClosingEntryDeleteView(DjangoLedgerSecurityMixIn, ClosingEntryModelViewQue
|
|
|
177
185
|
})
|
|
178
186
|
|
|
179
187
|
|
|
180
|
-
class ClosingEntryModelActionView(
|
|
188
|
+
class ClosingEntryModelActionView(ClosingEntryModelBaseView,
|
|
181
189
|
RedirectView,
|
|
182
|
-
ClosingEntryModelViewQuerySetMixIn,
|
|
183
190
|
SingleObjectMixin):
|
|
184
191
|
http_method_names = ['get']
|
|
185
192
|
pk_url_kwarg = 'closing_entry_pk'
|
django_ledger/views/mixins.py
CHANGED
|
@@ -361,6 +361,12 @@ class DjangoLedgerSecurityMixIn(LoginRequiredMixin, PermissionRequiredMixin):
|
|
|
361
361
|
return
|
|
362
362
|
return self.AUTHORIZED_ENTITY_MODEL
|
|
363
363
|
|
|
364
|
+
def get_authorized_entity_instance_name(self) -> Optional[str]:
|
|
365
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
366
|
+
if not entity_model:
|
|
367
|
+
return None
|
|
368
|
+
return entity_model.name
|
|
369
|
+
|
|
364
370
|
|
|
365
371
|
class EntityUnitMixIn:
|
|
366
372
|
UNIT_SLUG_KWARG = 'unit_slug'
|
django_ledger/views/unit.py
CHANGED
|
@@ -22,7 +22,7 @@ from django_ledger.views.mixins import (DjangoLedgerSecurityMixIn, QuarterlyRepo
|
|
|
22
22
|
PDFReportMixIn)
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class
|
|
25
|
+
class EntityUnitModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
26
26
|
queryset = None
|
|
27
27
|
|
|
28
28
|
def get_queryset(self):
|
|
@@ -34,7 +34,7 @@ class EntityUnitModelModelViewQuerySetMixIn:
|
|
|
34
34
|
return super().get_queryset()
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
class EntityUnitModelListView(
|
|
37
|
+
class EntityUnitModelListView(EntityUnitModelModelBaseView, ListView):
|
|
38
38
|
template_name = 'django_ledger/unit/unit_list.html'
|
|
39
39
|
PAGE_TITLE = _('Entity Unit List')
|
|
40
40
|
extra_context = {
|
|
@@ -45,7 +45,7 @@ class EntityUnitModelListView(DjangoLedgerSecurityMixIn, EntityUnitModelModelVie
|
|
|
45
45
|
context_object_name = 'unit_list'
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
class EntityUnitModelDetailView(
|
|
48
|
+
class EntityUnitModelDetailView(EntityUnitModelModelBaseView, DetailView):
|
|
49
49
|
template_name = 'django_ledger/unit/unit_detail.html'
|
|
50
50
|
PAGE_TITLE = _('Entity Unit Detail')
|
|
51
51
|
slug_url_kwarg = 'unit_slug'
|
|
@@ -57,7 +57,7 @@ class EntityUnitModelDetailView(DjangoLedgerSecurityMixIn, EntityUnitModelModelV
|
|
|
57
57
|
context_object_name = 'unit'
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
class EntityUnitModelCreateView(
|
|
60
|
+
class EntityUnitModelCreateView(EntityUnitModelModelBaseView, CreateView):
|
|
61
61
|
template_name = 'django_ledger/unit/unit_create.html'
|
|
62
62
|
PAGE_TITLE = _('Entity Unit Create')
|
|
63
63
|
extra_context = {
|
|
@@ -88,7 +88,7 @@ class EntityUnitModelCreateView(DjangoLedgerSecurityMixIn, EntityUnitModelModelV
|
|
|
88
88
|
return HttpResponseRedirect(self.get_success_url())
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
class EntityUnitUpdateView(
|
|
91
|
+
class EntityUnitUpdateView(EntityUnitModelModelBaseView, UpdateView):
|
|
92
92
|
template_name = 'django_ledger/unit/unit_update.html'
|
|
93
93
|
PAGE_TITLE = _('Entity Unit Update')
|
|
94
94
|
slug_url_kwarg = 'unit_slug'
|
|
@@ -123,7 +123,7 @@ class EntityUnitUpdateView(DjangoLedgerSecurityMixIn, EntityUnitModelModelViewQu
|
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
# BALANCE SHEET.....
|
|
126
|
-
class BaseEntityUnitModelBalanceSheetView(
|
|
126
|
+
class BaseEntityUnitModelBalanceSheetView(EntityUnitModelModelBaseView, RedirectView):
|
|
127
127
|
|
|
128
128
|
def get_redirect_url(self, *args, **kwargs):
|
|
129
129
|
year = get_localdate().year
|
|
@@ -135,8 +135,7 @@ class BaseEntityUnitModelBalanceSheetView(DjangoLedgerSecurityMixIn, RedirectVie
|
|
|
135
135
|
})
|
|
136
136
|
|
|
137
137
|
|
|
138
|
-
class FiscalYearEntityUnitModelBalanceSheetView(
|
|
139
|
-
EntityUnitModelModelViewQuerySetMixIn,
|
|
138
|
+
class FiscalYearEntityUnitModelBalanceSheetView(EntityUnitModelModelBaseView,
|
|
140
139
|
BaseDateNavigationUrlMixIn,
|
|
141
140
|
EntityUnitMixIn,
|
|
142
141
|
YearlyReportMixIn,
|
|
@@ -176,7 +175,7 @@ class DateEntityUnitModelBalanceSheetView(MonthlyEntityUnitModelBalanceSheetView
|
|
|
176
175
|
|
|
177
176
|
|
|
178
177
|
# INCOME STATEMENT....
|
|
179
|
-
class BaseEntityUnitModelIncomeStatementView(
|
|
178
|
+
class BaseEntityUnitModelIncomeStatementView(EntityUnitModelModelBaseView, RedirectView):
|
|
180
179
|
|
|
181
180
|
def get_redirect_url(self, *args, **kwargs):
|
|
182
181
|
year = get_localdate().year
|
|
@@ -188,8 +187,7 @@ class BaseEntityUnitModelIncomeStatementView(DjangoLedgerSecurityMixIn, Redirect
|
|
|
188
187
|
})
|
|
189
188
|
|
|
190
189
|
|
|
191
|
-
class FiscalYearEntityUnitModelIncomeStatementView(
|
|
192
|
-
EntityUnitModelModelViewQuerySetMixIn,
|
|
190
|
+
class FiscalYearEntityUnitModelIncomeStatementView(EntityUnitModelModelBaseView,
|
|
193
191
|
BaseDateNavigationUrlMixIn,
|
|
194
192
|
EntityUnitMixIn,
|
|
195
193
|
YearlyReportMixIn,
|
|
@@ -225,7 +223,7 @@ class DateIncomeStatementView(FiscalYearIncomeStatementView, DateReportMixIn):
|
|
|
225
223
|
|
|
226
224
|
|
|
227
225
|
# CASHFLOW STATEMENT
|
|
228
|
-
class BaseEntityUnitModelCashFlowStatementView(
|
|
226
|
+
class BaseEntityUnitModelCashFlowStatementView(EntityUnitModelModelBaseView, RedirectView):
|
|
229
227
|
|
|
230
228
|
def get_redirect_url(self, *args, **kwargs):
|
|
231
229
|
year = get_localdate().year
|
|
@@ -237,8 +235,7 @@ class BaseEntityUnitModelCashFlowStatementView(DjangoLedgerSecurityMixIn, Redire
|
|
|
237
235
|
})
|
|
238
236
|
|
|
239
237
|
|
|
240
|
-
class FiscalYearEntityUnitModelCashFlowStatementView(
|
|
241
|
-
EntityUnitModelModelViewQuerySetMixIn,
|
|
238
|
+
class FiscalYearEntityUnitModelCashFlowStatementView(EntityUnitModelModelBaseView,
|
|
242
239
|
BaseDateNavigationUrlMixIn,
|
|
243
240
|
EntityUnitMixIn,
|
|
244
241
|
YearlyReportMixIn,
|
django_ledger/views/vendor.py
CHANGED
|
@@ -16,7 +16,7 @@ from django_ledger.models.vendor import VendorModel
|
|
|
16
16
|
from django_ledger.views.mixins import DjangoLedgerSecurityMixIn
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class
|
|
19
|
+
class VendorModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
20
20
|
queryset = None
|
|
21
21
|
|
|
22
22
|
def get_queryset(self):
|
|
@@ -28,7 +28,7 @@ class VendorModelModelViewQuerySetMixIn:
|
|
|
28
28
|
return super().get_queryset()
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
class VendorModelListView(
|
|
31
|
+
class VendorModelListView(VendorModelModelBaseView, ListView):
|
|
32
32
|
template_name = 'django_ledger/vendor/vendor_list.html'
|
|
33
33
|
context_object_name = 'vendors'
|
|
34
34
|
PAGE_TITLE = _('Vendor List')
|
|
@@ -38,8 +38,14 @@ class VendorModelListView(DjangoLedgerSecurityMixIn, VendorModelModelViewQuerySe
|
|
|
38
38
|
'header_subtitle_icon': 'bi:person-lines-fill'
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
def get_context_data(self, **kwargs):
|
|
42
|
+
context = super().get_context_data(**kwargs)
|
|
43
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
44
|
+
context['header_subtitle'] = entity_model.name
|
|
45
|
+
return context
|
|
46
|
+
|
|
41
47
|
|
|
42
|
-
class VendorModelCreateView(
|
|
48
|
+
class VendorModelCreateView(VendorModelModelBaseView, CreateView):
|
|
43
49
|
template_name = 'django_ledger/vendor/vendor_create.html'
|
|
44
50
|
PAGE_TITLE = _('Create New Vendor')
|
|
45
51
|
form_class = VendorModelForm
|
|
@@ -66,7 +72,7 @@ class VendorModelCreateView(DjangoLedgerSecurityMixIn, VendorModelModelViewQuery
|
|
|
66
72
|
return super().form_valid(form)
|
|
67
73
|
|
|
68
74
|
|
|
69
|
-
class VendorModelUpdateView(
|
|
75
|
+
class VendorModelUpdateView(VendorModelModelBaseView, UpdateView):
|
|
70
76
|
template_name = 'django_ledger/vendor/vendor_update.html'
|
|
71
77
|
PAGE_TITLE = _('Vendor Update')
|
|
72
78
|
context_object_name = 'vendor'
|
|
@@ -89,7 +95,3 @@ class VendorModelUpdateView(DjangoLedgerSecurityMixIn, VendorModelModelViewQuery
|
|
|
89
95
|
kwargs={
|
|
90
96
|
'entity_slug': self.kwargs['entity_slug']
|
|
91
97
|
})
|
|
92
|
-
|
|
93
|
-
def form_valid(self, form):
|
|
94
|
-
form.save()
|
|
95
|
-
return super().form_valid(form)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: django-ledger
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.6.1
|
|
4
4
|
Summary: Double entry accounting system built on the Django Web Framework.
|
|
5
5
|
Author-email: Miguel Sanda <msanda@arrobalytics.com>
|
|
6
6
|
Maintainer-email: Miguel Sanda <msanda@arrobalytics.com>
|
|
@@ -48,6 +48,8 @@ Requires-Dist: furo; extra == "dev"
|
|
|
48
48
|
Django Ledger is a powerful financial management system built on the Django Web Framework. It offers a simplified API
|
|
49
49
|
for handling complex accounting tasks in financially driven applications.
|
|
50
50
|
|
|
51
|
+
Created and developed by [Miguel Sanda](https://www.miguelsanda.com).
|
|
52
|
+
|
|
51
53
|
[FREE Get Started Guide](https://www.djangoledger.com/get-started) | [Join our Discord](https://discord.gg/c7PZcbYgrc) | [Documentation](https://django-ledger.readthedocs.io/en/latest/) | [QuickStart Notebook](https://github.com/arrobalytics/django-ledger/blob/develop/notebooks/QuickStart%20Notebook.ipynb)
|
|
52
54
|
|
|
53
55
|
## Key Features
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
django_ledger/__init__.py,sha256=
|
|
1
|
+
django_ledger/__init__.py,sha256=MUwO2Divbce4snfcTQcqtZJZf6TMKSgX18eqO5JDspA,382
|
|
2
2
|
django_ledger/apps.py,sha256=H-zEWUjKGakgSDSZmLIoXChZ2h6e0dth0ZO5SpoT-8U,163
|
|
3
3
|
django_ledger/exceptions.py,sha256=rML8sQQ0Hq-DYMLZ76dfw2RYSAsXWUoyHuyC_yP9o1o,491
|
|
4
|
-
django_ledger/settings.py,sha256=
|
|
4
|
+
django_ledger/settings.py,sha256=QOMK8mhT8MLrMxVDEzNRJ9W01Pm-Po26y7KaBPLVeNk,8952
|
|
5
5
|
django_ledger/utils.py,sha256=eGEdrDRrnILIsk69FVN9pjX1VoDVc1nx_MfVAwiY5dg,3519
|
|
6
6
|
django_ledger/admin/__init__.py,sha256=-1h4Qg9dfRq9g-EoDZAq96L8lcOoGlwJXNBsbqVIY7U,472
|
|
7
7
|
django_ledger/admin/chart_of_accounts.py,sha256=tRQXsa5oi9behZc_A_aMsbDoT_wzxR2EvEF-aUuV0H8,3539
|
|
@@ -49,7 +49,7 @@ django_ledger/forms/auth.py,sha256=HaJDEIRFoAHEAv-s_ZfTe0rZbhzIQ7GkKnaBX1qiAW4,7
|
|
|
49
49
|
django_ledger/forms/bank_account.py,sha256=Ir6eQk4PSL7dii4mYGM895u6twrgvPm8vn3FCozSg8Q,4828
|
|
50
50
|
django_ledger/forms/bill.py,sha256=vJbLZhHpolhzM0WKZdSAcuBnQAXDGGeKmY3RrswB-ZM,10813
|
|
51
51
|
django_ledger/forms/chart_of_accounts.py,sha256=wymLQ8iLNPU_LgS79BOdMUapuLqoTvgqVdAyL1Pw0Ro,2414
|
|
52
|
-
django_ledger/forms/closing_entry.py,sha256=
|
|
52
|
+
django_ledger/forms/closing_entry.py,sha256=ARKHmwf8n2vLMpLTTven9xuwVBQ7aMBcIUMnnWkbUdw,1526
|
|
53
53
|
django_ledger/forms/customer.py,sha256=GrpREV8c3UsNhg5KzwNsofnuW5uv25Ue-Aa-pJeyXUc,2501
|
|
54
54
|
django_ledger/forms/data_import.py,sha256=AMb8C867KZ6qxTHtGkpexj7VY1yehPJX0DE0-4pFIcA,6930
|
|
55
55
|
django_ledger/forms/entity.py,sha256=b0QirmsFSnaM8YWDO4V6GQXfFgR_MLmdq27I2q2sGQ0,6880
|
|
@@ -57,7 +57,7 @@ django_ledger/forms/estimate.py,sha256=0A30F4mosT4uvIde61lAWbPV4JePUQIX87VAcTtby
|
|
|
57
57
|
django_ledger/forms/feedback.py,sha256=WUT-kI4uT6q5aqEYaDYwyIFfhXpmtwMv6qf9BFSYsDo,1850
|
|
58
58
|
django_ledger/forms/invoice.py,sha256=Y7m5DxlNYsjBoZKWb99SFquwIW_tbVuLkJBgqSZmt1g,9675
|
|
59
59
|
django_ledger/forms/item.py,sha256=i2pMhneb27a2HyQ9I48dYeHdSd1cgsZsjWYWDjGJ5UQ,12457
|
|
60
|
-
django_ledger/forms/journal_entry.py,sha256=
|
|
60
|
+
django_ledger/forms/journal_entry.py,sha256=DmL_5_akNm7Da4mAFeodg4wEx8hS9MSb9XoEGdkFyNE,3269
|
|
61
61
|
django_ledger/forms/ledger.py,sha256=jz2Ipdj-6hDBGeU4X0rodFT0yPQcFwTQ0EeUqDpKC6g,1739
|
|
62
62
|
django_ledger/forms/purchase_order.py,sha256=XIi7v6ZaBd9nYgcWLmgNKm9751XBXpbwmUtlpPJklHI,7479
|
|
63
63
|
django_ledger/forms/transactions.py,sha256=ockQjKihNY07m9NWL9nJtHBQMzROaQQO18QZSuiFn8s,3210
|
|
@@ -65,8 +65,8 @@ django_ledger/forms/unit.py,sha256=rXUefjpuAmUU0vPOqu1ObO4k-bN-_Q6kOqHJ4kp_Vlg,1
|
|
|
65
65
|
django_ledger/forms/utils.py,sha256=sgkwBZs15_rZ5NT7h-8Z7wi3-ItM1E1sqoVDo3NQ5Jc,513
|
|
66
66
|
django_ledger/forms/vendor.py,sha256=Nuh8MmSpz4ycMZwiVe--U9Ec6ezIsfACHDkhA2SyiZ4,2215
|
|
67
67
|
django_ledger/io/__init__.py,sha256=8m5AoBRiG2ymrX0Y4LVjq0275i7I5Sk7YRa1BTzVofI,369
|
|
68
|
-
django_ledger/io/io_context.py,sha256=
|
|
69
|
-
django_ledger/io/io_core.py,sha256=
|
|
68
|
+
django_ledger/io/io_context.py,sha256=2AiQyJSTkYUCu09Ig0ZPgYj8PtlvUKNS30KvRp9e7zA,4753
|
|
69
|
+
django_ledger/io/io_core.py,sha256=qG6ZDbdJw5OzADNR37zeLbhG7wAKWLpRBDfSkm0hv6k,87133
|
|
70
70
|
django_ledger/io/io_generator.py,sha256=IN_ZuMlPHXgoEffxA7PMN2fyTvWPJktzVR6yIaocsRs,34725
|
|
71
71
|
django_ledger/io/io_library.py,sha256=CGZABR4P80VfIube4QEryNOi01llrPq0Gh-8vVbtZDY,22496
|
|
72
72
|
django_ledger/io/io_middleware.py,sha256=vbWIBYA4V9nwoiEtB0W9pq19QIwPmaAyVJlo_1Gg2BY,20284
|
|
@@ -99,27 +99,27 @@ django_ledger/migrations/0020_remove_bankaccountmodel_django_ledg_cash_ac_59a8af
|
|
|
99
99
|
django_ledger/migrations/0021_alter_bankaccountmodel_account_model_and_more.py,sha256=b3eJA_QzNzvx7BPSaj2RCPIbsrCkZrpkvk_qN7v-4OA,1101
|
|
100
100
|
django_ledger/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
101
|
django_ledger/models/__init__.py,sha256=OesBx4My9GnqU1xB5WXuuGLOnmzgxEJxI-WWxRxi658,807
|
|
102
|
-
django_ledger/models/accounts.py,sha256=
|
|
103
|
-
django_ledger/models/bank_account.py,sha256=
|
|
104
|
-
django_ledger/models/bill.py,sha256=
|
|
105
|
-
django_ledger/models/chart_of_accounts.py,sha256=
|
|
106
|
-
django_ledger/models/closing_entry.py,sha256=
|
|
102
|
+
django_ledger/models/accounts.py,sha256=O4BYLGiTduA1fnKFVCo6_URVeQiXmTu2fAngchxBd6Y,36560
|
|
103
|
+
django_ledger/models/bank_account.py,sha256=S0bhQ4MIakdraFTvxy_7Y8mmd9GN2Trg43UsfInhcQs,7777
|
|
104
|
+
django_ledger/models/bill.py,sha256=LCuYvyOtkZ6H-tcV4AYN1GFe_C6s__QxEbR0IcfTak8,65000
|
|
105
|
+
django_ledger/models/chart_of_accounts.py,sha256=cMHAc0TQdYD1iMan9qbrq2FX3NlmPYI_g1qwXPa4sSU,30308
|
|
106
|
+
django_ledger/models/closing_entry.py,sha256=ILFNwxvCNvlEKuK2AL8z49izEBtfco-IT_oXcCMcbP8,18294
|
|
107
107
|
django_ledger/models/coa_default.py,sha256=CK4vOZ73QePciZUL93wigDXpxKamdXAKBaQR7r-G7tk,27482
|
|
108
|
-
django_ledger/models/customer.py,sha256=
|
|
109
|
-
django_ledger/models/data_import.py,sha256=
|
|
110
|
-
django_ledger/models/entity.py,sha256=
|
|
111
|
-
django_ledger/models/estimate.py,sha256=
|
|
112
|
-
django_ledger/models/invoice.py,sha256=
|
|
113
|
-
django_ledger/models/items.py,sha256
|
|
114
|
-
django_ledger/models/journal_entry.py,sha256=
|
|
115
|
-
django_ledger/models/ledger.py,sha256=
|
|
108
|
+
django_ledger/models/customer.py,sha256=2v6E1Ri9v3yBPMS8wpnqbEdDeLD897DEfR6vSDf2lVY,11336
|
|
109
|
+
django_ledger/models/data_import.py,sha256=uD2rdmguH6L8gTSltImFRZZ3vrBrmCEG-EWWdSJB0k8,47574
|
|
110
|
+
django_ledger/models/entity.py,sha256=mC7SprHV9zJkMYbvU_rC9NcER_6xFQF-g-j8svz1Lwg,124708
|
|
111
|
+
django_ledger/models/estimate.py,sha256=t3ZSBHZUUOdWP6eMCyQwNgvNSY4myKbkdfaFd9zlpH0,58056
|
|
112
|
+
django_ledger/models/invoice.py,sha256=l1yI-kpePNNSp0MfwGeccdPLAmTmvVV4CquNIxMrmc4,63222
|
|
113
|
+
django_ledger/models/items.py,sha256=cGv681aocJJxXSbsz9NlLhPp7kJ-gQrtxl7EcsiwULg,55087
|
|
114
|
+
django_ledger/models/journal_entry.py,sha256=Hqfz7oNUBXt1Vprd5W1adrFmZzCebemc2cvQZTlKVrk,66993
|
|
115
|
+
django_ledger/models/ledger.py,sha256=ltWmPIzauwxODO-FSupphIOkJYPDGT47-xKOst5DEvQ,26266
|
|
116
116
|
django_ledger/models/mixins.py,sha256=NKBbtARYi9Z3sWuZajYNQB7Tsx4VEAN5cL-VaVZgoAU,52575
|
|
117
|
-
django_ledger/models/purchase_order.py,sha256=
|
|
117
|
+
django_ledger/models/purchase_order.py,sha256=A0fKA1lU12CYePb43T--wSNqf_d6Vwap1deyNXUoFEg,44140
|
|
118
118
|
django_ledger/models/signals.py,sha256=3cm_8--Jz-Jb0fPgrVmm5xx_jKFARV6_A29VDjqHeIw,1563
|
|
119
|
-
django_ledger/models/transactions.py,sha256=
|
|
120
|
-
django_ledger/models/unit.py,sha256=
|
|
119
|
+
django_ledger/models/transactions.py,sha256=b_ChD6FG-ru7FgT7c9D_1ku1YyhCz840wSrnyVQN6AU,24045
|
|
120
|
+
django_ledger/models/unit.py,sha256=cHybPxSI3PUr6aSRQZSFUEyj8e-rAdhyafekNOkYoew,8375
|
|
121
121
|
django_ledger/models/utils.py,sha256=Weta2Cwsn4wRqvxMecIuD7aHYiiXBwUeMqpUDK4CokE,8360
|
|
122
|
-
django_ledger/models/vendor.py,sha256=
|
|
122
|
+
django_ledger/models/vendor.py,sha256=ha_sTc9BHY7RKk70n50eZ-EvqbKHbDObyf0_khhLWN8,11322
|
|
123
123
|
django_ledger/models/schemas/__init__.py,sha256=8Tvw33tVJtCvxoXje2lrs9C1bsP_iuGcVi1JqzdPUao,157
|
|
124
124
|
django_ledger/models/schemas/digest.py,sha256=ME_dJ4g2p3dQ97Skh_RTZMwuNLmwTi19BdLM1G6tyAo,1077
|
|
125
125
|
django_ledger/models/schemas/net_payable.py,sha256=2FcfLaaJySjZ3Yk_IMu8SxYWNO_sngEtbuFCXInrQUU,958
|
|
@@ -130,8 +130,6 @@ django_ledger/report/balance_sheet.py,sha256=iw8VOcJfJJHcKwFmdR9p2uYj5iKyX6avUjV
|
|
|
130
130
|
django_ledger/report/cash_flow_statement.py,sha256=61HlJHu-WguG-aR4dTZ8fs8kNDcPCLdEy1hfK1WLJp8,8718
|
|
131
131
|
django_ledger/report/core.py,sha256=MSWOHvYrAfAJJtm1_vXv7vZxgAja6ycKxknoaIvJT_g,7436
|
|
132
132
|
django_ledger/report/income_statement.py,sha256=m4pG0Yjpl7SELx3-yYKT4dCluKt6nT2bkD9gay9tNKI,11156
|
|
133
|
-
django_ledger/static/.DS_Store,sha256=ohv3-BA3m5CUHedTAFiR2MLIeBhMNEz_a0LMOFhljzc,6148
|
|
134
|
-
django_ledger/static/django_ledger/.DS_Store,sha256=EDcdC71oJjK355v2FDhienPd1ek36-Zl8YjoiTltcpk,8196
|
|
135
133
|
django_ledger/static/django_ledger/bundle/djetler.bundle.js,sha256=kTHqgMK1QbX-Yc192tyLANsuRjSH_94aDNz5EahGU0s,585360
|
|
136
134
|
django_ledger/static/django_ledger/bundle/styles.bundle.js,sha256=qlpwKrCVyhi5mcS5dZ36AZLORSis9sgXzRZJRFTWzMg,769929
|
|
137
135
|
django_ledger/static/django_ledger/img/daniel-weiss-aj2Os9mYgJU-unsplash.jpg,sha256=zYNOMM56QE4AdRkvdGRNifDqj4OJcUA49oebJqsRjuQ,276317
|
|
@@ -154,7 +152,6 @@ django_ledger/static/django_ledger/logo/django-ledger-text@2x.png,sha256=QJVyPER
|
|
|
154
152
|
django_ledger/static/django_ledger/logo/django-ledger-text@3x.png,sha256=ddWSMY9dXrAMPTS3LZ6K4sDVvJpYFW4KrVUTqJKU-wg,67707
|
|
155
153
|
django_ledger/static/django_ledger/logo/django-ledger-text@4x.png,sha256=d5hPUkvmJS_5LXPGgJ5VhcI_2CeteVsiNABv1Q2R6aw,99253
|
|
156
154
|
django_ledger/static/django_ledger/logo/favicon.png,sha256=7QIRzizQUig3PHi9zyV1tK8kXid410_mmin-WZ3zY4M,6434
|
|
157
|
-
django_ledger/static/django_ledger/logo_2/.DS_Store,sha256=c7XYmqnuWTT7tJYaMqpBJGL2BAD8sqK0RwupHKEu__g,6148
|
|
158
155
|
django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark.png,sha256=NtTFrUKckyevB2rIcDqAdqKdaO8QOADf9YoU9BBm-Ao,12705
|
|
159
156
|
django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@0.5x.png,sha256=HOt8mW4FHF4eEH3LD9YvPs7gpFZn4XC5SKYLB0XSCGs,5873
|
|
160
157
|
django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@2x.png,sha256=exEY0ViG9EeXxy2V7PGvPOnlaEzMGsMRu4sZnPXhsgE,27393
|
|
@@ -303,7 +300,7 @@ django_ledger/templates/django_ledger/journal_entry/je_update.html,sha256=XXxhA3
|
|
|
303
300
|
django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html,sha256=PU-tOMBuQcwxP73uXyNePaCF8aY0KutWuuAdYUWJofw,2547
|
|
304
301
|
django_ledger/templates/django_ledger/journal_entry/tags/je_table.html,sha256=IQyHXHA3goBjdGM0Hzih46Z82JVhMGPpCRgMVCNGmaA,5747
|
|
305
302
|
django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html,sha256=6gqASIlyKmeTgV-0Lp_DVB7SGLcL1y_U8cpR4sJFLyU,3366
|
|
306
|
-
django_ledger/templates/django_ledger/layouts/base.html,sha256=
|
|
303
|
+
django_ledger/templates/django_ledger/layouts/base.html,sha256=_M49Ivw6TKU4dFjESTBd7vcc1kqXLWbDgcBnHUy_5Z4,1910
|
|
307
304
|
django_ledger/templates/django_ledger/layouts/content_layout_1.html,sha256=U-32AnGwhIOGHtSTlSst580OwrUBIoDIt93_xZRtOTw,936
|
|
308
305
|
django_ledger/templates/django_ledger/layouts/content_layout_2.html,sha256=gqXgaGj3ByTI7EziEw0Wo-XBPZEB82selzrXDuCNz_Y,355
|
|
309
306
|
django_ledger/templates/django_ledger/ledger/ledger_create.html,sha256=eyfmLniuAVMUo12HWdMrq0YP3DfP1aCz6M2QZm8fuYc,896
|
|
@@ -381,7 +378,7 @@ django_ledger/urls/inventory.py,sha256=n7d4lX_8thDikWbQIGE4gyZIrjpSY1kVO0qYpjLBr
|
|
|
381
378
|
django_ledger/urls/invoice.py,sha256=Yf11g0Up_8uaosfyi1w0oc1YWEJSPk8Jo3HDldcE2KU,2999
|
|
382
379
|
django_ledger/urls/item.py,sha256=PZxdnaUMCegk17b7eSwKpd9k74apHFbzz12KRdp1ryo,2609
|
|
383
380
|
django_ledger/urls/journal_entry.py,sha256=sKuYtKDSaAVcW--iIe8GQecuVZ7wF6W3vOtgATUIr0c,2094
|
|
384
|
-
django_ledger/urls/ledger.py,sha256=
|
|
381
|
+
django_ledger/urls/ledger.py,sha256=4Np3M0OuVdyoNRKVMqYIEA6MmwdlJSQp0vrnqYCWSZM,2802
|
|
385
382
|
django_ledger/urls/purchase_order.py,sha256=iUNdzy8dcxkkmDAOt2fO4Up3e0pHDqZNSf9JOKbO4Wo,2388
|
|
386
383
|
django_ledger/urls/transactions.py,sha256=e_x_z5qbkR6i7o8OWWdXshDiY_WVmu9WVhR9A96fnhI,80
|
|
387
384
|
django_ledger/urls/unit.py,sha256=QEVKrgcw2dqMaaXsUHfqYecTa5-iaPlS9smrYJ1QsgM,1506
|
|
@@ -392,7 +389,7 @@ django_ledger/views/auth.py,sha256=I8Mv_aAfW-8Z5VYPOX7P3IUO4Fp5jJPkSuu1ZSVpWtI,7
|
|
|
392
389
|
django_ledger/views/bank_account.py,sha256=MbiVurJTNK-UsDPn17-ai4G8sE3qIMrdmXaWPX-J8n8,5025
|
|
393
390
|
django_ledger/views/bill.py,sha256=5tNb3pyh8GQM4hjV0FXqCXrEQF2LwpEWLkOkpknEdjA,22239
|
|
394
391
|
django_ledger/views/chart_of_accounts.py,sha256=wMdnXRNWzdPgxl1YeHbdAQXbCBU2VkmxVxxtUuk9NAQ,5485
|
|
395
|
-
django_ledger/views/closing_entry.py,sha256=
|
|
392
|
+
django_ledger/views/closing_entry.py,sha256=SbJMyBVG8KTfZ6oo4Gdzx03utKY5CoC7qioU_dm9n5I,8157
|
|
396
393
|
django_ledger/views/customer.py,sha256=FYnwhRx6JXE4bsjXQqFp8b9H8a4m7zv6ohoSj1OkZD8,3678
|
|
397
394
|
django_ledger/views/data_import.py,sha256=bRCCxfFJCzmthMkDcELDI_JfkgGjchTATrNnojv9p6c,8179
|
|
398
395
|
django_ledger/views/djl_api.py,sha256=6ADX9fBK8DroTeg8UIeCf2x4wt6-AF5xLlDQnqXBfsM,4411
|
|
@@ -406,14 +403,14 @@ django_ledger/views/invoice.py,sha256=BCCvQCtB1p7WBRQZeJakUhDJy4Fr5jvEYIDgLnZDh3
|
|
|
406
403
|
django_ledger/views/item.py,sha256=WvwvNWe4Wu9tZWbm75iciNvaSxh9b8h_P_FHt4jsKXs,20604
|
|
407
404
|
django_ledger/views/journal_entry.py,sha256=7qWagPqk8Nc8E9ylThYfCnvB4o8dsW1GQApMLG3Jb_8,11277
|
|
408
405
|
django_ledger/views/ledger.py,sha256=_-y8_Na5JyLYzkYIGrOJzAMWC3Hk8hzsikqXsxf8MkM,12178
|
|
409
|
-
django_ledger/views/mixins.py,sha256=
|
|
406
|
+
django_ledger/views/mixins.py,sha256=YuH1ATKepDonZNOEn1kMa-Y4lRnZwO-7jr8k83vsmLA,23244
|
|
410
407
|
django_ledger/views/purchase_order.py,sha256=CyftKrQWV1SBz7W0CvZOfZ81OPEiBHPD7b9zt1k6CFY,21088
|
|
411
408
|
django_ledger/views/transactions.py,sha256=3ijtJzdLPFkqG7OYpe-7N4QVjCyR2yl5ht_9RyfquBA,212
|
|
412
|
-
django_ledger/views/unit.py,sha256=
|
|
413
|
-
django_ledger/views/vendor.py,sha256=
|
|
414
|
-
django_ledger-0.7.
|
|
415
|
-
django_ledger-0.7.
|
|
416
|
-
django_ledger-0.7.
|
|
417
|
-
django_ledger-0.7.
|
|
418
|
-
django_ledger-0.7.
|
|
419
|
-
django_ledger-0.7.
|
|
409
|
+
django_ledger/views/unit.py,sha256=CarmOKzXANssVD3qMS1oXvJw614Y3rS0QHhSGJC0jBE,10069
|
|
410
|
+
django_ledger/views/vendor.py,sha256=7gtVK_bgnXxbVwNAHYtI_eNEJPefCz807LgE1vqOov8,3532
|
|
411
|
+
django_ledger-0.7.6.1.dist-info/AUTHORS.md,sha256=ShPwf-qniJkbjRzX5_lqhmgoLMEYMSHSwKPXHZtWmyk,824
|
|
412
|
+
django_ledger-0.7.6.1.dist-info/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
|
413
|
+
django_ledger-0.7.6.1.dist-info/METADATA,sha256=GiA6lMs26nLY1WXdJZUtOn6W12O7NnTuoF8i4fZzFy4,8828
|
|
414
|
+
django_ledger-0.7.6.1.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
|
|
415
|
+
django_ledger-0.7.6.1.dist-info/top_level.txt,sha256=fmHWehb2HfoDncQ3eQtYzeYc-gJMywf6q_ZpKBjwzoQ,38
|
|
416
|
+
django_ledger-0.7.6.1.dist-info/RECORD,,
|
django_ledger/static/.DS_Store
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|