django-ledger 0.7.0__py3-none-any.whl → 0.7.2__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/__init__.py +1 -1
- django_ledger/admin/{coa.py → chart_of_accounts.py} +1 -1
- django_ledger/admin/entity.py +1 -1
- django_ledger/forms/account.py +1 -1
- django_ledger/forms/bank_account.py +2 -0
- django_ledger/forms/chart_of_accounts.py +82 -0
- django_ledger/io/io_library.py +1 -1
- django_ledger/migrations/0018_transactionmodel_cleared_transactionmodel_reconciled_and_more.py +37 -0
- django_ledger/models/__init__.py +1 -1
- django_ledger/models/accounts.py +4 -0
- django_ledger/models/bank_account.py +6 -2
- django_ledger/models/bill.py +7 -3
- django_ledger/models/{coa.py → chart_of_accounts.py} +131 -27
- django_ledger/models/closing_entry.py +5 -7
- django_ledger/models/coa_default.py +1 -1
- django_ledger/models/customer.py +6 -2
- django_ledger/models/data_import.py +33 -8
- django_ledger/models/entity.py +27 -3
- django_ledger/models/estimate.py +6 -1
- django_ledger/models/invoice.py +14 -8
- django_ledger/models/items.py +19 -8
- django_ledger/models/journal_entry.py +71 -25
- django_ledger/models/ledger.py +8 -5
- django_ledger/models/purchase_order.py +9 -5
- django_ledger/models/transactions.py +23 -3
- django_ledger/models/unit.py +4 -0
- django_ledger/models/vendor.py +4 -0
- django_ledger/settings.py +28 -3
- django_ledger/templates/django_ledger/account/tags/accounts_table.html +3 -2
- django_ledger/templates/django_ledger/chart_of_accounts/coa_create.html +25 -0
- django_ledger/templates/django_ledger/chart_of_accounts/coa_list.html +25 -6
- django_ledger/templates/django_ledger/chart_of_accounts/coa_update.html +2 -2
- django_ledger/templates/django_ledger/chart_of_accounts/includes/coa_card.html +10 -4
- django_ledger/templates/django_ledger/data_import/tags/data_import_job_list_table.html +8 -0
- django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html +2 -2
- django_ledger/templates/django_ledger/includes/footer.html +2 -2
- django_ledger/urls/chart_of_accounts.py +6 -0
- django_ledger/utils.py +1 -36
- django_ledger/views/__init__.py +1 -1
- django_ledger/views/account.py +16 -3
- django_ledger/views/{coa.py → chart_of_accounts.py} +48 -44
- django_ledger/views/mixins.py +16 -5
- {django_ledger-0.7.0.dist-info → django_ledger-0.7.2.dist-info}/METADATA +1 -3
- {django_ledger-0.7.0.dist-info → django_ledger-0.7.2.dist-info}/RECORD +49 -47
- django_ledger/forms/coa.py +0 -47
- {django_ledger-0.7.0.dist-info → django_ledger-0.7.2.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.7.0.dist-info → django_ledger-0.7.2.dist-info}/LICENSE +0 -0
- {django_ledger-0.7.0.dist-info → django_ledger-0.7.2.dist-info}/WHEEL +0 -0
- {django_ledger-0.7.0.dist-info → django_ledger-0.7.2.dist-info}/top_level.txt +0 -0
django_ledger/settings.py
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
|
-
|
|
5
|
-
Contributions to this module:
|
|
6
|
-
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
4
|
"""
|
|
8
5
|
import logging
|
|
9
6
|
from decimal import Decimal
|
|
@@ -31,6 +28,34 @@ except ImportError:
|
|
|
31
28
|
|
|
32
29
|
logger.info(f'Django Ledger GraphQL Enabled: {DJANGO_LEDGER_GRAPHQL_SUPPORT_ENABLED}')
|
|
33
30
|
|
|
31
|
+
|
|
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.ChartOfAccountModelAbstract')
|
|
35
|
+
DJANGO_LEDGER_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_TRANSACTION_MODEL', 'django_ledger.TransactionModelAbstract')
|
|
36
|
+
DJANGO_LEDGER_JOURNAL_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_JOURNAL_ENTRY_MODEL', 'django_ledger.JournalEntryModelAbstract')
|
|
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.EntityModelAbstract')
|
|
39
|
+
DJANGO_LEDGER_ENTITY_STATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_STATE_MODEL', 'django_ledger.EntityStateModel')
|
|
40
|
+
|
|
41
|
+
DJANGO_LEDGER_ENTITY_UNIT_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_UNIT_MODEL', 'django_ledger.EntityUnitModelAbstract')
|
|
42
|
+
|
|
43
|
+
DJANGO_LEDGER_ESTIMATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ESTIMATE_MODEL', 'django_ledger.EstimateModelAbstract')
|
|
44
|
+
DJANGO_LEDGER_BILL_MODEL = getattr(settings, 'DJANGO_LEDGER_BILL_MODEL', 'django_ledger.BillModelAbstract')
|
|
45
|
+
DJANGO_LEDGER_INVOICE_MODEL = getattr(settings, 'DJANGO_LEDGER_INVOICE_MODEL', 'django_ledger.InvoiceModelAbstract')
|
|
46
|
+
DJANGO_LEDGER_PURCHASE_ORDER_MODEL = getattr(settings, 'DJANGO_LEDGER_PURCHASE_ORDER_MODEL', 'django_ledger.PurchaseOrderModelAbstract')
|
|
47
|
+
|
|
48
|
+
DJANGO_LEDGER_CUSTOMER_MODEL = getattr(settings, 'DJANGO_LEDGER_CUSTOMER_MODEL', 'django_ledger.CustomerModelAbstract')
|
|
49
|
+
DJANGO_LEDGER_VENDOR_MODEL = getattr(settings, 'DJANGO_LEDGER_VENDOR_MODEL', 'django_ledger.VendorModelAbstract')
|
|
50
|
+
|
|
51
|
+
DJANGO_LEDGER_BANK_ACCOUNT_MODEL = getattr(settings, 'DJANGO_LEDGER_BANK_ACCOUNT_MODEL', 'django_ledger.BackAccountModelAbstract')
|
|
52
|
+
DJANGO_LEDGER_CLOSING_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_CLOSING_ENTRY_MODEL', 'django_ledger.ClosingEntryTransactionModelAbstract')
|
|
53
|
+
DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL = getattr(settings, 'DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL', 'django_ledger.UnitOfMeasureModelAbstract')
|
|
54
|
+
DJANGO_LEDGER_ITEM_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_ITEM_TRANSACTION_MODEL', 'django_ledger.ItemTransactionModelAbstract')
|
|
55
|
+
DJANGO_LEDGER_ITEM_MODEL = getattr(settings, 'DJANGO_LEDGER_ITEM_MODEL', 'django_ledger.ItemModelAbstract')
|
|
56
|
+
DJANGO_LEDGER_STAGED_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_STAGED_TRANSACTION_MODEL', 'django_ledger.StagedTransactionModelAbstract')
|
|
57
|
+
DJANGO_LEDGER_IMPORT_JOB_MODEL = getattr(settings, 'DJANGO_LEDGER_IMPORT_JOB_MODEL', 'django_ledger.ImportJobModelAbstract')
|
|
58
|
+
|
|
34
59
|
DJANGO_LEDGER_USE_CLOSING_ENTRIES = getattr(settings, 'DJANGO_LEDGER_USE_CLOSING_ENTRIES', True)
|
|
35
60
|
DJANGO_LEDGER_DEFAULT_CLOSING_ENTRY_CACHE_TIMEOUT = getattr(settings,
|
|
36
61
|
'DJANGO_LEDGER_DEFAULT_CLOSING_ENTRY_CACHE_TIMEOUT', 3600)
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
<td></td>
|
|
17
17
|
<td></td>
|
|
18
18
|
<td></td>
|
|
19
|
+
<td></td>
|
|
19
20
|
</tr>
|
|
20
21
|
{% endif %}
|
|
21
22
|
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
<td></td>
|
|
38
39
|
<td></td>
|
|
39
40
|
<td></td>
|
|
40
|
-
|
|
41
|
+
<td></td>
|
|
41
42
|
<td></td>
|
|
42
43
|
</tr>
|
|
43
44
|
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
</span>
|
|
60
61
|
{% endif %}
|
|
61
62
|
</td>
|
|
62
|
-
|
|
63
|
+
|
|
63
64
|
<td class="has-text-centered">
|
|
64
65
|
{% if account.is_locked %}
|
|
65
66
|
<span class="icon has-text-success-dark">
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{% extends 'django_ledger/layouts/content_layout_1.html' %}
|
|
2
|
+
{% load i18n %}
|
|
3
|
+
{% load static %}
|
|
4
|
+
{% load django_ledger %}
|
|
5
|
+
|
|
6
|
+
{% block view_content %}
|
|
7
|
+
<div class="box">
|
|
8
|
+
<div class="columns is-centered is-multiline">
|
|
9
|
+
<div class="column is-12 has-text-centered">
|
|
10
|
+
<h1 class="is-size-2">{% trans 'Create Chart of Accounts' %}</h1>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="column is-8-tablet is-6-desktop">
|
|
13
|
+
<div class="box">
|
|
14
|
+
<form method="post" id="{{ form.get_form_id }}">
|
|
15
|
+
{% csrf_token %}
|
|
16
|
+
{{ form.as_p }}
|
|
17
|
+
<button type="submit" class="button is-primary is-fullwidth djetler_my_1">Submit</button>
|
|
18
|
+
<a class="button is-dark is-small is-fullwidth"
|
|
19
|
+
href="{{ entity_model.get_coa_list_url }}">Back</a>
|
|
20
|
+
</form>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
{% endblock %}
|
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
{% extends 'django_ledger/layouts/content_layout_1.html' %}
|
|
2
2
|
{% load i18n %}
|
|
3
3
|
{% load static %}
|
|
4
|
+
{% load icon from django_ledger %}
|
|
4
5
|
|
|
5
6
|
{% block view_content %}
|
|
6
|
-
<div class="
|
|
7
|
-
<div class="
|
|
8
|
-
|
|
9
|
-
<div class="column is-
|
|
10
|
-
|
|
7
|
+
<div class="card">
|
|
8
|
+
<div class="card-content">
|
|
9
|
+
<div class="columns">
|
|
10
|
+
<div class="column is-12">
|
|
11
|
+
<h1 class="is-size-1">Chart of Accounts
|
|
12
|
+
<a href="{{ entity_model.get_coa_create_url }}">
|
|
13
|
+
<span class="icon is-large has-text-success">{% icon 'carbon:add-alt' 60 %}</span></a>
|
|
14
|
+
</h1>
|
|
15
|
+
{% if not inactive %}
|
|
16
|
+
<a class="button is-warning" href="{{ entity_model.get_coa_list_inactive_url }}">
|
|
17
|
+
{% trans 'Show Inactive' %}</a>
|
|
18
|
+
{% else %}
|
|
19
|
+
<a class="button is-warning" href="{{ entity_model.get_coa_list_url }}">
|
|
20
|
+
{% trans 'Show Active' %}</a>
|
|
21
|
+
{% endif %}
|
|
22
|
+
|
|
11
23
|
</div>
|
|
12
|
-
|
|
24
|
+
</div>
|
|
25
|
+
<div class="columns is-centered is-multiline">
|
|
26
|
+
{% for coa_model in coa_list %}
|
|
27
|
+
<div class="column is-6">
|
|
28
|
+
{% include 'django_ledger/chart_of_accounts/includes/coa_card.html' with coa_model=coa_model %}
|
|
29
|
+
</div>
|
|
30
|
+
{% endfor %}
|
|
31
|
+
</div>
|
|
13
32
|
</div>
|
|
14
33
|
</div>
|
|
15
34
|
{% endblock %}
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
<div class="columns is-centered">
|
|
7
7
|
<div class="column is-8-tablet is-6-desktop">
|
|
8
8
|
<div class="box">
|
|
9
|
-
<form action="{{
|
|
9
|
+
<form action="{{ coa_model.get_update_url }}" id="{{ form.form_id }}" method="post">
|
|
10
10
|
{% csrf_token %}
|
|
11
11
|
{{ form.as_p }}
|
|
12
12
|
<button class="button is-primary is-outlined is-fullwidth djetler_my_1"
|
|
13
13
|
type="submit">Update
|
|
14
14
|
</button>
|
|
15
15
|
<a class="button is-small is-dark is-fullwidth"
|
|
16
|
-
href="{
|
|
16
|
+
href="{{ coa_model.get_coa_list_url }}"
|
|
17
17
|
type="submit">Back</a>
|
|
18
18
|
</form>
|
|
19
19
|
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
<div class="card">
|
|
7
|
-
<div class="card-header" {% if coa_model.is_default %}style="background-color: #04e304"{% endif %}>
|
|
7
|
+
<div class="card-header" {% if coa_model.is_default %}style="background-color: #04e304" {% elif not coa_model.is_active %}style="background-color: #d34e4e"{% endif %}>
|
|
8
8
|
<div class="card-header-icon">
|
|
9
9
|
{% icon "ic:baseline-business" 36 %}
|
|
10
10
|
</div>
|
|
@@ -42,6 +42,12 @@
|
|
|
42
42
|
</p>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
|
+
<footer class="card-footer">
|
|
46
|
+
<a href="{{ coa_model.get_update_url }}"
|
|
47
|
+
class="card-footer-item has-text-warning has-text-weight-bold">
|
|
48
|
+
{% trans 'Update' %}
|
|
49
|
+
</a>
|
|
50
|
+
</footer>
|
|
45
51
|
<footer class="card-footer">
|
|
46
52
|
<a href="{{ coa_model.get_account_list_url }}"
|
|
47
53
|
class="card-footer-item has-text-success has-text-weight-bold">
|
|
@@ -51,14 +57,14 @@
|
|
|
51
57
|
class="card-footer-item has-text-info has-text-weight-bold">
|
|
52
58
|
{% trans 'Add Account' %}
|
|
53
59
|
</a>
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
</footer>
|
|
61
|
+
<footer class="card-footer">
|
|
62
|
+
{% if coa_model.can_mark_as_default %}
|
|
56
63
|
<a href="{{ coa_model.mark_as_default_url }}"
|
|
57
64
|
class="card-footer-item has-text-danger has-text-weight-bold">
|
|
58
65
|
{% trans 'Mark as Default' %}
|
|
59
66
|
</a>
|
|
60
67
|
{% endif %}
|
|
61
|
-
|
|
62
68
|
{% if coa_model.can_deactivate %}
|
|
63
69
|
<a href="{{ coa_model.mark_as_inactive_url }}"
|
|
64
70
|
class="card-footer-item has-text-warning has-text-weight-bold">
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<th>Description</th>
|
|
10
10
|
<th>Bank Account</th>
|
|
11
11
|
<th>Created</th>
|
|
12
|
+
<th>Completed</th>
|
|
12
13
|
<th>Actions</th>
|
|
13
14
|
</tr>
|
|
14
15
|
</thead>
|
|
@@ -19,6 +20,13 @@
|
|
|
19
20
|
<td>{{ job.description }}</td>
|
|
20
21
|
<td>{{ job.bank_account_model }}</td>
|
|
21
22
|
<td>{{ job.created }}</td>
|
|
23
|
+
<td class="has-text-centered">
|
|
24
|
+
{% if job.is_complete %}
|
|
25
|
+
<span class="icon has-text-success">{% icon 'ant-design:check-circle-filled' 24 %}</span>
|
|
26
|
+
{% else %}
|
|
27
|
+
<span class="icon is-small has-text-danger">{% icon 'maki:roadblock-11' 24 %}</span>
|
|
28
|
+
{% endif %}
|
|
29
|
+
</td>
|
|
22
30
|
<td>
|
|
23
31
|
<div class="dropdown is-right" id="customer-action-{{ job.uuid }}">
|
|
24
32
|
|
django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html
CHANGED
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
</div>
|
|
61
61
|
<div class="dropdown-menu" id="dropdown-menu-{{ acc.uuid }}" role="menu">
|
|
62
62
|
<div class="dropdown-content">
|
|
63
|
-
<a href="{
|
|
63
|
+
<a href="{{ acc.get_absolute_url }}"
|
|
64
64
|
class="dropdown-item has-text-success">{% trans 'Detail' %}</a>
|
|
65
|
-
<a href="{
|
|
65
|
+
<a href="{{ acc.get_update_url }}"
|
|
66
66
|
class="dropdown-item has-text-warning">{% trans 'Update' %}</a>
|
|
67
67
|
</div>
|
|
68
68
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<footer class="footer">
|
|
2
2
|
<div class="content has-text-centered">
|
|
3
3
|
<p>
|
|
4
|
-
<strong>Django Ledger</strong> by <a href="https://miguelsanda.com" target="_blank">Miguel Sanda</a> and
|
|
5
|
-
<a href="https://
|
|
4
|
+
<strong>Django Ledger</strong> by <a href="https://www.miguelsanda.com" target="_blank">Miguel Sanda</a> and
|
|
5
|
+
<a href="https://miguelsanda.com" target="_blank">EDMA Group Inc</a>. The source code is licensed
|
|
6
6
|
<a href="https://opensource.org/licenses/GPL-3.0" target="_blank">GPL 3.0</a>
|
|
7
7
|
</p>
|
|
8
8
|
{% if user.is_superuser %}
|
|
@@ -6,6 +6,12 @@ urlpatterns = [
|
|
|
6
6
|
path('<slug:entity_slug>/list/',
|
|
7
7
|
views.ChartOfAccountModelListView.as_view(),
|
|
8
8
|
name='coa-list'),
|
|
9
|
+
path('<slug:entity_slug>/list/inactive/',
|
|
10
|
+
views.ChartOfAccountModelListView.as_view(inactive=True),
|
|
11
|
+
name='coa-list-inactive'),
|
|
12
|
+
path('<slug:entity_slug>/create/',
|
|
13
|
+
views.ChartOfAccountModelCreateView.as_view(),
|
|
14
|
+
name='coa-create'),
|
|
9
15
|
path('<slug:entity_slug>/detail/<slug:coa_slug>/',
|
|
10
16
|
views.ChartOfAccountModelListView.as_view(),
|
|
11
17
|
name='coa-detail'),
|
django_ledger/utils.py
CHANGED
|
@@ -18,7 +18,6 @@ from django.db.models import QuerySet
|
|
|
18
18
|
from django.utils.dateparse import parse_date
|
|
19
19
|
|
|
20
20
|
from django_ledger.io.io_core import get_localdate
|
|
21
|
-
from django_ledger.models import EntityModel
|
|
22
21
|
|
|
23
22
|
UserModel = get_user_model()
|
|
24
23
|
|
|
@@ -52,7 +51,7 @@ def get_default_unit_session_key():
|
|
|
52
51
|
return 'djl_default_unit_model'
|
|
53
52
|
|
|
54
53
|
|
|
55
|
-
def set_default_entity(request, entity_model
|
|
54
|
+
def set_default_entity(request, entity_model):
|
|
56
55
|
session_key = get_default_entity_session_key()
|
|
57
56
|
if not request.session.get(session_key):
|
|
58
57
|
request.session[session_key] = {
|
|
@@ -111,37 +110,3 @@ def get_end_date_from_session(entity_slug: str, request) -> date:
|
|
|
111
110
|
end_date = request.session.get(session_end_date_filter)
|
|
112
111
|
end_date = parse_date(end_date) if end_date else get_localdate()
|
|
113
112
|
return end_date
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def load_model_class(model_path: str):
|
|
117
|
-
"""
|
|
118
|
-
Loads a Python Model Class by using a string.
|
|
119
|
-
This functionality is inspired by the Django Blog Zinnia project.
|
|
120
|
-
This function allows for extension and customization of the stardard Django Ledger Models.
|
|
121
|
-
|
|
122
|
-
Examples
|
|
123
|
-
________
|
|
124
|
-
>>> model_class = load_model_class(model_path='module.models.MyModel')
|
|
125
|
-
|
|
126
|
-
Parameters
|
|
127
|
-
----------
|
|
128
|
-
model_path: str
|
|
129
|
-
The model path to load.
|
|
130
|
-
|
|
131
|
-
Returns
|
|
132
|
-
-------
|
|
133
|
-
The loaded Python model Class.
|
|
134
|
-
|
|
135
|
-
Raises
|
|
136
|
-
______
|
|
137
|
-
ImportError or AttributeError if unable to load model.
|
|
138
|
-
"""
|
|
139
|
-
dot = model_path.rindex('.')
|
|
140
|
-
module_name = model_path[:dot]
|
|
141
|
-
klass_name = model_path[dot + 1:]
|
|
142
|
-
try:
|
|
143
|
-
klass = getattr(import_module(module_name), klass_name)
|
|
144
|
-
return klass
|
|
145
|
-
except (ImportError, AttributeError) as e:
|
|
146
|
-
print(e)
|
|
147
|
-
raise ImproperlyConfigured(f'Model {model_path} cannot be imported!')
|
django_ledger/views/__init__.py
CHANGED
|
@@ -10,7 +10,7 @@ from django_ledger.views.account import *
|
|
|
10
10
|
from django_ledger.views.auth import *
|
|
11
11
|
from django_ledger.views.bank_account import *
|
|
12
12
|
from django_ledger.views.bill import *
|
|
13
|
-
from django_ledger.views.
|
|
13
|
+
from django_ledger.views.chart_of_accounts import *
|
|
14
14
|
from django_ledger.views.customer import *
|
|
15
15
|
from django_ledger.views.data_import import *
|
|
16
16
|
from django_ledger.views.djl_api import *
|
django_ledger/views/account.py
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
|
-
|
|
5
|
-
Contributions to this module:
|
|
6
|
-
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
4
|
"""
|
|
5
|
+
|
|
8
6
|
from django.contrib import messages
|
|
9
7
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
|
10
8
|
from django.http import HttpResponseRedirect
|
|
@@ -85,6 +83,16 @@ class AccountModelListView(BaseAccountModelBaseView, ListView):
|
|
|
85
83
|
return qs
|
|
86
84
|
|
|
87
85
|
|
|
86
|
+
|
|
87
|
+
def get(self, request, *args, **kwargs):
|
|
88
|
+
response = super().get(request, *args, **kwargs)
|
|
89
|
+
chart_of_accounts_model: ChartOfAccountModel = self.get_coa_model()
|
|
90
|
+
if not chart_of_accounts_model.is_active():
|
|
91
|
+
messages.error(request, _('WARNING: The chart of accounts list is inactive.'), extra_tags='is-danger')
|
|
92
|
+
return response
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
88
96
|
class AccountModelCreateView(BaseAccountModelBaseView, CreateView):
|
|
89
97
|
template_name = 'django_ledger/account/account_create.html'
|
|
90
98
|
PAGE_TITLE = _('Create Account')
|
|
@@ -101,6 +109,11 @@ class AccountModelCreateView(BaseAccountModelBaseView, CreateView):
|
|
|
101
109
|
**self.get_form_kwargs()
|
|
102
110
|
)
|
|
103
111
|
|
|
112
|
+
def get_initial(self):
|
|
113
|
+
return {
|
|
114
|
+
'coa_model': self.get_coa_model(),
|
|
115
|
+
}
|
|
116
|
+
|
|
104
117
|
def get_context_data(self, *args, **kwargs):
|
|
105
118
|
context = super().get_context_data(*args, **kwargs)
|
|
106
119
|
coa_model = self.get_coa_model()
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
|
-
|
|
5
|
-
Contributions to this module:
|
|
6
|
-
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
4
|
"""
|
|
8
5
|
|
|
9
6
|
from django.contrib import messages
|
|
10
7
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
|
11
|
-
from django.db.models import Count, Q
|
|
12
|
-
from django.urls import reverse
|
|
13
8
|
from django.utils.translation import gettext_lazy as _
|
|
14
|
-
from django.views.generic import UpdateView, ListView, RedirectView
|
|
9
|
+
from django.views.generic import UpdateView, ListView, RedirectView, CreateView
|
|
15
10
|
from django.views.generic.detail import SingleObjectMixin
|
|
16
11
|
|
|
17
|
-
from django_ledger.forms.
|
|
18
|
-
from django_ledger.models.
|
|
12
|
+
from django_ledger.forms.chart_of_accounts import ChartOfAccountsModelUpdateForm, ChartOfAccountsModelCreateForm
|
|
13
|
+
from django_ledger.models.chart_of_accounts import ChartOfAccountModel
|
|
19
14
|
from django_ledger.views.mixins import DjangoLedgerSecurityMixIn
|
|
20
15
|
|
|
21
16
|
|
|
@@ -25,65 +20,76 @@ class ChartOfAccountModelModelBaseViewMixIn(DjangoLedgerSecurityMixIn):
|
|
|
25
20
|
def get_queryset(self):
|
|
26
21
|
if self.queryset is None:
|
|
27
22
|
entity_model = self.get_authorized_entity_instance()
|
|
28
|
-
self.queryset = entity_model.chartofaccountmodel_set.all().
|
|
29
|
-
'entity').order_by('-updated')
|
|
23
|
+
self.queryset = entity_model.chartofaccountmodel_set.all().order_by('-updated')
|
|
30
24
|
return super().get_queryset()
|
|
31
25
|
|
|
32
26
|
|
|
33
27
|
class ChartOfAccountModelListView(ChartOfAccountModelModelBaseViewMixIn, ListView):
|
|
34
28
|
template_name = 'django_ledger/chart_of_accounts/coa_list.html'
|
|
35
|
-
extra_context = {
|
|
36
|
-
'page_title': _('Chart of Account List'),
|
|
37
|
-
'header_title': _('Chart of Account List'),
|
|
38
|
-
}
|
|
39
29
|
context_object_name = 'coa_list'
|
|
30
|
+
inactive = False
|
|
31
|
+
|
|
32
|
+
def get_queryset(self):
|
|
33
|
+
qs = super().get_queryset()
|
|
34
|
+
if self.inactive:
|
|
35
|
+
return qs.filter(active=False)
|
|
36
|
+
return qs.active()
|
|
40
37
|
|
|
41
38
|
def get_context_data(self, *, object_list=None, **kwargs):
|
|
42
39
|
context = super().get_context_data(object_list=None, **kwargs)
|
|
40
|
+
context['inactive'] = self.inactive
|
|
43
41
|
context['header_subtitle'] = self.AUTHORIZED_ENTITY_MODEL.name
|
|
44
42
|
context['header_subtitle_icon'] = 'gravity-ui:hierarchy'
|
|
43
|
+
context['page_title'] = 'Inactive Chart of Account List' if self.inactive else 'Chart of Accounts List'
|
|
44
|
+
context['header_title'] = 'Inactive Chart of Account List' if self.inactive else 'Chart of Accounts List'
|
|
45
45
|
return context
|
|
46
46
|
|
|
47
|
-
def get_queryset(self):
|
|
48
|
-
qs = super().get_queryset()
|
|
49
|
-
return qs.annotate(
|
|
50
|
-
accountmodel_total__count=Count(
|
|
51
|
-
'accountmodel',
|
|
52
|
-
# excludes coa root accounts...
|
|
53
|
-
filter=Q(accountmodel__depth__gt=2)
|
|
54
|
-
),
|
|
55
|
-
accountmodel_locked__count=Count(
|
|
56
|
-
'accountmodel',
|
|
57
|
-
# excludes coa root accounts...
|
|
58
|
-
filter=Q(accountmodel__depth__gt=2) & Q(accountmodel__locked=True)
|
|
59
|
-
),
|
|
60
|
-
accountmodel_active__count=Count(
|
|
61
|
-
'accountmodel',
|
|
62
|
-
# excludes coa root accounts...
|
|
63
|
-
filter=Q(accountmodel__depth__gt=2) & Q(accountmodel__active=True)
|
|
64
|
-
),
|
|
65
47
|
|
|
48
|
+
class ChartOfAccountModelCreateView(ChartOfAccountModelModelBaseViewMixIn, CreateView):
|
|
49
|
+
template_name = 'django_ledger/chart_of_accounts/coa_create.html'
|
|
50
|
+
extra_context = {
|
|
51
|
+
'header_title': _('Create Chart of Accounts'),
|
|
52
|
+
'page_title': _('Create Chart of Account'),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
def get_initial(self):
|
|
56
|
+
return {
|
|
57
|
+
'entity': self.get_authorized_entity_instance(),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
def get_form(self, form_class=None):
|
|
61
|
+
return ChartOfAccountsModelCreateForm(
|
|
62
|
+
entity_model=self.get_authorized_entity_instance(),
|
|
63
|
+
**self.get_form_kwargs()
|
|
66
64
|
)
|
|
67
65
|
|
|
66
|
+
def get_context_data(self, *, object_list=None, **kwargs):
|
|
67
|
+
context = super().get_context_data(object_list=None, **kwargs)
|
|
68
|
+
context['header_subtitle'] = f'New Chart of Accounts: {self.AUTHORIZED_ENTITY_MODEL.name}'
|
|
69
|
+
context['header_subtitle_icon'] = 'gravity-ui:hierarchy'
|
|
70
|
+
return context
|
|
71
|
+
|
|
72
|
+
def get_success_url(self):
|
|
73
|
+
chart_of_accounts_model: ChartOfAccountModel = self.object
|
|
74
|
+
return chart_of_accounts_model.get_coa_list_url()
|
|
75
|
+
|
|
68
76
|
|
|
69
77
|
class ChartOfAccountModelUpdateView(ChartOfAccountModelModelBaseViewMixIn, UpdateView):
|
|
70
|
-
context_object_name = '
|
|
78
|
+
context_object_name = 'coa_model'
|
|
71
79
|
slug_url_kwarg = 'coa_slug'
|
|
72
80
|
template_name = 'django_ledger/chart_of_accounts/coa_update.html'
|
|
73
81
|
form_class = ChartOfAccountsModelUpdateForm
|
|
74
82
|
|
|
75
83
|
def get_context_data(self, **kwargs):
|
|
76
84
|
context = super().get_context_data(**kwargs)
|
|
77
|
-
|
|
78
|
-
context['
|
|
85
|
+
chart_of_accounts_model: ChartOfAccountModel = self.object
|
|
86
|
+
context['page_title'] = f'Update Chart of Account {chart_of_accounts_model.name}'
|
|
87
|
+
context['header_title'] = f'Update Chart of Account {chart_of_accounts_model.name}'
|
|
79
88
|
return context
|
|
80
89
|
|
|
81
90
|
def get_success_url(self):
|
|
82
|
-
|
|
83
|
-
return
|
|
84
|
-
kwargs={
|
|
85
|
-
'entity_slug': entity_slug
|
|
86
|
-
})
|
|
91
|
+
chart_of_accounts_model: ChartOfAccountModel = self.object
|
|
92
|
+
return chart_of_accounts_model.get_coa_list_url()
|
|
87
93
|
|
|
88
94
|
|
|
89
95
|
# todo: centralize this functionality into a separate class for ALL Action views...
|
|
@@ -96,10 +102,8 @@ class CharOfAccountModelActionView(ChartOfAccountModelModelBaseViewMixIn,
|
|
|
96
102
|
commit = True
|
|
97
103
|
|
|
98
104
|
def get_redirect_url(self, *args, **kwargs):
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
'entity_slug': kwargs['entity_slug']
|
|
102
|
-
})
|
|
105
|
+
chart_of_accounts_model: ChartOfAccountModel = self.get_object()
|
|
106
|
+
return chart_of_accounts_model.get_coa_list_url()
|
|
103
107
|
|
|
104
108
|
def get(self, request, *args, **kwargs):
|
|
105
109
|
kwargs['user_model'] = self.request.user
|
django_ledger/views/mixins.py
CHANGED
|
@@ -314,10 +314,20 @@ class SuccessUrlNextMixIn:
|
|
|
314
314
|
|
|
315
315
|
class DjangoLedgerSecurityMixIn(LoginRequiredMixin, PermissionRequiredMixin):
|
|
316
316
|
ENTITY_SLUG_URL_KWARG = 'entity_slug'
|
|
317
|
-
|
|
317
|
+
ENTITY_MODEL_CONTEXT_NAME = 'entity_model'
|
|
318
318
|
AUTHORIZE_SUPERUSER: bool = DJANGO_LEDGER_AUTHORIZED_SUPERUSER
|
|
319
319
|
permission_required = []
|
|
320
320
|
|
|
321
|
+
def __init__(self, *args, **kwargs):
|
|
322
|
+
self.AUTHORIZED_ENTITY_MODEL: Optional[EntityModel] = None
|
|
323
|
+
super().__init__(*args, **kwargs)
|
|
324
|
+
|
|
325
|
+
def get_context_data(self, **kwargs):
|
|
326
|
+
context = super().get_context_data(**kwargs)
|
|
327
|
+
context[self.ENTITY_MODEL_CONTEXT_NAME] = self.get_authorized_entity_instance(raise_exception=False)
|
|
328
|
+
return context
|
|
329
|
+
|
|
330
|
+
|
|
321
331
|
def get_login_url(self):
|
|
322
332
|
return reverse('django_ledger:login')
|
|
323
333
|
|
|
@@ -355,12 +365,13 @@ class DjangoLedgerSecurityMixIn(LoginRequiredMixin, PermissionRequiredMixin):
|
|
|
355
365
|
return EntityModel.objects.for_user(
|
|
356
366
|
user_model=self.request.user,
|
|
357
367
|
authorized_superuser=self.get_superuser_authorization(),
|
|
358
|
-
)
|
|
359
|
-
'uuid', 'slug', 'name', 'default_coa', 'admin')
|
|
368
|
+
)
|
|
360
369
|
|
|
361
|
-
def get_authorized_entity_instance(self) -> Optional[EntityModel]:
|
|
370
|
+
def get_authorized_entity_instance(self, raise_exception: bool = True) -> Optional[EntityModel]:
|
|
362
371
|
if self.AUTHORIZED_ENTITY_MODEL is None:
|
|
363
|
-
|
|
372
|
+
if raise_exception:
|
|
373
|
+
raise Http404()
|
|
374
|
+
return
|
|
364
375
|
return self.AUTHORIZED_ENTITY_MODEL
|
|
365
376
|
|
|
366
377
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-ledger
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
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>
|
|
@@ -41,8 +41,6 @@ Requires-Dist: furo ; extra == 'dev'
|
|
|
41
41
|
|
|
42
42
|

|
|
43
43
|
|
|
44
|
-
Here's a more concise and readable version of the Django Ledger README:
|
|
45
|
-
|
|
46
44
|
# Django Ledger
|
|
47
45
|
|
|
48
46
|
## A Double Entry Accounting Engine for Django
|