django-ledger 0.7.3__py3-none-any.whl → 0.7.4.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/contrib/django_ledger_graphene/journal_entry/schema.py +2 -3
- django_ledger/contrib/django_ledger_graphene/transaction/schema.py +9 -7
- django_ledger/forms/journal_entry.py +19 -12
- django_ledger/forms/transactions.py +8 -12
- django_ledger/io/io_core.py +14 -11
- django_ledger/io/io_library.py +3 -3
- django_ledger/migrations/0001_initial.py +1 -1
- django_ledger/migrations/0019_alter_transactionmodel_amount_and_more.py +33 -0
- django_ledger/models/bill.py +17 -2
- django_ledger/models/chart_of_accounts.py +4 -0
- django_ledger/models/closing_entry.py +8 -6
- django_ledger/models/invoice.py +12 -4
- django_ledger/models/journal_entry.py +843 -481
- django_ledger/models/ledger.py +45 -4
- django_ledger/models/transactions.py +303 -305
- django_ledger/models/unit.py +42 -22
- django_ledger/templates/django_ledger/account/tags/accounts_table.html +1 -1
- django_ledger/templates/django_ledger/bills/bill_detail.html +1 -1
- django_ledger/templates/django_ledger/invoice/invoice_detail.html +1 -1
- django_ledger/templates/django_ledger/journal_entry/je_create.html +2 -3
- django_ledger/templates/django_ledger/journal_entry/je_delete.html +2 -3
- django_ledger/templates/django_ledger/journal_entry/je_detail.html +1 -1
- django_ledger/templates/django_ledger/journal_entry/je_detail_txs.html +8 -8
- django_ledger/templates/django_ledger/journal_entry/je_list.html +16 -13
- django_ledger/templates/django_ledger/journal_entry/je_update.html +2 -3
- django_ledger/templates/django_ledger/journal_entry/tags/je_table.html +24 -24
- django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html +17 -14
- django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html +38 -37
- django_ledger/templates/django_ledger/transactions/tags/txs_table.html +69 -0
- django_ledger/templatetags/django_ledger.py +25 -45
- django_ledger/urls/account.py +4 -4
- django_ledger/views/account.py +7 -7
- django_ledger/views/journal_entry.py +84 -101
- django_ledger/views/ledger.py +16 -21
- django_ledger/views/mixins.py +11 -10
- {django_ledger-0.7.3.dist-info → django_ledger-0.7.4.1.dist-info}/METADATA +8 -3
- {django_ledger-0.7.3.dist-info → django_ledger-0.7.4.1.dist-info}/RECORD +42 -40
- {django_ledger-0.7.3.dist-info → django_ledger-0.7.4.1.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.7.3.dist-info → django_ledger-0.7.4.1.dist-info}/LICENSE +0 -0
- {django_ledger-0.7.3.dist-info → django_ledger-0.7.4.1.dist-info}/WHEEL +0 -0
- {django_ledger-0.7.3.dist-info → django_ledger-0.7.4.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{% load i18n %}
|
|
2
|
+
{% load django_ledger %}
|
|
3
|
+
|
|
4
|
+
{% if style == 'detail' %}
|
|
5
|
+
<div class="table-container">
|
|
6
|
+
<table class="table is-fullwidth is-narrow is-striped is-bordered django-ledger-table-bottom-margin-75">
|
|
7
|
+
<tr>
|
|
8
|
+
<th>{% trans 'Timestamp' %}</th>
|
|
9
|
+
<th>{% trans 'Account' %}</th>
|
|
10
|
+
<th>{% trans 'Account Name' %}</th>
|
|
11
|
+
<th>{% trans 'Unit' %}</th>
|
|
12
|
+
<th>{% trans 'Credit' %}</th>
|
|
13
|
+
<th>{% trans 'Debit' %}</th>
|
|
14
|
+
<th>{% trans 'Description' %}</th>
|
|
15
|
+
</tr>
|
|
16
|
+
{% for transaction_model in transaction_model_qs %}
|
|
17
|
+
<tr>
|
|
18
|
+
<td>{{ transaction_model.timestamp }}</td>
|
|
19
|
+
<td>{{ transaction_model.account_code }}</td>
|
|
20
|
+
<td>{{ transaction_model.account_name }}</td>
|
|
21
|
+
<td>{% if transaction_model.entity_unit_name %}
|
|
22
|
+
{{ transaction_model.entity_unit_name }}{% endif %}</td>
|
|
23
|
+
<td>{% if transaction_model.is_credit %}$
|
|
24
|
+
{{ transaction_model.amount | currency_format }}{% endif %}</td>
|
|
25
|
+
<td>{% if transaction_model.is_debit %}$
|
|
26
|
+
{{ transaction_model.amount | currency_format }}{% endif %}</td>
|
|
27
|
+
<td>{% if transaction_model.description %}{{ transaction_model.description }}{% endif %}</td>
|
|
28
|
+
</tr>
|
|
29
|
+
{% endfor %}
|
|
30
|
+
<tr class="has-text-weight-bold">
|
|
31
|
+
<td></td>
|
|
32
|
+
<td></td>
|
|
33
|
+
<td></td>
|
|
34
|
+
<td class="has-text-right">Total</td>
|
|
35
|
+
<td>{% currency_symbol %}{{ total_credits | currency_format }}</td>
|
|
36
|
+
<td>{% currency_symbol %}{{ total_debits | currency_format }}</td>
|
|
37
|
+
<td></td>
|
|
38
|
+
</tr>
|
|
39
|
+
</table>
|
|
40
|
+
</div>
|
|
41
|
+
{% elif style == 'compact' %}
|
|
42
|
+
<div class="table-container">
|
|
43
|
+
<table class="table is-fullwidth is-narrow is-striped is-bordered django-ledger-table-bottom-margin-75">
|
|
44
|
+
<tr>
|
|
45
|
+
<th>{% trans 'Account' %}</th>
|
|
46
|
+
<th>{% trans 'Account Name' %}</th>
|
|
47
|
+
<th>{% trans 'Credit' %}</th>
|
|
48
|
+
<th>{% trans 'Debit' %}</th>
|
|
49
|
+
<th>{% trans 'Description' %}</th>
|
|
50
|
+
</tr>
|
|
51
|
+
{% for transaction_model in transaction_model_qs %}
|
|
52
|
+
<tr>
|
|
53
|
+
<td>{{ transaction_model.account_code }}</td>
|
|
54
|
+
<td>{{ transaction_model.account_name }}</td>
|
|
55
|
+
<td>{% if transaction_model.is_credit %}${{ transaction_model.amount | currency_format }}{% endif %}</td>
|
|
56
|
+
<td>{% if transaction_model.is_debit %}${{ transaction_model.amount | currency_format }}{% endif %}</td>
|
|
57
|
+
<td>{% if transaction_model.description %}{{ transaction_model.description }}{% endif %}</td>
|
|
58
|
+
</tr>
|
|
59
|
+
{% endfor %}
|
|
60
|
+
<tr class="has-text-weight-bold">
|
|
61
|
+
<td></td>
|
|
62
|
+
<td class="has-text-right">{% trans 'Total' %}</td>
|
|
63
|
+
<td>{% currency_symbol %}{{ total_credits | currency_format }}</td>
|
|
64
|
+
<td>{% currency_symbol %}{{ total_debits | currency_format }}</td>
|
|
65
|
+
<td></td>
|
|
66
|
+
</tr>
|
|
67
|
+
</table>
|
|
68
|
+
</div>
|
|
69
|
+
{% endif %}
|
|
@@ -8,8 +8,10 @@ Miguel Sanda <msanda@arrobalytics.com>
|
|
|
8
8
|
|
|
9
9
|
from calendar import month_abbr
|
|
10
10
|
from random import randint
|
|
11
|
+
from typing import Union
|
|
11
12
|
|
|
12
13
|
from django import template
|
|
14
|
+
from django.core.exceptions import ValidationError
|
|
13
15
|
from django.db.models import Sum
|
|
14
16
|
from django.urls import reverse
|
|
15
17
|
from django.utils.formats import number_format
|
|
@@ -17,9 +19,9 @@ from django.utils.formats import number_format
|
|
|
17
19
|
from django_ledger import __version__
|
|
18
20
|
from django_ledger.forms.app_filters import EntityFilterForm, ActivityFilterForm
|
|
19
21
|
from django_ledger.forms.feedback import BugReportForm, RequestNewFeatureForm
|
|
20
|
-
from django_ledger.io import
|
|
22
|
+
from django_ledger.io import ROLES_ORDER_ALL
|
|
21
23
|
from django_ledger.io.io_core import validate_activity, get_localdate
|
|
22
|
-
from django_ledger.models import
|
|
24
|
+
from django_ledger.models import BillModel, InvoiceModel, JournalEntryModel
|
|
23
25
|
from django_ledger.settings import (
|
|
24
26
|
DJANGO_LEDGER_FINANCIAL_ANALYSIS, DJANGO_LEDGER_CURRENCY_SYMBOL,
|
|
25
27
|
DJANGO_LEDGER_SPACED_CURRENCY_SYMBOL)
|
|
@@ -216,65 +218,43 @@ def jes_table(context, journal_entry_qs, next_url=None):
|
|
|
216
218
|
'ledger_pk': ledger_pk
|
|
217
219
|
})
|
|
218
220
|
return {
|
|
219
|
-
'
|
|
221
|
+
'journal_entry_qs': journal_entry_qs,
|
|
220
222
|
'entity_slug': entity_slug,
|
|
221
223
|
'ledger_pk': ledger_pk,
|
|
222
224
|
'next_url': next_url
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
|
|
226
|
-
@register.inclusion_tag('django_ledger/
|
|
227
|
-
def
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
'
|
|
233
|
-
|
|
234
|
-
'
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
@register.inclusion_tag('django_ledger/journal_entry/tags/je_txs_table.html', takes_context=True)
|
|
240
|
-
def bill_txs_table(context, bill_model: BillModel):
|
|
241
|
-
# todo: move this to bill model...
|
|
242
|
-
txs_queryset = TransactionModel.objects.for_bill(
|
|
243
|
-
bill_model=bill_model.uuid,
|
|
244
|
-
user_model=context['request'].user,
|
|
245
|
-
entity_slug=context['view'].kwargs['entity_slug']
|
|
246
|
-
).select_related('journal_entry', 'journal_entry__entity_unit', 'account').order_by('-journal_entry__timestamp')
|
|
247
|
-
total_credits = sum(tx.amount for tx in txs_queryset if tx.tx_type == CREDIT)
|
|
248
|
-
total_debits = sum(tx.amount for tx in txs_queryset if tx.tx_type == DEBIT)
|
|
249
|
-
return {
|
|
250
|
-
'style': 'detail',
|
|
251
|
-
'txs': txs_queryset,
|
|
252
|
-
'total_debits': total_debits,
|
|
253
|
-
'total_credits': total_credits
|
|
254
|
-
}
|
|
228
|
+
@register.inclusion_tag('django_ledger/transactions/tags/txs_table.html')
|
|
229
|
+
def transactions_table(object_type: Union[JournalEntryModel, BillModel, InvoiceModel], style='detail'):
|
|
230
|
+
if isinstance(object_type, JournalEntryModel):
|
|
231
|
+
transaction_model_qs = object_type.transactionmodel_set.all().with_annotated_details().order_by(
|
|
232
|
+
'-timestamp')
|
|
233
|
+
elif isinstance(object_type, BillModel):
|
|
234
|
+
transaction_model_qs = object_type.get_transaction_queryset(annotated=True).order_by('-timestamp')
|
|
235
|
+
elif isinstance(object_type, InvoiceModel):
|
|
236
|
+
transaction_model_qs = object_type.get_transaction_queryset(annotated=True).order_by('-timestamp')
|
|
237
|
+
else:
|
|
238
|
+
raise ValidationError(
|
|
239
|
+
'Cannot handle object of type {} to get transaction model queryset'.format(type(object_type))
|
|
240
|
+
)
|
|
255
241
|
|
|
242
|
+
total_credits = sum(tx.amount for tx in transaction_model_qs if tx.is_credit())
|
|
243
|
+
total_debits = sum(tx.amount for tx in transaction_model_qs if tx.is_debit())
|
|
256
244
|
|
|
257
|
-
@register.inclusion_tag('django_ledger/journal_entry/tags/je_txs_table.html', takes_context=True)
|
|
258
|
-
def invoice_txs_table(context, invoice_model: InvoiceModel):
|
|
259
|
-
txs_queryset = TransactionModel.objects.for_invoice(
|
|
260
|
-
invoice_model=invoice_model,
|
|
261
|
-
user_model=context['request'].user,
|
|
262
|
-
entity_slug=context['view'].kwargs['entity_slug']
|
|
263
|
-
).select_related('journal_entry', 'journal_entry__entity_unit', 'account').order_by('-journal_entry__timestamp')
|
|
264
|
-
total_credits = sum(tx.amount for tx in txs_queryset if tx.tx_type == CREDIT)
|
|
265
|
-
total_debits = sum(tx.amount for tx in txs_queryset if tx.tx_type == DEBIT)
|
|
266
245
|
return {
|
|
267
|
-
'style':
|
|
268
|
-
'
|
|
246
|
+
'style': style,
|
|
247
|
+
'transaction_model_qs': transaction_model_qs,
|
|
269
248
|
'total_debits': total_debits,
|
|
270
|
-
'total_credits': total_credits
|
|
249
|
+
'total_credits': total_credits,
|
|
250
|
+
'object': object_type
|
|
271
251
|
}
|
|
272
252
|
|
|
273
253
|
|
|
274
254
|
@register.inclusion_tag('django_ledger/ledger/tags/ledgers_table.html', takes_context=True)
|
|
275
255
|
def ledgers_table(context, ledger_model_qs):
|
|
276
256
|
return {
|
|
277
|
-
'
|
|
257
|
+
'ledger_model_qs': ledger_model_qs,
|
|
278
258
|
'entity_slug': context['view'].kwargs['entity_slug'],
|
|
279
259
|
}
|
|
280
260
|
|
django_ledger/urls/account.py
CHANGED
|
@@ -36,15 +36,15 @@ urlpatterns = [
|
|
|
36
36
|
|
|
37
37
|
# Account Actions...
|
|
38
38
|
path('<slug:entity_slug>/<slug:coa_slug>/action/<uuid:account_pk>/activate/',
|
|
39
|
-
views.
|
|
39
|
+
views.BaseAccountModelActionView.as_view(action_name='activate'),
|
|
40
40
|
name='account-action-activate'),
|
|
41
41
|
path('<slug:entity_slug>/<slug:coa_slug>/action/<uuid:account_pk>/deactivate/',
|
|
42
|
-
views.
|
|
42
|
+
views.BaseAccountModelActionView.as_view(action_name='deactivate'),
|
|
43
43
|
name='account-action-deactivate'),
|
|
44
44
|
path('<slug:entity_slug>/<slug:coa_slug>/action/<uuid:account_pk>/lock/',
|
|
45
|
-
views.
|
|
45
|
+
views.BaseAccountModelActionView.as_view(action_name='lock'),
|
|
46
46
|
name='account-action-lock'),
|
|
47
47
|
path('<slug:entity_slug>/<slug:coa_slug>/action/<uuid:account_pk>/unlock/',
|
|
48
|
-
views.
|
|
48
|
+
views.BaseAccountModelActionView.as_view(action_name='unlock'),
|
|
49
49
|
name='account-action-unlock')
|
|
50
50
|
]
|
django_ledger/views/account.py
CHANGED
|
@@ -200,28 +200,28 @@ class AccountModelYearDetailView(BaseAccountModelBaseView,
|
|
|
200
200
|
return context
|
|
201
201
|
|
|
202
202
|
|
|
203
|
-
class AccountModelQuarterDetailView(
|
|
203
|
+
class AccountModelQuarterDetailView(AccountModelYearDetailView, QuarterlyReportMixIn):
|
|
204
204
|
"""
|
|
205
205
|
Account Model Quarter Detail View
|
|
206
206
|
"""
|
|
207
207
|
|
|
208
208
|
|
|
209
|
-
class AccountModelMonthDetailView(
|
|
209
|
+
class AccountModelMonthDetailView(AccountModelYearDetailView, MonthlyReportMixIn):
|
|
210
210
|
"""
|
|
211
211
|
Account Model Month Detail View
|
|
212
212
|
"""
|
|
213
213
|
|
|
214
214
|
|
|
215
|
-
class AccountModelDateDetailView(
|
|
215
|
+
class AccountModelDateDetailView(AccountModelYearDetailView, DateReportMixIn):
|
|
216
216
|
"""
|
|
217
217
|
Account Model Date Detail View
|
|
218
218
|
"""
|
|
219
219
|
|
|
220
220
|
|
|
221
221
|
# ACTIONS...
|
|
222
|
-
class
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
class BaseAccountModelActionView(BaseAccountModelBaseView,
|
|
223
|
+
RedirectView,
|
|
224
|
+
SingleObjectMixin):
|
|
225
225
|
http_method_names = ['get']
|
|
226
226
|
pk_url_kwarg = 'account_pk'
|
|
227
227
|
action_name = None
|
|
@@ -235,7 +235,7 @@ class AccountModelModelActionView(BaseAccountModelBaseView,
|
|
|
235
235
|
kwargs['user_model'] = self.request.user
|
|
236
236
|
if not self.action_name:
|
|
237
237
|
raise ImproperlyConfigured('View attribute action_name is required.')
|
|
238
|
-
response = super(
|
|
238
|
+
response = super(BaseAccountModelActionView, self).get(request, *args, **kwargs)
|
|
239
239
|
account_model: AccountModel = self.get_object()
|
|
240
240
|
|
|
241
241
|
try:
|
|
@@ -5,75 +5,72 @@ Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
|
5
5
|
Contributions to this module:
|
|
6
6
|
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
"""
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
8
10
|
from django.contrib import messages
|
|
9
11
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
|
10
|
-
from django.db.models import Count
|
|
11
12
|
from django.http import HttpResponseForbidden
|
|
12
13
|
from django.urls import reverse
|
|
13
14
|
from django.utils.translation import gettext_lazy as _
|
|
14
|
-
from django.views.generic import (
|
|
15
|
-
|
|
15
|
+
from django.views.generic import (
|
|
16
|
+
YearArchiveView, MonthArchiveView, DetailView, UpdateView, CreateView, RedirectView,
|
|
17
|
+
ArchiveIndexView, DeleteView
|
|
18
|
+
)
|
|
16
19
|
from django.views.generic.detail import SingleObjectMixin
|
|
17
20
|
|
|
18
|
-
from django_ledger.forms.journal_entry import (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
from django_ledger.forms.journal_entry import (
|
|
22
|
+
JournalEntryModelUpdateForm,
|
|
23
|
+
JournalEntryModelCannotEditForm,
|
|
24
|
+
JournalEntryModelCreateForm
|
|
25
|
+
)
|
|
21
26
|
from django_ledger.forms.transactions import get_transactionmodel_formset_class
|
|
22
27
|
from django_ledger.io.io_core import get_localtime
|
|
28
|
+
from django_ledger.models import EntityModel, LedgerModel
|
|
23
29
|
from django_ledger.models.journal_entry import JournalEntryModel
|
|
24
|
-
from django_ledger.models.ledger import LedgerModel
|
|
25
30
|
from django_ledger.views.mixins import DjangoLedgerSecurityMixIn
|
|
26
31
|
|
|
27
32
|
|
|
28
|
-
class
|
|
33
|
+
class JournalEntryModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
29
34
|
queryset = None
|
|
35
|
+
ledger_model: Optional[LedgerModel] = None
|
|
30
36
|
|
|
31
37
|
def get_queryset(self):
|
|
32
38
|
if self.queryset is None:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
ledger_model: LedgerModel = self.get_ledger_model()
|
|
40
|
+
journal_entry_queryset = ledger_model.journal_entries.select_related('entity_unit', 'ledger', 'ledger__entity').order_by('-timestamp')
|
|
41
|
+
self.queryset = journal_entry_queryset
|
|
42
|
+
return self.queryset
|
|
43
|
+
|
|
44
|
+
def get_ledger_model(self) -> LedgerModel:
|
|
45
|
+
if self.ledger_model is None:
|
|
46
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
47
|
+
self.ledger_model = entity_model.get_ledgers().get(uuid__exact=self.kwargs['ledger_pk'])
|
|
48
|
+
return self.ledger_model
|
|
39
49
|
|
|
40
50
|
|
|
41
51
|
# JE Views ---
|
|
42
|
-
class JournalEntryCreateView(
|
|
52
|
+
class JournalEntryCreateView(JournalEntryModelModelBaseView, CreateView):
|
|
43
53
|
template_name = 'django_ledger/journal_entry/je_create.html'
|
|
44
54
|
PAGE_TITLE = _('Create Journal Entry')
|
|
45
55
|
extra_context = {
|
|
46
56
|
'page_title': PAGE_TITLE,
|
|
47
57
|
'header_title': PAGE_TITLE
|
|
48
58
|
}
|
|
49
|
-
|
|
50
|
-
pk_url_kwarg = 'ledger_pk'
|
|
51
|
-
ledger_model = None
|
|
59
|
+
ledger_model: Optional[LedgerModel] = None
|
|
52
60
|
|
|
53
61
|
def get_context_data(self, **kwargs):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return ctx
|
|
62
|
-
|
|
63
|
-
def get_queryset(self):
|
|
64
|
-
return LedgerModel.objects.for_entity(
|
|
65
|
-
user_model=self.request.user,
|
|
66
|
-
entity_slug=self.kwargs['entity_slug'],
|
|
67
|
-
)
|
|
62
|
+
context = super().get_context_data(**kwargs)
|
|
63
|
+
ledger_model: LedgerModel = self.get_ledger_model()
|
|
64
|
+
context['page_title'] = self.PAGE_TITLE
|
|
65
|
+
context['header_title'] = self.PAGE_TITLE
|
|
66
|
+
context['header_subtitle'] = ledger_model.name
|
|
67
|
+
context['ledger_model'] = ledger_model
|
|
68
|
+
return context
|
|
68
69
|
|
|
69
70
|
def get_form(self, form_class=None):
|
|
70
|
-
if self.ledger_model is None:
|
|
71
|
-
ledger_model = self.get_object()
|
|
72
|
-
self.ledger_model = ledger_model
|
|
73
71
|
return JournalEntryModelCreateForm(
|
|
74
|
-
|
|
75
|
-
ledger_model=self.
|
|
76
|
-
user_model=self.request.user,
|
|
72
|
+
entity_model=self.get_authorized_entity_instance(),
|
|
73
|
+
ledger_model=self.get_ledger_model(),
|
|
77
74
|
**self.get_form_kwargs()
|
|
78
75
|
)
|
|
79
76
|
|
|
@@ -83,42 +80,51 @@ class JournalEntryCreateView(DjangoLedgerSecurityMixIn, CreateView, SingleObject
|
|
|
83
80
|
}
|
|
84
81
|
|
|
85
82
|
def get_success_url(self):
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
'entity_slug': self.kwargs.get('entity_slug'),
|
|
89
|
-
'ledger_pk': self.kwargs.get('ledger_pk')
|
|
90
|
-
})
|
|
83
|
+
ledger_model = self.get_ledger_model()
|
|
84
|
+
return ledger_model.get_journal_entry_list_url()
|
|
91
85
|
|
|
92
86
|
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
# ARCHIVE VIEWS START....
|
|
88
|
+
class JournalEntryListView(JournalEntryModelModelBaseView, ArchiveIndexView):
|
|
89
|
+
context_object_name = 'journal_entry_qs'
|
|
95
90
|
template_name = 'django_ledger/journal_entry/je_list.html'
|
|
96
91
|
PAGE_TITLE = _('Journal Entries')
|
|
97
|
-
extra_context = {
|
|
98
|
-
'page_title': PAGE_TITLE,
|
|
99
|
-
'header_title': PAGE_TITLE
|
|
100
|
-
}
|
|
101
92
|
http_method_names = ['get']
|
|
102
93
|
date_field = 'timestamp'
|
|
103
94
|
paginate_by = 20
|
|
104
95
|
allow_empty = True
|
|
105
96
|
|
|
106
|
-
def
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return qs
|
|
97
|
+
def get_context_data(self, **kwargs):
|
|
98
|
+
context = super().get_context_data(**kwargs)
|
|
99
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
110
100
|
|
|
101
|
+
ledger_model = self.get_ledger_model()
|
|
102
|
+
context['ledger_model'] = ledger_model
|
|
103
|
+
context['page_title'] = self.PAGE_TITLE
|
|
104
|
+
context['header_title'] = self.PAGE_TITLE
|
|
105
|
+
context['header_subtitle'] = f'{entity_model.name} | Ledger: {ledger_model.name}'
|
|
106
|
+
context['header_subtitle_icon'] = 'bi:journal-check'
|
|
111
107
|
|
|
112
|
-
|
|
108
|
+
if ledger_model.is_locked():
|
|
109
|
+
messages.add_message(self.request,
|
|
110
|
+
message=_('Locked Journal Entry. Must unlock ledger to add new Journal Entries.'),
|
|
111
|
+
level=messages.WARNING,
|
|
112
|
+
extra_tags='is-warning')
|
|
113
|
+
return context
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class JournalEntryYearListView(JournalEntryListView, YearArchiveView):
|
|
113
117
|
make_object_list = True
|
|
114
118
|
|
|
115
119
|
|
|
116
|
-
class JournalEntryMonthListView(
|
|
120
|
+
class JournalEntryMonthListView(JournalEntryListView, MonthArchiveView):
|
|
117
121
|
make_object_list = True
|
|
118
122
|
month_format = '%m'
|
|
119
123
|
|
|
120
124
|
|
|
121
|
-
|
|
125
|
+
# ARCHIVE VIEWS END....
|
|
126
|
+
|
|
127
|
+
class JournalEntryUpdateView(JournalEntryModelModelBaseView, UpdateView):
|
|
122
128
|
context_object_name = 'journal_entry'
|
|
123
129
|
template_name = 'django_ledger/journal_entry/je_update.html'
|
|
124
130
|
pk_url_kwarg = 'je_pk'
|
|
@@ -128,34 +134,18 @@ class JournalEntryUpdateView(DjangoLedgerSecurityMixIn, JournalEntryModelModelVi
|
|
|
128
134
|
'header_title': PAGE_TITLE
|
|
129
135
|
}
|
|
130
136
|
|
|
131
|
-
def
|
|
137
|
+
def get_form_class(self, form_class=None):
|
|
132
138
|
je_model: JournalEntryModel = self.object
|
|
133
139
|
if not je_model.can_edit():
|
|
134
|
-
return JournalEntryModelCannotEditForm
|
|
135
|
-
|
|
136
|
-
ledger_model=je_model.ledger,
|
|
137
|
-
user_model=self.request.user,
|
|
138
|
-
**self.get_form_kwargs()
|
|
139
|
-
)
|
|
140
|
-
return JournalEntryModelUpdateForm(
|
|
141
|
-
entity_slug=self.kwargs['entity_slug'],
|
|
142
|
-
ledger_model=je_model.ledger,
|
|
143
|
-
user_model=self.request.user,
|
|
144
|
-
**self.get_form_kwargs()
|
|
145
|
-
)
|
|
140
|
+
return JournalEntryModelCannotEditForm
|
|
141
|
+
return JournalEntryModelUpdateForm
|
|
146
142
|
|
|
147
143
|
def get_success_url(self):
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
'ledger_pk': self.kwargs['ledger_pk']
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
def get_queryset(self):
|
|
154
|
-
qs = super().get_queryset()
|
|
155
|
-
return qs.prefetch_related('transactionmodel_set', 'transactionmodel_set__account')
|
|
144
|
+
je_model: JournalEntryModel = self.object
|
|
145
|
+
return je_model.get_journal_entry_list_url()
|
|
156
146
|
|
|
157
147
|
|
|
158
|
-
class JournalEntryDetailView(
|
|
148
|
+
class JournalEntryDetailView(JournalEntryModelModelBaseView, DetailView):
|
|
159
149
|
context_object_name = 'journal_entry'
|
|
160
150
|
template_name = 'django_ledger/journal_entry/je_detail.html'
|
|
161
151
|
slug_url_kwarg = 'je_pk'
|
|
@@ -168,28 +158,19 @@ class JournalEntryDetailView(DjangoLedgerSecurityMixIn, JournalEntryModelModelVi
|
|
|
168
158
|
}
|
|
169
159
|
http_method_names = ['get']
|
|
170
160
|
|
|
171
|
-
def get_queryset(self):
|
|
172
|
-
qs = super().get_queryset()
|
|
173
|
-
return qs.prefetch_related('transactionmodel_set', 'transactionmodel_set__account')
|
|
174
|
-
|
|
175
161
|
|
|
176
|
-
class JournalEntryDeleteView(
|
|
162
|
+
class JournalEntryDeleteView(JournalEntryModelModelBaseView, DeleteView):
|
|
177
163
|
template_name = 'django_ledger/journal_entry/je_delete.html'
|
|
178
164
|
context_object_name = 'je_model'
|
|
179
165
|
pk_url_kwarg = 'je_pk'
|
|
180
166
|
|
|
181
167
|
def get_success_url(self) -> str:
|
|
182
168
|
je_model: JournalEntryModel = self.object
|
|
183
|
-
return
|
|
184
|
-
viewname='django_ledger:je-list',
|
|
185
|
-
kwargs={
|
|
186
|
-
'entity_slug': self.AUTHORIZED_ENTITY_MODEL.slug,
|
|
187
|
-
'ledger_pk': je_model.ledger_id
|
|
188
|
-
}
|
|
189
|
-
)
|
|
169
|
+
return je_model.get_journal_entry_list_url()
|
|
190
170
|
|
|
191
171
|
|
|
192
|
-
|
|
172
|
+
# todo:.... move this to transaction list view?.....
|
|
173
|
+
class JournalEntryModelTXSDetailView(JournalEntryModelModelBaseView, DetailView):
|
|
193
174
|
template_name = 'django_ledger/journal_entry/je_detail_txs.html'
|
|
194
175
|
PAGE_TITLE = _('Edit Transactions')
|
|
195
176
|
pk_url_kwarg = 'je_pk'
|
|
@@ -214,11 +195,8 @@ class JournalEntryModelTXSDetailView(DjangoLedgerSecurityMixIn, JournalEntryMode
|
|
|
214
195
|
if not txs_formset:
|
|
215
196
|
TransactionModelFormSet = get_transactionmodel_formset_class(journal_entry_model=je_model)
|
|
216
197
|
context['txs_formset'] = TransactionModelFormSet(
|
|
217
|
-
user_model=self.request.user,
|
|
218
198
|
je_model=je_model,
|
|
219
|
-
|
|
220
|
-
entity_slug=self.kwargs['entity_slug'],
|
|
221
|
-
queryset=je_model.transactionmodel_set.all().order_by('account__code')
|
|
199
|
+
entity_model=self.get_authorized_entity_instance(),
|
|
222
200
|
)
|
|
223
201
|
else:
|
|
224
202
|
context['txs_formset'] = txs_formset
|
|
@@ -234,9 +212,7 @@ class JournalEntryModelTXSDetailView(DjangoLedgerSecurityMixIn, JournalEntryMode
|
|
|
234
212
|
|
|
235
213
|
TransactionModelFormSet = get_transactionmodel_formset_class(journal_entry_model=je_model)
|
|
236
214
|
txs_formset = TransactionModelFormSet(request.POST,
|
|
237
|
-
|
|
238
|
-
ledger_pk=kwargs['ledger_pk'],
|
|
239
|
-
entity_slug=kwargs['entity_slug'],
|
|
215
|
+
entity_model=self.get_authorized_entity_instance(),
|
|
240
216
|
je_model=je_model)
|
|
241
217
|
|
|
242
218
|
if je_model.locked:
|
|
@@ -271,7 +247,11 @@ class JournalEntryModelTXSDetailView(DjangoLedgerSecurityMixIn, JournalEntryMode
|
|
|
271
247
|
|
|
272
248
|
|
|
273
249
|
# ACTION VIEWS...
|
|
274
|
-
class BaseJournalEntryActionView(
|
|
250
|
+
class BaseJournalEntryActionView(
|
|
251
|
+
JournalEntryModelModelBaseView,
|
|
252
|
+
RedirectView,
|
|
253
|
+
SingleObjectMixin
|
|
254
|
+
):
|
|
275
255
|
http_method_names = ['get']
|
|
276
256
|
pk_url_kwarg = 'je_pk'
|
|
277
257
|
action_name = None
|
|
@@ -279,11 +259,14 @@ class BaseJournalEntryActionView(DjangoLedgerSecurityMixIn, RedirectView, Single
|
|
|
279
259
|
|
|
280
260
|
def get_queryset(self):
|
|
281
261
|
return JournalEntryModel.objects.for_entity(
|
|
282
|
-
entity_slug=self.
|
|
262
|
+
entity_slug=self.get_authorized_entity_instance(),
|
|
283
263
|
user_model=self.request.user
|
|
284
|
-
)
|
|
264
|
+
).for_ledger(ledger_pk=self.kwargs['ledger_pk'])
|
|
285
265
|
|
|
286
266
|
def get_redirect_url(self, *args, **kwargs):
|
|
267
|
+
next_url = self.request.GET.get('next')
|
|
268
|
+
if next_url:
|
|
269
|
+
return next_url
|
|
287
270
|
return reverse('django_ledger:je-list',
|
|
288
271
|
kwargs={
|
|
289
272
|
'entity_slug': kwargs['entity_slug'],
|