Skip to content

Commit 77d4893

Browse files
committed
Closing Entry Model and workflow optimization.
1 parent a9b7005 commit 77d4893

File tree

3 files changed

+63
-47
lines changed

3 files changed

+63
-47
lines changed

django_ledger/models/closing_entry.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from django.core.exceptions import ValidationError
1414
from django.core.validators import MinValueValidator
1515
from django.db import models
16-
from django.db.models import Q
16+
from django.db.models import Q, Count
1717
from django.db.models.signals import pre_save
1818
from django.urls import reverse
1919
from django.utils.timezone import make_aware
@@ -42,6 +42,12 @@ def not_posted(self):
4242

4343
class ClosingEntryModelManager(models.Manager):
4444

45+
def get_queryset(self):
46+
qs = ClosingEntryModelQuerySet(self.model, using=self._db)
47+
return qs.annotate(
48+
ce_txs_count=Count('closingentrytransactionmodel')
49+
)
50+
4551
def for_user(self, user_model):
4652
qs = self.get_queryset()
4753
if user_model.is_superuser:
@@ -102,6 +108,7 @@ def get_closing_date_as_timestamp(self):
102108
return make_aware(datetime.combine(self.closing_date, time.max))
103109

104110
def migrate(self):
111+
105112
ce_txs = self.closingentrytransactionmodel_set.all().select_related(
106113
'account_model',
107114
'unit_model'
@@ -118,7 +125,6 @@ def migrate(self):
118125
ce_txs_gb = groupby(ce_txs, key=lambda k: k.tx_type)
119126

120127
# adding DEBITS and CREDITS...
121-
# ce_txs_gb = {k: list(l) for k, l in ce_txs_gb}
122128
ce_txs_sum = {k: sum(v.balance for v in l) for k, l in ce_txs_gb}
123129

124130
if len(ce_txs_sum) and ce_txs_sum[TransactionModel.DEBIT] != ce_txs_sum[TransactionModel.CREDIT]:
@@ -131,7 +137,9 @@ def migrate(self):
131137

132138
ce_txs.sort(key=key_func)
133139
ce_txs_gb = groupby(ce_txs, key=key_func)
134-
ce_txs_gb = {unit_model_id: list(je_txs) for unit_model_id, je_txs in 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+
}
135143

136144
ce_txs_journal_entries = {
137145
(unit_model_id, activity): JournalEntryModel(
@@ -347,8 +355,6 @@ class Meta(ClosingEntryModelAbstract.Meta):
347355
abstract = False
348356

349357

350-
# todo: Remove this model!
351-
352358
class ClosingEntryTransactionModelQuerySet(models.QuerySet):
353359
pass
354360

django_ledger/models/journal_entry.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,10 @@ def generate_activity(self,
12431243
self.activity = None
12441244
else:
12451245
role_list = self.get_txs_roles(txs_qs, exclude_cash_role=True)
1246-
self.activity = self.get_activity_from_roles(role_set=role_list)
1246+
self.activity = self.get_activity_from_roles(
1247+
role_set=role_list,
1248+
raise_exception=raise_exception
1249+
)
12471250
return self.activity
12481251

12491252
# todo: add entity_model as parameter on all functions...
@@ -1534,7 +1537,7 @@ def save(
15341537

15351538
if verify:
15361539
txs_qs, is_verified = self.clean(verify=True)
1537-
if self.is_verified() and post_on_verify:
1540+
if is_verified and post_on_verify:
15381541
# Mark as posted if verification succeeds and posting is requested
15391542
self.mark_as_posted(commit=False, verify=False, force_lock=True, raise_exception=True)
15401543

django_ledger/views/closing_entry.py

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88

99
from django.contrib import messages
1010
from django.core.exceptions import ValidationError, ImproperlyConfigured
11-
from django.db.models import Count
1211
from django.http import HttpResponseRedirect
13-
from django.shortcuts import get_object_or_404
1412
from django.urls import reverse
1513
from django.utils.translation import gettext_lazy as _
16-
from django.views.generic import ArchiveIndexView, YearArchiveView, MonthArchiveView, DetailView, \
17-
RedirectView, CreateView, DeleteView, UpdateView
14+
from django.views.generic import (
15+
ArchiveIndexView, YearArchiveView,
16+
MonthArchiveView, DetailView,
17+
RedirectView, CreateView,
18+
DeleteView, UpdateView
19+
)
1820
from django.views.generic.detail import SingleObjectMixin
1921

2022
from django_ledger.forms.closing_entry import ClosingEntryCreateForm, ClosingEntryUpdateForm
@@ -24,25 +26,21 @@
2426
from django_ledger.views import DjangoLedgerSecurityMixIn
2527

2628

27-
class ClosingEntryModelViewQuerySetMixIn:
29+
class ClosingEntryModelBaseView(DjangoLedgerSecurityMixIn):
2830
queryset = None
29-
queryset_annotate_txs_count = False
3031

3132
def get_queryset(self):
3233
if self.queryset is None:
33-
qs = ClosingEntryModel.objects.for_entity(
34-
entity_slug=self.kwargs['entity_slug'],
35-
user_model=self.request.user
36-
).select_related('entity_model', 'ledger_model')
37-
if self.queryset_annotate_txs_count:
38-
qs = qs.annotate(ce_txs_count=Count('closingentrytransactionmodel'))
39-
self.queryset = qs
40-
return super().get_queryset()
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):
4644
template_name = 'django_ledger/closing_entry/closing_entry_list.html'
4745
date_field = 'closing_date'
4846
allow_future = False
@@ -56,23 +54,21 @@ class ClosingEntryModelListView(DjangoLedgerSecurityMixIn,
5654
'header_title': PAGE_TITLE,
5755
'header_subtitle_icon': 'file-icons:finaldraft'
5856
}
59-
queryset_annotate_txs_count = True
6057

6158

62-
class ClosingEntryModelYearListView(YearArchiveView, ClosingEntryModelListView):
59+
class ClosingEntryModelYearListView(ClosingEntryModelListView, YearArchiveView):
6360
paginate_by = 10
6461
make_object_list = True
6562

6663

67-
class ClosingEntryModelMonthListView(MonthArchiveView, ClosingEntryModelListView):
64+
class ClosingEntryModelMonthListView(ClosingEntryModelListView, MonthArchiveView):
6865
paginate_by = 10
6966
month_format = '%m'
7067
date_list_period = 'year'
7168

7269

73-
class ClosingEntryModelCreateView(DjangoLedgerSecurityMixIn, ClosingEntryModelViewQuerySetMixIn, CreateView):
70+
class ClosingEntryModelCreateView(ClosingEntryModelBaseView, CreateView):
7471
template_name = 'django_ledger/closing_entry/closing_entry_create.html'
75-
form_class = ClosingEntryCreateForm
7672
PAGE_TITLE = _('Create Closing Entry')
7773
extra_context = {
7874
'page_title': PAGE_TITLE,
@@ -85,23 +81,25 @@ def get_initial(self):
8581
'closing_date': get_localdate()
8682
}
8783

88-
def get_object(self, queryset=None):
89-
if not getattr(self, 'object'):
90-
entity_model_qs = EntityModel.objects.for_user(user_model=self.request.user)
91-
entity_model = get_object_or_404(entity_model_qs, slug__exact=self.kwargs['entity_slug'])
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+
)
9488

9589
def get_context_data(self, **kwargs):
9690
ctx = super().get_context_data(**kwargs)
97-
entity_model = self.get_object()
91+
entity_model: EntityModel = self.get_authorized_entity_instance()
9892
ctx['header_subtitle'] = entity_model.name
9993
return ctx
10094

10195
def form_valid(self, form):
10296
closing_date = form.cleaned_data['closing_date']
103-
entity_model: EntityModel = self.get_object()
104-
ce_model, _ = entity_model.close_entity_books(closing_date=closing_date, force_update=True)
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+
)
105103
self.ce_model = ce_model
106104
return HttpResponseRedirect(self.get_success_url())
107105

@@ -115,15 +113,14 @@ def get_success_url(self):
115113
)
116114

117115

118-
class ClosingEntryModelDetailView(DjangoLedgerSecurityMixIn, ClosingEntryModelViewQuerySetMixIn, DetailView):
116+
class ClosingEntryModelDetailView(ClosingEntryModelBaseView, DetailView):
119117
template_name = 'django_ledger/closing_entry/closing_entry_detail.html'
120118
pk_url_kwarg = 'closing_entry_pk'
121119
context_object_name = 'closing_entry_model'
122120
extra_context = {
123121
'header_title': 'Closing Entry Detail',
124122
'header_subtitle_icon': 'file-icons:finaldraft'
125123
}
126-
queryset_annotate_txs_count = True
127124

128125
def get_context_data(self, **kwargs):
129126
ctx = super().get_context_data(**kwargs)
@@ -135,12 +132,11 @@ def get_context_data(self, **kwargs):
135132
return ctx
136133

137134

138-
class ClosingEntryModelUpdateView(DjangoLedgerSecurityMixIn, ClosingEntryModelViewQuerySetMixIn, UpdateView):
135+
class ClosingEntryModelUpdateView(ClosingEntryModelBaseView, UpdateView):
139136
template_name = 'django_ledger/closing_entry/closing_entry_update.html'
140137
pk_url_kwarg = 'closing_entry_pk'
141138
form_class = ClosingEntryUpdateForm
142139
context_object_name = 'closing_entry_model'
143-
queryset_annotate_txs_count = True
144140
extra_context = {
145141
'header_title': 'Closing Entry Detail',
146142
'header_subtitle_icon': 'file-icons:finaldraft'
@@ -165,10 +161,22 @@ def get_success_url(self):
165161
)
166162

167163

168-
class ClosingEntryDeleteView(DjangoLedgerSecurityMixIn, ClosingEntryModelViewQuerySetMixIn, DeleteView):
164+
class ClosingEntryDeleteView(ClosingEntryModelBaseView, DeleteView):
169165
template_name = 'django_ledger/closing_entry/closing_entry_delete.html'
170166
pk_url_kwarg = 'closing_entry_pk'
171167
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
172180

173181
def get_success_url(self):
174182
return reverse(viewname='django_ledger:closing-entry-list',
@@ -177,9 +185,8 @@ def get_success_url(self):
177185
})
178186

179187

180-
class ClosingEntryModelActionView(DjangoLedgerSecurityMixIn,
188+
class ClosingEntryModelActionView(ClosingEntryModelBaseView,
181189
RedirectView,
182-
ClosingEntryModelViewQuerySetMixIn,
183190
SingleObjectMixin):
184191
http_method_names = ['get']
185192
pk_url_kwarg = 'closing_entry_pk'

0 commit comments

Comments
 (0)