django-ledger 0.5.6.5__py3-none-any.whl → 0.6.0.1__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/io/io_core.py +20 -16
- django_ledger/io/io_digest.py +1 -1
- django_ledger/io/io_middleware.py +2 -4
- django_ledger/models/accounts.py +11 -1
- django_ledger/models/closing_entry.py +4 -4
- django_ledger/models/coa.py +251 -74
- django_ledger/models/entity.py +21 -2
- django_ledger/models/mixins.py +1 -1
- django_ledger/models/transactions.py +209 -111
- django_ledger/models/utils.py +117 -116
- django_ledger/views/account.py +1 -1
- {django_ledger-0.5.6.5.dist-info → django_ledger-0.6.0.1.dist-info}/METADATA +71 -121
- {django_ledger-0.5.6.5.dist-info → django_ledger-0.6.0.1.dist-info}/RECORD +18 -19
- django_ledger/static/django_ledger/bundle/djetler.bundle.js.LICENSE.txt +0 -28
- {django_ledger-0.5.6.5.dist-info → django_ledger-0.6.0.1.dist-info}/AUTHORS.md +0 -0
- {django_ledger-0.5.6.5.dist-info → django_ledger-0.6.0.1.dist-info}/LICENSE +0 -0
- {django_ledger-0.5.6.5.dist-info → django_ledger-0.6.0.1.dist-info}/WHEEL +0 -0
- {django_ledger-0.5.6.5.dist-info → django_ledger-0.6.0.1.dist-info}/top_level.txt +0 -0
|
@@ -5,15 +5,16 @@ Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
|
5
5
|
Contributions to this module:
|
|
6
6
|
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
|
|
8
|
-
The TransactionModel is the lowest accounting level where
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
A transaction
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
production of financial statements.
|
|
8
|
+
The TransactionModel is the lowest accounting level where financial information is recorded. Every transaction with a
|
|
9
|
+
financial implication must be part of a JournalEntryModel, which encapsulates a collection of TransactionModels.
|
|
10
|
+
Transaction models cannot exist without being part of a validated JournalEntryModel. Orphan TransactionModels are not
|
|
11
|
+
allowed, and this is enforced by the database.
|
|
12
|
+
|
|
13
|
+
A transaction must perform a CREDIT or a DEBIT to the underlying AccountModel. The IOMixIn is crucial for the
|
|
14
|
+
production of financial statements and sets its foundation in the TransactionModel API. It allows for effective
|
|
15
|
+
querying and aggregating transactions at the Database layer without pulling all TransactionModels into memory.
|
|
16
|
+
This approach streamlines the production of financial statements. The IOMixIn in the TransactionModel API is essential
|
|
17
|
+
for efficient and effective financial statement generation.
|
|
17
18
|
"""
|
|
18
19
|
from datetime import datetime, date
|
|
19
20
|
from typing import List, Union, Optional
|
|
@@ -46,7 +47,37 @@ class TransactionModelValidationError(ValidationError):
|
|
|
46
47
|
|
|
47
48
|
class TransactionModelQuerySet(QuerySet):
|
|
48
49
|
"""
|
|
49
|
-
A custom
|
|
50
|
+
A custom QuerySet class for TransactionModels implementing methods to effectively and safely read
|
|
51
|
+
TransactionModels from the database.
|
|
52
|
+
|
|
53
|
+
Methods
|
|
54
|
+
-------
|
|
55
|
+
posted() -> TransactionModelQuerySet:
|
|
56
|
+
Fetches a QuerySet of posted transactions only.
|
|
57
|
+
|
|
58
|
+
for_accounts(account_list: List[str or AccountModel]) -> TransactionModelQuerySet:
|
|
59
|
+
Fetches a QuerySet of TransactionModels which AccountModel has a specific role.
|
|
60
|
+
|
|
61
|
+
for_roles(role_list: Union[str, List[str]]) -> TransactionModelQuerySet:
|
|
62
|
+
Fetches a QuerySet of TransactionModels which AccountModel has a specific role.
|
|
63
|
+
|
|
64
|
+
for_unit(unit_slug: Union[str, EntityUnitModel]) -> TransactionModelQuerySet:
|
|
65
|
+
Fetches a QuerySet of TransactionModels associated with a specific EntityUnitModel.
|
|
66
|
+
|
|
67
|
+
for_activity(activity_list: Union[str, List[str]]) -> TransactionModelQuerySet:
|
|
68
|
+
Fetches a QuerySet of TransactionModels associated with a specific activity or list of activities.
|
|
69
|
+
|
|
70
|
+
to_date(to_date: Union[str, date, datetime]) -> TransactionModelQuerySet:
|
|
71
|
+
Fetches a QuerySet of TransactionModels associated with a maximum date or timestamp filter.
|
|
72
|
+
|
|
73
|
+
from_date(from_date: Union[str, date, datetime]) -> TransactionModelQuerySet:
|
|
74
|
+
Fetches a QuerySet of TransactionModels associated with a minimum date or timestamp filter.
|
|
75
|
+
|
|
76
|
+
not_closing_entry() -> TransactionModelQuerySet:
|
|
77
|
+
Fetches a QuerySet of TransactionModels that are not part of a closing entry.
|
|
78
|
+
|
|
79
|
+
is_closing_entry() -> TransactionModelQuerySet:
|
|
80
|
+
Fetches a QuerySet of TransactionModels that are part of a closing entry.
|
|
50
81
|
"""
|
|
51
82
|
|
|
52
83
|
def posted(self) -> QuerySet:
|
|
@@ -189,38 +220,62 @@ class TransactionModelQuerySet(QuerySet):
|
|
|
189
220
|
return self.filter(journal_entry__timestamp__gte=from_date)
|
|
190
221
|
|
|
191
222
|
def not_closing_entry(self):
|
|
223
|
+
"""
|
|
224
|
+
Filter the Transactions based on whether they are closing entries or not.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
QuerySet: A filtered QuerySet of entries where the journal_entry__is_closing_entry field is False.
|
|
228
|
+
"""
|
|
192
229
|
return self.filter(journal_entry__is_closing_entry=False)
|
|
193
230
|
|
|
194
231
|
def is_closing_entry(self):
|
|
232
|
+
"""
|
|
233
|
+
Filter the Transactions based on whether they are closing entries or not.
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
QuerySet: A filtered QuerySet of entries where the journal_entry__is_closing_entry field is True.
|
|
237
|
+
"""
|
|
195
238
|
return self.filter(journal_entry__is_closing_entry=True)
|
|
196
239
|
|
|
197
240
|
|
|
198
241
|
class TransactionModelAdmin(models.Manager):
|
|
242
|
+
"""
|
|
243
|
+
A manager class for the TransactionModel.
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
def get_queryset(self) -> TransactionModelQuerySet:
|
|
247
|
+
qs = TransactionModelQuerySet(self.model, using=self._db)
|
|
248
|
+
return qs.select_related(
|
|
249
|
+
'journal_entry',
|
|
250
|
+
'account',
|
|
251
|
+
'account__coa_model',
|
|
252
|
+
)
|
|
199
253
|
|
|
200
254
|
def for_user(self, user_model) -> TransactionModelQuerySet:
|
|
201
255
|
"""
|
|
202
|
-
Fetches a QuerySet of TransactionModels that the UserModel as access to. For convenience, the AccountModel
|
|
203
|
-
information is selected, since much of the operations associated with transactions will involve information
|
|
204
|
-
from the AccountModel. For example, the AccountModel balance type plays a crucial role in the production of
|
|
205
|
-
financial statements.
|
|
206
|
-
|
|
207
|
-
May include TransactionModels from multiple Entities.
|
|
208
|
-
|
|
209
|
-
The user has access to transactions if:
|
|
210
|
-
1. Is listed as Manager of Entity.
|
|
211
|
-
2. Is the Admin of the Entity.
|
|
212
|
-
|
|
213
256
|
Parameters
|
|
214
257
|
----------
|
|
215
|
-
user_model
|
|
216
|
-
|
|
258
|
+
user_model : User model object
|
|
259
|
+
The user model object representing the user for whom to filter the transactions.
|
|
217
260
|
|
|
218
261
|
Returns
|
|
219
262
|
-------
|
|
220
263
|
TransactionModelQuerySet
|
|
221
|
-
|
|
264
|
+
A queryset of transaction models filtered based on the user's permissions.
|
|
265
|
+
|
|
266
|
+
Raises
|
|
267
|
+
------
|
|
268
|
+
None
|
|
269
|
+
|
|
270
|
+
Description
|
|
271
|
+
-----------
|
|
272
|
+
This method filters the transactions based on the user's permissions.
|
|
273
|
+
If the user is a superuser, all transactions are returned. Otherwise, the transactions are filtered based on
|
|
274
|
+
the user's relationship to the entities associated with the transactions. Specifically, the transactions are
|
|
275
|
+
filtered to include only those where either the user is an admin of the entity associated with the transaction's
|
|
276
|
+
ledger or the user is one of the managers of the entity associated with the transaction's ledger.
|
|
222
277
|
"""
|
|
223
|
-
qs = self.get_queryset()
|
|
278
|
+
qs = self.get_queryset()
|
|
224
279
|
if user_model.is_superuser:
|
|
225
280
|
return qs
|
|
226
281
|
return qs.filter(
|
|
@@ -233,22 +288,20 @@ class TransactionModelAdmin(models.Manager):
|
|
|
233
288
|
user_model: Optional[UserModel] = None,
|
|
234
289
|
) -> TransactionModelQuerySet:
|
|
235
290
|
"""
|
|
236
|
-
Fetches a QuerySet of TransactionModels associated with the specified
|
|
237
|
-
EntityModel. For security if UserModel is provided, will make sure the user_model provided is either the admin
|
|
238
|
-
or the manager of the entity.
|
|
239
|
-
|
|
240
291
|
Parameters
|
|
241
292
|
----------
|
|
242
|
-
entity_slug: str
|
|
243
|
-
The entity slug or
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
293
|
+
entity_slug : Union[EntityModel, str, UUID]
|
|
294
|
+
The entity slug or ID for which to retrieve transactions.
|
|
295
|
+
Can be an instance of EntityModel, a string representing the slug, or a UUID.
|
|
296
|
+
user_model : Optional[UserModel], optional
|
|
297
|
+
The user model for which to filter transactions.
|
|
298
|
+
If provided, only transactions associated with the specified user will be returned.
|
|
299
|
+
Defaults to None.
|
|
247
300
|
|
|
248
301
|
Returns
|
|
249
302
|
-------
|
|
250
303
|
TransactionModelQuerySet
|
|
251
|
-
|
|
304
|
+
A QuerySet of TransactionModel instances filtered by the provided parameters.
|
|
252
305
|
"""
|
|
253
306
|
|
|
254
307
|
if user_model:
|
|
@@ -267,22 +320,19 @@ class TransactionModelAdmin(models.Manager):
|
|
|
267
320
|
ledger_model: Union[LedgerModel, UUID],
|
|
268
321
|
user_model: Optional[UserModel] = None):
|
|
269
322
|
"""
|
|
270
|
-
Fetches a QuerySet of TransactionModels that the UserModel as access to and are associated with a specific
|
|
271
|
-
LedgerModel instance.
|
|
272
|
-
|
|
273
323
|
Parameters
|
|
274
324
|
----------
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
The
|
|
279
|
-
|
|
280
|
-
The
|
|
325
|
+
entity_slug : Union[EntityModel, str]
|
|
326
|
+
The slug or instance of the entity for which to filter the ledger.
|
|
327
|
+
ledger_model : Union[LedgerModel, UUID]
|
|
328
|
+
The ledger model or UUID of the ledger for which to filter the journal entries.
|
|
329
|
+
user_model : Optional[UserModel], optional
|
|
330
|
+
The user model associated with the entity. Default is None.
|
|
281
331
|
|
|
282
332
|
Returns
|
|
283
333
|
-------
|
|
284
|
-
|
|
285
|
-
|
|
334
|
+
QuerySet
|
|
335
|
+
The filtered QuerySet containing the journal entries for the specified entity and ledger.
|
|
286
336
|
"""
|
|
287
337
|
qs = self.for_entity(user_model=user_model, entity_slug=entity_slug)
|
|
288
338
|
if isinstance(ledger_model, UUID):
|
|
@@ -294,22 +344,26 @@ class TransactionModelAdmin(models.Manager):
|
|
|
294
344
|
unit_slug: str = Union[EntityUnitModel, str],
|
|
295
345
|
user_model: Optional[UserModel] = None):
|
|
296
346
|
"""
|
|
297
|
-
|
|
298
|
-
EntityUnitModel instance.
|
|
347
|
+
Returns the queryset filtered for the specified entity unit.
|
|
299
348
|
|
|
300
349
|
Parameters
|
|
301
350
|
----------
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
The entity
|
|
306
|
-
|
|
307
|
-
The
|
|
351
|
+
entity_slug : Union[EntityModel, str]
|
|
352
|
+
The entity model or slug used to filter the queryset.
|
|
353
|
+
unit_slug : Union[EntityUnitModel, str]
|
|
354
|
+
The entity unit model or slug used to filter the queryset.
|
|
355
|
+
user_model : Optional[UserModel], optional
|
|
356
|
+
The user model to consider for filtering the queryset, by default None.
|
|
308
357
|
|
|
309
358
|
Returns
|
|
310
359
|
-------
|
|
311
|
-
|
|
312
|
-
|
|
360
|
+
QuerySet
|
|
361
|
+
The filtered queryset based on the specified entity unit.
|
|
362
|
+
|
|
363
|
+
Notes
|
|
364
|
+
-----
|
|
365
|
+
- If `unit_slug` is an instance of `EntityUnitModel`, the queryset is filtered using `journal_entry__entity_unit=unit_slug`.
|
|
366
|
+
- If `unit_slug` is a string, the queryset is filtered using `journal_entry__entity_unit__slug__exact=unit_slug`.
|
|
313
367
|
"""
|
|
314
368
|
qs = self.for_entity(user_model=user_model, entity_slug=entity_slug)
|
|
315
369
|
if isinstance(unit_slug, EntityUnitModel):
|
|
@@ -322,24 +376,23 @@ class TransactionModelAdmin(models.Manager):
|
|
|
322
376
|
je_model,
|
|
323
377
|
user_model: Optional[UserModel] = None):
|
|
324
378
|
"""
|
|
325
|
-
Fetches a QuerySet of TransactionModels that the UserModel as access to and are associated with a specific
|
|
326
|
-
LedgerModel AND JournalEntryModel instance.
|
|
327
|
-
|
|
328
379
|
Parameters
|
|
329
380
|
----------
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
The
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
381
|
+
entity_slug : Union[EntityModel, str]
|
|
382
|
+
The entity slug or instance of EntityModel representing the entity for which the journal entry is requested.
|
|
383
|
+
ledger_model : Union[LedgerModel, str, UUID]
|
|
384
|
+
The ledger model or its identifier (str or UUID) representing the ledger for which the journal entry
|
|
385
|
+
is requested.
|
|
386
|
+
je_model : Type[JournalEntryModel]
|
|
387
|
+
The journal entry model or its identifier (str or UUID) representing the journal entry to filter by.
|
|
388
|
+
user_model : Optional[UserModel], default=None
|
|
389
|
+
An optional user model instance representing the user for whom the journal entry is requested.
|
|
338
390
|
|
|
339
391
|
Returns
|
|
340
392
|
-------
|
|
341
|
-
|
|
342
|
-
|
|
393
|
+
QuerySet
|
|
394
|
+
The filtered queryset of journal entries.
|
|
395
|
+
|
|
343
396
|
"""
|
|
344
397
|
qs = self.for_ledger(user_model=user_model,
|
|
345
398
|
entity_slug=entity_slug,
|
|
@@ -354,22 +407,20 @@ class TransactionModelAdmin(models.Manager):
|
|
|
354
407
|
entity_slug: str,
|
|
355
408
|
bill_model: Union[BillModel, str, UUID]):
|
|
356
409
|
"""
|
|
357
|
-
Fetches a QuerySet of TransactionModels that the UserModel as access to and are associated with a specific
|
|
358
|
-
BillModel instance.
|
|
359
|
-
|
|
360
410
|
Parameters
|
|
361
411
|
----------
|
|
362
|
-
user_model
|
|
363
|
-
|
|
364
|
-
entity_slug: str
|
|
365
|
-
The
|
|
366
|
-
bill_model: BillModel
|
|
367
|
-
|
|
412
|
+
user_model : Type
|
|
413
|
+
An instance of user model.
|
|
414
|
+
entity_slug : str
|
|
415
|
+
The slug of the entity.
|
|
416
|
+
bill_model : Union[BillModel, str, UUID]
|
|
417
|
+
An instance of bill model or a string/UUID representing the UUID of the bill model.
|
|
368
418
|
|
|
369
419
|
Returns
|
|
370
420
|
-------
|
|
371
|
-
|
|
372
|
-
|
|
421
|
+
FilterQuerySet
|
|
422
|
+
A filtered queryset based on the user model, entity slug, and bill model.
|
|
423
|
+
|
|
373
424
|
"""
|
|
374
425
|
qs = self.for_entity(
|
|
375
426
|
user_model=user_model,
|
|
@@ -383,22 +434,19 @@ class TransactionModelAdmin(models.Manager):
|
|
|
383
434
|
entity_slug: str,
|
|
384
435
|
invoice_model: Union[InvoiceModel, str, UUID]):
|
|
385
436
|
"""
|
|
386
|
-
Fetches a QuerySet of TransactionModels that the UserModel as access to and are associated with a specific
|
|
387
|
-
InvoiceModel instance.
|
|
388
|
-
|
|
389
437
|
Parameters
|
|
390
438
|
----------
|
|
391
|
-
user_model
|
|
392
|
-
|
|
393
|
-
entity_slug: str
|
|
394
|
-
The
|
|
395
|
-
invoice_model: InvoiceModel
|
|
396
|
-
The
|
|
439
|
+
user_model : [type]
|
|
440
|
+
The user model used for filtering entities.
|
|
441
|
+
entity_slug : str
|
|
442
|
+
The slug of the entity used for filtering.
|
|
443
|
+
invoice_model : Union[InvoiceModel, str, UUID]
|
|
444
|
+
The invoice model or its identifier used for filtering.
|
|
397
445
|
|
|
398
446
|
Returns
|
|
399
447
|
-------
|
|
400
|
-
|
|
401
|
-
|
|
448
|
+
QuerySet
|
|
449
|
+
The filtered queryset based on the specified parameters.
|
|
402
450
|
"""
|
|
403
451
|
qs = self.for_entity(
|
|
404
452
|
user_model=user_model,
|
|
@@ -410,27 +458,46 @@ class TransactionModelAdmin(models.Manager):
|
|
|
410
458
|
|
|
411
459
|
class TransactionModelAbstract(CreateUpdateMixIn):
|
|
412
460
|
"""
|
|
413
|
-
This is the main abstract class which the TransactionModel database will inherit from.
|
|
414
|
-
The TransactionModel inherits functionality from the following MixIns:
|
|
415
461
|
|
|
416
|
-
|
|
462
|
+
TransactionModelAbstract
|
|
463
|
+
|
|
464
|
+
An abstract class that represents a transaction in the ledger system.
|
|
417
465
|
|
|
418
466
|
Attributes
|
|
419
467
|
----------
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
468
|
+
|
|
469
|
+
- CREDIT: A constant representing a credit transaction.
|
|
470
|
+
- DEBIT: A constant representing a debit transaction.
|
|
471
|
+
|
|
472
|
+
- TX_TYPE: A list of tuples representing the transaction type choices.
|
|
473
|
+
|
|
474
|
+
- uuid: A UUIDField representing the unique identifier of the transaction.
|
|
475
|
+
This field is automatically generated and is not editable.
|
|
476
|
+
|
|
477
|
+
- tx_type: A CharField representing the type of the transaction.
|
|
478
|
+
It has a maximum length of 10 characters and accepts choices from the TX_TYPE list.
|
|
479
|
+
|
|
480
|
+
- journal_entry: A ForeignKey representing the journal entry associated with the transaction.
|
|
481
|
+
It references the 'django_ledger.JournalEntryModel' model.
|
|
482
|
+
|
|
483
|
+
- account: A ForeignKey representing the account associated with the transaction.
|
|
484
|
+
It references the 'django_ledger.AccountModel' model.
|
|
485
|
+
|
|
486
|
+
- amount: A DecimalField representing the amount of the transaction.
|
|
487
|
+
It has a maximum of 2 decimal places and a maximum of 20 digits.
|
|
488
|
+
It defaults to 0.00 and accepts a minimum value of 0.
|
|
489
|
+
|
|
490
|
+
- description: A CharField representing the description of the transaction.
|
|
491
|
+
It has a maximum length of 100 characters and is optional.
|
|
492
|
+
|
|
493
|
+
- objects: An instance of the TransactionModelAdmin class.
|
|
494
|
+
|
|
495
|
+
Methods
|
|
496
|
+
-------
|
|
497
|
+
|
|
498
|
+
- clean(): Performs validation on the transaction instance.
|
|
499
|
+
Raises a TransactionModelValidationError if the account is a root account.
|
|
500
|
+
|
|
434
501
|
"""
|
|
435
502
|
|
|
436
503
|
CREDIT = 'credit'
|
|
@@ -463,7 +530,8 @@ class TransactionModelAbstract(CreateUpdateMixIn):
|
|
|
463
530
|
blank=True,
|
|
464
531
|
verbose_name=_('Tx Description'),
|
|
465
532
|
help_text=_('A description to be included with this individual transaction'))
|
|
466
|
-
|
|
533
|
+
|
|
534
|
+
objects = TransactionModelAdmin()
|
|
467
535
|
|
|
468
536
|
class Meta:
|
|
469
537
|
abstract = True
|
|
@@ -499,9 +567,39 @@ class TransactionModel(TransactionModelAbstract):
|
|
|
499
567
|
|
|
500
568
|
|
|
501
569
|
def transactionmodel_presave(instance: TransactionModel, **kwargs):
|
|
502
|
-
|
|
570
|
+
"""
|
|
571
|
+
Parameters
|
|
572
|
+
----------
|
|
573
|
+
instance : TransactionModel
|
|
574
|
+
The transaction model instance that is being saved.
|
|
575
|
+
kwargs : dict
|
|
576
|
+
Additional keyword arguments.
|
|
577
|
+
|
|
578
|
+
Notes
|
|
579
|
+
-----
|
|
580
|
+
This method is called before saving a transaction model instance.
|
|
581
|
+
It performs some checks before allowing the save operation.
|
|
582
|
+
|
|
583
|
+
Raises
|
|
584
|
+
------
|
|
585
|
+
TransactionModelValidationError
|
|
586
|
+
If one of the following conditions is met:
|
|
587
|
+
- `bypass_account_state` is False and the `can_transact` method of the associated account model returns False.
|
|
588
|
+
- The journal entry associated with the transaction is locked.
|
|
589
|
+
|
|
590
|
+
"""
|
|
591
|
+
bypass_account_state = kwargs.get('bypass_account_state', False)
|
|
592
|
+
if all([
|
|
593
|
+
not bypass_account_state,
|
|
594
|
+
not instance.account.can_transact()
|
|
595
|
+
]):
|
|
596
|
+
raise TransactionModelValidationError(
|
|
597
|
+
message=_(f'Cannot create or modify transactions on account model {instance.account}.')
|
|
598
|
+
)
|
|
599
|
+
|
|
600
|
+
if instance.journal_entry.is_locked():
|
|
503
601
|
raise TransactionModelValidationError(
|
|
504
|
-
message=_('Cannot modify transactions on locked journal entries')
|
|
602
|
+
message=_('Cannot modify transactions on locked journal entries.')
|
|
505
603
|
)
|
|
506
604
|
|
|
507
605
|
|