django-ledger 0.7.4.1__py3-none-any.whl → 0.7.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of django-ledger might be problematic. Click here for more details.
- django_ledger/__init__.py +1 -1
- django_ledger/contrib/django_ledger_graphene/bank_account/schema.py +1 -1
- django_ledger/forms/bank_account.py +16 -12
- django_ledger/forms/data_import.py +70 -33
- django_ledger/io/io_core.py +945 -127
- django_ledger/io/io_generator.py +7 -3
- django_ledger/io/ofx.py +37 -16
- django_ledger/migrations/0020_remove_bankaccountmodel_django_ledg_cash_ac_59a8af_idx_and_more.py +44 -0
- django_ledger/migrations/0021_alter_bankaccountmodel_account_model_and_more.py +33 -0
- django_ledger/models/bank_account.py +14 -11
- django_ledger/models/customer.py +3 -13
- django_ledger/models/data_import.py +690 -35
- django_ledger/models/entity.py +39 -24
- django_ledger/models/journal_entry.py +18 -8
- django_ledger/models/mixins.py +17 -3
- django_ledger/models/vendor.py +2 -2
- django_ledger/settings.py +18 -22
- django_ledger/templates/django_ledger/bank_account/tags/bank_accounts_table.html +2 -2
- django_ledger/templates/django_ledger/data_import/data_import_job_txs.html +1 -1
- django_ledger/templates/django_ledger/data_import/import_job_create.html +11 -2
- django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html +1 -1
- django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html +5 -2
- django_ledger/templatetags/django_ledger.py +6 -7
- django_ledger/views/bank_account.py +1 -1
- django_ledger/views/data_import.py +60 -134
- {django_ledger-0.7.4.1.dist-info → django_ledger-0.7.5.dist-info}/METADATA +17 -17
- {django_ledger-0.7.4.1.dist-info → django_ledger-0.7.5.dist-info}/RECORD +31 -29
- {django_ledger-0.7.4.1.dist-info → django_ledger-0.7.5.dist-info}/WHEEL +1 -1
- {django_ledger-0.7.4.1.dist-info → django_ledger-0.7.5.dist-info}/top_level.txt +1 -0
- {django_ledger-0.7.4.1.dist-info → django_ledger-0.7.5.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.7.4.1.dist-info → django_ledger-0.7.5.dist-info}/LICENSE +0 -0
django_ledger/io/io_core.py
CHANGED
|
@@ -2,17 +2,90 @@
|
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
This module serves as a core component of the Django Ledger framework, providing an optimized interface and
|
|
6
|
+
utilities for handling financial transactions, journal entries, and generating financial statements.
|
|
7
|
+
It is designed to allow efficient interaction with the database, minimizing Python's memory usage by emphasizing
|
|
8
|
+
database-level aggregations while enforcing proper accounting principles.
|
|
9
|
+
|
|
10
|
+
Key Features:
|
|
11
|
+
-------------
|
|
12
|
+
1. **Transaction and Journal Management**:
|
|
13
|
+
- Provides capabilities for creating, validating, and balancing transactions at the database level.
|
|
14
|
+
- Supports integration of Closing Entries as optimizations for financial data aggregation.
|
|
15
|
+
|
|
16
|
+
2. **Validation Utilities**:
|
|
17
|
+
- Validates transaction balances, timestamps, and input data for minimal errors.
|
|
18
|
+
- Ensures consistency with Django Ledger configurations, such as handling timezone-awareness and closing dates.
|
|
19
|
+
|
|
20
|
+
3. **Database Interaction**:
|
|
21
|
+
- Aggregation and querying of financial data at the database layer to improve memory efficiency.
|
|
22
|
+
- Implements advanced filtering options for transactions based on attributes like activity, account roles, business units, and time periods.
|
|
23
|
+
- Leverages Closing Entries as "checkpoints" to minimize aggregation workload on large datasets.
|
|
24
|
+
|
|
25
|
+
4. **Financial Statement Reports**:
|
|
26
|
+
- Offers functionalities to generate financial statements, including:
|
|
27
|
+
- Balance Sheet
|
|
28
|
+
- Income Statement
|
|
29
|
+
- Cash Flow Statement
|
|
30
|
+
- Supports PDF generation for these reports (if PDF support is enabled).
|
|
31
|
+
|
|
32
|
+
5. **Extensibility**:
|
|
33
|
+
- Implements a layered architecture with reusable mixins (`IODatabaseMixIn`, `IOReportMixIn`, `IOMixIn`) that allow developers to customize behavior for specific use cases or extend functionality when needed.
|
|
34
|
+
|
|
35
|
+
6. **Middleware and Ratios**:
|
|
36
|
+
- Includes middleware support for handling roles, financial groups, and ratios as additional processing layers for generated reports.
|
|
37
|
+
|
|
38
|
+
Classes:
|
|
39
|
+
--------
|
|
40
|
+
- `IOResult`:
|
|
41
|
+
A data carrier class for managing aggregated transaction and account balance data during digest operations.
|
|
42
|
+
|
|
43
|
+
- `IODatabaseMixIn`:
|
|
44
|
+
Handles database interactions for aggregating transaction data efficiently and applying accounting rules.
|
|
45
|
+
|
|
46
|
+
- `IOReportMixIn`:
|
|
47
|
+
Offers methods for generating financial reports, including support for PDF output (if enabled).
|
|
48
|
+
|
|
49
|
+
- `IOMixIn`:
|
|
50
|
+
Combines database operations and reporting features into a single reusable mixin for comprehensive I/O management.
|
|
51
|
+
|
|
52
|
+
Functions:
|
|
53
|
+
----------
|
|
54
|
+
- **Utility Functions**:
|
|
55
|
+
- `diff_tx_data()`: Validates whether the credits and debits for a given transaction dataset are balanced.
|
|
56
|
+
- `check_tx_balance()`: Ensures transaction datasets are corrected to be balanced if requested.
|
|
57
|
+
- `validate_io_timestamp()`: Ensures that input dates or timestamps are valid and timezone-aware.
|
|
58
|
+
- `get_localtime()`, `get_localdate()`: Retrieve local time or local date based on Django's timezone settings.
|
|
59
|
+
- `validate_dates()`: Validates and parses `from_date` and `to_date` inputs.
|
|
60
|
+
|
|
61
|
+
- **Digest Operations**:
|
|
62
|
+
- `database_digest()`: Processes and aggregates transactions directly in the database with support for filters such as activity, role, and period.
|
|
63
|
+
- `python_digest()`: Applies additional processing and group-by operations on transaction data after database-level aggregation.
|
|
64
|
+
- `digest()`: A unified entry point for performing database digests and Python-level post-processing, with options to process roles, groups, ratios, and financial statements.
|
|
65
|
+
|
|
66
|
+
- **Report Data Generation**:
|
|
67
|
+
- `get_balance_sheet_statement()`, `get_income_statement()`, `get_cash_flow_statement()`: Generate specific financial statements, with optional PDF output.
|
|
68
|
+
- `get_financial_statements()`: Generate all key financial statements together (Balance Sheet, Income Statement, Cash Flow Statement).
|
|
69
|
+
|
|
70
|
+
Error Handling:
|
|
71
|
+
---------------
|
|
72
|
+
- **Custom Exceptions**:
|
|
73
|
+
- `IOValidationError`: Raised for input validation errors during transaction or journal entry processing.
|
|
74
|
+
|
|
75
|
+
Supported Features:
|
|
76
|
+
-------------------
|
|
77
|
+
- Database-level transaction aggregation for performance optimization.
|
|
78
|
+
- Timezone-aware operations for timestamp handling.
|
|
79
|
+
- Modular architecture leveraging mixins for different components.
|
|
80
|
+
- Middleware for advanced role processing and financial grouping.
|
|
81
|
+
- Optional PDF generation using settings from Django Ledger.
|
|
82
|
+
|
|
83
|
+
Notes:
|
|
84
|
+
------
|
|
85
|
+
- Ensure `DJANGO_LEDGER_PDF_SUPPORT_ENABLED` is properly configured to enable PDF output in financial reports.
|
|
86
|
+
- Closing Entries play a critical role in improving aggregation times for entities with significant transactions.
|
|
87
|
+
- The module is designed to work seamlessly with Django's ORM and custom models through utilities provided in
|
|
88
|
+
the Django Ledger framework.
|
|
16
89
|
"""
|
|
17
90
|
from collections import namedtuple
|
|
18
91
|
from dataclasses import dataclass
|
|
@@ -35,7 +108,7 @@ from django.utils.translation import gettext_lazy as _
|
|
|
35
108
|
|
|
36
109
|
from django_ledger import settings
|
|
37
110
|
from django_ledger.exceptions import InvalidDateInputError, TransactionNotInBalanceError
|
|
38
|
-
from django_ledger.io import roles as roles_module
|
|
111
|
+
from django_ledger.io import roles as roles_module, CREDIT, DEBIT
|
|
39
112
|
from django_ledger.io.io_context import IODigestContextManager
|
|
40
113
|
from django_ledger.io.io_middleware import (
|
|
41
114
|
AccountRoleIOMiddleware,
|
|
@@ -53,26 +126,64 @@ UserModel = get_user_model()
|
|
|
53
126
|
|
|
54
127
|
|
|
55
128
|
def diff_tx_data(tx_data: list, raise_exception: bool = True):
|
|
129
|
+
"""
|
|
130
|
+
Calculates the difference between credits and debits in a transaction dataset
|
|
131
|
+
and validates if the transactions are in balance. Supports both dictionary-like
|
|
132
|
+
data and `TransactionModel` objects.
|
|
133
|
+
|
|
134
|
+
The function checks whether the provided transaction data is in balance by
|
|
135
|
+
comparing the sum of credits and debits. If they are not in balance, the function
|
|
136
|
+
optionally raises an exception when the discrepancy exceeds the defined tolerance
|
|
137
|
+
limit. It also indicates whether the transaction data is modeled using
|
|
138
|
+
`TransactionModel`.
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
tx_data : list
|
|
143
|
+
A list of transactions, which can either be dictionaries or instances
|
|
144
|
+
of `TransactionModel`. Each transaction must have an `amount` field and
|
|
145
|
+
a `tx_type` field. The `tx_type` should be either 'credit' or 'debit'.
|
|
146
|
+
raise_exception : bool, optional
|
|
147
|
+
Whether to raise an exception if the transactions are not balanced and
|
|
148
|
+
the difference exceeds the defined tolerance value. Defaults to True.
|
|
149
|
+
|
|
150
|
+
Returns
|
|
151
|
+
-------
|
|
152
|
+
tuple
|
|
153
|
+
A tuple containing the following:
|
|
154
|
+
1. `IS_TX_MODEL` (bool): Indicates whether the transaction data uses the `TransactionModel`.
|
|
155
|
+
2. `is_valid` (bool): Indicates whether the total credits match the total debits within the defined tolerance.
|
|
156
|
+
3. `diff` (float): The difference between the sum of credits and the sum of debits.
|
|
157
|
+
|
|
158
|
+
Raises
|
|
159
|
+
------
|
|
160
|
+
ValidationError
|
|
161
|
+
If the `tx_data` is neither a list of dictionaries nor a list of
|
|
162
|
+
`TransactionModel` instances.
|
|
163
|
+
TransactionNotInBalanceError
|
|
164
|
+
If the transactions are not in balance (when `is_valid` is False), the
|
|
165
|
+
difference exceeds the maximum tolerance, and `raise_exception` is True.
|
|
166
|
+
"""
|
|
56
167
|
IS_TX_MODEL = False
|
|
57
168
|
TransactionModel = lazy_loader.get_txs_model()
|
|
58
169
|
|
|
59
170
|
if isinstance(tx_data[0], TransactionModel):
|
|
60
|
-
|
|
61
|
-
|
|
171
|
+
credits = sum(tx.amount for tx in tx_data if tx.tx_type == CREDIT)
|
|
172
|
+
debits = sum(tx.amount for tx in tx_data if tx.tx_type == DEBIT)
|
|
62
173
|
IS_TX_MODEL = True
|
|
63
174
|
elif isinstance(tx_data[0], dict):
|
|
64
|
-
|
|
65
|
-
|
|
175
|
+
credits = sum(tx['amount'] for tx in tx_data if tx['tx_type'] == CREDIT)
|
|
176
|
+
debits = sum(tx['amount'] for tx in tx_data if tx['tx_type'] == DEBIT)
|
|
66
177
|
else:
|
|
67
178
|
raise ValidationError('Only Dictionary or TransactionModel allowed.')
|
|
68
179
|
|
|
69
|
-
is_valid = (
|
|
70
|
-
diff =
|
|
180
|
+
is_valid = (credits == debits)
|
|
181
|
+
diff = credits - debits
|
|
71
182
|
|
|
72
183
|
if not is_valid and abs(diff) > settings.DJANGO_LEDGER_TRANSACTION_MAX_TOLERANCE:
|
|
73
184
|
if raise_exception:
|
|
74
185
|
raise TransactionNotInBalanceError(
|
|
75
|
-
f'Invalid tx data. Credits and debits must match. Currently cr: {
|
|
186
|
+
f'Invalid tx data. Credits and debits must match. Currently cr: {credits}, db {debits}.'
|
|
76
187
|
f'Max Tolerance {settings.DJANGO_LEDGER_TRANSACTION_MAX_TOLERANCE}'
|
|
77
188
|
)
|
|
78
189
|
|
|
@@ -80,6 +191,27 @@ def diff_tx_data(tx_data: list, raise_exception: bool = True):
|
|
|
80
191
|
|
|
81
192
|
|
|
82
193
|
def check_tx_balance(tx_data: list, perform_correction: bool = False) -> bool:
|
|
194
|
+
"""
|
|
195
|
+
Checks the validity of a list of transactions and optionally corrects the balance
|
|
196
|
+
discrepancy if any. The function assesses whether the total balance from the
|
|
197
|
+
transactions satisfies the predefined tolerance settings. If `perform_correction`
|
|
198
|
+
is enabled, it adjusts the transactions iteratively to correct discrepancies.
|
|
199
|
+
|
|
200
|
+
Parameters
|
|
201
|
+
----------
|
|
202
|
+
tx_data : list
|
|
203
|
+
A list of transaction data where each transaction contains information
|
|
204
|
+
such as amount and type ('debit' or 'credit').
|
|
205
|
+
perform_correction : bool, optional
|
|
206
|
+
A flag indicating whether to attempt to correct balance discrepancies
|
|
207
|
+
in the transaction data. Defaults to False.
|
|
208
|
+
|
|
209
|
+
Returns
|
|
210
|
+
-------
|
|
211
|
+
bool
|
|
212
|
+
Returns True if the transactions are valid and satisfy the balance
|
|
213
|
+
tolerance (with or without correction). Returns False otherwise.
|
|
214
|
+
"""
|
|
83
215
|
if tx_data:
|
|
84
216
|
|
|
85
217
|
IS_TX_MODEL, is_valid, diff = diff_tx_data(tx_data, raise_exception=perform_correction)
|
|
@@ -91,19 +223,19 @@ def check_tx_balance(tx_data: list, perform_correction: bool = False) -> bool:
|
|
|
91
223
|
return False
|
|
92
224
|
|
|
93
225
|
while not is_valid:
|
|
94
|
-
tx_type_choice = choice([
|
|
226
|
+
tx_type_choice = choice([DEBIT, CREDIT])
|
|
95
227
|
txs_candidates = list(tx for tx in tx_data if tx['tx_type'] == tx_type_choice)
|
|
96
228
|
if len(txs_candidates) > 0:
|
|
97
229
|
tx = choice(list(tx for tx in tx_data if tx['tx_type'] == tx_type_choice))
|
|
98
|
-
if any([diff > 0 and tx_type_choice ==
|
|
99
|
-
diff < 0 and tx_type_choice ==
|
|
230
|
+
if any([diff > 0 and tx_type_choice == DEBIT,
|
|
231
|
+
diff < 0 and tx_type_choice == CREDIT]):
|
|
100
232
|
if IS_TX_MODEL:
|
|
101
233
|
tx.amount += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
|
|
102
234
|
else:
|
|
103
235
|
tx['amount'] += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
|
|
104
236
|
|
|
105
|
-
elif any([diff < 0 and tx_type_choice ==
|
|
106
|
-
diff > 0 and tx_type_choice ==
|
|
237
|
+
elif any([diff < 0 and tx_type_choice == DEBIT,
|
|
238
|
+
diff > 0 and tx_type_choice == CREDIT]):
|
|
107
239
|
if IS_TX_MODEL:
|
|
108
240
|
tx.amount -= settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
|
|
109
241
|
else:
|
|
@@ -116,16 +248,24 @@ def check_tx_balance(tx_data: list, perform_correction: bool = False) -> bool:
|
|
|
116
248
|
|
|
117
249
|
def get_localtime(tz=None) -> datetime:
|
|
118
250
|
"""
|
|
119
|
-
|
|
251
|
+
Retrieve the local time based on the specified timezone.
|
|
252
|
+
|
|
253
|
+
Determines the local time depending on whether timezone support (``USE_TZ``) is
|
|
254
|
+
enabled in global settings. If timezone support is enabled, it uses the
|
|
255
|
+
`localtime` function to obtain the local time according to the provided
|
|
256
|
+
timezone. If timezone support is disabled, it defaults to the current time
|
|
257
|
+
with respect to the given timezone.
|
|
120
258
|
|
|
121
259
|
Parameters
|
|
122
260
|
----------
|
|
123
|
-
tz:
|
|
124
|
-
|
|
261
|
+
tz : timezone or None, optional
|
|
262
|
+
The timezone to determine the local time. If `None`, defaults to the system
|
|
263
|
+
timezone.
|
|
125
264
|
|
|
126
265
|
Returns
|
|
127
266
|
-------
|
|
128
267
|
datetime
|
|
268
|
+
A datetime object representing the calculated local time.
|
|
129
269
|
"""
|
|
130
270
|
if global_settings.USE_TZ:
|
|
131
271
|
return localtime(timezone=tz)
|
|
@@ -134,11 +274,17 @@ def get_localtime(tz=None) -> datetime:
|
|
|
134
274
|
|
|
135
275
|
def get_localdate() -> date:
|
|
136
276
|
"""
|
|
137
|
-
|
|
277
|
+
Fetches the current local date, optionally considering time zone settings.
|
|
138
278
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
279
|
+
This function retrieves the current local date. If the global settings indicate
|
|
280
|
+
the use of time zones (`USE_TZ` is True), the date is determined based on the
|
|
281
|
+
local time zone. Otherwise, the date is based on the system's local time without
|
|
282
|
+
any time zone consideration.
|
|
283
|
+
|
|
284
|
+
Returns
|
|
285
|
+
-------
|
|
286
|
+
date
|
|
287
|
+
The current local date, adjusted for the time zone setting if applicable.
|
|
142
288
|
"""
|
|
143
289
|
if global_settings.USE_TZ:
|
|
144
290
|
return localdate()
|
|
@@ -149,6 +295,46 @@ def validate_io_timestamp(
|
|
|
149
295
|
dt: Union[str, date, datetime],
|
|
150
296
|
no_parse_localdate: bool = True
|
|
151
297
|
) -> Optional[Union[datetime, date]]:
|
|
298
|
+
"""
|
|
299
|
+
Validates and processes a given date or datetime input and returns a processed
|
|
300
|
+
datetime or date object depending on the parsing and processing results. This
|
|
301
|
+
function is designed to handle multiple types of inputs including strings,
|
|
302
|
+
date objects, and datetime objects, while accounting for timezone awareness
|
|
303
|
+
and other scenarios where inputs may be invalid or improperly formed.
|
|
304
|
+
|
|
305
|
+
Parameters
|
|
306
|
+
----------
|
|
307
|
+
dt : Union[str, date, datetime]
|
|
308
|
+
The input value to be validated and processed. This can be a string
|
|
309
|
+
representing a date or datetime, a `date` object, or a `datetime` object.
|
|
310
|
+
If the input is invalid or cannot be parsed, an error will be raised.
|
|
311
|
+
no_parse_localdate : bool, optional
|
|
312
|
+
A flag to indicate if the local date should be returned directly when the
|
|
313
|
+
input cannot be parsed or is unavailable. Defaults to True.
|
|
314
|
+
|
|
315
|
+
Returns
|
|
316
|
+
-------
|
|
317
|
+
Optional[Union[datetime, date]]
|
|
318
|
+
Returns a timezone-aware or naive `datetime` object that was processed
|
|
319
|
+
depending on input and timezone settings. May also return a `date` object
|
|
320
|
+
in specific scenarios. Returns `None` if the input is empty or invalid.
|
|
321
|
+
|
|
322
|
+
Raises
|
|
323
|
+
------
|
|
324
|
+
InvalidDateInputError
|
|
325
|
+
Raised when the provided string cannot be parsed into a valid `date` or
|
|
326
|
+
`datetime` object.
|
|
327
|
+
|
|
328
|
+
Notes
|
|
329
|
+
-----
|
|
330
|
+
- The function handles both timezone-aware and naive datetime objects, and
|
|
331
|
+
attempts to make objects timezone-aware when global time zone settings
|
|
332
|
+
are enabled.
|
|
333
|
+
- String inputs are first attempted to be parsed into `date` objects before
|
|
334
|
+
attempting to parse them into `datetime` objects if the initial attempt fails.
|
|
335
|
+
- When `no_parse_localdate` is True, the function defaults to returning the
|
|
336
|
+
local time for cases where parsing is not possible.
|
|
337
|
+
"""
|
|
152
338
|
if not dt:
|
|
153
339
|
return
|
|
154
340
|
|
|
@@ -191,15 +377,69 @@ def validate_io_timestamp(
|
|
|
191
377
|
|
|
192
378
|
|
|
193
379
|
def validate_dates(
|
|
194
|
-
from_date: Union[str, datetime, date] = None,
|
|
195
|
-
to_date: Union[str, datetime, date] = None
|
|
380
|
+
from_date: Optional[Union[str, datetime, date]] = None,
|
|
381
|
+
to_date: Optional[Union[str, datetime, date]] = None
|
|
196
382
|
) -> Tuple[date, date]:
|
|
383
|
+
"""
|
|
384
|
+
Validates and converts the input dates to date objects. This function ensures that the
|
|
385
|
+
provided `from_date` and `to_date` are correctly parsed into `date` objects. If the dates
|
|
386
|
+
are given as strings or datetime objects, they will be validated and converted to `date`
|
|
387
|
+
objects accordingly.
|
|
388
|
+
|
|
389
|
+
Parameters
|
|
390
|
+
----------
|
|
391
|
+
from_date : str, datetime, date, optional
|
|
392
|
+
The start date, which can be provided as a string, datetime, or date object.
|
|
393
|
+
If not provided, it may default depending on the implementation of the
|
|
394
|
+
`validate_io_timestamp` function.
|
|
395
|
+
to_date : str, datetime, date, optional
|
|
396
|
+
The end date, which can be provided as a string, datetime, or date object.
|
|
397
|
+
If not provided, it may default depending on the implementation of the
|
|
398
|
+
`validate_io_timestamp` function.
|
|
399
|
+
|
|
400
|
+
Returns
|
|
401
|
+
-------
|
|
402
|
+
Tuple[date, date]
|
|
403
|
+
A tuple containing the validated `from_date` and `to_date` as `date` objects.
|
|
404
|
+
The first element is the validated start date, and the second element is the
|
|
405
|
+
validated end date.
|
|
406
|
+
"""
|
|
197
407
|
from_date = validate_io_timestamp(from_date, no_parse_localdate=False)
|
|
198
408
|
to_date = validate_io_timestamp(to_date)
|
|
199
409
|
return from_date, to_date
|
|
200
410
|
|
|
201
411
|
|
|
202
412
|
def validate_activity(activity: str, raise_404: bool = False):
|
|
413
|
+
"""
|
|
414
|
+
Validates the given activity against the list of valid activities and raises
|
|
415
|
+
appropriate exceptions if it is invalid.
|
|
416
|
+
|
|
417
|
+
This function checks whether the provided activity is included in the list
|
|
418
|
+
of valid activities defined within the JournalEntryModel. It raises a
|
|
419
|
+
ValidationError or Http404 error depending on the value of `raise_404`
|
|
420
|
+
if the activity is not valid. If the activity is valid or not provided,
|
|
421
|
+
it returns the activity unaltered.
|
|
422
|
+
|
|
423
|
+
Parameters
|
|
424
|
+
----------
|
|
425
|
+
activity : str
|
|
426
|
+
The activity string to validate against the valid activities.
|
|
427
|
+
raise_404 : bool, optional
|
|
428
|
+
Whether to raise an Http404 error instead of ValidationError when the
|
|
429
|
+
activity is invalid. Default is False.
|
|
430
|
+
|
|
431
|
+
Returns
|
|
432
|
+
-------
|
|
433
|
+
str
|
|
434
|
+
The activity string if it is valid.
|
|
435
|
+
|
|
436
|
+
Raises
|
|
437
|
+
------
|
|
438
|
+
ValidationError
|
|
439
|
+
If the activity is invalid and `raise_404` is False.
|
|
440
|
+
Http404
|
|
441
|
+
If the activity is invalid and `raise_404` is True.
|
|
442
|
+
"""
|
|
203
443
|
# idea: move to model???...
|
|
204
444
|
JournalEntryModel = lazy_loader.get_journal_entry_model()
|
|
205
445
|
valid = activity in JournalEntryModel.VALID_ACTIVITIES
|
|
@@ -218,7 +458,30 @@ class IOValidationError(ValidationError):
|
|
|
218
458
|
@dataclass
|
|
219
459
|
class IOResult:
|
|
220
460
|
"""
|
|
221
|
-
|
|
461
|
+
Represents the input-output result schema for data aggregation and processing.
|
|
462
|
+
|
|
463
|
+
This class encapsulates details related to database aggregation, closing entry
|
|
464
|
+
lookup parameters, and the final dataset used for evaluation. It also provides
|
|
465
|
+
utility to check bounded date constraints for closing entry lookups.
|
|
466
|
+
|
|
467
|
+
Attributes
|
|
468
|
+
----------
|
|
469
|
+
db_from_date : Optional[date]
|
|
470
|
+
The starting date for database aggregation queries.
|
|
471
|
+
db_to_date : Optional[date]
|
|
472
|
+
The ending date for database aggregation queries.
|
|
473
|
+
ce_match : bool
|
|
474
|
+
Indicates whether closing entry matches are applicable.
|
|
475
|
+
ce_from_date : Optional[date]
|
|
476
|
+
The starting date for closing entry lookups.
|
|
477
|
+
ce_to_date : Optional[date]
|
|
478
|
+
The ending date for closing entry lookups.
|
|
479
|
+
txs_queryset
|
|
480
|
+
The final queryset used for evaluation, typically containing processed
|
|
481
|
+
transaction data.
|
|
482
|
+
accounts_digest : Optional[List[Dict]]
|
|
483
|
+
A summary or aggregation of account balances derived from the processed
|
|
484
|
+
data.
|
|
222
485
|
"""
|
|
223
486
|
# DB Aggregation...
|
|
224
487
|
db_from_date: Optional[date] = None
|
|
@@ -245,46 +508,117 @@ class IOResult:
|
|
|
245
508
|
|
|
246
509
|
class IODatabaseMixIn:
|
|
247
510
|
"""
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
This is
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
511
|
+
Mix-in class for database interactions and aggregation for IO models.
|
|
512
|
+
|
|
513
|
+
This class is designed to encapsulate several common behaviors for models
|
|
514
|
+
related to database queries and aggregations in the context of IO operations
|
|
515
|
+
such as transactions, ledger models, and entity models. It facilitates the
|
|
516
|
+
derivation of specific models, validation of query parameters, and execution
|
|
517
|
+
of data aggregation queries with flexible filtering and grouping options.
|
|
518
|
+
|
|
519
|
+
Attributes
|
|
520
|
+
----------
|
|
521
|
+
TRANSACTION_MODEL_CLASS : NoneType or Type
|
|
522
|
+
Specifies the Django model class for transactions. If None, a lazy loader
|
|
523
|
+
will be used to determine the model dynamically.
|
|
524
|
+
JOURNAL_ENTRY_MODEL_CLASS : NoneType or Type
|
|
525
|
+
Specifies the Django model class for journal entries. If None, a lazy
|
|
526
|
+
loader will be used to determine the model dynamically.
|
|
260
527
|
"""
|
|
261
528
|
|
|
262
529
|
TRANSACTION_MODEL_CLASS = None
|
|
263
530
|
JOURNAL_ENTRY_MODEL_CLASS = None
|
|
264
531
|
|
|
265
532
|
def is_entity_model(self):
|
|
533
|
+
"""
|
|
534
|
+
Check if the instance is an EntityModel.
|
|
535
|
+
|
|
536
|
+
Returns
|
|
537
|
+
-------
|
|
538
|
+
bool
|
|
539
|
+
True if the instance is an entity model, False otherwise.
|
|
540
|
+
"""
|
|
266
541
|
return isinstance(self, lazy_loader.get_entity_model())
|
|
267
542
|
|
|
268
543
|
def is_ledger_model(self):
|
|
544
|
+
"""
|
|
545
|
+
Checks if the current instance is a LedgerModel.
|
|
546
|
+
|
|
547
|
+
Returns
|
|
548
|
+
-------
|
|
549
|
+
bool
|
|
550
|
+
True if the instance is of type ledger model, False otherwise.
|
|
551
|
+
"""
|
|
269
552
|
return isinstance(self, lazy_loader.get_ledger_model())
|
|
270
553
|
|
|
271
554
|
def is_entity_unit_model(self):
|
|
555
|
+
"""
|
|
556
|
+
Checks if the current instance is an EntityUnitModel.
|
|
557
|
+
|
|
558
|
+
Returns
|
|
559
|
+
-------
|
|
560
|
+
bool
|
|
561
|
+
`True` if the object is an instance of the entity unit model;
|
|
562
|
+
`False` otherwise.
|
|
563
|
+
"""
|
|
272
564
|
return isinstance(self, lazy_loader.get_entity_unit_model())
|
|
273
565
|
|
|
274
566
|
def get_entity_model_from_io(self):
|
|
567
|
+
"""
|
|
568
|
+
Retrieves the entity model associated with the current instance.
|
|
569
|
+
|
|
570
|
+
This method determines the type of the current model instance and retrieves
|
|
571
|
+
the corresponding entity model if applicable. If the instance itself is an
|
|
572
|
+
EntityModel, it returns itself. If the instance is a ledgerModel or EntityUnitModel
|
|
573
|
+
model, the associated entity model is retrieved from its attributes.
|
|
574
|
+
|
|
575
|
+
Returns
|
|
576
|
+
-------
|
|
577
|
+
entity : EntityModel
|
|
578
|
+
Retrieves the associated entity model if the instance is a ledger
|
|
579
|
+
or entity unit model.
|
|
580
|
+
"""
|
|
275
581
|
if self.is_entity_model():
|
|
276
582
|
return self
|
|
277
583
|
elif self.is_ledger_model():
|
|
278
|
-
return self
|
|
584
|
+
return getattr(self, 'entity')
|
|
279
585
|
elif self.is_entity_unit_model():
|
|
280
|
-
return self
|
|
586
|
+
return getattr(self, 'entity')
|
|
587
|
+
raise IOValidationError(
|
|
588
|
+
message=_(f'IODatabaseMixIn not compatible with {self.__class__.__name__} model.')
|
|
589
|
+
)
|
|
281
590
|
|
|
282
591
|
def get_transaction_model(self):
|
|
592
|
+
"""
|
|
593
|
+
Retrieve the transaction model class used for handling transactions.
|
|
594
|
+
|
|
595
|
+
The method checks whether a specific transaction model class is explicitly
|
|
596
|
+
set via the `TRANSACTION_MODEL_CLASS` attribute. If set, it returns that
|
|
597
|
+
class as the transaction model. If not set, it falls back to a default
|
|
598
|
+
transaction model obtained from the `lazy_loader.get_txs_model()` method.
|
|
599
|
+
|
|
600
|
+
Returns
|
|
601
|
+
-------
|
|
602
|
+
type
|
|
603
|
+
The transaction model class defined in `TRANSACTION_MODEL_CLASS` or
|
|
604
|
+
the default transaction model provided by `lazy_loader.get_txs_model()`.
|
|
605
|
+
"""
|
|
283
606
|
if self.TRANSACTION_MODEL_CLASS is not None:
|
|
284
607
|
return self.TRANSACTION_MODEL_CLASS
|
|
285
608
|
return lazy_loader.get_txs_model()
|
|
286
609
|
|
|
287
610
|
def get_journal_entry_model(self):
|
|
611
|
+
"""
|
|
612
|
+
Retrieves the class model for journal entries. If the `JOURNAL_ENTRY_MODEL_CLASS`
|
|
613
|
+
attribute is set, it returns its value. Otherwise, it dynamically loads and
|
|
614
|
+
returns the journal entry model using the `lazy_loader`.
|
|
615
|
+
|
|
616
|
+
Returns
|
|
617
|
+
-------
|
|
618
|
+
Type
|
|
619
|
+
The journal entry model class, either explicitly defined in
|
|
620
|
+
`JOURNAL_ENTRY_MODEL_CLASS` or loaded dynamically.
|
|
621
|
+
"""
|
|
288
622
|
if self.JOURNAL_ENTRY_MODEL_CLASS is not None:
|
|
289
623
|
return self.JOURNAL_ENTRY_MODEL_CLASS
|
|
290
624
|
return lazy_loader.get_journal_entry_model()
|
|
@@ -307,47 +641,71 @@ class IODatabaseMixIn:
|
|
|
307
641
|
use_closing_entries: bool = False,
|
|
308
642
|
**kwargs) -> IOResult:
|
|
309
643
|
"""
|
|
310
|
-
|
|
311
|
-
|
|
644
|
+
Aggregates transaction data based on the provided parameters to generate a
|
|
645
|
+
digest of financial entries. This method is designed to work with various
|
|
646
|
+
models (EntityModel, EntityUnitModel, LedgerModel) and processes
|
|
647
|
+
transactions, including handling closing entries to optimize database
|
|
648
|
+
queries. The resulting data can be customized based on specific filters
|
|
649
|
+
or aggregation criteria, such as activity, transaction type, or time periods.
|
|
312
650
|
|
|
313
651
|
Parameters
|
|
314
652
|
----------
|
|
315
|
-
entity_slug: str
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
unit_slug: str
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
user_model: UserModel
|
|
322
|
-
The
|
|
323
|
-
|
|
324
|
-
from_date: date
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
653
|
+
entity_slug : Optional[str]
|
|
654
|
+
The identifier for the entity. Used to filter transactions for a specific
|
|
655
|
+
entity in cases where the model operates at the entity level.
|
|
656
|
+
unit_slug : Optional[str]
|
|
657
|
+
The identifier for the unit. Valid when filtering transactions for a
|
|
658
|
+
specific unit within an entity.
|
|
659
|
+
user_model : Optional[UserModel]
|
|
660
|
+
The user model instance. Represents the user context in which the
|
|
661
|
+
transaction filtering applies.
|
|
662
|
+
from_date : Optional[Union[date, datetime]]
|
|
663
|
+
The starting date for filtering transactions. Aggregates data from
|
|
664
|
+
the given date if specified.
|
|
665
|
+
to_date : Optional[Union[date, datetime]]
|
|
666
|
+
The ending date for filtering transactions. Aggregates data up to this
|
|
667
|
+
date if specified.
|
|
668
|
+
by_activity : bool
|
|
669
|
+
Determines whether results should be aggregated by activity. Defaults
|
|
670
|
+
to False.
|
|
671
|
+
by_tx_type : bool
|
|
672
|
+
Indicates if results should be grouped by transaction type. Defaults
|
|
673
|
+
to False.
|
|
674
|
+
by_period : bool
|
|
675
|
+
Determines if results should be grouped by time period (e.g., months).
|
|
676
|
+
Defaults to False.
|
|
677
|
+
by_unit : bool
|
|
678
|
+
Indicates whether transactions should be grouped by entity unit.
|
|
679
|
+
Defaults to False.
|
|
680
|
+
activity : Optional[str]
|
|
681
|
+
A specific activity identifier to filter results. If provided, only
|
|
682
|
+
transactions related to this activity will be included.
|
|
683
|
+
role : Optional[str]
|
|
684
|
+
A specific role to filter transactions by. Transactions matching this
|
|
685
|
+
role will be included in the aggregation.
|
|
686
|
+
accounts : Optional[Union[str, List[str], Set[str]]]
|
|
687
|
+
Specifies accounts to filter by. Can be a single account or a list/set
|
|
688
|
+
of accounts. Filters transactions associated with the provided accounts.
|
|
689
|
+
posted : bool
|
|
690
|
+
Indicates whether to filter transactions that are posted (committed).
|
|
691
|
+
Defaults to True.
|
|
692
|
+
exclude_zero_bal : bool
|
|
693
|
+
If True, transactions with zero-balance amounts will be excluded.
|
|
694
|
+
Defaults to True.
|
|
695
|
+
use_closing_entries : bool
|
|
696
|
+
Specifies whether closing entries should be used to optimize database
|
|
697
|
+
aggregation. If not provided, the value is determined by the system-global
|
|
698
|
+
setting.
|
|
699
|
+
kwargs : dict
|
|
700
|
+
Additional parameters that can be passed for extended flexibility or
|
|
701
|
+
customization when filtering and processing transactions.
|
|
702
|
+
|
|
348
703
|
Returns
|
|
349
704
|
-------
|
|
350
705
|
IOResult
|
|
706
|
+
An object containing the aggregated results, filtered transaction querysets,
|
|
707
|
+
and metadata such as database query bounds or details about closing
|
|
708
|
+
entry matches.
|
|
351
709
|
"""
|
|
352
710
|
|
|
353
711
|
TransactionModel = self.get_transaction_model()
|
|
@@ -477,7 +835,7 @@ class IODatabaseMixIn:
|
|
|
477
835
|
txs_queryset = txs_queryset.posted()
|
|
478
836
|
|
|
479
837
|
if accounts:
|
|
480
|
-
if
|
|
838
|
+
if isinstance(accounts, str):
|
|
481
839
|
accounts = [accounts]
|
|
482
840
|
txs_queryset = txs_queryset.for_accounts(account_list=accounts)
|
|
483
841
|
|
|
@@ -553,53 +911,55 @@ class IODatabaseMixIn:
|
|
|
553
911
|
force_queryset_sorting: bool = False,
|
|
554
912
|
**kwargs) -> IOResult:
|
|
555
913
|
"""
|
|
556
|
-
|
|
557
|
-
|
|
914
|
+
Computes and returns the digest of transactions for a given entity, unit,
|
|
915
|
+
and optional filters such as date range, account role, and activity. The
|
|
916
|
+
digest includes aggregated balances by specified group-by keys.
|
|
558
917
|
|
|
559
918
|
Parameters
|
|
560
919
|
----------
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
Defaults to None.
|
|
570
|
-
from_date: date
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
Defaults to false.
|
|
920
|
+
user_model : Optional[UserModel]
|
|
921
|
+
The user model to be used for the computation. Defaults to None.
|
|
922
|
+
entity_slug : Optional[str]
|
|
923
|
+
The slug representing the entity to compute the digest for. Defaults
|
|
924
|
+
to None.
|
|
925
|
+
unit_slug : Optional[str]
|
|
926
|
+
The slug representing the unit within the entity. Defaults to None.
|
|
927
|
+
to_date : Optional[Union[date, datetime, str]]
|
|
928
|
+
The end date for the transaction filter. Defaults to None.
|
|
929
|
+
from_date : Optional[Union[date, datetime, str]]
|
|
930
|
+
The start date for the transaction filter. Defaults to None.
|
|
931
|
+
equity_only : bool
|
|
932
|
+
Whether to compute results only for earnings-related accounts. Defaults
|
|
933
|
+
to False.
|
|
934
|
+
activity : str
|
|
935
|
+
An optional activity filter for transactions. Defaults to None.
|
|
936
|
+
role : Optional[Union[Set[str], List[str]]]
|
|
937
|
+
The account roles to include in the digest. Defaults to None.
|
|
938
|
+
accounts : Optional[Union[Set[str], List[str]]]
|
|
939
|
+
A list or set of specific accounts to include. Defaults to None.
|
|
940
|
+
signs : bool
|
|
941
|
+
Whether to adjust the signs for the account balances based on balance type and account role.
|
|
942
|
+
Defaults to True.
|
|
943
|
+
by_unit : bool
|
|
944
|
+
Whether to group the results by unit. Defaults to False.
|
|
945
|
+
by_activity : bool
|
|
946
|
+
Whether to group the results by activity. Defaults to False.
|
|
947
|
+
by_tx_type : bool
|
|
948
|
+
Whether to group the results by transaction type. Defaults to False.
|
|
949
|
+
by_period : bool
|
|
950
|
+
Whether to group the results by period (year and month). Defaults to False.
|
|
951
|
+
use_closing_entries : bool
|
|
952
|
+
Whether to include closing entries in the computation. Defaults to False.
|
|
953
|
+
force_queryset_sorting : bool
|
|
954
|
+
Whether to force sorting of the transaction queryset. Defaults to False.
|
|
955
|
+
**kwargs : dict
|
|
956
|
+
Additional keyword arguments passed to the computation.
|
|
599
957
|
|
|
600
958
|
Returns
|
|
601
959
|
-------
|
|
602
960
|
IOResult
|
|
961
|
+
An object containing the transaction queryset, grouped and aggregated
|
|
962
|
+
account balances, and other relevant digest information.
|
|
603
963
|
"""
|
|
604
964
|
|
|
605
965
|
if equity_only:
|
|
@@ -650,12 +1010,12 @@ class IODatabaseMixIn:
|
|
|
650
1010
|
for acc in accounts_digest:
|
|
651
1011
|
if any([
|
|
652
1012
|
all([acc['role_bs'] == roles_module.BS_ASSET_ROLE,
|
|
653
|
-
acc['balance_type'] ==
|
|
1013
|
+
acc['balance_type'] == CREDIT]),
|
|
654
1014
|
all([acc['role_bs'] in (
|
|
655
1015
|
roles_module.BS_LIABILITIES_ROLE,
|
|
656
1016
|
roles_module.BS_EQUITY_ROLE
|
|
657
1017
|
),
|
|
658
|
-
acc['balance_type'] ==
|
|
1018
|
+
acc['balance_type'] == DEBIT])
|
|
659
1019
|
]):
|
|
660
1020
|
acc['balance'] = -acc['balance']
|
|
661
1021
|
|
|
@@ -664,6 +1024,45 @@ class IODatabaseMixIn:
|
|
|
664
1024
|
|
|
665
1025
|
@staticmethod
|
|
666
1026
|
def aggregate_balances(k, g):
|
|
1027
|
+
"""
|
|
1028
|
+
Aggregates balances from grouped data, providing a summarized representation of
|
|
1029
|
+
account attributes and their balances over a specified period. The function is
|
|
1030
|
+
used to compile essential details such as account identifiers, roles, activity,
|
|
1031
|
+
and balance, summarizing them for further processing or presentation.
|
|
1032
|
+
|
|
1033
|
+
Parameters
|
|
1034
|
+
----------
|
|
1035
|
+
k : tuple
|
|
1036
|
+
A tuple consisting of grouped key values. Expected structure:
|
|
1037
|
+
- The first element represents the account UUID.
|
|
1038
|
+
- The second element represents the unit UUID.
|
|
1039
|
+
- The third and fourth elements represent the period year and month, respectively.
|
|
1040
|
+
- The sixth element represents the transaction type.
|
|
1041
|
+
|
|
1042
|
+
g : iterable
|
|
1043
|
+
An iterable of grouped account data, typically containing dictionaries with
|
|
1044
|
+
detailed account properties and their respective balance information.
|
|
1045
|
+
|
|
1046
|
+
Returns
|
|
1047
|
+
-------
|
|
1048
|
+
dict
|
|
1049
|
+
A dictionary containing the aggregated balance information and related
|
|
1050
|
+
attributes, structured with the following keys:
|
|
1051
|
+
- 'account_uuid'
|
|
1052
|
+
- 'coa_slug'
|
|
1053
|
+
- 'unit_uuid'
|
|
1054
|
+
- 'unit_name'
|
|
1055
|
+
- 'activity'
|
|
1056
|
+
- 'period_year'
|
|
1057
|
+
- 'period_month'
|
|
1058
|
+
- 'role_bs'
|
|
1059
|
+
- 'role'
|
|
1060
|
+
- 'code'
|
|
1061
|
+
- 'name'
|
|
1062
|
+
- 'balance_type'
|
|
1063
|
+
- 'tx_type'
|
|
1064
|
+
- 'balance'
|
|
1065
|
+
"""
|
|
667
1066
|
gl = list(g)
|
|
668
1067
|
return {
|
|
669
1068
|
'account_uuid': k[0],
|
|
@@ -706,7 +1105,70 @@ class IODatabaseMixIn:
|
|
|
706
1105
|
cash_flow_statement: bool = False,
|
|
707
1106
|
use_closing_entry: Optional[bool] = None,
|
|
708
1107
|
**kwargs) -> IODigestContextManager:
|
|
1108
|
+
"""
|
|
1109
|
+
Processes financial data and generates various financial statements, ratios, or activity digests
|
|
1110
|
+
based on the provided arguments. The method applies specific processing pipelines, such as role
|
|
1111
|
+
processing, grouping, ratio computation, activity-based operations, or generating financial
|
|
1112
|
+
statements like balance sheet, income statement, and cash flow statement.
|
|
709
1113
|
|
|
1114
|
+
Parameters
|
|
1115
|
+
----------
|
|
1116
|
+
entity_slug : Optional[str]
|
|
1117
|
+
The slug identifier for the entity to process the financial data for.
|
|
1118
|
+
unit_slug : Optional[str]
|
|
1119
|
+
The slug identifier for the specific unit of the entity to filter the data for.
|
|
1120
|
+
to_date : Optional[Union[date, datetime, str]]
|
|
1121
|
+
The upper limit of the date range for which the data will be processed. Can be a `date`,
|
|
1122
|
+
`datetime`, or ISO 8601 formatted `str`.
|
|
1123
|
+
from_date : Optional[Union[date, datetime, str]]
|
|
1124
|
+
The lower limit of the date range for which the data will be processed. Can be a `date`,
|
|
1125
|
+
`datetime`, or ISO 8601 formatted `str`.
|
|
1126
|
+
user_model : Optional[UserModel]
|
|
1127
|
+
A user model instance to filter data or apply user-specific permissions during processing.
|
|
1128
|
+
accounts : Optional[Union[Set[str], List[str]]]
|
|
1129
|
+
A collection of account identifiers to filter the financial data to process.
|
|
1130
|
+
role : Optional[Union[Set[str], List[str]]]
|
|
1131
|
+
A collection of roles used to filter or organize the data during processing.
|
|
1132
|
+
activity : Optional[str]
|
|
1133
|
+
Specific activity identifier to filter or process the data for.
|
|
1134
|
+
signs : bool, default=True
|
|
1135
|
+
If `True`, account roles with predefined signs will be applied to the financial data.
|
|
1136
|
+
process_roles : bool, default=False
|
|
1137
|
+
If `True`, processes account roles and organizes financial data accordingly.
|
|
1138
|
+
process_groups : bool, default=False
|
|
1139
|
+
If `True`, processes and organizes the financial data into predetermined account groups.
|
|
1140
|
+
process_ratios : bool, default=False
|
|
1141
|
+
If `True`, computes and processes financial ratios for the provided data.
|
|
1142
|
+
process_activity : bool, default=False
|
|
1143
|
+
If `True`, specific activity-based computation or segregation will be executed.
|
|
1144
|
+
equity_only : bool, default=False
|
|
1145
|
+
Processes only equity-specific accounts if set to `True`.
|
|
1146
|
+
by_period : bool, default=False
|
|
1147
|
+
Organizes or groups the output by accounting periods if `True`.
|
|
1148
|
+
by_unit : bool, default=False
|
|
1149
|
+
Organizes or processes data specific to each unit when set to `True`.
|
|
1150
|
+
by_activity : bool, default=False
|
|
1151
|
+
Groups or segregates the processed data by activity when `True`.
|
|
1152
|
+
by_tx_type : bool, default=False
|
|
1153
|
+
Groups or organizes the result by transaction type when `True`.
|
|
1154
|
+
balance_sheet_statement : bool, default=False
|
|
1155
|
+
If `True`, prepares a balance sheet statement as part of the processing.
|
|
1156
|
+
income_statement : bool, default=False
|
|
1157
|
+
If `True`, generates an income statement as part of the processed result.
|
|
1158
|
+
cash_flow_statement : bool, default=False
|
|
1159
|
+
If `True`, prepares a cash flow statement based on the provided data.
|
|
1160
|
+
use_closing_entry : Optional[bool]
|
|
1161
|
+
Specifies whether to account for closing entries in the financial statement computation.
|
|
1162
|
+
**kwargs
|
|
1163
|
+
Additional named arguments that can be passed to adjust the behavior of specific processing
|
|
1164
|
+
modules or middleware.
|
|
1165
|
+
|
|
1166
|
+
Returns
|
|
1167
|
+
-------
|
|
1168
|
+
IODigestContextManager
|
|
1169
|
+
A context manager instance containing the processed financial data and results, including
|
|
1170
|
+
financial statements, ratios, or any activity digest generated as per the input parameters.
|
|
1171
|
+
"""
|
|
710
1172
|
if balance_sheet_statement:
|
|
711
1173
|
from_date = None
|
|
712
1174
|
|
|
@@ -817,7 +1279,55 @@ class IODatabaseMixIn:
|
|
|
817
1279
|
je_origin=None,
|
|
818
1280
|
force_je_retrieval: bool = False,
|
|
819
1281
|
**kwargs):
|
|
1282
|
+
"""
|
|
1283
|
+
Commits a set of financial transactions to a journal entry, after performing
|
|
1284
|
+
validation checks. Validations include ensuring balanced transactions, ensuring
|
|
1285
|
+
timestamp integrity, and verifying relationships between models. This method
|
|
1286
|
+
creates or retrieves a journal entry based on the provided details and assigns
|
|
1287
|
+
the given transactions accordingly, supporting conditional posting.
|
|
1288
|
+
|
|
1289
|
+
Parameters
|
|
1290
|
+
----------
|
|
1291
|
+
je_timestamp : str or datetime or date
|
|
1292
|
+
The timestamp for the journal entry. Validates against entity's closed
|
|
1293
|
+
periods and is required to be in a valid format.
|
|
1294
|
+
je_txs : list of dict
|
|
1295
|
+
A list of transactions to be committed, each represented as a dictionary.
|
|
1296
|
+
Each transaction should include keys such as 'account', 'amount', 'tx_type',
|
|
1297
|
+
and 'description'.
|
|
1298
|
+
je_posted : bool, optional
|
|
1299
|
+
Whether the created or retrieved journal entry should be marked as posted
|
|
1300
|
+
after verification. Defaults to False.
|
|
1301
|
+
je_ledger_model : object, optional
|
|
1302
|
+
An optional instance of LedgerModel used for validating ledger associations.
|
|
1303
|
+
If not provided, defaults to the current ledger model.
|
|
1304
|
+
je_unit_model : object, optional
|
|
1305
|
+
An optional instance of EntityUnitModel used for validating entity unit
|
|
1306
|
+
associations with transactions.
|
|
1307
|
+
je_desc : str, optional
|
|
1308
|
+
A description for the journal entry. Defaults to None if not provided.
|
|
1309
|
+
je_origin : str, optional
|
|
1310
|
+
Specifies the origin or source of the journal entry. Defaults to None.
|
|
1311
|
+
force_je_retrieval : bool, optional
|
|
1312
|
+
Whether to force retrieval of an existing journal entry with the given
|
|
1313
|
+
timestamp instead of creating a new one. Defaults to False.
|
|
1314
|
+
**kwargs : dict
|
|
1315
|
+
Additional keyword arguments that may be required for handling specific
|
|
1316
|
+
customization details during journal entry creation or retrieval.
|
|
820
1317
|
|
|
1318
|
+
Returns
|
|
1319
|
+
-------
|
|
1320
|
+
tuple
|
|
1321
|
+
A tuple containing the journal entry model (je_model) and a list of
|
|
1322
|
+
transaction models (txs_models) created or associated with the journal entry.
|
|
1323
|
+
|
|
1324
|
+
Raises
|
|
1325
|
+
------
|
|
1326
|
+
IOValidationError
|
|
1327
|
+
Raised for various validation errors including invalid timestamps, attempting
|
|
1328
|
+
to commit on locked or closed ledgers, association errors with ledger or
|
|
1329
|
+
entity models, and inability to retrieve a required journal entry.
|
|
1330
|
+
"""
|
|
821
1331
|
TransactionModel = self.get_transaction_model()
|
|
822
1332
|
JournalEntryModel = self.get_journal_entry_model()
|
|
823
1333
|
|
|
@@ -920,6 +1430,31 @@ class IODatabaseMixIn:
|
|
|
920
1430
|
|
|
921
1431
|
|
|
922
1432
|
class IOReportMixIn:
|
|
1433
|
+
"""
|
|
1434
|
+
Provides functionality for generating and managing financial reports.
|
|
1435
|
+
|
|
1436
|
+
This mixin class facilitates the generation, processing, and management of
|
|
1437
|
+
various financial statements, including balance sheet statements, income
|
|
1438
|
+
statements, and cash flow statements. Reports can be created in multiple
|
|
1439
|
+
formats, such as plain data representation or as PDF files. The class
|
|
1440
|
+
integrates support for financial data digestion and report serialization,
|
|
1441
|
+
including saving PDF reports to specified file paths. Common use cases include
|
|
1442
|
+
generating summarized financial data for reporting purposes and outputting
|
|
1443
|
+
them in PDF format.
|
|
1444
|
+
|
|
1445
|
+
Attributes
|
|
1446
|
+
----------
|
|
1447
|
+
PDF_REPORT_ORIENTATION : str
|
|
1448
|
+
Indicates the orientation of the generated PDF reports ('P' for portrait, 'L' for landscape).
|
|
1449
|
+
PDF_REPORT_MEASURE_UNIT : str
|
|
1450
|
+
Specifies the measurement unit used in the PDF reports (e.g., 'mm', 'cm').
|
|
1451
|
+
PDF_REPORT_PAGE_SIZE : str
|
|
1452
|
+
Defines the size of the pages in the generated PDF reports (e.g., 'Letter', 'A4').
|
|
1453
|
+
ReportTuple : namedtuple
|
|
1454
|
+
A tuple structure containing three fields: `balance_sheet_statement`,
|
|
1455
|
+
`income_statement`, and `cash_flow_statement`. Each field represents a
|
|
1456
|
+
respective financial report.
|
|
1457
|
+
"""
|
|
923
1458
|
PDF_REPORT_ORIENTATION = 'P'
|
|
924
1459
|
PDF_REPORT_MEASURE_UNIT = 'mm'
|
|
925
1460
|
PDF_REPORT_PAGE_SIZE = 'Letter'
|
|
@@ -936,6 +1471,33 @@ class IOReportMixIn:
|
|
|
936
1471
|
user_model: Optional[UserModel] = None,
|
|
937
1472
|
txs_queryset: Optional[QuerySet] = None,
|
|
938
1473
|
**kwargs: Dict) -> IODigestContextManager:
|
|
1474
|
+
"""
|
|
1475
|
+
Digest the balance sheet for a specific time period, user, and optionally a specific set
|
|
1476
|
+
of transactions. Returns a context manager for digesting the specified balance sheet data.
|
|
1477
|
+
|
|
1478
|
+
Parameters
|
|
1479
|
+
----------
|
|
1480
|
+
to_date : Union[date, datetime]
|
|
1481
|
+
The date till which the balance sheet needs to be digested, including transactions
|
|
1482
|
+
occurring on this date.
|
|
1483
|
+
|
|
1484
|
+
user_model : Optional[UserModel], optional
|
|
1485
|
+
The model instance representing the user whose balance sheet is to be
|
|
1486
|
+
digested. This can be `None` to indicate no specific user.
|
|
1487
|
+
|
|
1488
|
+
txs_queryset : Optional[QuerySet], optional
|
|
1489
|
+
A queryset containing specific transactions to be included in the calculation.
|
|
1490
|
+
If not provided, all transactions up to `to_date` will be considered.
|
|
1491
|
+
|
|
1492
|
+
kwargs : Dict
|
|
1493
|
+
Additional keyword arguments that can be used for the digestion process.
|
|
1494
|
+
Allows flexible filtering or additional specifications.
|
|
1495
|
+
|
|
1496
|
+
Returns
|
|
1497
|
+
-------
|
|
1498
|
+
IODigestContextManager
|
|
1499
|
+
A context manager for handling the digestion process of the balance sheet.
|
|
1500
|
+
"""
|
|
939
1501
|
return self.digest(
|
|
940
1502
|
user_model=user_model,
|
|
941
1503
|
to_date=to_date,
|
|
@@ -955,7 +1517,50 @@ class IOReportMixIn:
|
|
|
955
1517
|
save_pdf: bool = False,
|
|
956
1518
|
**kwargs
|
|
957
1519
|
) -> IODigestContextManager:
|
|
1520
|
+
"""
|
|
1521
|
+
Generates a balance sheet statement with an option to save it as a PDF file.
|
|
1522
|
+
|
|
1523
|
+
This method fetches and processes financial data to create a balance sheet
|
|
1524
|
+
statement using the provided date range, user model, and additional optional
|
|
1525
|
+
settings. It supports generating a PDF output for the balance sheet if
|
|
1526
|
+
configured. The class responsible for PDF generation is dynamically loaded,
|
|
1527
|
+
allowing modularity and flexibility.
|
|
1528
|
+
|
|
1529
|
+
Note that PDF generation functionality is dependent on the presence of the
|
|
1530
|
+
`DJANGO_LEDGER_PDF_SUPPORT_ENABLED` flag. If the flag is not enabled, the
|
|
1531
|
+
method raises an exception.
|
|
958
1532
|
|
|
1533
|
+
Parameters
|
|
1534
|
+
----------
|
|
1535
|
+
to_date : Union[date, datetime]
|
|
1536
|
+
The end date for the balance sheet report. The data will be considered
|
|
1537
|
+
up to this date for the financial statement.
|
|
1538
|
+
subtitle : Optional[str], default=None
|
|
1539
|
+
An optional subtitle for the generated report. This can be used to include
|
|
1540
|
+
additional context or descriptions in the report.
|
|
1541
|
+
filepath : Optional[Path], default=None
|
|
1542
|
+
Specifies the directory path where the PDF file should be saved. If not
|
|
1543
|
+
provided, a default directory is used based on application settings.
|
|
1544
|
+
filename : Optional[str], default=None
|
|
1545
|
+
Name of the file to save the PDF report. Defaults to an automatically
|
|
1546
|
+
generated filename if not provided.
|
|
1547
|
+
user_model : Optional[UserModel], default=None
|
|
1548
|
+
The user context associated with the balance sheet report. Includes
|
|
1549
|
+
permissions or specific user-related data.
|
|
1550
|
+
save_pdf : bool, default=False
|
|
1551
|
+
A flag indicating whether the balance sheet should be saved as a PDF. If
|
|
1552
|
+
True, the method generates and stores the PDF in the specified location.
|
|
1553
|
+
**kwargs
|
|
1554
|
+
Additional keyword arguments required for generating the balance sheet.
|
|
1555
|
+
It may include filtering, formatting, or any other relevant parameters.
|
|
1556
|
+
|
|
1557
|
+
Returns
|
|
1558
|
+
-------
|
|
1559
|
+
IODigestContextManager
|
|
1560
|
+
The context manager object handling the generated balance sheet, either in
|
|
1561
|
+
memory or in saved PDF format. If the `save_pdf` option is enabled, the PDF
|
|
1562
|
+
report is saved at the specified location.
|
|
1563
|
+
"""
|
|
959
1564
|
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
960
1565
|
raise IOValidationError(
|
|
961
1566
|
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
@@ -989,6 +1594,36 @@ class IOReportMixIn:
|
|
|
989
1594
|
user_model: Optional[UserModel] = None,
|
|
990
1595
|
txs_queryset: Optional[QuerySet] = None,
|
|
991
1596
|
**kwargs) -> IODigestContextManager:
|
|
1597
|
+
"""
|
|
1598
|
+
Digest the income statement within the specified date range and optionally filter
|
|
1599
|
+
by user and transaction queryset.
|
|
1600
|
+
|
|
1601
|
+
This method generates a digest context manager for the income statement,
|
|
1602
|
+
allowing granular control over the data derived within the requested range
|
|
1603
|
+
and applying any additional filters provided. It supports optional user and
|
|
1604
|
+
transaction queryset filters for tailored data processing.
|
|
1605
|
+
|
|
1606
|
+
Parameters
|
|
1607
|
+
----------
|
|
1608
|
+
from_date : Union[date, datetime]
|
|
1609
|
+
The starting date for filtering the income statement.
|
|
1610
|
+
to_date : Union[date, datetime]
|
|
1611
|
+
The ending date for filtering the income statement.
|
|
1612
|
+
user_model : Optional[UserModel], optional
|
|
1613
|
+
An optional user model instance to filter income statement data
|
|
1614
|
+
by a specific user.
|
|
1615
|
+
txs_queryset : Optional[QuerySet], optional
|
|
1616
|
+
An optional transaction queryset to filter the income statement
|
|
1617
|
+
by specific transaction records.
|
|
1618
|
+
**kwargs : dict
|
|
1619
|
+
Additional keyword arguments for customization or requirements in
|
|
1620
|
+
the income statement digest generation process.
|
|
1621
|
+
|
|
1622
|
+
Returns
|
|
1623
|
+
-------
|
|
1624
|
+
IODigestContextManager
|
|
1625
|
+
A context manager containing the processed income statement data.
|
|
1626
|
+
"""
|
|
992
1627
|
return self.digest(
|
|
993
1628
|
user_model=user_model,
|
|
994
1629
|
from_date=from_date,
|
|
@@ -1011,6 +1646,50 @@ class IOReportMixIn:
|
|
|
1011
1646
|
save_pdf: bool = False,
|
|
1012
1647
|
**kwargs
|
|
1013
1648
|
):
|
|
1649
|
+
"""
|
|
1650
|
+
Generates an income statement report for a specific time period and allows optional PDF
|
|
1651
|
+
saving functionality. The function utilizes configurations, user-provided parameters,
|
|
1652
|
+
and transactions data to create an income statement report, which can either be returned
|
|
1653
|
+
as a report object or saved as a PDF on the filesystem.
|
|
1654
|
+
|
|
1655
|
+
Parameters
|
|
1656
|
+
----------
|
|
1657
|
+
from_date : date or datetime
|
|
1658
|
+
The starting date of the income statement period. Must be provided.
|
|
1659
|
+
to_date : date or datetime
|
|
1660
|
+
The ending date of the income statement period. Must be provided.
|
|
1661
|
+
subtitle : str, optional
|
|
1662
|
+
An optional subtitle for the income statement report.
|
|
1663
|
+
filepath : Path, optional
|
|
1664
|
+
The directory path where the PDF report should be saved, if `save_pdf` is set to True.
|
|
1665
|
+
filename : str, optional
|
|
1666
|
+
The filename for the PDF report. If not provided, a default filename is generated.
|
|
1667
|
+
user_model : UserModel, optional
|
|
1668
|
+
A user model instance, providing additional context or filtering for the income
|
|
1669
|
+
statement generation.
|
|
1670
|
+
txs_queryset : QuerySet, optional
|
|
1671
|
+
A queryset containing transactions data to be included in the income statement
|
|
1672
|
+
report. If not provided, transactions may be automatically determined by other
|
|
1673
|
+
parameters or configurations.
|
|
1674
|
+
save_pdf : bool
|
|
1675
|
+
Indicates whether the generated income statement should be saved as a PDF file.
|
|
1676
|
+
Defaults to False.
|
|
1677
|
+
**kwargs :
|
|
1678
|
+
Additional optional keyword arguments for further customization or filtering.
|
|
1679
|
+
|
|
1680
|
+
Raises
|
|
1681
|
+
------
|
|
1682
|
+
IOValidationError
|
|
1683
|
+
Raised if PDF support is not enabled in the configuration. The error provides a
|
|
1684
|
+
message suggesting installing PDF support.
|
|
1685
|
+
|
|
1686
|
+
Returns
|
|
1687
|
+
-------
|
|
1688
|
+
IncomeStatementReport
|
|
1689
|
+
A configured instance of the IncomeStatementReport class, representing the
|
|
1690
|
+
generated income statement report. If `save_pdf` is True, the report will also
|
|
1691
|
+
be saved as a PDF file at the specified location.
|
|
1692
|
+
"""
|
|
1014
1693
|
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
1015
1694
|
raise IOValidationError(
|
|
1016
1695
|
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
@@ -1045,6 +1724,31 @@ class IOReportMixIn:
|
|
|
1045
1724
|
user_model: Optional[UserModel] = None,
|
|
1046
1725
|
txs_queryset: Optional[QuerySet] = None,
|
|
1047
1726
|
**kwargs) -> IODigestContextManager:
|
|
1727
|
+
"""
|
|
1728
|
+
Generates a digest of the cash flow statement for a specified date range, user model,
|
|
1729
|
+
and optional transaction query set. This method utilizes an internal digest
|
|
1730
|
+
mechanism to compile and return the cash flow statement context.
|
|
1731
|
+
|
|
1732
|
+
Parameters
|
|
1733
|
+
----------
|
|
1734
|
+
from_date : Union[date, datetime]
|
|
1735
|
+
The start date of the period for the cash flow statement.
|
|
1736
|
+
to_date : Union[date, datetime]
|
|
1737
|
+
The end date of the period for the cash flow statement.
|
|
1738
|
+
user_model : Optional[UserModel]
|
|
1739
|
+
The user model instance for which the digest is generated. If None, the
|
|
1740
|
+
default user model is used.
|
|
1741
|
+
txs_queryset : Optional[QuerySet]
|
|
1742
|
+
An optional queryset of transactions to include in the digest. If None,
|
|
1743
|
+
defaults to all transactions within the date range.
|
|
1744
|
+
**kwargs : dict
|
|
1745
|
+
Additional keyword arguments passed to the digest function.
|
|
1746
|
+
|
|
1747
|
+
Returns
|
|
1748
|
+
-------
|
|
1749
|
+
IODigestContextManager
|
|
1750
|
+
Context manager providing the digested cash flow statement.
|
|
1751
|
+
"""
|
|
1048
1752
|
return self.digest(
|
|
1049
1753
|
user_model=user_model,
|
|
1050
1754
|
from_date=from_date,
|
|
@@ -1065,7 +1769,44 @@ class IOReportMixIn:
|
|
|
1065
1769
|
user_model: Optional[UserModel] = None,
|
|
1066
1770
|
save_pdf: bool = False,
|
|
1067
1771
|
**kwargs):
|
|
1772
|
+
"""
|
|
1773
|
+
Generates a cash flow statement report within a specified date range and provides
|
|
1774
|
+
an option to save the report as a PDF file. The method retrieves financial data, processes
|
|
1775
|
+
it into a structured cash flow statement, and uses a PDF report generator to create the report.
|
|
1776
|
+
|
|
1777
|
+
Parameters
|
|
1778
|
+
----------
|
|
1779
|
+
from_date : Union[date, datetime]
|
|
1780
|
+
The start date for the cash flow statement.
|
|
1781
|
+
to_date : Union[date, datetime]
|
|
1782
|
+
The end date for the cash flow statement.
|
|
1783
|
+
subtitle : Optional[str], default=None
|
|
1784
|
+
Subtitle text for the report.
|
|
1785
|
+
filepath : Optional[Path], default=None
|
|
1786
|
+
The directory path where the PDF report will be saved. Defaults to the
|
|
1787
|
+
base directory if not provided.
|
|
1788
|
+
filename : Optional[str], default=None
|
|
1789
|
+
The name of the PDF report file. If not provided, a default name is generated.
|
|
1790
|
+
user_model : Optional[UserModel], default=None
|
|
1791
|
+
The user model instance, optionally used for filtering or customization of the
|
|
1792
|
+
report content.
|
|
1793
|
+
save_pdf : bool, default=False
|
|
1794
|
+
Flag to save the generated report as a PDF file.
|
|
1795
|
+
kwargs : dict
|
|
1796
|
+
Additional keyword arguments that are passed to the `digest_cash_flow_statement`
|
|
1797
|
+
method for further customization or additional processing.
|
|
1068
1798
|
|
|
1799
|
+
Returns
|
|
1800
|
+
-------
|
|
1801
|
+
CashFlowStatementReport
|
|
1802
|
+
An instance of the cash flow statement report class, either saved as a PDF if
|
|
1803
|
+
`save_pdf` is True or ready for further processing or display.
|
|
1804
|
+
|
|
1805
|
+
Raises
|
|
1806
|
+
------
|
|
1807
|
+
IOValidationError
|
|
1808
|
+
If PDF support is not enabled in the system's Django ledger configuration.
|
|
1809
|
+
"""
|
|
1069
1810
|
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
1070
1811
|
raise IOValidationError(
|
|
1071
1812
|
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
@@ -1099,7 +1840,40 @@ class IOReportMixIn:
|
|
|
1099
1840
|
to_date: Union[date, datetime],
|
|
1100
1841
|
user_model: Optional[UserModel] = None,
|
|
1101
1842
|
**kwargs) -> IODigestContextManager:
|
|
1843
|
+
"""
|
|
1844
|
+
Digest financial statements within a given date range, allowing optional
|
|
1845
|
+
customization through `kwargs`. The method processes and provides access
|
|
1846
|
+
to balance sheet statements, income statements, and cash flow statements
|
|
1847
|
+
for the specified date range. Results are encapsulated in an
|
|
1848
|
+
IODigestContextManager for ease of management.
|
|
1849
|
+
|
|
1850
|
+
The function provides flexibility to include a user model for domain-specific
|
|
1851
|
+
processing needs while ensuring support for both date and datetime objects.
|
|
1852
|
+
|
|
1853
|
+
Parameters
|
|
1854
|
+
----------
|
|
1855
|
+
from_date : date or datetime
|
|
1856
|
+
The starting date of the range for which financial statements are
|
|
1857
|
+
to be processed.
|
|
1858
|
+
|
|
1859
|
+
to_date : date or datetime
|
|
1860
|
+
The ending date of the range for which financial statements are
|
|
1861
|
+
to be processed.
|
|
1862
|
+
|
|
1863
|
+
user_model : Optional[UserModel], default=None
|
|
1864
|
+
A user model instance that allows for context-specific processing
|
|
1865
|
+
during the digestion of financial statements.
|
|
1102
1866
|
|
|
1867
|
+
kwargs : dict
|
|
1868
|
+
Additional optional parameters that may be used to further
|
|
1869
|
+
customize the processing of financial statements.
|
|
1870
|
+
|
|
1871
|
+
Returns
|
|
1872
|
+
-------
|
|
1873
|
+
IODigestContextManager
|
|
1874
|
+
Represents the context manager containing the digested financial
|
|
1875
|
+
statements for the specified date range.
|
|
1876
|
+
"""
|
|
1103
1877
|
return self.digest(
|
|
1104
1878
|
from_date=from_date,
|
|
1105
1879
|
to_date=to_date,
|
|
@@ -1119,7 +1893,44 @@ class IOReportMixIn:
|
|
|
1119
1893
|
save_pdf: bool = False,
|
|
1120
1894
|
filepath: Optional[Path] = None,
|
|
1121
1895
|
**kwargs) -> ReportTuple:
|
|
1896
|
+
"""
|
|
1897
|
+
Generates financial statements for a specified date range, optionally saving them as
|
|
1898
|
+
PDF files. This method consolidates the balance sheet, income statement, and cash flow
|
|
1899
|
+
statement for the given dates. If PDF saving is enabled, the financial statements will
|
|
1900
|
+
be saved to the specified path or the application's base directory. The results are
|
|
1901
|
+
returned as a tuple containing the reports.
|
|
1902
|
+
|
|
1903
|
+
Parameters
|
|
1904
|
+
----------
|
|
1905
|
+
from_date : Union[date, datetime]
|
|
1906
|
+
The start date for the financial statements.
|
|
1907
|
+
to_date : Union[date, datetime]
|
|
1908
|
+
The end date for the financial statements.
|
|
1909
|
+
dt_strfmt : str
|
|
1910
|
+
The string format used for the filenames of the generated PDF reports. Defaults to
|
|
1911
|
+
'%Y%m%d'.
|
|
1912
|
+
user_model : Optional[UserModel], optional
|
|
1913
|
+
The user model instance, if applicable. Defaults to None.
|
|
1914
|
+
save_pdf : bool, optional
|
|
1915
|
+
Determines whether to save the generated financial statements as PDF files.
|
|
1916
|
+
Defaults to False.
|
|
1917
|
+
filepath : Optional[Path], optional
|
|
1918
|
+
The directory path where the PDF files will be saved. If not provided, the files will
|
|
1919
|
+
be saved in the application's base directory. Defaults to None.
|
|
1920
|
+
**kwargs
|
|
1921
|
+
Additional keyword arguments for customizing financial statement generation.
|
|
1122
1922
|
|
|
1923
|
+
Returns
|
|
1924
|
+
-------
|
|
1925
|
+
ReportTuple
|
|
1926
|
+
A named tuple containing the generated balance sheet, income statement, and cash
|
|
1927
|
+
flow statement as objects.
|
|
1928
|
+
|
|
1929
|
+
Raises
|
|
1930
|
+
------
|
|
1931
|
+
IOValidationError
|
|
1932
|
+
Raised if PDF support is not enabled in the application configuration.
|
|
1933
|
+
"""
|
|
1123
1934
|
if not DJANGO_LEDGER_PDF_SUPPORT_ENABLED:
|
|
1124
1935
|
raise IOValidationError(
|
|
1125
1936
|
message=_('PDF support not enabled. Install PDF support from Pipfile.')
|
|
@@ -1176,4 +1987,11 @@ class IOMixIn(
|
|
|
1176
1987
|
IODatabaseMixIn,
|
|
1177
1988
|
IOReportMixIn
|
|
1178
1989
|
):
|
|
1179
|
-
|
|
1990
|
+
"""
|
|
1991
|
+
Provides input and output functionalities by mixing in database and
|
|
1992
|
+
reporting environments.
|
|
1993
|
+
|
|
1994
|
+
This class is a mixin that combines functionalities from IODatabaseMixIn
|
|
1995
|
+
and IOReportMixIn. It is designed to integrate database input/output
|
|
1996
|
+
operations with report generation features seamlessly.
|
|
1997
|
+
"""
|