django-ledger 0.7.10__py3-none-any.whl → 0.8.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/context.py +12 -0
- django_ledger/forms/bill.py +0 -4
- django_ledger/forms/closing_entry.py +13 -1
- django_ledger/forms/data_import.py +1 -1
- django_ledger/forms/estimate.py +3 -6
- django_ledger/forms/invoice.py +3 -7
- django_ledger/forms/item.py +10 -18
- django_ledger/forms/purchase_order.py +2 -4
- django_ledger/io/io_core.py +25 -32
- django_ledger/io/io_generator.py +7 -6
- django_ledger/io/io_library.py +1 -2
- django_ledger/migrations/0024_billmodel_entity_model_invoicemodel_entity_model.py +24 -0
- django_ledger/migrations/0025_alter_billmodel_cash_account_and_more.py +70 -0
- django_ledger/models/accounts.py +109 -69
- django_ledger/models/bank_account.py +40 -23
- django_ledger/models/bill.py +89 -63
- django_ledger/models/chart_of_accounts.py +173 -105
- django_ledger/models/closing_entry.py +99 -48
- django_ledger/models/customer.py +60 -39
- django_ledger/models/data_import.py +55 -41
- django_ledger/models/deprecations.py +61 -0
- django_ledger/models/entity.py +18 -16
- django_ledger/models/estimate.py +57 -28
- django_ledger/models/invoice.py +58 -28
- django_ledger/models/items.py +503 -142
- django_ledger/models/journal_entry.py +61 -47
- django_ledger/models/ledger.py +106 -42
- django_ledger/models/mixins.py +16 -10
- django_ledger/models/purchase_order.py +39 -17
- django_ledger/models/transactions.py +152 -113
- django_ledger/models/unit.py +57 -30
- django_ledger/models/vendor.py +75 -43
- django_ledger/report/core.py +2 -14
- django_ledger/settings.py +56 -71
- django_ledger/static/django_ledger/bundle/djetler.bundle.js +1 -1
- django_ledger/static/django_ledger/bundle/djetler.bundle.js.LICENSE.txt +25 -0
- django_ledger/static/django_ledger/bundle/styles.bundle.js +1 -1
- django_ledger/static/django_ledger/css/djl_styles.css +273 -0
- django_ledger/templates/django_ledger/bills/includes/card_bill.html +2 -2
- django_ledger/templates/django_ledger/components/menu.html +41 -26
- django_ledger/templates/django_ledger/customer/tags/customer_table.html +5 -5
- django_ledger/templates/django_ledger/entity/includes/card_entity.html +12 -6
- django_ledger/templates/django_ledger/financial_statements/balance_sheet.html +1 -1
- django_ledger/templates/django_ledger/financial_statements/cash_flow.html +4 -1
- django_ledger/templates/django_ledger/financial_statements/income_statement.html +4 -1
- django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html +27 -3
- django_ledger/templates/django_ledger/financial_statements/tags/cash_flow_statement.html +16 -4
- django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html +73 -18
- django_ledger/templates/django_ledger/includes/widget_ratios.html +18 -24
- django_ledger/templates/django_ledger/invoice/includes/card_invoice.html +3 -3
- django_ledger/templates/django_ledger/layouts/base.html +6 -1
- django_ledger/templates/django_ledger/vendor/tags/vendor_table.html +9 -5
- django_ledger/tests/test_accounts.py +1 -2
- django_ledger/tests/test_io.py +17 -0
- django_ledger/tests/test_purchase_order.py +3 -3
- django_ledger/tests/test_transactions.py +1 -2
- django_ledger/urls/__init__.py +0 -4
- django_ledger/views/bill.py +8 -13
- django_ledger/views/chart_of_accounts.py +6 -4
- django_ledger/views/closing_entry.py +11 -7
- django_ledger/views/customer.py +13 -17
- django_ledger/views/data_import.py +7 -6
- django_ledger/views/djl_api.py +3 -5
- django_ledger/views/entity.py +2 -4
- django_ledger/views/estimate.py +3 -7
- django_ledger/views/inventory.py +3 -5
- django_ledger/views/invoice.py +4 -6
- django_ledger/views/item.py +7 -11
- django_ledger/views/journal_entry.py +1 -2
- django_ledger/views/mixins.py +25 -19
- django_ledger/views/purchase_order.py +24 -35
- django_ledger/views/unit.py +1 -2
- django_ledger/views/vendor.py +1 -2
- {django_ledger-0.7.10.dist-info → django_ledger-0.8.0.dist-info}/METADATA +43 -75
- {django_ledger-0.7.10.dist-info → django_ledger-0.8.0.dist-info}/RECORD +80 -108
- {django_ledger-0.7.10.dist-info → django_ledger-0.8.0.dist-info}/WHEEL +1 -1
- django_ledger-0.8.0.dist-info/top_level.txt +1 -0
- django_ledger/contrib/django_ledger_graphene/__init__.py +0 -0
- django_ledger/contrib/django_ledger_graphene/accounts/schema.py +0 -33
- django_ledger/contrib/django_ledger_graphene/api.py +0 -42
- django_ledger/contrib/django_ledger_graphene/apps.py +0 -6
- django_ledger/contrib/django_ledger_graphene/auth/mutations.py +0 -49
- django_ledger/contrib/django_ledger_graphene/auth/schema.py +0 -6
- django_ledger/contrib/django_ledger_graphene/bank_account/mutations.py +0 -61
- django_ledger/contrib/django_ledger_graphene/bank_account/schema.py +0 -34
- django_ledger/contrib/django_ledger_graphene/bill/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/bill/schema.py +0 -34
- django_ledger/contrib/django_ledger_graphene/coa/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/coa/schema.py +0 -30
- django_ledger/contrib/django_ledger_graphene/customers/__init__.py +0 -0
- django_ledger/contrib/django_ledger_graphene/customers/mutations.py +0 -71
- django_ledger/contrib/django_ledger_graphene/customers/schema.py +0 -43
- django_ledger/contrib/django_ledger_graphene/data_import/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/data_import/schema.py +0 -0
- django_ledger/contrib/django_ledger_graphene/entity/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/entity/schema.py +0 -94
- django_ledger/contrib/django_ledger_graphene/item/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/item/schema.py +0 -31
- django_ledger/contrib/django_ledger_graphene/journal_entry/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/journal_entry/schema.py +0 -35
- django_ledger/contrib/django_ledger_graphene/ledger/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/ledger/schema.py +0 -32
- django_ledger/contrib/django_ledger_graphene/purchase_order/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/purchase_order/schema.py +0 -31
- django_ledger/contrib/django_ledger_graphene/transaction/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/transaction/schema.py +0 -36
- django_ledger/contrib/django_ledger_graphene/unit/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/unit/schema.py +0 -27
- django_ledger/contrib/django_ledger_graphene/vendor/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/vendor/schema.py +0 -37
- django_ledger/contrib/django_ledger_graphene/views.py +0 -12
- django_ledger-0.7.10.dist-info/top_level.txt +0 -4
- {django_ledger-0.7.10.dist-info → django_ledger-0.8.0.dist-info/licenses}/AUTHORS.md +0 -0
- {django_ledger-0.7.10.dist-info → django_ledger-0.8.0.dist-info/licenses}/LICENSE +0 -0
django_ledger/__init__.py
CHANGED
django_ledger/context.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from django.conf import settings
|
|
2
|
+
|
|
3
|
+
from django_ledger import __version__
|
|
4
|
+
from django_ledger.settings import DJANGO_LEDGER_THEME
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def django_ledger_context(request):
|
|
8
|
+
return {
|
|
9
|
+
'DEBUG': settings.DEBUG,
|
|
10
|
+
'VERSION': __version__,
|
|
11
|
+
'DJANGO_LEDGER_THEME': DJANGO_LEDGER_THEME,
|
|
12
|
+
}
|
django_ledger/forms/bill.py
CHANGED
|
@@ -214,10 +214,6 @@ class BillModelConfigureForm(BaseBillModelUpdateForm):
|
|
|
214
214
|
|
|
215
215
|
class BillItemTransactionForm(ModelForm):
|
|
216
216
|
|
|
217
|
-
# def __init__(self, entity_unit_qs, *args, **kwargs):
|
|
218
|
-
# super().__init__(self, *args, **kwargs)
|
|
219
|
-
# self.fields['entity_unit'].queryset = entity_unit_qs
|
|
220
|
-
|
|
221
217
|
def clean(self):
|
|
222
218
|
cleaned_data = super(BillItemTransactionForm, self).clean()
|
|
223
219
|
itemtxs_model: ItemTransactionModel = self.instance
|
|
@@ -1,15 +1,25 @@
|
|
|
1
|
-
from django.forms import DateInput, ValidationError, ModelForm, Textarea
|
|
1
|
+
from django.forms import DateInput, ValidationError, ModelForm, Textarea, HiddenInput
|
|
2
2
|
from django.utils.translation import gettext_lazy as _
|
|
3
3
|
|
|
4
4
|
from django_ledger.io.io_core import get_localdate
|
|
5
5
|
from django_ledger.models.closing_entry import ClosingEntryModel
|
|
6
|
+
from django_ledger.models.entity import EntityModel
|
|
6
7
|
from django_ledger.settings import DJANGO_LEDGER_FORM_INPUT_CLASSES
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class ClosingEntryCreateForm(ModelForm):
|
|
10
11
|
|
|
12
|
+
def __init__(self, entity_model: EntityModel, *args, **kwargs):
|
|
13
|
+
super().__init__(*args, **kwargs)
|
|
14
|
+
self.ENTITY_MODEL: EntityModel = entity_model
|
|
15
|
+
self.fields['entity_model'].disabled = True
|
|
16
|
+
|
|
17
|
+
def clean_entity_model(self):
|
|
18
|
+
return self.ENTITY_MODEL
|
|
19
|
+
|
|
11
20
|
def clean_closing_date(self):
|
|
12
21
|
closing_date = self.cleaned_data['closing_date']
|
|
22
|
+
|
|
13
23
|
if closing_date > get_localdate():
|
|
14
24
|
raise ValidationError(
|
|
15
25
|
message=_('Cannot create a closing entry with a future date.'), code='invalid_date'
|
|
@@ -19,10 +29,12 @@ class ClosingEntryCreateForm(ModelForm):
|
|
|
19
29
|
class Meta:
|
|
20
30
|
model = ClosingEntryModel
|
|
21
31
|
fields = [
|
|
32
|
+
'entity_model',
|
|
22
33
|
'closing_date'
|
|
23
34
|
]
|
|
24
35
|
|
|
25
36
|
widgets = {
|
|
37
|
+
'entity_model': HiddenInput(),
|
|
26
38
|
'closing_date': DateInput(attrs={
|
|
27
39
|
'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-large',
|
|
28
40
|
'placeholder': _('Closing Date (YYYY-MM-DD)...'),
|
|
@@ -40,7 +40,7 @@ class ImportJobModelCreateForm(ModelForm):
|
|
|
40
40
|
widgets = {
|
|
41
41
|
'description': TextInput(attrs={
|
|
42
42
|
'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-large',
|
|
43
|
-
'placeholder': _('
|
|
43
|
+
'placeholder': _('Name this import...')
|
|
44
44
|
}),
|
|
45
45
|
'bank_account_model': Select(
|
|
46
46
|
attrs={
|
django_ledger/forms/estimate.py
CHANGED
|
@@ -25,8 +25,7 @@ class EstimateModelCreateForm(forms.ModelForm):
|
|
|
25
25
|
|
|
26
26
|
def get_customer_queryset(self):
|
|
27
27
|
return CustomerModel.objects.for_entity(
|
|
28
|
-
|
|
29
|
-
user_model=self.USER_MODEL
|
|
28
|
+
entity_model=self.ENTITY_SLUG,
|
|
30
29
|
).active()
|
|
31
30
|
|
|
32
31
|
class Meta:
|
|
@@ -116,13 +115,11 @@ class BaseEstimateItemModelFormset(BaseModelFormSet):
|
|
|
116
115
|
self.ENTITY_SLUG = entity_slug
|
|
117
116
|
|
|
118
117
|
items_qs = ItemModel.objects.for_estimate(
|
|
119
|
-
|
|
120
|
-
user_model=self.USER_MODEL
|
|
118
|
+
entity_model=self.ENTITY_SLUG
|
|
121
119
|
)
|
|
122
120
|
|
|
123
121
|
unit_qs = EntityUnitModel.objects.for_entity(
|
|
124
|
-
|
|
125
|
-
user_model=self.USER_MODEL
|
|
122
|
+
entity_model=self.ENTITY_SLUG
|
|
126
123
|
)
|
|
127
124
|
|
|
128
125
|
for form in self.forms:
|
django_ledger/forms/invoice.py
CHANGED
|
@@ -29,8 +29,7 @@ class InvoiceModelCreateForEstimateForm(ModelForm):
|
|
|
29
29
|
def get_customer_queryset(self):
|
|
30
30
|
if 'customer' in self.fields:
|
|
31
31
|
customer_qs = CustomerModel.objects.for_entity(
|
|
32
|
-
|
|
33
|
-
entity_slug=self.ENTITY_SLUG
|
|
32
|
+
entity_model=self.ENTITY_SLUG
|
|
34
33
|
).active()
|
|
35
34
|
self.fields['customer'].queryset = customer_qs
|
|
36
35
|
|
|
@@ -43,7 +42,6 @@ class InvoiceModelCreateForEstimateForm(ModelForm):
|
|
|
43
42
|
]):
|
|
44
43
|
|
|
45
44
|
account_qs = AccountModel.objects.for_entity(
|
|
46
|
-
user_model=self.USER_MODEL,
|
|
47
45
|
entity_model=self.ENTITY_SLUG
|
|
48
46
|
).for_invoice()
|
|
49
47
|
|
|
@@ -237,8 +235,7 @@ class BaseInvoiceItemTransactionFormset(BaseModelFormSet):
|
|
|
237
235
|
self.ENTITY_SLUG = entity_slug
|
|
238
236
|
|
|
239
237
|
items_qs = ItemModel.objects.for_invoice(
|
|
240
|
-
|
|
241
|
-
user_model=self.USER_MODEL
|
|
238
|
+
entity_model=self.ENTITY_SLUG
|
|
242
239
|
)
|
|
243
240
|
|
|
244
241
|
for form in self.forms:
|
|
@@ -252,8 +249,7 @@ class BaseInvoiceItemTransactionFormset(BaseModelFormSet):
|
|
|
252
249
|
def get_queryset(self):
|
|
253
250
|
if not self.queryset:
|
|
254
251
|
self.queryset = ItemTransactionModel.objects.for_invoice(
|
|
255
|
-
|
|
256
|
-
user_model=self.USER_MODEL,
|
|
252
|
+
entity_model=self.ENTITY_SLUG,
|
|
257
253
|
invoice_pk=self.INVOICE_MODEL.uuid
|
|
258
254
|
)
|
|
259
255
|
else:
|
django_ledger/forms/item.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from django.forms import ModelForm, TextInput, Select
|
|
1
|
+
from django.forms import ModelForm, TextInput, Select
|
|
2
2
|
from django.utils.translation import gettext_lazy as _
|
|
3
3
|
|
|
4
4
|
from django_ledger.io.roles import GROUP_INCOME, ASSET_CA_INVENTORY, GROUP_EXPENSES, GROUP_COGS
|
|
@@ -48,7 +48,6 @@ class ProductCreateForm(ModelForm):
|
|
|
48
48
|
|
|
49
49
|
accounts_qs = AccountModel.objects.for_entity(
|
|
50
50
|
entity_model=self.ENTITY_SLUG,
|
|
51
|
-
user_model=self.USER_MODEL
|
|
52
51
|
).with_roles(
|
|
53
52
|
roles=self.PRODUCT_OR_SERVICE_ROLES
|
|
54
53
|
).active()
|
|
@@ -62,8 +61,7 @@ class ProductCreateForm(ModelForm):
|
|
|
62
61
|
|
|
63
62
|
if 'uom' in self.fields:
|
|
64
63
|
uom_qs = UnitOfMeasureModel.objects.for_entity_active(
|
|
65
|
-
|
|
66
|
-
user_model=self.USER_MODEL
|
|
64
|
+
entity_model=self.ENTITY_SLUG
|
|
67
65
|
)
|
|
68
66
|
self.fields['uom'].queryset = uom_qs
|
|
69
67
|
|
|
@@ -142,8 +140,7 @@ class ServiceCreateForm(ModelForm):
|
|
|
142
140
|
super().__init__(*args, **kwargs)
|
|
143
141
|
|
|
144
142
|
accounts_qs = AccountModel.objects.for_entity(
|
|
145
|
-
entity_model=self.ENTITY_SLUG
|
|
146
|
-
user_model=self.USER_MODEL
|
|
143
|
+
entity_model=self.ENTITY_SLUG
|
|
147
144
|
).with_roles(
|
|
148
145
|
roles=self.SERVICE_ROLES,
|
|
149
146
|
).active()
|
|
@@ -156,8 +153,7 @@ class ServiceCreateForm(ModelForm):
|
|
|
156
153
|
|
|
157
154
|
if 'uom' in self.fields:
|
|
158
155
|
uom_qs = UnitOfMeasureModel.objects.for_entity_active(
|
|
159
|
-
|
|
160
|
-
user_model=self.USER_MODEL
|
|
156
|
+
entity_model=self.ENTITY_SLUG,
|
|
161
157
|
)
|
|
162
158
|
self.fields['uom'].queryset = uom_qs
|
|
163
159
|
|
|
@@ -229,8 +225,7 @@ class ExpenseItemCreateForm(ModelForm):
|
|
|
229
225
|
super().__init__(*args, **kwargs)
|
|
230
226
|
|
|
231
227
|
accounts_qs = AccountModel.objects.for_entity(
|
|
232
|
-
entity_model=self.ENTITY_SLUG
|
|
233
|
-
user_model=self.USER_MODEL
|
|
228
|
+
entity_model=self.ENTITY_SLUG
|
|
234
229
|
).with_roles(
|
|
235
230
|
roles=GROUP_EXPENSES
|
|
236
231
|
).active()
|
|
@@ -239,9 +234,8 @@ class ExpenseItemCreateForm(ModelForm):
|
|
|
239
234
|
|
|
240
235
|
if 'uom' in self.fields:
|
|
241
236
|
uom_qs = UnitOfMeasureModel.objects.for_entity(
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
)
|
|
237
|
+
entity_model=self.ENTITY_SLUG
|
|
238
|
+
).for_user(user_model=self.USER_MODEL)
|
|
245
239
|
self.fields['uom'].queryset = uom_qs
|
|
246
240
|
|
|
247
241
|
class Meta:
|
|
@@ -313,18 +307,16 @@ class InventoryItemCreateForm(ModelForm):
|
|
|
313
307
|
self.USER_MODEL = user_model
|
|
314
308
|
super().__init__(*args, **kwargs)
|
|
315
309
|
|
|
316
|
-
|
|
310
|
+
inventory_account_qs = AccountModel.objects.for_entity(
|
|
317
311
|
entity_model=self.ENTITY_SLUG,
|
|
318
|
-
user_model=self.USER_MODEL
|
|
319
312
|
).with_roles(
|
|
320
313
|
roles=[ASSET_CA_INVENTORY]
|
|
321
314
|
).active()
|
|
322
|
-
self.fields['inventory_account'].queryset =
|
|
315
|
+
self.fields['inventory_account'].queryset = inventory_account_qs
|
|
323
316
|
|
|
324
317
|
if 'uom' in self.fields:
|
|
325
318
|
uom_qs = UnitOfMeasureModel.objects.for_entity_active(
|
|
326
|
-
|
|
327
|
-
user_model=self.USER_MODEL
|
|
319
|
+
entity_model=self.ENTITY_SLUG,
|
|
328
320
|
)
|
|
329
321
|
self.fields['uom'].queryset = uom_qs
|
|
330
322
|
|
|
@@ -155,13 +155,11 @@ class BasePurchaseOrderItemFormset(BaseModelFormSet):
|
|
|
155
155
|
self.PO_MODEL = po_model
|
|
156
156
|
|
|
157
157
|
items_qs = ItemModel.objects.for_po(
|
|
158
|
-
|
|
159
|
-
user_model=self.USER_MODEL
|
|
158
|
+
entity_model=self.ENTITY_SLUG,
|
|
160
159
|
)
|
|
161
160
|
|
|
162
161
|
unit_qs = EntityUnitModel.objects.for_entity(
|
|
163
|
-
|
|
164
|
-
user_model=self.USER_MODEL
|
|
162
|
+
entity_model=self.ENTITY_SLUG
|
|
165
163
|
)
|
|
166
164
|
|
|
167
165
|
for form in self.forms:
|
django_ledger/io/io_core.py
CHANGED
|
@@ -120,7 +120,6 @@ from django_ledger.io.io_middleware import (
|
|
|
120
120
|
)
|
|
121
121
|
from django_ledger.io.ratios import FinancialRatioManager
|
|
122
122
|
from django_ledger.models.utils import lazy_loader
|
|
123
|
-
from django_ledger.settings import DJANGO_LEDGER_PDF_SUPPORT_ENABLED
|
|
124
123
|
|
|
125
124
|
UserModel = get_user_model()
|
|
126
125
|
|
|
@@ -224,18 +223,29 @@ def check_tx_balance(tx_data: list, perform_correction: bool = False) -> bool:
|
|
|
224
223
|
|
|
225
224
|
while not is_valid:
|
|
226
225
|
tx_type_choice = choice([DEBIT, CREDIT])
|
|
227
|
-
|
|
226
|
+
|
|
227
|
+
if IS_TX_MODEL:
|
|
228
|
+
txs_candidates = list(tx for tx in tx_data if tx.tx_type == tx_type_choice)
|
|
229
|
+
else:
|
|
230
|
+
txs_candidates = list(tx for tx in tx_data if tx['tx_type'] == tx_type_choice)
|
|
231
|
+
|
|
228
232
|
if len(txs_candidates) > 0:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
233
|
+
|
|
234
|
+
tx = choice(txs_candidates)
|
|
235
|
+
|
|
236
|
+
if any([
|
|
237
|
+
diff > 0 and tx_type_choice == DEBIT,
|
|
238
|
+
diff < 0 and tx_type_choice == CREDIT
|
|
239
|
+
]):
|
|
232
240
|
if IS_TX_MODEL:
|
|
233
241
|
tx.amount += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
|
|
234
242
|
else:
|
|
235
243
|
tx['amount'] += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
|
|
236
244
|
|
|
237
|
-
elif any([
|
|
238
|
-
|
|
245
|
+
elif any([
|
|
246
|
+
diff < 0 and tx_type_choice == DEBIT,
|
|
247
|
+
diff > 0 and tx_type_choice == CREDIT
|
|
248
|
+
]):
|
|
239
249
|
if IS_TX_MODEL:
|
|
240
250
|
tx.amount -= settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
|
|
241
251
|
else:
|
|
@@ -719,14 +729,12 @@ class IODatabaseMixIn:
|
|
|
719
729
|
if unit_slug:
|
|
720
730
|
|
|
721
731
|
txs_queryset_init = TransactionModel.objects.for_entity(
|
|
722
|
-
|
|
723
|
-
entity_slug=entity_slug or self.slug
|
|
732
|
+
entity_model=entity_slug or self.slug
|
|
724
733
|
).for_unit(unit_slug=unit_slug)
|
|
725
734
|
|
|
726
735
|
else:
|
|
727
736
|
txs_queryset_init = TransactionModel.objects.for_entity(
|
|
728
|
-
|
|
729
|
-
entity_slug=self
|
|
737
|
+
entity_model=self
|
|
730
738
|
)
|
|
731
739
|
elif self.is_entity_unit_model():
|
|
732
740
|
if not entity_slug:
|
|
@@ -734,8 +742,7 @@ class IODatabaseMixIn:
|
|
|
734
742
|
'Calling digest from Entity Unit requires entity_slug explicitly for safety')
|
|
735
743
|
|
|
736
744
|
txs_queryset_init = TransactionModel.objects.for_entity(
|
|
737
|
-
|
|
738
|
-
entity_slug=entity_slug,
|
|
745
|
+
entity_model=entity_slug
|
|
739
746
|
).for_unit(unit_slug=unit_slug or self)
|
|
740
747
|
|
|
741
748
|
elif self.is_ledger_model():
|
|
@@ -744,8 +751,7 @@ class IODatabaseMixIn:
|
|
|
744
751
|
'Calling digest from Ledger Model requires entity_slug explicitly for safety')
|
|
745
752
|
|
|
746
753
|
txs_queryset_init = TransactionModel.objects.for_entity(
|
|
747
|
-
|
|
748
|
-
user_model=user_model,
|
|
754
|
+
entity_model=entity_slug
|
|
749
755
|
).for_ledger(ledger_model=self)
|
|
750
756
|
|
|
751
757
|
else:
|
|
@@ -889,6 +895,10 @@ class IODatabaseMixIn:
|
|
|
889
895
|
'tx_type',
|
|
890
896
|
]
|
|
891
897
|
|
|
898
|
+
if kwargs.get('for_test'):
|
|
899
|
+
VALUES.append('journal_entry__ledger_id')
|
|
900
|
+
VALUES.append('journal_entry__ledger__entity_id')
|
|
901
|
+
|
|
892
902
|
ANNOTATE = {'balance': Sum('amount')}
|
|
893
903
|
if io_result.is_bounded:
|
|
894
904
|
ANNOTATE = {'balance': Sum('amount_io')}
|
|
@@ -1587,10 +1597,6 @@ class IOReportMixIn:
|
|
|
1587
1597
|
memory or in saved PDF format. If the `save_pdf` option is enabled, the PDF
|
|
1588
1598
|
report is saved at the specified location.
|
|
1589
1599
|
"""
|
|
1590
|
-
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
1591
|
-
raise IOValidationError(
|
|
1592
|
-
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
1593
|
-
)
|
|
1594
1600
|
|
|
1595
1601
|
io_digest = self.digest_balance_sheet(
|
|
1596
1602
|
to_date=to_date,
|
|
@@ -1716,10 +1722,6 @@ class IOReportMixIn:
|
|
|
1716
1722
|
generated income statement report. If `save_pdf` is True, the report will also
|
|
1717
1723
|
be saved as a PDF file at the specified location.
|
|
1718
1724
|
"""
|
|
1719
|
-
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
1720
|
-
raise IOValidationError(
|
|
1721
|
-
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
1722
|
-
)
|
|
1723
1725
|
|
|
1724
1726
|
io_digest = self.digest_income_statement(
|
|
1725
1727
|
from_date=from_date,
|
|
@@ -1833,10 +1835,6 @@ class IOReportMixIn:
|
|
|
1833
1835
|
IOValidationError
|
|
1834
1836
|
If PDF support is not enabled in the system's Django ledger configuration.
|
|
1835
1837
|
"""
|
|
1836
|
-
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
1837
|
-
raise IOValidationError(
|
|
1838
|
-
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
1839
|
-
)
|
|
1840
1838
|
|
|
1841
1839
|
io_digest = self.digest_cash_flow_statement(
|
|
1842
1840
|
from_date=from_date,
|
|
@@ -1957,11 +1955,6 @@ class IOReportMixIn:
|
|
|
1957
1955
|
IOValidationError
|
|
1958
1956
|
Raised if PDF support is not enabled in the application configuration.
|
|
1959
1957
|
"""
|
|
1960
|
-
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
1961
|
-
raise IOValidationError(
|
|
1962
|
-
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
1963
|
-
)
|
|
1964
|
-
|
|
1965
1958
|
io_digest = self.digest_financial_statements(
|
|
1966
1959
|
from_date=from_date,
|
|
1967
1960
|
to_date=to_date,
|
django_ledger/io/io_generator.py
CHANGED
|
@@ -138,8 +138,7 @@ class EntityDataGenerator(LoggingMixIn):
|
|
|
138
138
|
|
|
139
139
|
self.logger.info('Checking for existing transactions...')
|
|
140
140
|
txs_qs = TransactionModel.objects.for_entity(
|
|
141
|
-
|
|
142
|
-
user_model=self.user_model
|
|
141
|
+
entity_model=self.entity_model
|
|
143
142
|
)
|
|
144
143
|
|
|
145
144
|
if txs_qs.count() > 0 and not force_populate:
|
|
@@ -546,10 +545,12 @@ class EntityDataGenerator(LoggingMixIn):
|
|
|
546
545
|
|
|
547
546
|
if random() > 0.50:
|
|
548
547
|
date_approved = self.get_next_timestamp(date_in_review)
|
|
549
|
-
bill_model.mark_as_approved(
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
548
|
+
bill_model.mark_as_approved(
|
|
549
|
+
commit=True,
|
|
550
|
+
entity_slug=self.entity_model.slug,
|
|
551
|
+
user_model=self.user_model,
|
|
552
|
+
date_approved=date_approved
|
|
553
|
+
)
|
|
553
554
|
|
|
554
555
|
if random() > 0.25:
|
|
555
556
|
paid_date = self.get_next_timestamp(date_approved)
|
django_ledger/io/io_library.py
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Generated by Django 5.2.1 on 2025-08-26 12:40
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('django_ledger', '0023_customermodel_customer_code_customermodel_picture_and_more'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name='billmodel',
|
|
16
|
+
name='entity_model',
|
|
17
|
+
field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='django_ledger.entitymodel'),
|
|
18
|
+
),
|
|
19
|
+
migrations.AddField(
|
|
20
|
+
model_name='invoicemodel',
|
|
21
|
+
name='entity_model',
|
|
22
|
+
field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='django_ledger.entitymodel'),
|
|
23
|
+
),
|
|
24
|
+
]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-08 21:32
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
dependencies = [
|
|
9
|
+
('django_ledger', '0024_billmodel_entity_model_invoicemodel_entity_model'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name='billmodel',
|
|
15
|
+
name='cash_account',
|
|
16
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT,
|
|
17
|
+
related_name='bill_cash_account', to='django_ledger.accountmodel',
|
|
18
|
+
verbose_name='Cash Account'),
|
|
19
|
+
),
|
|
20
|
+
migrations.AlterField(
|
|
21
|
+
model_name='billmodel',
|
|
22
|
+
name='prepaid_account',
|
|
23
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT,
|
|
24
|
+
related_name='bill_prepaid_account', to='django_ledger.accountmodel',
|
|
25
|
+
verbose_name='Prepaid Account'),
|
|
26
|
+
),
|
|
27
|
+
migrations.AlterField(
|
|
28
|
+
model_name='billmodel',
|
|
29
|
+
name='unearned_account',
|
|
30
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT,
|
|
31
|
+
related_name='bill_unearned_account', to='django_ledger.accountmodel',
|
|
32
|
+
verbose_name='Unearned Account'),
|
|
33
|
+
),
|
|
34
|
+
migrations.AlterField(
|
|
35
|
+
model_name='customermodel',
|
|
36
|
+
name='address_1',
|
|
37
|
+
field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Address Line 1'),
|
|
38
|
+
),
|
|
39
|
+
migrations.AlterField(
|
|
40
|
+
model_name='entitymodel',
|
|
41
|
+
name='address_1',
|
|
42
|
+
field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Address Line 1'),
|
|
43
|
+
),
|
|
44
|
+
migrations.AlterField(
|
|
45
|
+
model_name='invoicemodel',
|
|
46
|
+
name='cash_account',
|
|
47
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT,
|
|
48
|
+
related_name='invoice_cash_account', to='django_ledger.accountmodel',
|
|
49
|
+
verbose_name='Cash Account'),
|
|
50
|
+
),
|
|
51
|
+
migrations.AlterField(
|
|
52
|
+
model_name='invoicemodel',
|
|
53
|
+
name='prepaid_account',
|
|
54
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT,
|
|
55
|
+
related_name='invoice_prepaid_account', to='django_ledger.accountmodel',
|
|
56
|
+
verbose_name='Prepaid Account'),
|
|
57
|
+
),
|
|
58
|
+
migrations.AlterField(
|
|
59
|
+
model_name='invoicemodel',
|
|
60
|
+
name='unearned_account',
|
|
61
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT,
|
|
62
|
+
related_name='invoice_unearned_account', to='django_ledger.accountmodel',
|
|
63
|
+
verbose_name='Unearned Account'),
|
|
64
|
+
),
|
|
65
|
+
migrations.AlterField(
|
|
66
|
+
model_name='vendormodel',
|
|
67
|
+
name='address_1',
|
|
68
|
+
field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Address Line 1'),
|
|
69
|
+
),
|
|
70
|
+
]
|