django-ledger 0.6.3__py3-none-any.whl → 0.7.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.

Files changed (115) hide show
  1. django_ledger/__init__.py +1 -4
  2. django_ledger/admin/coa.py +1 -2
  3. django_ledger/contrib/django_ledger_graphene/accounts/schema.py +1 -1
  4. django_ledger/forms/account.py +60 -44
  5. django_ledger/forms/bank_account.py +3 -2
  6. django_ledger/forms/bill.py +24 -36
  7. django_ledger/forms/customer.py +1 -1
  8. django_ledger/forms/data_import.py +3 -3
  9. django_ledger/forms/estimate.py +1 -1
  10. django_ledger/forms/invoice.py +5 -7
  11. django_ledger/forms/item.py +24 -15
  12. django_ledger/forms/transactions.py +3 -3
  13. django_ledger/io/io_core.py +4 -2
  14. django_ledger/io/io_middleware.py +5 -0
  15. django_ledger/io/roles.py +6 -0
  16. django_ledger/migrations/0017_alter_accountmodel_unique_together_and_more.py +31 -0
  17. django_ledger/models/accounts.py +629 -342
  18. django_ledger/models/bank_account.py +0 -4
  19. django_ledger/models/bill.py +0 -3
  20. django_ledger/models/closing_entry.py +0 -3
  21. django_ledger/models/coa.py +59 -48
  22. django_ledger/models/coa_default.py +9 -8
  23. django_ledger/models/customer.py +0 -4
  24. django_ledger/models/data_import.py +0 -3
  25. django_ledger/models/entity.py +80 -40
  26. django_ledger/models/estimate.py +0 -9
  27. django_ledger/models/invoice.py +0 -3
  28. django_ledger/models/items.py +4 -6
  29. django_ledger/models/journal_entry.py +2 -5
  30. django_ledger/models/ledger.py +0 -3
  31. django_ledger/models/mixins.py +0 -3
  32. django_ledger/models/purchase_order.py +0 -4
  33. django_ledger/models/signals.py +0 -3
  34. django_ledger/models/transactions.py +2 -5
  35. django_ledger/models/unit.py +0 -3
  36. django_ledger/models/utils.py +0 -3
  37. django_ledger/models/vendor.py +0 -3
  38. django_ledger/report/cash_flow_statement.py +1 -1
  39. django_ledger/static/.DS_Store +0 -0
  40. django_ledger/static/django_ledger/.DS_Store +0 -0
  41. django_ledger/static/django_ledger/logo_2/.DS_Store +0 -0
  42. django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark.png +0 -0
  43. django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@0.5x.png +0 -0
  44. django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@2x.png +0 -0
  45. django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@3x.png +0 -0
  46. django_ledger/static/django_ledger/logo_2/djl-full-vert.png +0 -0
  47. django_ledger/static/django_ledger/logo_2/djl-full-vert@0.5x.png +0 -0
  48. django_ledger/static/django_ledger/logo_2/djl-full-vert@2x.png +0 -0
  49. django_ledger/static/django_ledger/logo_2/djl-full-vert@3x.png +0 -0
  50. django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz.png +0 -0
  51. django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz@0.5x.png +0 -0
  52. django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz@2x.png +0 -0
  53. django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz@3x.png +0 -0
  54. django_ledger/static/django_ledger/logo_2/djl-logo-full-vert.png +0 -0
  55. django_ledger/static/django_ledger/logo_2/djl-logo-full-vert@0.5x.png +0 -0
  56. django_ledger/static/django_ledger/logo_2/djl-logo-full-vert@2x.png +0 -0
  57. django_ledger/static/django_ledger/logo_2/djl-logo-full-vert@3x.png +0 -0
  58. django_ledger/static/django_ledger/logo_2/djl-logo.png +0 -0
  59. django_ledger/static/django_ledger/logo_2/djl-logo@0.5x.png +0 -0
  60. django_ledger/static/django_ledger/logo_2/djl-logo@2x.png +0 -0
  61. django_ledger/static/django_ledger/logo_2/djl-logo@3x.png +0 -0
  62. django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz.png +0 -0
  63. django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz@0.5x.png +0 -0
  64. django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz@2x.png +0 -0
  65. django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz@3x.png +0 -0
  66. django_ledger/static/django_ledger/logo_2/djl-txt-full-vert.png +0 -0
  67. django_ledger/static/django_ledger/logo_2/djl-txt-full-vert@0.5x.png +0 -0
  68. django_ledger/static/django_ledger/logo_2/djl-txt-full-vert@2x.png +0 -0
  69. django_ledger/static/django_ledger/logo_2/djl-txt-full-vert@3x.png +0 -0
  70. django_ledger/static/django_ledger/logo_2/djl-txt-horiz.png +0 -0
  71. django_ledger/static/django_ledger/logo_2/djl-txt-horiz@0.5x.png +0 -0
  72. django_ledger/static/django_ledger/logo_2/djl-txt-horiz@2x.png +0 -0
  73. django_ledger/static/django_ledger/logo_2/djl-txt-horiz@3x.png +0 -0
  74. django_ledger/templates/django_ledger/account/account_create.html +2 -2
  75. django_ledger/templates/django_ledger/account/account_update.html +1 -1
  76. django_ledger/templates/django_ledger/account/tags/account_txs_table.html +1 -0
  77. django_ledger/templates/django_ledger/account/tags/accounts_table.html +27 -18
  78. django_ledger/templates/django_ledger/bills/bill_detail.html +3 -3
  79. django_ledger/templates/django_ledger/expense/tags/expense_item_table.html +7 -0
  80. django_ledger/templates/django_ledger/invoice/invoice_detail.html +3 -3
  81. django_ledger/templatetags/django_ledger.py +7 -1
  82. django_ledger/tests/base.py +23 -7
  83. django_ledger/tests/test_accounts.py +145 -9
  84. django_ledger/urls/account.py +17 -24
  85. django_ledger/utils.py +8 -0
  86. django_ledger/views/__init__.py +1 -1
  87. django_ledger/views/account.py +80 -118
  88. django_ledger/views/auth.py +1 -1
  89. django_ledger/views/bank_account.py +9 -11
  90. django_ledger/views/bill.py +91 -80
  91. django_ledger/views/closing_entry.py +8 -0
  92. django_ledger/views/coa.py +2 -1
  93. django_ledger/views/customer.py +1 -1
  94. django_ledger/views/data_import.py +1 -1
  95. django_ledger/views/entity.py +1 -1
  96. django_ledger/views/estimate.py +13 -8
  97. django_ledger/views/feedback.py +1 -1
  98. django_ledger/views/financial_statement.py +1 -1
  99. django_ledger/views/home.py +1 -1
  100. django_ledger/views/inventory.py +9 -0
  101. django_ledger/views/invoice.py +5 -2
  102. django_ledger/views/item.py +58 -68
  103. django_ledger/views/journal_entry.py +1 -1
  104. django_ledger/views/ledger.py +3 -1
  105. django_ledger/views/mixins.py +9 -8
  106. django_ledger/views/purchase_order.py +1 -1
  107. django_ledger/views/transactions.py +1 -1
  108. django_ledger/views/unit.py +9 -0
  109. django_ledger/views/vendor.py +1 -1
  110. {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/AUTHORS.md +8 -2
  111. {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/METADATA +34 -43
  112. {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/RECORD +115 -79
  113. {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/WHEEL +1 -1
  114. {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/top_level.txt +0 -1
  115. {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/LICENSE +0 -0
@@ -2,10 +2,6 @@
2
2
  Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
3
3
  Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
4
4
 
5
- Contributions to this module:
6
- * Miguel Sanda <msanda@arrobalytics.com>
7
- * Pranav P Tulshyan <Ptulshyan77@gmail.com>
8
-
9
5
  A purchase order is a commercial source document that is issued by a business purchasing department when placing an
10
6
  order with its vendors or suppliers. The document indicates the details on the items that are to be purchased, such as
11
7
  the types of goods, quantity, and price. In simple terms, it is the contract drafted by the buyer when purchasing goods
@@ -2,9 +2,6 @@
2
2
  Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
3
3
  Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
4
4
 
5
- Contributions to this module:
6
- * Miguel Sanda <msanda@arrobalytics.com>
7
-
8
5
  The signals module provide the means to notify listeners about important events or states in the models,
9
6
  such as a ledger model being posted or a bill status changing.
10
7
  """
@@ -2,9 +2,6 @@
2
2
  Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
3
3
  Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
4
4
 
5
- Contributions to this module:
6
- * Miguel Sanda <msanda@arrobalytics.com>
7
-
8
5
  The TransactionModel is the lowest accounting level where financial information is recorded. Every transaction with a
9
6
  financial implication must be part of a JournalEntryModel, which encapsulates a collection of TransactionModels.
10
7
  Transaction models cannot exist without being part of a validated JournalEntryModel. Orphan TransactionModels are not
@@ -24,7 +21,7 @@ from django.contrib.auth import get_user_model
24
21
  from django.core.exceptions import ValidationError
25
22
  from django.core.validators import MinValueValidator
26
23
  from django.db import models
27
- from django.db.models import Q, QuerySet, F
24
+ from django.db.models import Q, QuerySet, Manager
28
25
  from django.db.models.signals import pre_save
29
26
  from django.utils.translation import gettext_lazy as _
30
27
 
@@ -209,7 +206,7 @@ class TransactionModelQuerySet(QuerySet):
209
206
  return self.filter(journal_entry__is_closing_entry=True)
210
207
 
211
208
 
212
- class TransactionModelManager(models.Manager):
209
+ class TransactionModelManager(Manager):
213
210
  """
214
211
  A manager class for the TransactionModel.
215
212
  """
@@ -2,9 +2,6 @@
2
2
  Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
3
3
  Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
4
4
 
5
- Contributions to this module:
6
- * Miguel Sanda <msanda@arrobalytics.com>
7
-
8
5
  An EntityUnit is a logical, user-defined grouping which is assigned to JournalEntryModels to help segregate business
9
6
  operations into separate components. Examples of business units may include Departments (i.e. Human Resources, IT, etc.)
10
7
  office locations, a real estate property, or any other label relevant to the business.
@@ -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
 
9
6
  from django.apps import apps
@@ -2,9 +2,6 @@
2
2
  Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
3
3
  Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
4
4
 
5
- Contributions to this module:
6
- * Miguel Sanda <msanda@arrobalytics.com>
7
-
8
5
  A Vendor refers to the person or entity that provides products and services to the business for a fee.
9
6
  Vendors are an integral part of the billing process as they are the providers of goods and services for the
10
7
  business.
@@ -1,7 +1,7 @@
1
1
  from datetime import datetime, date
2
2
  from typing import Optional, Dict, Union
3
3
 
4
- from django_ledger.io.io_digest import IODigestContextManager
4
+ from django_ledger.io.io_context import IODigestContextManager
5
5
  from django_ledger.report.core import BaseReportSupport, PDFReportValidationError
6
6
  from django_ledger.settings import DJANGO_LEDGER_CURRENCY_SYMBOL
7
7
  from django_ledger.templatetags.django_ledger import currency_format
Binary file
@@ -13,12 +13,12 @@
13
13
  </div>
14
14
  <div class="column is-8-tablet is-6-desktop">
15
15
  <div class="box">
16
- <form method="post">
16
+ <form method="post" id="{{ form.form_id }}">
17
17
  {% csrf_token %}
18
18
  {{ form.as_p }}
19
19
  <button type="submit" class="button is-primary is-fullwidth djetler_my_1">Submit</button>
20
20
  <a class="button is-dark is-small is-fullwidth"
21
- href="{% url 'django_ledger:account-list' entity_slug=view.kwargs.entity_slug %}">Back</a>
21
+ href="{{ coa_model.get_account_list_url }}">Back</a>
22
22
  </form>
23
23
  </div>
24
24
  </div>
@@ -18,7 +18,7 @@
18
18
  {{ form.as_p }}
19
19
  <button type="submit" class="button is-primary is-fullwidth djetler_my_1">Submit</button>
20
20
  <a class="button is-dark is-small is-fullwidth"
21
- href="{% url 'django_ledger:account-list' entity_slug=view.kwargs.entity_slug %}">Back</a>
21
+ href="{{ coa_model.get_account_list_url }}">Back</a>
22
22
  </form>
23
23
  </div>
24
24
  </div>
@@ -32,6 +32,7 @@
32
32
  </div>
33
33
  <div class="dropdown-menu" id="dropdown-menu-{{ tx.uuid }}" role="menu">
34
34
  <div class="dropdown-content">
35
+ {# TODO: These URLs need to be replaced with the future mode method that generates it. #}
35
36
  <a href="{% url 'django_ledger:je-detail' entity_slug=entity_slug ledger_pk=tx.journal_entry.ledger.uuid je_pk=tx.journal_entry.uuid %}"
36
37
  class="dropdown-item has-text-success">View JE</a>
37
38
  {% if tx.journal_entry.ledger.billmodel %}
@@ -15,7 +15,6 @@
15
15
  <td></td>
16
16
  <td></td>
17
17
  <td></td>
18
- {# <td></td>#}
19
18
  <td></td>
20
19
  </tr>
21
20
  {% endif %}
@@ -25,6 +24,7 @@
25
24
  <th>{% trans 'CoA' %}</th>
26
25
  <th>{% trans 'Balance Type' %}</th>
27
26
  <th>{% trans 'Active' %}</th>
27
+ <th>{% trans 'Locked' %}</th>
28
28
  <th>{% trans 'CoA Role Default' %}</th>
29
29
  <th>{% trans 'Actions' %}</th>
30
30
  </tr>
@@ -49,28 +49,29 @@
49
49
  <td>{{ account.coa_model.name }}</td>
50
50
  <td>{{ account.get_balance_type_display }}</td>
51
51
  <td class="has-text-centered">
52
- {% if account.active %}
52
+ {% if account.is_active %}
53
53
  <span class="icon has-text-success-dark">
54
54
  {% icon 'ant-design:check-circle-filled' 24 %}
55
55
  </span>
56
- {% elif not account.active %}
56
+ {% else %}
57
57
  <span class="icon has-text-danger-dark">
58
58
  {% icon 'mdi:dangerous' 24 %}
59
59
  </span>
60
60
  {% endif %}
61
61
  </td>
62
+
63
+ <td class="has-text-centered">
64
+ {% if account.is_locked %}
65
+ <span class="icon has-text-success-dark">
66
+ {% icon 'ooui:lock' 24 %}
67
+ </span>
68
+ {% else %}
69
+ <span class="icon has-text-danger-dark">
70
+ {% icon 'ooui:un-lock' 24 %}
71
+ </span>
72
+ {% endif %}
73
+ </td>
62
74
 
63
- {# <td class="has-text-centered">#}
64
- {# {% if account.locked %}#}
65
- {# <span class="icon has-text-success-dark">#}
66
- {# {% icon 'bi:lock-fill' 24 %}#}
67
- {# </span>#}
68
- {# {% elif not account.locked %}#}
69
- {# <span class="icon has-text-danger-dark">#}
70
- {# {% icon 'bx:bx-lock-open-alt' 24 %}#}
71
- {# </span>#}
72
- {# {% endif %}#}
73
- {# </td>#}
74
75
  <td class="has-text-centered">
75
76
  {% if account.role_default %}
76
77
  <span class="icon has-text-success-dark">
@@ -94,18 +95,26 @@
94
95
  </div>
95
96
  <div class="dropdown-menu" id="dropdown-menu-{{ account.uuid }}" role="menu">
96
97
  <div class="dropdown-content">
97
- <a href="{% url 'django_ledger:account-detail' entity_slug=entity_slug account_pk=account.uuid %}"
98
+ <a href="{{ account.get_absolute_url }}"
98
99
  class="dropdown-item has-text-success">{% trans 'Detail' %}</a>
99
- <a href="{% url 'django_ledger:account-update' entity_slug=entity_slug account_pk=account.uuid %}"
100
+ <a href="{{ account.get_update_url }}"
100
101
  class="dropdown-item has-text-warning">{% trans 'Update' %}</a>
101
102
  {% if account.can_activate %}
102
- <a href="{% url 'django_ledger:account-action-activate' entity_slug=entity_slug account_pk=account.uuid %}"
103
+ <a href="{{ account.get_action_activate_url }}"
103
104
  class="dropdown-item has-text-success has-text-weight-bold">{% trans 'Activate' %}</a>
104
105
  {% endif %}
105
106
  {% if account.can_deactivate %}
106
- <a href="{% url 'django_ledger:account-action-deactivate' entity_slug=entity_slug account_pk=account.uuid %}"
107
+ <a href="{{ account.get_action_deactivate_url }}"
107
108
  class="dropdown-item has-text-danger has-text-weight-bold">{% trans 'Deactivate' %}</a>
108
109
  {% endif %}
110
+ {% if account.can_lock %}
111
+ <a href="{{ account.get_action_lock_url }}"
112
+ class="dropdown-item has-text-success has-text-weight-bold">{% trans 'Lock' %}</a>
113
+ {% endif %}
114
+ {% if account.can_unlock %}
115
+ <a href="{{ account.get_action_unlock_url }}"
116
+ class="dropdown-item has-text-danger has-text-weight-bold">{% trans 'Unlock' %}</a>
117
+ {% endif %}
109
118
  </div>
110
119
  </div>
111
120
  </div>
@@ -29,7 +29,7 @@
29
29
  <div class="level-item has-text-centered">
30
30
  <div>
31
31
  <p class="heading">{% trans 'Cash Account' %}:
32
- <a href="{% url 'django_ledger:account-detail' account_pk=bill.cash_account.uuid entity_slug=view.kwargs.entity_slug %}"
32
+ <a href="{% url 'django_ledger:account-detail' account_pk=bill.cash_account.uuid coa_slug=bill.cash_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}"
33
33
  class="has-text-danger">{{ bill.cash_account.code }}</a>
34
34
  <p class="title" id="djl-bill-detail-amount-paid">
35
35
  {% currency_symbol %}{{ bill.get_amount_cash | absolute | currency_format }}</p>
@@ -40,7 +40,7 @@
40
40
  <div class="level-item has-text-centered">
41
41
  <div>
42
42
  <p class="heading">{% trans 'Prepaid Account' %}:
43
- <a href="{% url 'django_ledger:account-detail' account_pk=bill.prepaid_account.uuid entity_slug=view.kwargs.entity_slug %}"
43
+ <a href="{% url 'django_ledger:account-detail' account_pk=bill.prepaid_account.uuid coa_slug=bill.prepaid_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}"
44
44
  class="has-text-danger">{{ bill.prepaid_account.code }}</a>
45
45
  </p>
46
46
  <p class="title has-text-success" id="djl-bill-detail-amount-prepaid">
@@ -50,7 +50,7 @@
50
50
  <div class="level-item has-text-centered">
51
51
  <div>
52
52
  <p class="heading">{% trans 'Accounts Payable' %}:
53
- <a href="{% url 'django_ledger:account-detail' account_pk=bill.unearned_account.uuid entity_slug=view.kwargs.entity_slug %}"
53
+ <a href="{% url 'django_ledger:account-detail' account_pk=bill.unearned_account.uuid coa_slug=bill.unearned_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}"
54
54
  class="has-text-danger">{{ bill.unearned_account.code }}</a>
55
55
  </p>
56
56
  <p class="title has-text-danger" id="djl-bill-detail-amount-unearned">
@@ -9,6 +9,7 @@
9
9
  <th>{% trans 'Item' %}</th>
10
10
  <th>{% trans 'UOM' %}</th>
11
11
  <th>{% trans 'Expense Account' %}</th>
12
+ <th>{% trans 'Is Active' %}</th>
12
13
  <th>{% trans 'Actions' %}</th>
13
14
  </tr>
14
15
  </thead>
@@ -19,6 +20,12 @@
19
20
  <td>{{ expense_item.name }}</td>
20
21
  <td>{{ expense_item.uom }}</td>
21
22
  <td>{{ expense_item.expense_account }}</td>
23
+ <td class="has-text-centered">
24
+ {% if expense_item.is_active %}
25
+ <span class="icon is-small has-text-success">{% icon 'bi:check-circle-fill' 24 %}</span>
26
+ {% else %}
27
+ <span class="icon is-small has-text-danger">{% icon 'healthicons:no' 24 %}</span>
28
+ {% endif %} </td>
22
29
  <td>
23
30
  <div class="dropdown is-right is-hoverable" id="invoice-action-{{ invoice.uuid }}">
24
31
  <div class="dropdown-trigger">
@@ -28,7 +28,7 @@
28
28
  <div class="level-item has-text-centered">
29
29
  <div>
30
30
  <p class="heading">{% trans 'Cash Account' %}:
31
- <a href="{% url 'django_ledger:account-detail' account_pk=invoice.cash_account.uuid entity_slug=view.kwargs.entity_slug %}"
31
+ <a href="{% url 'django_ledger:account-detail' account_pk=invoice.cash_account.uuid coa_slug=invoice.cash_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}"
32
32
  class="has-text-danger">{{ invoice.cash_account.code }}</a>
33
33
  <p class="title">
34
34
  {% currency_symbol %}{{ invoice.get_amount_cash | absolute | currency_format }}</p>
@@ -39,7 +39,7 @@
39
39
  <div class="level-item has-text-centered">
40
40
  <div>
41
41
  <p class="heading">{% trans 'Accounts Receivable' %}:
42
- <a href="{% url 'django_ledger:account-detail' account_pk=invoice.prepaid_account.uuid entity_slug=view.kwargs.entity_slug %}"
42
+ <a href="{% url 'django_ledger:account-detail' account_pk=invoice.prepaid_account.uuid coa_slug=invoice.prepaid_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}"
43
43
  class="has-text-danger">{{ invoice.prepaid_account.code }}</a>
44
44
  </p>
45
45
  <p class="title has-text-success">
@@ -49,7 +49,7 @@
49
49
  <div class="level-item has-text-centered">
50
50
  <div>
51
51
  <p class="heading">{% trans 'Deferred Revenue' %}:
52
- <a href="{% url 'django_ledger:account-detail' account_pk=invoice.unearned_account.uuid entity_slug=view.kwargs.entity_slug %}"
52
+ <a href="{% url 'django_ledger:account-detail' account_pk=invoice.unearned_account.uuid coa_slug=invoice.unearned_account.coa_model.slug entity_slug=view.kwargs.entity_slug %}"
53
53
  class="has-text-danger">{{ invoice.unearned_account.code }}</a>
54
54
 
55
55
  </p>
@@ -542,6 +542,9 @@ def period_navigation(context, base_url: str):
542
542
  if context['view'].kwargs.get('unit_slug'):
543
543
  kwargs['unit_slug'] = context['view'].kwargs.get('unit_slug')
544
544
 
545
+ if context['view'].kwargs.get('coa_slug'):
546
+ kwargs['coa_slug'] = context['view'].kwargs.get('coa_slug')
547
+
545
548
  ctx = dict()
546
549
  ctx['year'] = context['year']
547
550
  ctx['has_year'] = context.get('has_year')
@@ -567,12 +570,15 @@ def period_navigation(context, base_url: str):
567
570
  'year': dt.year,
568
571
  'month': dt.month
569
572
  }
573
+
570
574
  if 'unit_slug' in kwargs:
571
575
  KWARGS_CURRENT_MONTH['unit_slug'] = kwargs['unit_slug']
572
576
  if 'account_pk' in kwargs:
573
577
  KWARGS_CURRENT_MONTH['account_pk'] = kwargs['account_pk']
574
578
  if 'ledger_pk' in kwargs:
575
579
  KWARGS_CURRENT_MONTH['ledger_pk'] = kwargs['ledger_pk']
580
+ if 'coa_slug' in kwargs:
581
+ KWARGS_CURRENT_MONTH['coa_slug'] = kwargs['coa_slug']
576
582
 
577
583
  ctx['current_month_url'] = reverse(f'django_ledger:{base_url}-month',
578
584
  kwargs=KWARGS_CURRENT_MONTH)
@@ -743,7 +749,7 @@ def navigation_menu(context, style):
743
749
  {
744
750
  'type': 'link',
745
751
  'title': 'Ledgers',
746
- 'url': reverse('django_ledger:ledger-list', kwargs={'entity_slug': ENTITY_SLUG})
752
+ 'url': reverse('django_ledger:ledger-list-visible', kwargs={'entity_slug': ENTITY_SLUG})
747
753
  },
748
754
  {
749
755
  'type': 'link',
@@ -8,7 +8,7 @@ from zoneinfo import ZoneInfo
8
8
 
9
9
  from django.conf import settings
10
10
  from django.contrib.auth import get_user_model
11
- from django.core.exceptions import ObjectDoesNotExist
11
+ from django.core.exceptions import ObjectDoesNotExist, ValidationError
12
12
  from django.test import TestCase
13
13
  from django.test.client import Client
14
14
  from django.utils.timezone import get_default_timezone
@@ -30,7 +30,7 @@ class DjangoLedgerBaseTest(TestCase):
30
30
  TEST_DATA = list()
31
31
  CLIENT = None
32
32
  TZ = None
33
- N = None
33
+ N = 1
34
34
  USER_EMAIL = None
35
35
  PASSWORD = None
36
36
  USERNAME = None
@@ -46,7 +46,6 @@ class DjangoLedgerBaseTest(TestCase):
46
46
  cls.USERNAME: str = 'testuser'
47
47
  cls.PASSWORD: str = 'NeverUseThisPassword12345'
48
48
  cls.USER_EMAIL: str = 'testuser@djangoledger.com'
49
- cls.N: int = 1
50
49
 
51
50
  cls.DAYS_FWD: int = randint(180, 180 * 3)
52
51
  cls.TZ = get_default_timezone()
@@ -191,14 +190,15 @@ class DjangoLedgerBaseTest(TestCase):
191
190
 
192
191
  def get_random_account(self,
193
192
  entity_model: EntityModel,
194
- balance_type: Literal['credit', 'debit', None] = None) -> AccountModel:
193
+ balance_type: Literal['credit', 'debit', None] = None,
194
+ active: bool = True,
195
+ locked: bool = False) -> AccountModel:
195
196
  """
196
197
  Returns 1 random AccountModel with the specified balance_type.
197
198
  """
198
- account_qs: AccountModelQuerySet = entity_model.get_coa_accounts(active=True)
199
+ account_qs: AccountModelQuerySet = entity_model.get_coa_accounts(active=active, locked=locked)
199
200
  account_qs = account_qs.filter(balance_type=balance_type) if balance_type else account_qs
200
- # limits the queryset in case of large querysets...
201
- return choice(account_qs[:50])
201
+ return choice(account_qs)
202
202
 
203
203
  def get_random_ledger(self,
204
204
  entity_model: EntityModel,
@@ -278,3 +278,19 @@ class DjangoLedgerBaseTest(TestCase):
278
278
  entity_model.validate_ledger_model_for_entity(ledger_model)
279
279
  txs_model_qs = je_model.transactionmodel_set.all()
280
280
  return choice(txs_model_qs[:qs_limit])
281
+
282
+ def resolve_url_patterns(self, url_patterns):
283
+ self.URL_PATTERNS = {
284
+ p.name: set(p.pattern.converters.keys()) for p in url_patterns
285
+ }
286
+
287
+ def resolve_url_kwars(self):
288
+ url_patterns = getattr(self, 'URL_PATTERNS', None)
289
+ if not url_patterns:
290
+ raise ValidationError(
291
+ message='Must call resolve_url_patterns before calling resolve_url_kwars.'
292
+ )
293
+
294
+ return set.union(*[
295
+ set(v) for v in self.URL_PATTERNS.values()
296
+ ])