django-ledger 0.5.5.5__py3-none-any.whl → 0.5.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of django-ledger might be problematic. Click here for more details.
- django_ledger/__init__.py +1 -1
- django_ledger/admin/entity.py +16 -2
- django_ledger/admin/ledger.py +2 -1
- django_ledger/forms/entity.py +4 -12
- django_ledger/forms/ledger.py +19 -0
- django_ledger/forms/transactions.py +1 -1
- django_ledger/io/__init__.py +4 -1
- django_ledger/io/{io_mixin.py → io_core.py} +49 -28
- django_ledger/io/io_digest.py +7 -0
- django_ledger/io/{data_generator.py → io_generator.py} +51 -8
- django_ledger/io/io_library.py +317 -0
- django_ledger/io/{io_context.py → io_middleware.py} +16 -9
- django_ledger/migrations/0001_initial.py +413 -132
- django_ledger/migrations/0014_ledgermodel_ledger_xid_and_more.py +22 -0
- django_ledger/models/accounts.py +8 -7
- django_ledger/models/bank_account.py +12 -11
- django_ledger/models/bill.py +5 -9
- django_ledger/models/closing_entry.py +14 -14
- django_ledger/models/coa.py +1 -1
- django_ledger/models/customer.py +5 -11
- django_ledger/models/data_import.py +12 -6
- django_ledger/models/entity.py +88 -10
- django_ledger/models/estimate.py +12 -9
- django_ledger/models/invoice.py +10 -4
- django_ledger/models/items.py +11 -6
- django_ledger/models/journal_entry.py +6 -13
- django_ledger/models/ledger.py +65 -15
- django_ledger/models/mixins.py +2 -3
- django_ledger/models/purchase_order.py +11 -7
- django_ledger/models/transactions.py +3 -1
- django_ledger/models/unit.py +13 -14
- django_ledger/models/vendor.py +12 -11
- django_ledger/templates/django_ledger/journal_entry/je_list.html +3 -0
- django_ledger/templatetags/django_ledger.py +1 -1
- django_ledger/tests/base.py +1 -1
- django_ledger/urls/ledger.py +3 -0
- django_ledger/views/entity.py +9 -3
- django_ledger/views/ledger.py +14 -7
- django_ledger/views/mixins.py +9 -1
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/METADATA +8 -8
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/RECORD +45 -43
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/LICENSE +0 -0
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/WHEEL +0 -0
- {django_ledger-0.5.5.5.dist-info → django_ledger-0.5.6.0.dist-info}/top_level.txt +0 -0
django_ledger/models/ledger.py
CHANGED
|
@@ -38,7 +38,7 @@ from django.db.models import Q, Min, F, Count
|
|
|
38
38
|
from django.urls import reverse
|
|
39
39
|
from django.utils.translation import gettext_lazy as _
|
|
40
40
|
|
|
41
|
-
from django_ledger.io.
|
|
41
|
+
from django_ledger.io.io_core import IOMixIn
|
|
42
42
|
from django_ledger.models import lazy_loader
|
|
43
43
|
from django_ledger.models.mixins import CreateUpdateMixIn
|
|
44
44
|
|
|
@@ -54,6 +54,28 @@ class LedgerModelQuerySet(models.QuerySet):
|
|
|
54
54
|
Custom defined LedgerModel QuerySet.
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
|
+
def locked(self):
|
|
58
|
+
"""
|
|
59
|
+
Filters the QuerySet to only locked LedgerModel.
|
|
60
|
+
|
|
61
|
+
Returns
|
|
62
|
+
-------
|
|
63
|
+
LedgerModelQuerySet
|
|
64
|
+
A QuerySet with applied filters.
|
|
65
|
+
"""
|
|
66
|
+
return self.filter(locked=True)
|
|
67
|
+
|
|
68
|
+
def unlocked(self):
|
|
69
|
+
"""
|
|
70
|
+
Filters the QuerySet to only un-locked LedgerModel.
|
|
71
|
+
|
|
72
|
+
Returns
|
|
73
|
+
-------
|
|
74
|
+
LedgerModelQuerySet
|
|
75
|
+
A QuerySet with applied filters.
|
|
76
|
+
"""
|
|
77
|
+
return self.filter(locked=False)
|
|
78
|
+
|
|
57
79
|
def posted(self):
|
|
58
80
|
"""
|
|
59
81
|
Filters the QuerySet to only posted LedgerModel.
|
|
@@ -65,6 +87,17 @@ class LedgerModelQuerySet(models.QuerySet):
|
|
|
65
87
|
"""
|
|
66
88
|
return self.filter(posted=True)
|
|
67
89
|
|
|
90
|
+
def unposted(self):
|
|
91
|
+
"""
|
|
92
|
+
Filters the QuerySet to only un-posted LedgerModel.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
LedgerModelQuerySet
|
|
97
|
+
A QuerySet with applied filters.
|
|
98
|
+
"""
|
|
99
|
+
return self.filter(posted=True)
|
|
100
|
+
|
|
68
101
|
def hidden(self):
|
|
69
102
|
return self.filter(hidden=True)
|
|
70
103
|
|
|
@@ -73,7 +106,8 @@ class LedgerModelQuerySet(models.QuerySet):
|
|
|
73
106
|
|
|
74
107
|
def current(self):
|
|
75
108
|
return self.filter(
|
|
76
|
-
earliest_timestamp__gt=F('entity__last_closing_date')
|
|
109
|
+
Q(earliest_timestamp__gt=F('entity__last_closing_date'))
|
|
110
|
+
| Q(earliest_timestamp__isnull=True)
|
|
77
111
|
)
|
|
78
112
|
|
|
79
113
|
|
|
@@ -92,6 +126,8 @@ class LedgerModelManager(models.Manager):
|
|
|
92
126
|
|
|
93
127
|
def for_user(self, user_model):
|
|
94
128
|
qs = self.get_queryset()
|
|
129
|
+
if user_model.is_superuser:
|
|
130
|
+
return qs
|
|
95
131
|
return qs.filter(
|
|
96
132
|
Q(entity__admin=user_model) |
|
|
97
133
|
Q(entity__managers__in=[user_model])
|
|
@@ -114,21 +150,13 @@ class LedgerModelManager(models.Manager):
|
|
|
114
150
|
LedgerModelQuerySet
|
|
115
151
|
A Filtered LedgerModelQuerySet.
|
|
116
152
|
"""
|
|
117
|
-
qs = self.
|
|
153
|
+
qs = self.for_user(user_model)
|
|
118
154
|
if isinstance(entity_slug, lazy_loader.get_entity_model()):
|
|
119
155
|
return qs.filter(
|
|
120
|
-
Q(entity=entity_slug)
|
|
121
|
-
(
|
|
122
|
-
Q(entity__admin=user_model) |
|
|
123
|
-
Q(entity__managers__in=[user_model])
|
|
124
|
-
)
|
|
156
|
+
Q(entity=entity_slug)
|
|
125
157
|
)
|
|
126
158
|
return qs.filter(
|
|
127
|
-
Q(entity__slug__exact=entity_slug)
|
|
128
|
-
(
|
|
129
|
-
Q(entity__admin=user_model) |
|
|
130
|
-
Q(entity__managers__in=[user_model])
|
|
131
|
-
)
|
|
159
|
+
Q(entity__slug__exact=entity_slug)
|
|
132
160
|
)
|
|
133
161
|
|
|
134
162
|
|
|
@@ -142,6 +170,8 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
|
|
|
142
170
|
This is a unique primary key generated for the table. The default value of this field is uuid4().
|
|
143
171
|
name: str
|
|
144
172
|
Human-readable name of the LedgerModel. Maximum 150 characters.
|
|
173
|
+
ledger_xid: str
|
|
174
|
+
A unique user-defined identifier for the LedgerModel. Unique for the Entity Model.
|
|
145
175
|
entity: EntityModel
|
|
146
176
|
The EntityModel associated with the LedgerModel instance.
|
|
147
177
|
posted: bool
|
|
@@ -153,6 +183,9 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
|
|
|
153
183
|
"""
|
|
154
184
|
_WRAPPED_MODEL_KEY = 'wrapped_model'
|
|
155
185
|
uuid = models.UUIDField(default=uuid4, editable=False, primary_key=True)
|
|
186
|
+
ledger_xid = models.SlugField(allow_unicode=True, max_length=150, null=True, blank=True,
|
|
187
|
+
verbose_name=_('Ledger Slug'),
|
|
188
|
+
help_text=_('User Defined Ledger ID'))
|
|
156
189
|
name = models.CharField(max_length=150, null=True, blank=True, verbose_name=_('Ledger Name'))
|
|
157
190
|
|
|
158
191
|
# todo: rename to entity_model...
|
|
@@ -180,6 +213,9 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
|
|
|
180
213
|
models.Index(fields=['entity', 'posted']),
|
|
181
214
|
models.Index(fields=['entity', 'locked']),
|
|
182
215
|
]
|
|
216
|
+
unique_together = [
|
|
217
|
+
('entity', 'ledger_xid')
|
|
218
|
+
]
|
|
183
219
|
|
|
184
220
|
def __str__(self):
|
|
185
221
|
return self.name
|
|
@@ -509,9 +545,8 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
|
|
|
509
545
|
str
|
|
510
546
|
URL as a string.
|
|
511
547
|
"""
|
|
512
|
-
return reverse('django_ledger:
|
|
548
|
+
return reverse(viewname='django_ledger:je-list',
|
|
513
549
|
kwargs={
|
|
514
|
-
# pylint: disable=no-member
|
|
515
550
|
'entity_slug': self.entity.slug,
|
|
516
551
|
'ledger_pk': self.uuid
|
|
517
552
|
})
|
|
@@ -547,6 +582,21 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
|
|
|
547
582
|
'ledger_pk': self.uuid
|
|
548
583
|
})
|
|
549
584
|
|
|
585
|
+
def get_list_url(self) -> str:
|
|
586
|
+
"""
|
|
587
|
+
Determines the list URL of the LedgerModel instances.
|
|
588
|
+
Results in additional Database query if entity field is not selected in QuerySet.
|
|
589
|
+
|
|
590
|
+
Returns
|
|
591
|
+
-------
|
|
592
|
+
str
|
|
593
|
+
URL as a string.
|
|
594
|
+
"""
|
|
595
|
+
return reverse('django_ledger:ledger-list',
|
|
596
|
+
kwargs={
|
|
597
|
+
'entity_slug': self.entity.slug
|
|
598
|
+
})
|
|
599
|
+
|
|
550
600
|
def get_balance_sheet_url(self):
|
|
551
601
|
return reverse(
|
|
552
602
|
viewname='django_ledger:ledger-bs',
|
django_ledger/models/mixins.py
CHANGED
|
@@ -13,7 +13,7 @@ from collections import defaultdict
|
|
|
13
13
|
from datetime import timedelta, date, datetime
|
|
14
14
|
from decimal import Decimal
|
|
15
15
|
from itertools import groupby
|
|
16
|
-
from typing import Optional, Union, Dict
|
|
16
|
+
from typing import Optional, Union, Dict
|
|
17
17
|
from uuid import UUID
|
|
18
18
|
|
|
19
19
|
from django.conf import settings
|
|
@@ -27,8 +27,7 @@ from django.utils.timezone import localdate, localtime
|
|
|
27
27
|
from django.utils.translation import gettext_lazy as _
|
|
28
28
|
from markdown import markdown
|
|
29
29
|
|
|
30
|
-
from django_ledger.io import
|
|
31
|
-
validate_io_date)
|
|
30
|
+
from django_ledger.io.io_core import validate_io_date, check_tx_balance
|
|
32
31
|
from django_ledger.models.utils import lazy_loader
|
|
33
32
|
|
|
34
33
|
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
|
|
@@ -101,6 +101,15 @@ class PurchaseOrderModelManager(models.Manager):
|
|
|
101
101
|
A custom defined PurchaseOrderModel Manager.
|
|
102
102
|
"""
|
|
103
103
|
|
|
104
|
+
def for_user(self, user_model):
|
|
105
|
+
qs = self.get_queryset()
|
|
106
|
+
if user_model.is_superuser:
|
|
107
|
+
return qs
|
|
108
|
+
return qs.filter(
|
|
109
|
+
Q(entity__admin=user_model) |
|
|
110
|
+
Q(entity__managers__in=[user_model])
|
|
111
|
+
)
|
|
112
|
+
|
|
104
113
|
def for_entity(self, entity_slug, user_model) -> PurchaseOrderModelQuerySet:
|
|
105
114
|
"""
|
|
106
115
|
Fetches a QuerySet of PurchaseOrderModel associated with a specific EntityModel & UserModel.
|
|
@@ -111,15 +120,10 @@ class PurchaseOrderModelManager(models.Manager):
|
|
|
111
120
|
PurchaseOrderModelQuerySet
|
|
112
121
|
A PurchaseOrderModelQuerySet with applied filters.
|
|
113
122
|
"""
|
|
114
|
-
qs = self.
|
|
123
|
+
qs = self.for_user(user_model)
|
|
115
124
|
if isinstance(entity_slug, EntityModel):
|
|
116
125
|
qs = qs.filter(entity=entity_slug)
|
|
117
|
-
|
|
118
|
-
qs = qs.filter(entity__slug__exact=entity_slug)
|
|
119
|
-
return qs.filter(
|
|
120
|
-
Q(entity__admin=user_model) |
|
|
121
|
-
Q(entity__managers__in=[user_model])
|
|
122
|
-
)
|
|
126
|
+
return qs.filter(entity__slug__exact=entity_slug)
|
|
123
127
|
|
|
124
128
|
|
|
125
129
|
class PurchaseOrderModelAbstract(CreateUpdateMixIn,
|
|
@@ -26,7 +26,7 @@ from django.db import models
|
|
|
26
26
|
from django.db.models import Q, QuerySet
|
|
27
27
|
from django.utils.translation import gettext_lazy as _
|
|
28
28
|
|
|
29
|
-
from django_ledger.io import validate_io_date
|
|
29
|
+
from django_ledger.io.io_core import validate_io_date
|
|
30
30
|
from django_ledger.models.accounts import AccountModel
|
|
31
31
|
from django_ledger.models.bill import BillModel
|
|
32
32
|
from django_ledger.models.entity import EntityModel
|
|
@@ -220,6 +220,8 @@ class TransactionModelAdmin(models.Manager):
|
|
|
220
220
|
Returns a TransactionModelQuerySet with applied filters.
|
|
221
221
|
"""
|
|
222
222
|
qs = self.get_queryset()
|
|
223
|
+
if user_model.is_superuser:
|
|
224
|
+
return qs
|
|
223
225
|
return qs.filter(
|
|
224
226
|
Q(journal_entry__ledger__entity__admin=user_model) |
|
|
225
227
|
Q(journal_entry__ledger__entity__managers__in=[user_model])
|
django_ledger/models/unit.py
CHANGED
|
@@ -34,7 +34,7 @@ from django.utils.text import slugify
|
|
|
34
34
|
from django.utils.translation import gettext_lazy as _
|
|
35
35
|
from treebeard.mp_tree import MP_Node, MP_NodeManager, MP_NodeQuerySet
|
|
36
36
|
|
|
37
|
-
from django_ledger.io.
|
|
37
|
+
from django_ledger.io.io_core import IOMixIn
|
|
38
38
|
from django_ledger.models import lazy_loader
|
|
39
39
|
from django_ledger.models.mixins import CreateUpdateMixIn, SlugNameMixIn
|
|
40
40
|
|
|
@@ -53,6 +53,15 @@ class EntityUnitModelQuerySet(MP_NodeQuerySet):
|
|
|
53
53
|
|
|
54
54
|
class EntityUnitModelManager(MP_NodeManager):
|
|
55
55
|
|
|
56
|
+
def for_user(self, user_model):
|
|
57
|
+
qs = self.get_queryset()
|
|
58
|
+
if user_model.is_superuser:
|
|
59
|
+
return qs
|
|
60
|
+
return qs.filter(
|
|
61
|
+
Q(entity__admin=user_model) |
|
|
62
|
+
Q(entity__managers__in=[user_model])
|
|
63
|
+
)
|
|
64
|
+
|
|
56
65
|
def for_entity(self, entity_slug: str, user_model):
|
|
57
66
|
"""
|
|
58
67
|
Fetches a QuerySet of EntityUnitModels associated with a specific EntityModel & UserModel.
|
|
@@ -76,23 +85,14 @@ class EntityUnitModelManager(MP_NodeManager):
|
|
|
76
85
|
EntityUnitModelQuerySet
|
|
77
86
|
Returns a EntityUnitModelQuerySet with applied filters.
|
|
78
87
|
"""
|
|
79
|
-
qs = self.
|
|
88
|
+
qs = self.for_user(user_model)
|
|
80
89
|
if isinstance(entity_slug, lazy_loader.get_entity_model()):
|
|
81
90
|
return qs.filter(
|
|
82
|
-
Q(entity=entity_slug)
|
|
83
|
-
(
|
|
84
|
-
Q(entity__admin=user_model) |
|
|
85
|
-
Q(entity__managers__in=[user_model])
|
|
86
|
-
)
|
|
91
|
+
Q(entity=entity_slug)
|
|
87
92
|
|
|
88
93
|
)
|
|
89
94
|
return qs.filter(
|
|
90
|
-
Q(entity__slug__exact=entity_slug)
|
|
91
|
-
(
|
|
92
|
-
Q(entity__admin=user_model) |
|
|
93
|
-
Q(entity__managers__in=[user_model])
|
|
94
|
-
)
|
|
95
|
-
|
|
95
|
+
Q(entity__slug__exact=entity_slug)
|
|
96
96
|
)
|
|
97
97
|
|
|
98
98
|
|
|
@@ -222,7 +222,6 @@ class EntityUnitModelAbstract(MP_Node,
|
|
|
222
222
|
)
|
|
223
223
|
|
|
224
224
|
|
|
225
|
-
|
|
226
225
|
class EntityUnitModel(EntityUnitModelAbstract):
|
|
227
226
|
"""
|
|
228
227
|
Base Model Class for EntityUnitModel
|
django_ledger/models/vendor.py
CHANGED
|
@@ -91,6 +91,15 @@ class VendorModelManager(models.Manager):
|
|
|
91
91
|
Custom defined VendorModel Manager, which defines many methods for initial query of the Database.
|
|
92
92
|
"""
|
|
93
93
|
|
|
94
|
+
def for_user(self, user_model):
|
|
95
|
+
qs = self.get_queryset()
|
|
96
|
+
if user_model.is_superuser:
|
|
97
|
+
return qs
|
|
98
|
+
return qs.filter(
|
|
99
|
+
Q(entity_model__admin=user_model) |
|
|
100
|
+
Q(entity_model__managers__in=[user_model])
|
|
101
|
+
)
|
|
102
|
+
|
|
94
103
|
def for_entity(self, entity_slug, user_model) -> VendorModelQuerySet:
|
|
95
104
|
"""
|
|
96
105
|
Fetches a QuerySet of VendorModel associated with a specific EntityModel & UserModel.
|
|
@@ -114,21 +123,13 @@ class VendorModelManager(models.Manager):
|
|
|
114
123
|
VendorModelQuerySet
|
|
115
124
|
A filtered VendorModel QuerySet.
|
|
116
125
|
"""
|
|
117
|
-
qs = self.
|
|
126
|
+
qs = self.for_user(user_model)
|
|
118
127
|
if isinstance(entity_slug, lazy_loader.get_entity_model()):
|
|
119
128
|
return qs.filter(
|
|
120
|
-
Q(entity_model=entity_slug)
|
|
121
|
-
(
|
|
122
|
-
Q(entity_model__admin=user_model) |
|
|
123
|
-
Q(entity_model__managers__in=[user_model])
|
|
124
|
-
)
|
|
129
|
+
Q(entity_model=entity_slug)
|
|
125
130
|
)
|
|
126
131
|
return qs.filter(
|
|
127
|
-
Q(entity_model__slug__exact=entity_slug)
|
|
128
|
-
(
|
|
129
|
-
Q(entity_model__admin=user_model) |
|
|
130
|
-
Q(entity_model__managers__in=[user_model])
|
|
131
|
-
)
|
|
132
|
+
Q(entity_model__slug__exact=entity_slug)
|
|
132
133
|
)
|
|
133
134
|
|
|
134
135
|
|
|
@@ -19,7 +19,7 @@ from django_ledger import __version__
|
|
|
19
19
|
from django_ledger.forms.app_filters import EntityFilterForm, ActivityFilterForm
|
|
20
20
|
from django_ledger.forms.feedback import BugReportForm, RequestNewFeatureForm
|
|
21
21
|
from django_ledger.io import CREDIT, DEBIT, ROLES_ORDER_ALL
|
|
22
|
-
from django_ledger.io.
|
|
22
|
+
from django_ledger.io.io_core import validate_activity
|
|
23
23
|
from django_ledger.models import TransactionModel, BillModel, InvoiceModel, EntityUnitModel
|
|
24
24
|
from django_ledger.settings import (
|
|
25
25
|
DJANGO_LEDGER_FINANCIAL_ANALYSIS, DJANGO_LEDGER_CURRENCY_SYMBOL,
|
django_ledger/tests/base.py
CHANGED
|
@@ -12,7 +12,7 @@ from django.test import TestCase
|
|
|
12
12
|
from django.test.client import Client
|
|
13
13
|
from django.utils.timezone import get_default_timezone
|
|
14
14
|
|
|
15
|
-
from django_ledger.io.
|
|
15
|
+
from django_ledger.io.io_generator import EntityDataGenerator
|
|
16
16
|
from django_ledger.models.entity import EntityModel, EntityModelQuerySet
|
|
17
17
|
|
|
18
18
|
UserModel = get_user_model()
|
django_ledger/urls/ledger.py
CHANGED
|
@@ -20,6 +20,9 @@ urlpatterns = [
|
|
|
20
20
|
path('<slug:entity_slug>/create/',
|
|
21
21
|
views.LedgerModelCreateView.as_view(),
|
|
22
22
|
name='ledger-create'),
|
|
23
|
+
path('<slug:entity_slug>/detail/<uuid:ledger_pk>/',
|
|
24
|
+
views.LedgerModelUpdateView.as_view(),
|
|
25
|
+
name='ledger-detail'),
|
|
23
26
|
path('<slug:entity_slug>/update/<uuid:ledger_pk>/',
|
|
24
27
|
views.LedgerModelUpdateView.as_view(),
|
|
25
28
|
name='ledger-update'),
|
django_ledger/views/entity.py
CHANGED
|
@@ -17,8 +17,14 @@ from django.utils.translation import gettext_lazy as _
|
|
|
17
17
|
from django.views.generic import ListView, DetailView, UpdateView, CreateView, RedirectView, DeleteView
|
|
18
18
|
|
|
19
19
|
from django_ledger.forms.entity import EntityModelUpdateForm, EntityModelCreateForm
|
|
20
|
-
from django_ledger.io.
|
|
21
|
-
from django_ledger.models import (
|
|
20
|
+
from django_ledger.io.io_generator import EntityDataGenerator
|
|
21
|
+
from django_ledger.models import (
|
|
22
|
+
EntityModel,
|
|
23
|
+
ItemTransactionModel,
|
|
24
|
+
TransactionModel,
|
|
25
|
+
InvoiceModel,
|
|
26
|
+
BillModel
|
|
27
|
+
)
|
|
22
28
|
from django_ledger.views.mixins import (
|
|
23
29
|
QuarterlyReportMixIn, YearlyReportMixIn,
|
|
24
30
|
MonthlyReportMixIn, DateReportMixIn, DjangoLedgerSecurityMixIn, EntityUnitMixIn,
|
|
@@ -97,7 +103,7 @@ class EntityModelCreateView(DjangoLedgerSecurityMixIn, EntityModelModelViewQuery
|
|
|
97
103
|
start_dttm=localtime() - timedelta(days=30 * 8),
|
|
98
104
|
capital_contribution=Decimal.from_float(50000),
|
|
99
105
|
days_forward=30 * 7,
|
|
100
|
-
tx_quantity=
|
|
106
|
+
tx_quantity=50
|
|
101
107
|
)
|
|
102
108
|
entity_generator.populate_entity()
|
|
103
109
|
|
django_ledger/views/ledger.py
CHANGED
|
@@ -7,7 +7,6 @@ Miguel Sanda <msanda@arrobalytics.com>
|
|
|
7
7
|
"""
|
|
8
8
|
from django.contrib import messages
|
|
9
9
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
|
10
|
-
from django.db.models import Count
|
|
11
10
|
from django.urls import reverse
|
|
12
11
|
from django.utils.timezone import localdate
|
|
13
12
|
from django.utils.translation import gettext_lazy as _
|
|
@@ -18,12 +17,12 @@ from django.views.generic import (
|
|
|
18
17
|
from django.views.generic.detail import SingleObjectMixin
|
|
19
18
|
|
|
20
19
|
from django_ledger.forms.ledger import LedgerModelCreateForm, LedgerModelUpdateForm
|
|
21
|
-
from django_ledger.models.entity import EntityModel
|
|
22
20
|
from django_ledger.models.ledger import LedgerModel
|
|
23
21
|
from django_ledger.views.mixins import (
|
|
24
22
|
YearlyReportMixIn, QuarterlyReportMixIn,
|
|
25
23
|
MonthlyReportMixIn, DjangoLedgerSecurityMixIn, DateReportMixIn, BaseDateNavigationUrlMixIn,
|
|
26
|
-
EntityUnitMixIn, PDFReportMixIn
|
|
24
|
+
EntityUnitMixIn, PDFReportMixIn
|
|
25
|
+
)
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
class LedgerModelModelViewQuerySetMixIn:
|
|
@@ -42,7 +41,7 @@ class LedgerModelListView(DjangoLedgerSecurityMixIn, LedgerModelModelViewQuerySe
|
|
|
42
41
|
context_object_name = 'ledger_list'
|
|
43
42
|
template_name = 'django_ledger/ledger/ledger_list.html'
|
|
44
43
|
PAGE_TITLE = _('Entity Ledgers')
|
|
45
|
-
paginate_by =
|
|
44
|
+
paginate_by = 30
|
|
46
45
|
extra_context = {
|
|
47
46
|
'page_title': PAGE_TITLE,
|
|
48
47
|
'header_title': PAGE_TITLE
|
|
@@ -106,10 +105,8 @@ class LedgerModelCreateView(DjangoLedgerSecurityMixIn, LedgerModelModelViewQuery
|
|
|
106
105
|
)
|
|
107
106
|
|
|
108
107
|
def form_valid(self, form):
|
|
109
|
-
entity = EntityModel.objects.for_user(
|
|
110
|
-
user_model=self.request.user).get(slug__exact=self.kwargs['entity_slug'])
|
|
111
108
|
instance = form.save(commit=False)
|
|
112
|
-
instance.entity =
|
|
109
|
+
instance.entity = self.AUTHORIZED_ENTITY_MODEL
|
|
113
110
|
self.object = form.save()
|
|
114
111
|
return super().form_valid(form)
|
|
115
112
|
|
|
@@ -120,6 +117,16 @@ class LedgerModelCreateView(DjangoLedgerSecurityMixIn, LedgerModelModelViewQuery
|
|
|
120
117
|
})
|
|
121
118
|
|
|
122
119
|
|
|
120
|
+
class LedgerModelDetailView(DjangoLedgerSecurityMixIn, LedgerModelModelViewQuerySetMixIn, RedirectView):
|
|
121
|
+
|
|
122
|
+
def get_redirect_url(self, *args, **kwargs):
|
|
123
|
+
return reverse('django_ledger:je-list',
|
|
124
|
+
kwargs={
|
|
125
|
+
'ledger_pk': self.kwargs['ledger_pk'],
|
|
126
|
+
'entity_slug': self.kwargs['entity_slug']
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
|
|
123
130
|
class LedgerModelUpdateView(DjangoLedgerSecurityMixIn, LedgerModelModelViewQuerySetMixIn, UpdateView):
|
|
124
131
|
context_object_name = 'ledger'
|
|
125
132
|
pk_url_kwarg = 'ledger_pk'
|
django_ledger/views/mixins.py
CHANGED
|
@@ -305,7 +305,15 @@ class DjangoLedgerSecurityMixIn(PermissionRequiredMixin):
|
|
|
305
305
|
'uuid', 'slug', 'name', 'default_coa', 'admin')
|
|
306
306
|
|
|
307
307
|
def has_permission(self):
|
|
308
|
-
if self.request.user.
|
|
308
|
+
if self.request.user.is_superuser:
|
|
309
|
+
if 'entity_slug' in self.kwargs:
|
|
310
|
+
try:
|
|
311
|
+
entity_model_qs = self.get_authorized_entity_queryset()
|
|
312
|
+
self.AUTHORIZED_ENTITY_MODEL = entity_model_qs.get(slug__exact=self.kwargs['entity_slug'])
|
|
313
|
+
except ObjectDoesNotExist:
|
|
314
|
+
return False
|
|
315
|
+
return True
|
|
316
|
+
elif self.request.user.is_authenticated:
|
|
309
317
|
has_perm = super().has_permission()
|
|
310
318
|
if not has_perm:
|
|
311
319
|
return False
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-ledger
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.6.0
|
|
4
4
|
Summary: Bookkeeping & Financial analysis backend for Django. Balance Sheet, Income Statements, Chart of Accounts, Entities
|
|
5
5
|
Author-email: Miguel Sanda <msanda@arrobalytics.com>
|
|
6
6
|
Maintainer-email: Miguel Sanda <msanda@arrobalytics.com>
|
|
@@ -132,13 +132,13 @@ More details available in the [Django Ledger v0.5 Page](https://www.arrobalytics
|
|
|
132
132
|
* Generate all Django Ledger Model documentation.
|
|
133
133
|
* ~~__0.5.3__~~: High Level EntityModel API.
|
|
134
134
|
* ~~__0.5.4__~~: Balance Sheet Statement, Income Statement & Cash Flow Statement API & PDF report export.
|
|
135
|
-
* __0.5.5__
|
|
136
|
-
* 0.5.5.1
|
|
137
|
-
* 0.5.5.2
|
|
138
|
-
* 0.5.5.3
|
|
139
|
-
* __0.5.6__:
|
|
140
|
-
* __0.5.7__:
|
|
141
|
-
* __0.5.8__:
|
|
135
|
+
* ~~__0.5.5__~~: Closing Entries.
|
|
136
|
+
* ~~0.5.5.1~~: Open Financial Exchange Imports (OFX) Bugfixes and Optimizations.
|
|
137
|
+
* ~~0.5.5.2~~: BugFixes and Optimizations..
|
|
138
|
+
* ~~0.5.5.3~~: Closing Entries will be used if requested date is present. Documentation Update.
|
|
139
|
+
* __0.5.6__: Transaction Library & Blueprints.
|
|
140
|
+
* __0.5.7__: Chart of Accounts Import.
|
|
141
|
+
* __0.5.8__: Trial Balance Import.
|
|
142
142
|
|
|
143
143
|
### Version 0.6
|
|
144
144
|
|